summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtchang%redhat.com <devnull@localhost>2006-02-03 22:31:50 +0000
committerwtchang%redhat.com <devnull@localhost>2006-02-03 22:31:50 +0000
commit71dd583dd38e670fde0e6911918c88e8f6e658a4 (patch)
tree9d50fec28ff1dfb646edf62d33a23f4a3f986c76
parent2e6af2f66e7ff350c552d4fd48b2c4670f5096f7 (diff)
downloadnss-hg-71dd583dd38e670fde0e6911918c88e8f6e658a4.tar.gz
Bugzilla Bug 317620: upgraded the NSS version on the MOZILLA_1_8_BRANCH to
NSS 3.11.1 Beta. Tag: MOZILLA_1_8_BRANCH
-rw-r--r--security/coreconf/AIX.mk2
-rw-r--r--security/coreconf/BSD_OS.mk2
-rw-r--r--security/coreconf/Darwin.mk5
-rw-r--r--security/coreconf/FreeBSD.mk6
-rw-r--r--security/coreconf/HP-UX.mk18
-rw-r--r--[-rwxr-xr-x]security/coreconf/HP-UXB.11.23.mk (renamed from security/coreconf/nsinstall/nfspwd)35
-rw-r--r--security/coreconf/HP-UXB.11.mk20
-rw-r--r--security/coreconf/IRIX.mk2
-rw-r--r--security/coreconf/Linux.mk30
-rw-r--r--security/coreconf/Linux2.1.mk7
-rw-r--r--security/coreconf/Linux2.2.mk7
-rw-r--r--security/coreconf/Linux2.4.mk7
-rw-r--r--security/coreconf/Linux2.5.mk7
-rw-r--r--security/coreconf/Linux2.6.mk9
-rw-r--r--security/coreconf/NCR3.0.mk2
-rw-r--r--security/coreconf/NEC4.2.mk2
-rw-r--r--security/coreconf/NetBSD.mk2
-rw-r--r--security/coreconf/OS2.mk21
-rw-r--r--security/coreconf/OSF1.mk2
-rw-r--r--security/coreconf/OpenUNIX.mk2
-rwxr-xr-xsecurity/coreconf/OpenVMS.mk7
-rw-r--r--security/coreconf/ReliantUNIX.mk2
-rw-r--r--security/coreconf/SCO_SV3.2.mk2
-rw-r--r--security/coreconf/SunOS5.mk20
-rw-r--r--security/coreconf/UNIXWARE2.1.mk2
-rw-r--r--security/coreconf/WIN16.mk2
-rw-r--r--security/coreconf/WIN32.mk2
-rw-r--r--security/coreconf/WINCE.mk2
-rw-r--r--security/coreconf/WINNT5.2.mk (renamed from security/nss/cmd/lib/makefile.win)59
-rw-r--r--security/coreconf/arch.mk19
-rw-r--r--security/coreconf/command.mk1
-rwxr-xr-xsecurity/coreconf/import.pl1
-rw-r--r--security/coreconf/jdk.mk143
-rw-r--r--security/coreconf/location.mk8
-rw-r--r--security/coreconf/makefile.win104
-rw-r--r--security/coreconf/nsinstall/Makefile4
-rw-r--r--security/coreconf/nsinstall/nfspwd.pl50
-rwxr-xr-xsecurity/coreconf/release.pl27
-rw-r--r--security/coreconf/rules.mk29
-rw-r--r--security/coreconf/ruleset.mk3
-rw-r--r--security/nss/cmd/Makefile4
-rw-r--r--security/nss/cmd/SSLsample/Makefile.NSS62
-rw-r--r--security/nss/cmd/SSLsample/README8
-rwxr-xr-xsecurity/nss/cmd/SSLsample/nmakefilent.nss63
-rw-r--r--security/nss/cmd/SSLsample/server.c3
-rw-r--r--security/nss/cmd/SSLsample/sslsample.c6
-rw-r--r--security/nss/cmd/atob/makefile.win159
-rw-r--r--security/nss/cmd/bltest/blapitest.c7
-rw-r--r--security/nss/cmd/btoa/makefile.win134
-rw-r--r--security/nss/cmd/certutil/certutil.c211
-rw-r--r--security/nss/cmd/certutil/makefile.win159
-rw-r--r--security/nss/cmd/checkcert/makefile.win134
-rw-r--r--security/nss/cmd/crlutil/makefile.win134
-rw-r--r--security/nss/cmd/crmftest/Makefile6
-rw-r--r--security/nss/cmd/crmftest/testcrmf.c104
-rw-r--r--security/nss/cmd/dbtest/makefile.win134
-rw-r--r--security/nss/cmd/derdump/makefile.win134
-rw-r--r--security/nss/cmd/digest/makefile.win134
-rwxr-xr-xsecurity/nss/cmd/fipstest/Makefile171
-rw-r--r--security/nss/cmd/fipstest/aes.sh94
-rw-r--r--security/nss/cmd/fipstest/ecdsa.sh29
-rw-r--r--security/nss/cmd/fipstest/fipstest.c3884
-rwxr-xr-xsecurity/nss/cmd/fipstest/hmac.sh20
-rw-r--r--security/nss/cmd/fipstest/manifest.mn112
-rw-r--r--security/nss/cmd/fipstest/sha.sh46
-rw-r--r--security/nss/cmd/fipstest/tdea.sh87
-rw-r--r--security/nss/cmd/lib/secutil.c10
-rw-r--r--security/nss/cmd/makefile.inc88
-rw-r--r--security/nss/cmd/makepqg/makefile.win160
-rw-r--r--security/nss/cmd/manifest.mn5
-rw-r--r--security/nss/cmd/modutil/modutil.c5
-rw-r--r--security/nss/cmd/pk11util/pk11table.c40
-rw-r--r--security/nss/cmd/pk11util/pk11util.c125
-rw-r--r--security/nss/cmd/pk11util/pk11util.h6
-rw-r--r--security/nss/cmd/pk11util/scripts/dosign162
-rw-r--r--security/nss/cmd/pk11util/scripts/lcert35
-rw-r--r--security/nss/cmd/pk11util/scripts/mechanisms11
-rw-r--r--security/nss/cmd/pk11util/scripts/pLabel16
-rw-r--r--security/nss/cmd/pk11util/scripts/pMechanisms8
-rw-r--r--security/nss/cmd/pk11util/scripts/pcert30
-rw-r--r--security/nss/cmd/pk12util/pk12util.c3
-rw-r--r--security/nss/cmd/platlibs.mk56
-rw-r--r--security/nss/cmd/pwdecrypt/pwdecrypt.c27
-rw-r--r--security/nss/cmd/rsaperf/rsaperf.c2
-rw-r--r--security/nss/cmd/selfserv/makefile.win140
-rw-r--r--security/nss/cmd/selfserv/selfserv.c48
-rw-r--r--security/nss/cmd/shlibsign/Makefile29
-rw-r--r--security/nss/cmd/shlibsign/manifest.mn2
-rw-r--r--security/nss/cmd/shlibsign/shlibsign.c14
-rw-r--r--security/nss/cmd/shlibsign/sign.cmd6
-rw-r--r--security/nss/cmd/shlibsign/sign.sh33
-rw-r--r--security/nss/cmd/signtool/javascript.c4
-rw-r--r--security/nss/cmd/signver/signver.c57
-rw-r--r--security/nss/cmd/ssltap/config.mk56
-rw-r--r--security/nss/cmd/ssltap/ssltap.c49
-rw-r--r--security/nss/cmd/strsclnt/strsclnt.c348
-rw-r--r--security/nss/cmd/tstclnt/makefile.win134
-rw-r--r--security/nss/cmd/tstclnt/tstclnt.c39
-rw-r--r--security/nss/cmd/vfyserv/makefile.win134
-rw-r--r--security/nss/cmd/vfyserv/vfyserv.c2
-rw-r--r--security/nss/cmd/vfyserv/vfyutil.c6
-rw-r--r--security/nss/lib/certdb/certdb.c44
-rw-r--r--security/nss/lib/certdb/certdb.h7
-rw-r--r--security/nss/lib/certdb/certt.h15
-rw-r--r--security/nss/lib/certdb/genname.c2
-rw-r--r--security/nss/lib/certhigh/certhigh.c8
-rw-r--r--security/nss/lib/certhigh/certhtml.c15
-rw-r--r--security/nss/lib/certhigh/certreq.c165
-rw-r--r--security/nss/lib/certhigh/crlv2.c5
-rw-r--r--security/nss/lib/certhigh/ocsp.c7
-rw-r--r--security/nss/lib/ckfw/builtins/Makefile27
-rw-r--r--security/nss/lib/ckfw/builtins/nssckbi.h7
-rw-r--r--security/nss/lib/ckfw/capi/Makefile (renamed from security/nss/cmd/modutil/config.mk)100
-rw-r--r--security/nss/lib/ckfw/capi/README7
-rw-r--r--security/nss/lib/ckfw/capi/anchor.c55
-rw-r--r--security/nss/lib/ckfw/capi/cfind.c595
-rw-r--r--security/nss/lib/ckfw/capi/cinst.c148
-rw-r--r--security/nss/lib/ckfw/capi/ckcapi.h309
-rw-r--r--security/nss/lib/ckfw/capi/ckcapiver.c59
-rw-r--r--security/nss/lib/ckfw/capi/cobject.c2346
-rw-r--r--[-rwxr-xr-x]security/nss/lib/ckfw/capi/config.mk (renamed from security/nss/cmd/SSLsample/nmakefile95.nss)45
-rw-r--r--security/nss/lib/ckfw/capi/constants.c98
-rw-r--r--security/nss/lib/ckfw/capi/crsa.c748
-rw-r--r--security/nss/lib/ckfw/capi/csession.c131
-rw-r--r--security/nss/lib/ckfw/capi/cslot.c129
-rw-r--r--security/nss/lib/ckfw/capi/ctoken.c246
-rw-r--r--security/nss/lib/ckfw/capi/manifest.mn (renamed from security/nss/cmd/makefile.win)34
-rw-r--r--security/nss/lib/ckfw/capi/nsscapi.def58
-rw-r--r--security/nss/lib/ckfw/capi/nsscapi.h75
-rw-r--r--security/nss/lib/ckfw/capi/nsscapi.rc97
-rw-r--r--security/nss/lib/ckfw/capi/staticobj.c74
-rw-r--r--security/nss/lib/ckfw/ckfwm.h7
-rw-r--r--security/nss/lib/ckfw/manifest.mn1
-rw-r--r--security/nss/lib/ckfw/mutex.c56
-rw-r--r--security/nss/lib/ckfw/wrap.c49
-rw-r--r--security/nss/lib/crmf/cmmfrec.c32
-rw-r--r--security/nss/lib/cryptohi/hasht.h4
-rw-r--r--security/nss/lib/cryptohi/keyhi.h2
-rw-r--r--security/nss/lib/cryptohi/manifest.mn5
-rw-r--r--security/nss/lib/cryptohi/sechash.c28
-rw-r--r--security/nss/lib/cryptohi/seckey.c30
-rw-r--r--security/nss/lib/cryptohi/secsign.c65
-rw-r--r--security/nss/lib/cryptohi/secvfy.c142
-rw-r--r--security/nss/lib/freebl/Makefile354
-rw-r--r--security/nss/lib/freebl/aeskeywrap.c59
-rw-r--r--security/nss/lib/freebl/alg2268.c66
-rw-r--r--security/nss/lib/freebl/alghmac.c (renamed from security/nss/lib/softoken/alghmac.c)79
-rw-r--r--security/nss/lib/freebl/alghmac.h (renamed from security/nss/lib/softoken/alghmac.h)11
-rw-r--r--security/nss/lib/freebl/arcfour-amd64-gas.s4
-rw-r--r--security/nss/lib/freebl/arcfour.c46
-rw-r--r--security/nss/lib/freebl/blapi.h74
-rw-r--r--security/nss/lib/freebl/blapit.h23
-rw-r--r--security/nss/lib/freebl/config.mk67
-rw-r--r--security/nss/lib/freebl/desblapi.c34
-rw-r--r--security/nss/lib/freebl/dsa.c167
-rw-r--r--security/nss/lib/freebl/ec.c177
-rw-r--r--security/nss/lib/freebl/ecl/ec2.h3
-rw-r--r--security/nss/lib/freebl/ecl/ec2_aff.c76
-rw-r--r--security/nss/lib/freebl/ecl/ecl-curve.h4
-rw-r--r--security/nss/lib/freebl/ecl/ecl-priv.h1
-rw-r--r--security/nss/lib/freebl/ecl/ecl.c22
-rw-r--r--security/nss/lib/freebl/ecl/ecl.h7
-rw-r--r--security/nss/lib/freebl/ecl/ecl_mult.c45
-rw-r--r--security/nss/lib/freebl/ecl/ecp.h3
-rw-r--r--security/nss/lib/freebl/ecl/ecp_aff.c73
-rw-r--r--security/nss/lib/freebl/ecl/ecp_jm.c2
-rw-r--r--security/nss/lib/freebl/ecl/tests/ec2_test.c13
-rw-r--r--security/nss/lib/freebl/ecl/tests/ecp_test.c13
-rw-r--r--security/nss/lib/freebl/freebl.def58
-rw-r--r--security/nss/lib/freebl/freeblver.c56
-rw-r--r--security/nss/lib/freebl/ldvector.c48
-rw-r--r--security/nss/lib/freebl/loader.c594
-rw-r--r--security/nss/lib/freebl/loader.h74
-rw-r--r--security/nss/lib/freebl/manifest.mn62
-rw-r--r--security/nss/lib/freebl/md2.c5
-rw-r--r--security/nss/lib/freebl/md5.c25
-rw-r--r--security/nss/lib/freebl/mpi/Makefile3
-rw-r--r--security/nss/lib/freebl/mpi/mp_comba.c1306
-rw-r--r--security/nss/lib/freebl/mpi/mp_comba_amd64_sun.s16097
-rw-r--r--security/nss/lib/freebl/mpi/mpcpucache.c773
-rw-r--r--security/nss/lib/freebl/mpi/mpcpucache_amd64.s891
-rw-r--r--security/nss/lib/freebl/mpi/mpcpucache_x86.s931
-rw-r--r--security/nss/lib/freebl/mpi/mpi-priv.h29
-rw-r--r--security/nss/lib/freebl/mpi/mpi.c48
-rw-r--r--security/nss/lib/freebl/mpi/mpi_amd64_gas.s4
-rw-r--r--security/nss/lib/freebl/mpi/mpmontg.c632
-rw-r--r--security/nss/lib/freebl/mpi/mpv_sparcv8.s148
-rw-r--r--security/nss/lib/freebl/mpi/mpv_sparcv8x.s175
-rw-r--r--security/nss/lib/freebl/mpi/target.mk3
-rw-r--r--security/nss/lib/freebl/pqg.c13
-rw-r--r--security/nss/lib/freebl/prng_fips1861.c355
-rw-r--r--security/nss/lib/freebl/rawhash.c (renamed from security/nss/lib/softoken/rawhash.c)42
-rw-r--r--security/nss/lib/freebl/ret_cr16.s (renamed from security/nss/lib/util/ret_cr16.s)0
-rw-r--r--security/nss/lib/freebl/rijndael.c68
-rw-r--r--security/nss/lib/freebl/rijndael.h41
-rw-r--r--security/nss/lib/freebl/secmpi.h1
-rw-r--r--security/nss/lib/freebl/sha-fast-amd64-sun.s2142
-rw-r--r--security/nss/lib/freebl/sha512.c15
-rw-r--r--security/nss/lib/freebl/sha_fast.c500
-rw-r--r--security/nss/lib/freebl/sha_fast.h130
-rw-r--r--security/nss/lib/freebl/tlsprfalg.c164
-rw-r--r--security/nss/lib/manifest.mn4
-rw-r--r--security/nss/lib/nss/config.mk10
-rw-r--r--security/nss/lib/nss/nss.def15
-rw-r--r--security/nss/lib/nss/nss.h47
-rw-r--r--security/nss/lib/nss/nssinit.c54
-rw-r--r--security/nss/lib/pk11wrap/manifest.mn5
-rw-r--r--security/nss/lib/pk11wrap/pk11akey.c894
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c394
-rw-r--r--security/nss/lib/pk11wrap/pk11err.c6
-rw-r--r--security/nss/lib/pk11wrap/pk11load.c77
-rw-r--r--security/nss/lib/pk11wrap/pk11mech.c7
-rw-r--r--security/nss/lib/pk11wrap/pk11nobj.c152
-rw-r--r--security/nss/lib/pk11wrap/pk11obj.c44
-rw-r--r--security/nss/lib/pk11wrap/pk11pars.c4
-rw-r--r--security/nss/lib/pk11wrap/pk11pqg.c6
-rw-r--r--security/nss/lib/pk11wrap/pk11priv.h8
-rw-r--r--security/nss/lib/pk11wrap/pk11pub.h91
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c328
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c239
-rw-r--r--security/nss/lib/pk11wrap/pk11util.c273
-rw-r--r--security/nss/lib/pk11wrap/secmodi.h3
-rw-r--r--security/nss/lib/pk11wrap/secmodt.h1
-rw-r--r--security/nss/lib/pk11wrap/secmodti.h28
-rw-r--r--security/nss/lib/pkcs12/manifest.mn4
-rw-r--r--security/nss/lib/pkcs12/p12d.c59
-rw-r--r--security/nss/lib/pkcs12/p12e.c15
-rw-r--r--security/nss/lib/pkcs7/p7decode.c20
-rw-r--r--security/nss/lib/pkcs7/p7encode.c8
-rw-r--r--security/nss/lib/pkcs7/p7local.c24
-rw-r--r--security/nss/lib/pki/certificate.c99
-rw-r--r--security/nss/lib/pki/pkim.h7
-rw-r--r--security/nss/lib/pki/pkistore.c21
-rw-r--r--security/nss/lib/pki/pkitm.h10
-rw-r--r--security/nss/lib/pki/tdcache.c18
-rw-r--r--security/nss/lib/smime/cmscipher.c26
-rw-r--r--security/nss/lib/smime/cmsencdata.c10
-rw-r--r--security/nss/lib/smime/cmsenvdata.c10
-rw-r--r--security/nss/lib/smime/cmsrecinfo.c19
-rw-r--r--security/nss/lib/smime/cmsreclist.c3
-rw-r--r--security/nss/lib/smime/cmssiginfo.c20
-rw-r--r--security/nss/lib/smime/cmsutil.c10
-rw-r--r--security/nss/lib/smime/config.mk11
-rw-r--r--security/nss/lib/softoken/cdbhdl.h4
-rw-r--r--security/nss/lib/softoken/config.mk13
-rw-r--r--security/nss/lib/softoken/dbinit.c49
-rw-r--r--security/nss/lib/softoken/fipstest.c476
-rw-r--r--security/nss/lib/softoken/fipstokn.c114
-rw-r--r--security/nss/lib/softoken/keydb.c279
-rw-r--r--security/nss/lib/softoken/keydbi.h2
-rw-r--r--security/nss/lib/softoken/lowcert.c49
-rw-r--r--security/nss/lib/softoken/lowpbe.c6
-rw-r--r--security/nss/lib/softoken/manifest.mn3
-rw-r--r--security/nss/lib/softoken/pcert.h3
-rw-r--r--security/nss/lib/softoken/pcertdb.c103
-rw-r--r--security/nss/lib/softoken/pk11db.c18
-rw-r--r--security/nss/lib/softoken/pk11pars.h21
-rw-r--r--security/nss/lib/softoken/pkcs11.c886
-rw-r--r--security/nss/lib/softoken/pkcs11c.c337
-rw-r--r--security/nss/lib/softoken/pkcs11f.h14
-rw-r--r--security/nss/lib/softoken/pkcs11i.h119
-rw-r--r--security/nss/lib/softoken/pkcs11n.h10
-rw-r--r--security/nss/lib/softoken/pkcs11ni.h52
-rw-r--r--security/nss/lib/softoken/pkcs11t.h656
-rw-r--r--security/nss/lib/softoken/pkcs11u.c823
-rw-r--r--security/nss/lib/softoken/tlsprf.c126
-rw-r--r--security/nss/lib/ssl/config.mk38
-rw-r--r--security/nss/lib/ssl/derive.c481
-rw-r--r--security/nss/lib/ssl/manifest.mn6
-rw-r--r--security/nss/lib/ssl/nsskea.c6
-rw-r--r--security/nss/lib/ssl/preenc.h94
-rw-r--r--security/nss/lib/ssl/prelib.c197
-rw-r--r--security/nss/lib/ssl/ssl.h18
-rw-r--r--security/nss/lib/ssl/ssl3con.c4326
-rw-r--r--security/nss/lib/ssl/ssl3ecc.c673
-rw-r--r--security/nss/lib/ssl/ssl3gthr.c8
-rw-r--r--security/nss/lib/ssl/ssl3prot.h19
-rw-r--r--security/nss/lib/ssl/sslauth.c9
-rw-r--r--security/nss/lib/ssl/sslcon.c124
-rw-r--r--security/nss/lib/ssl/ssldef.c2
-rw-r--r--security/nss/lib/ssl/sslenum.c5
-rw-r--r--security/nss/lib/ssl/sslgathr.c14
-rw-r--r--security/nss/lib/ssl/sslimpl.h257
-rw-r--r--security/nss/lib/ssl/sslinfo.c59
-rw-r--r--security/nss/lib/ssl/sslnonce.c2
-rw-r--r--security/nss/lib/ssl/sslproto.h6
-rw-r--r--security/nss/lib/ssl/sslsecur.c135
-rw-r--r--security/nss/lib/ssl/sslsnce.c23
-rw-r--r--security/nss/lib/ssl/sslsock.c394
-rw-r--r--security/nss/lib/ssl/sslt.h6
-rw-r--r--security/nss/lib/util/Makefile6
-rw-r--r--security/nss/lib/util/quickder.c10
-rw-r--r--security/nss/lib/util/secasn1.h7
-rw-r--r--security/nss/makefile.win104
-rw-r--r--security/nss/pkg/linux/Makefile31
-rw-r--r--security/nss/pkg/linux/sun-nss.spec2
-rw-r--r--security/nss/pkg/solaris/SUNWtls/prototype_i3868
-rw-r--r--security/nss/pkg/solaris/SUNWtls/prototype_sparc28
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsd/prototype2
-rwxr-xr-xsecurity/nss/tests/all.sh3
-rwxr-xr-xsecurity/nss/tests/cert/cert.sh4
-rw-r--r--security/nss/tests/cert/eccert.sh6
-rwxr-xr-xsecurity/nss/tests/cert/noeccert.sh658
-rw-r--r--security/nss/tests/crmf/crmf.sh121
-rwxr-xr-xsecurity/nss/tests/fixtests.sh7
-rw-r--r--security/nss/tests/smime/ecsmime.sh260
-rwxr-xr-xsecurity/nss/tests/smime/smime.sh88
-rwxr-xr-xsecurity/nss/tests/ssl/ssl.sh95
-rw-r--r--security/nss/tests/tools/noectools.sh193
309 files changed, 44385 insertions, 12924 deletions
diff --git a/security/coreconf/AIX.mk b/security/coreconf/AIX.mk
index b0841b695..255be17b4 100644
--- a/security/coreconf/AIX.mk
+++ b/security/coreconf/AIX.mk
@@ -84,7 +84,7 @@ else
DSO_LDOPTS += -bexpall
endif
-PROCESS_MAP_FILE = grep -v ';+' $(LIBRARY_NAME).def | grep -v ';-' | \
+PROCESS_MAP_FILE = grep -v ';+' $< | grep -v ';-' | \
sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' > $@
ifdef BUILD_OPT
diff --git a/security/coreconf/BSD_OS.mk b/security/coreconf/BSD_OS.mk
index 8b9fe68b7..e9492c11b 100644
--- a/security/coreconf/BSD_OS.mk
+++ b/security/coreconf/BSD_OS.mk
@@ -84,7 +84,7 @@ ifdef MAPFILE
# Add LD options to restrict exported symbols to those in the map file
endif
# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = cp $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = cp $< $@
G++INCLUDES = -I/usr/include/g++
diff --git a/security/coreconf/Darwin.mk b/security/coreconf/Darwin.mk
index a8e434821..83f568bf3 100644
--- a/security/coreconf/Darwin.mk
+++ b/security/coreconf/Darwin.mk
@@ -59,7 +59,7 @@ ifneq (,$(MACOS_SDK_DIR))
ifeq (,$(filter-out 2 3,$(GCC_VERSION_MAJOR)))
# GCC <= 3
- DARWIN_SDK_FRAMEWORKS = -F$(MACOS_SDK_DIR)/System/Library/Frameworks
+ DARWIN_SDK_FRAMEWORKS = -F$(MACOS_SDK_DIR)/System/Library/Frameworks
ifneq (,$(shell find $(MACOS_SDK_DIR)/Library/Frameworks -maxdepth 0))
DARWIN_SDK_FRAMEWORKS += -F$(MACOS_SDK_DIR)/Library/Frameworks
endif
@@ -105,12 +105,13 @@ endif
ARCH = darwin
+DSO_CFLAGS = -fPIC
# May override this with -bundle to create a loadable module.
DSO_LDOPTS = -dynamiclib -compatibility_version 1 -current_version 1 -install_name @executable_path/$(notdir $@) -headerpad_max_install_names $(DARWIN_SDK_DSOFLAGS)
MKSHLIB = $(CC) -arch $(CPU_ARCH) $(DSO_LDOPTS)
DLL_SUFFIX = dylib
-PROCESS_MAP_FILE = grep -v ';+' $(LIBRARY_NAME).def | grep -v ';-' | \
+PROCESS_MAP_FILE = grep -v ';+' $< | grep -v ';-' | \
sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,^,_,' > $@
G++INCLUDES = -I/usr/include/g++
diff --git a/security/coreconf/FreeBSD.mk b/security/coreconf/FreeBSD.mk
index d8cf2dec1..e0ac591dc 100644
--- a/security/coreconf/FreeBSD.mk
+++ b/security/coreconf/FreeBSD.mk
@@ -75,10 +75,10 @@ endif
MKSHLIB = $(CC) $(DSO_LDOPTS)
ifdef MAPFILE
-# Add LD options to restrict exported symbols to those in the map file
+ MKSHLIB += -Wl,--version-script,$(MAPFILE)
endif
-# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = cp $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = grep -v ';-' $< | \
+ sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
G++INCLUDES = -I/usr/include/g++
diff --git a/security/coreconf/HP-UX.mk b/security/coreconf/HP-UX.mk
index a16eab8d9..ef895337d 100644
--- a/security/coreconf/HP-UX.mk
+++ b/security/coreconf/HP-UX.mk
@@ -43,8 +43,17 @@ include $(CORE_DEPTH)/coreconf/UNIX.mk
DEFAULT_COMPILER = cc
-CPU_ARCH = hppa
-DLL_SUFFIX = sl
+ifeq ($(OS_TEST),ia64)
+ CPU_ARCH = ia64
+ CPU_TAG = _$(CPU_ARCH)
+ ifneq ($(USE_64),1)
+ 64BIT_TAG = _32
+ endif
+ DLL_SUFFIX = so
+else
+ CPU_ARCH = hppa
+ DLL_SUFFIX = sl
+endif
CC = cc
CCC = CC
OS_CFLAGS += -Ae $(DSO_CFLAGS) -DHPUX -D$(CPU_ARCH) -D_HPUX_SOURCE -D_USE_BIG_FDS
@@ -71,10 +80,13 @@ MKSHLIB = $(LD) $(DSO_LDOPTS)
ifdef MAPFILE
MKSHLIB += -c $(MAPFILE)
endif
-PROCESS_MAP_FILE = grep -v ';+' $(LIBRARY_NAME).def | grep -v ';-' | \
+PROCESS_MAP_FILE = grep -v ';+' $< | grep -v ';-' | \
sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,^,+e ,' > $@
DSO_LDOPTS = -b +h $(notdir $@)
+ifeq ($(OS_TEST),ia64)
+ DSO_LDOPTS += +b '$$ORIGIN'
+endif
DSO_LDFLAGS =
# +Z generates position independent code for use in shared libraries.
diff --git a/security/coreconf/nsinstall/nfspwd b/security/coreconf/HP-UXB.11.23.mk
index 66345aa07..392fc94c1 100755..100644
--- a/security/coreconf/nsinstall/nfspwd
+++ b/security/coreconf/HP-UXB.11.23.mk
@@ -1,4 +1,3 @@
-#! perl
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
@@ -17,7 +16,7 @@
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
+# Portions created by the Initial Developer are Copyright (C) 2002
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
@@ -36,15 +35,25 @@
#
# ***** END LICENSE BLOCK *****
-require "fastcwd.pl";
+# On HP-UX 10.30 and 11.x, the default implementation strategy is
+# pthreads. Classic nspr and pthreads-user are also available.
-$_ = &fastcwd;
-if (m@^/[uh]/@o || s@^/tmp_mnt/@/@o) {
- print("$_\n");
-} elsif ((($user, $rest) = m@^/usr/people/(\w+)/(.*)@o)
- && readlink("/u/$user") eq "/usr/people/$user") {
- print("/u/$user/$rest\n");
-} else {
- chop($host = `hostname`);
- print("/h/$host$_\n");
-}
+ifeq ($(OS_RELEASE),B.11.23)
+OS_CFLAGS += -DHPUX10
+DEFAULT_IMPL_STRATEGY = _PTH
+endif
+
+#
+# To use the true pthread (kernel thread) library on 10.30 and
+# 11.x, we should define _POSIX_C_SOURCE to be 199506L.
+# The _REENTRANT macro is deprecated.
+#
+
+ifdef USE_PTHREADS
+ OS_CFLAGS += -D_POSIX_C_SOURCE=199506L
+endif
+
+#
+# Config stuff for HP-UXB.11.x.
+#
+include $(CORE_DEPTH)/coreconf/HP-UXB.11.mk
diff --git a/security/coreconf/HP-UXB.11.mk b/security/coreconf/HP-UXB.11.mk
index 2afaa55ea..1fe74f918 100644
--- a/security/coreconf/HP-UXB.11.mk
+++ b/security/coreconf/HP-UXB.11.mk
@@ -36,15 +36,11 @@
# ***** END LICENSE BLOCK *****
include $(CORE_DEPTH)/coreconf/HP-UX.mk
-ifdef USE_LONG_LONGS
-USE_HYBRID = 1
-endif
-
ifndef NS_USE_GCC
CCC = /opt/aCC/bin/aCC -ext
ifeq ($(USE_64), 1)
ifeq ($(OS_TEST), ia64)
- OS_CFLAGS += -Aa +e +p +DD64
+ ARCHFLAG = -Aa +e +p +DD64
else
# Our HP-UX build machine has a strange problem. If
# a 64-bit PA-RISC executable calls getcwd() in a
@@ -57,27 +53,23 @@ ifndef NS_USE_GCC
# as a 32-bit PA-RISC executable for 64-bit PA-RISC
# builds. -- wtc 2003-06-03
ifdef INTERNAL_TOOLS
- OS_CFLAGS += +DAportable +DS2.0
+ ARCHFLAG = +DAportable +DS2.0
else
- OS_CFLAGS += -Aa +e +DA2.0W +DS2.0 +DChpux
+ ARCHFLAG = -Aa +e +DA2.0W +DS2.0 +DChpux
endif
endif
else
ifeq ($(OS_TEST), ia64)
- OS_CFLAGS += -Aa +e +p +DD32
+ ARCHFLAG = -Aa +e +p +DD32
else
- ifdef USE_HYBRID
- OS_CFLAGS += -Aa +e +DA2.0 +DS2.0
- else
- OS_CFLAGS += +DAportable +DS2.0
- endif
+ ARCHFLAG = +DAportable +DS2.0
endif
endif
else
CCC = aCC
endif
-OS_CFLAGS += -DHPUX11
+OS_CFLAGS += $(ARCHFLAG) -DHPUX11
OS_LIBS += -lpthread -lm -lrt
#ifeq ($(USE_64), 1)
#OS_LIBS += -ldl
diff --git a/security/coreconf/IRIX.mk b/security/coreconf/IRIX.mk
index 48882feb6..9d7cd8992 100644
--- a/security/coreconf/IRIX.mk
+++ b/security/coreconf/IRIX.mk
@@ -107,7 +107,7 @@ ifdef MAPFILE
# Add LD options to restrict exported symbols to those in the map file
endif
# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = cp $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = cp $< $@
DSO_LDOPTS = -elf -shared -all
diff --git a/security/coreconf/Linux.mk b/security/coreconf/Linux.mk
index 7907ce3c2..d87c4ce82 100644
--- a/security/coreconf/Linux.mk
+++ b/security/coreconf/Linux.mk
@@ -55,7 +55,14 @@ DEFAULT_COMPILER = gcc
ifeq ($(OS_TEST),m68k)
OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE
CPU_ARCH = m68k
-else
+else
+ifeq ($(OS_TEST),ppc64)
+ OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE
+ CPU_ARCH = ppc
+ifeq ($(USE_64),1)
+ ARCHFLAG = -m64
+endif
+else
ifeq ($(OS_TEST),ppc)
OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE
CPU_ARCH = ppc
@@ -69,9 +76,15 @@ ifeq ($(OS_TEST),ia64)
CPU_ARCH = ia64
else
ifeq ($(OS_TEST),x86_64)
+ifeq ($(USE_64),1)
OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE
CPU_ARCH = x86_64
else
+ OS_REL_CFLAGS = -DLINUX1_2 -Di386 -D_XOPEN_SOURCE
+ CPU_ARCH = x86
+ ARCHFLAG = -m32
+endif
+else
ifeq ($(OS_TEST),sparc)
OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE
CPU_ARCH = sparc
@@ -119,6 +132,7 @@ endif
endif
endif
endif
+endif
LIBC_TAG = _glibc
@@ -126,21 +140,22 @@ LIBC_TAG = _glibc
ifeq ($(OS_RELEASE),2.0)
OS_REL_CFLAGS += -DLINUX2_0
MKSHLIB = $(CC) -shared -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so)
- ifdef BUILD_OPT
- OPTIMIZER = -O2
- endif
ifdef MAPFILE
MKSHLIB += -Wl,--version-script,$(MAPFILE)
endif
- PROCESS_MAP_FILE = grep -v ';-' $(LIBRARY_NAME).def | \
+ PROCESS_MAP_FILE = grep -v ';-' $< | \
sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
endif
+ifdef BUILD_OPT
+ OPTIMIZER = -O2
+endif
+
ifeq ($(USE_PTHREADS),1)
OS_PTHREAD = -lpthread
endif
-OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -ansi -Wall -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR
+OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) -ansi -Wall -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR
OS_LIBS = $(OS_PTHREAD) -ldl -lc
ifdef USE_PTHREADS
@@ -150,8 +165,9 @@ endif
ARCH = linux
DSO_CFLAGS = -fPIC
-DSO_LDOPTS = -shared
+DSO_LDOPTS = -shared $(ARCHFLAG)
DSO_LDFLAGS =
+LDFLAGS += $(ARCHFLAG)
# INCLUDES += -I/usr/include -Y/usr/include/linux
G++INCLUDES = -I/usr/include/g++
diff --git a/security/coreconf/Linux2.1.mk b/security/coreconf/Linux2.1.mk
index 300659d4a..7569e1b10 100644
--- a/security/coreconf/Linux2.1.mk
+++ b/security/coreconf/Linux2.1.mk
@@ -38,14 +38,11 @@
include $(CORE_DEPTH)/coreconf/Linux.mk
ifeq ($(OS_RELEASE),2.1)
OS_REL_CFLAGS += -DLINUX2_1
- MKSHLIB = $(CC) -shared -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so)
- ifdef BUILD_OPT
- OPTIMIZER = -O2
- endif
+ MKSHLIB = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so)
ifdef MAPFILE
MKSHLIB += -Wl,--version-script,$(MAPFILE)
endif
- PROCESS_MAP_FILE = grep -v ';-' $(LIBRARY_NAME).def | \
+ PROCESS_MAP_FILE = grep -v ';-' $< | \
sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
endif
diff --git a/security/coreconf/Linux2.2.mk b/security/coreconf/Linux2.2.mk
index 72de8d55f..86bffef75 100644
--- a/security/coreconf/Linux2.2.mk
+++ b/security/coreconf/Linux2.2.mk
@@ -38,14 +38,11 @@
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
+MKSHLIB = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so)
ifdef MAPFILE
MKSHLIB += -Wl,--version-script,$(MAPFILE)
endif
-PROCESS_MAP_FILE = grep -v ';-' $(LIBRARY_NAME).def | \
+PROCESS_MAP_FILE = grep -v ';-' $< | \
sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
diff --git a/security/coreconf/Linux2.4.mk b/security/coreconf/Linux2.4.mk
index 72de8d55f..86bffef75 100644
--- a/security/coreconf/Linux2.4.mk
+++ b/security/coreconf/Linux2.4.mk
@@ -38,14 +38,11 @@
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
+MKSHLIB = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so)
ifdef MAPFILE
MKSHLIB += -Wl,--version-script,$(MAPFILE)
endif
-PROCESS_MAP_FILE = grep -v ';-' $(LIBRARY_NAME).def | \
+PROCESS_MAP_FILE = grep -v ';-' $< | \
sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
diff --git a/security/coreconf/Linux2.5.mk b/security/coreconf/Linux2.5.mk
index 72de8d55f..86bffef75 100644
--- a/security/coreconf/Linux2.5.mk
+++ b/security/coreconf/Linux2.5.mk
@@ -38,14 +38,11 @@
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
+MKSHLIB = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so)
ifdef MAPFILE
MKSHLIB += -Wl,--version-script,$(MAPFILE)
endif
-PROCESS_MAP_FILE = grep -v ';-' $(LIBRARY_NAME).def | \
+PROCESS_MAP_FILE = grep -v ';-' $< | \
sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
diff --git a/security/coreconf/Linux2.6.mk b/security/coreconf/Linux2.6.mk
index 72de8d55f..d51f5a952 100644
--- a/security/coreconf/Linux2.6.mk
+++ b/security/coreconf/Linux2.6.mk
@@ -37,15 +37,14 @@
include $(CORE_DEPTH)/coreconf/Linux.mk
+DSO_LDOPTS += -Wl,-z,defs
+
OS_REL_CFLAGS += -DLINUX2_1
-MKSHLIB = $(CC) -shared -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so)
-ifdef BUILD_OPT
- OPTIMIZER = -O2
-endif
+MKSHLIB = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so)
ifdef MAPFILE
MKSHLIB += -Wl,--version-script,$(MAPFILE)
endif
-PROCESS_MAP_FILE = grep -v ';-' $(LIBRARY_NAME).def | \
+PROCESS_MAP_FILE = grep -v ';-' $< | \
sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
diff --git a/security/coreconf/NCR3.0.mk b/security/coreconf/NCR3.0.mk
index e624e34d7..5be97e1ef 100644
--- a/security/coreconf/NCR3.0.mk
+++ b/security/coreconf/NCR3.0.mk
@@ -72,7 +72,7 @@ ifdef MAPFILE
# Add LD options to restrict exported symbols to those in the map file
endif
# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = cp $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = cp $< $@
CPU_ARCH = x86
ARCH = ncr
diff --git a/security/coreconf/NEC4.2.mk b/security/coreconf/NEC4.2.mk
index e7ed4fba1..71d7187a9 100644
--- a/security/coreconf/NEC4.2.mk
+++ b/security/coreconf/NEC4.2.mk
@@ -55,7 +55,7 @@ ifdef MAPFILE
# Add LD options to restrict exported symbols to those in the map file
endif
# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = cp $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = cp $< $@
RANLIB = /bin/true
diff --git a/security/coreconf/NetBSD.mk b/security/coreconf/NetBSD.mk
index 18a852308..3f2900150 100644
--- a/security/coreconf/NetBSD.mk
+++ b/security/coreconf/NetBSD.mk
@@ -80,7 +80,7 @@ ifdef MAPFILE
# Add LD options to restrict exported symbols to those in the map file
endif
# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = cp $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = cp $< $@
G++INCLUDES = -I/usr/include/g++
diff --git a/security/coreconf/OS2.mk b/security/coreconf/OS2.mk
index 4c965531f..575fd8b55 100644
--- a/security/coreconf/OS2.mk
+++ b/security/coreconf/OS2.mk
@@ -101,7 +101,7 @@ PROCESS_MAP_FILE = \
echo CODE LOADONCALL MOVEABLE DISCARDABLE >> $@; \
echo DATA PRELOAD MOVEABLE MULTIPLE NONSHARED >> $@; \
echo EXPORTS >> $@; \
- grep -v ';+' $(LIBRARY_NAME).def | grep -v ';-' | \
+ grep -v ';+' $< | grep -v ';-' | \
sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,\([\t ]*\),\1_,' | \
awk 'BEGIN {ord=1;} { print($$0 " @" ord " RESIDENTNAME"); ord++;}' >> $@
@@ -109,12 +109,6 @@ endif #NO_SHARED_LIB
OS_CFLAGS = -Wall -W -Wno-unused -Wpointer-arith -Wcast-align -Zomf -DDEBUG -DTRACING -g
-# Where the libraries are
-MOZ_COMPONENT_NSPR_LIBS=-L$(DIST)/lib $(NSPR_LIBS)
-NSPR_LIBS = -lplds4 -lplc4 -lnspr4
-NSPR_INCLUDE_DIR =
-
-
ifdef BUILD_OPT
OPTIMIZER = -O2 -s
DEFINES += -UDEBUG -U_DEBUG -DNDEBUG
@@ -174,7 +168,7 @@ PROCESS_MAP_FILE = \
echo CODE LOADONCALL MOVEABLE DISCARDABLE >> $@; \
echo DATA PRELOAD MOVEABLE MULTIPLE NONSHARED >> $@; \
echo EXPORTS >> $@; \
- grep -v ';+' $(LIBRARY_NAME).def | grep -v ';-' | \
+ grep -v ';+' $< | grep -v ';-' | \
sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' >> $@
endif #NO_SHARED_LIB
@@ -182,12 +176,6 @@ OS_CFLAGS = /Q /qlibansi /Gd /Gm /Su4 /Mp /Tl-
INCLUDES += -I$(CORE_DEPTH)/../dist/include
DEFINES += -DXP_OS2_VACPP -DTCPV40HDRS
-# Where the libraries are
-NSPR_LIBS = $(DIST)/lib/nspr4.lib $(DIST)/lib/plc4.lib $(DIST)/lib/plds4.lib
-MOZ_COMPONENT_NSPR_LIBS=-L$(DIST)/lib $(NSPR_LIBS)
-NSPR_INCLUDE_DIR =
-
-
DLLFLAGS = /DLL /O:$@ /INC:_dllentry /MAP:$(@:.dll=.map)
EXEFLAGS = -PMTYPE:VIO -OUT:$@ -MAP:$(@:.exe=.map) -nologo -NOE
LDFLAGS = /FREE /NOE /LINENUMBERS /nologo
@@ -231,8 +219,7 @@ MKDEPENDENCIES = $(OBJDIR_NAME)/depend.mk
# defined, the default is "install using relative symbolic
# links". The two possible values are "copy", which copies files
# but preserves source mtime, and "absolute_symlink", which
-# installs using absolute symbolic links. The "absolute_symlink"
-# option requires NFSPWD.
+# installs using absolute symbolic links.
# - THIS IS NOT PART OF THE NEW BINARY RELEASE PLAN for 9/30/97
# - WE'RE KEEPING IT ONLY FOR BACKWARDS COMPATIBILITY
####################################################################
@@ -245,7 +232,7 @@ else
ifeq ($(NSDISTMODE),absolute_symlink)
# install using absolute symbolic links
INSTALL = $(NSINSTALL)
- INSTALL += -L `$(NFSPWD)`
+ INSTALL += -L `pwd`
else
# install using relative symbolic links
INSTALL = $(NSINSTALL)
diff --git a/security/coreconf/OSF1.mk b/security/coreconf/OSF1.mk
index bdcfb09b6..93c09de77 100644
--- a/security/coreconf/OSF1.mk
+++ b/security/coreconf/OSF1.mk
@@ -68,7 +68,7 @@ MKSHLIB += ld -shared -expect_unresolved "*" -soname $(notdir $@)
ifdef MAPFILE
MKSHLIB += -hidden -input $(MAPFILE)
endif
-PROCESS_MAP_FILE = grep -v ';+' $(LIBRARY_NAME).def | grep -v ';-' | \
+PROCESS_MAP_FILE = grep -v ';+' $< | grep -v ';-' | \
sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,^,-exported_symbol ,' > $@
DSO_LDOPTS += -shared
diff --git a/security/coreconf/OpenUNIX.mk b/security/coreconf/OpenUNIX.mk
index 8a0f9b4bf..5a38181ea 100644
--- a/security/coreconf/OpenUNIX.mk
+++ b/security/coreconf/OpenUNIX.mk
@@ -79,7 +79,7 @@ ifdef MAPFILE
# Add LD options to restrict exported symbols to those in the map file
endif
# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = cp $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = cp $< $@
#
# These defines are for building unix plugins
diff --git a/security/coreconf/OpenVMS.mk b/security/coreconf/OpenVMS.mk
index 93c9d94a2..6d9b0168b 100755
--- a/security/coreconf/OpenVMS.mk
+++ b/security/coreconf/OpenVMS.mk
@@ -51,11 +51,6 @@ CPU_ARCH := $(shell uname -Wh)
OS_CFLAGS = -DVMS
OS_CXXFLAGS = -DVMS
-# Maybe this should go into rules.mk or something?
-ifdef NSPR_INCLUDE_DIR
-INCLUDES += -I$(NSPR_INCLUDE_DIR)
-endif
-
#
# XCFLAGS are the only CFLAGS that are used during a link operation. Defining
# OPTIMIZER in XCFLAGS means that each compilation line gets OPTIMIZER
@@ -71,7 +66,7 @@ ifdef MAPFILE
# Add LD options to restrict exported symbols to those in the map file
endif
# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = cp $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = cp $< $@
#
diff --git a/security/coreconf/ReliantUNIX.mk b/security/coreconf/ReliantUNIX.mk
index c118aeb5e..cdf71ed08 100644
--- a/security/coreconf/ReliantUNIX.mk
+++ b/security/coreconf/ReliantUNIX.mk
@@ -71,7 +71,7 @@ ifdef MAPFILE
# Add LD options to restrict exported symbols to those in the map file
endif
# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = cp $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = cp $< $@
NOSUCHFILE = /sni-rm-f-sucks
ODD_CFLAGS += -DSVR4 -DSNI -DRELIANTUNIX
diff --git a/security/coreconf/SCO_SV3.2.mk b/security/coreconf/SCO_SV3.2.mk
index 075389dcc..db9bec6a9 100644
--- a/security/coreconf/SCO_SV3.2.mk
+++ b/security/coreconf/SCO_SV3.2.mk
@@ -79,7 +79,7 @@ ifdef MAPFILE
# Add LD options to restrict exported symbols to those in the map file
endif
# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = cp $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = cp $< $@
#
# These defines are for building unix plugins
diff --git a/security/coreconf/SunOS5.mk b/security/coreconf/SunOS5.mk
index c7c36da62..fff1d1a3b 100644
--- a/security/coreconf/SunOS5.mk
+++ b/security/coreconf/SunOS5.mk
@@ -50,8 +50,7 @@ endif
# Sun's WorkShop defines v8, v8plus and v9 architectures.
# gcc on Solaris defines v8 and v9 "cpus".
# gcc's v9 is equivalent to Workshop's v8plus.
-# gcc apparently has no equivalent to Workshop's v9
-# We always use Sun's assembler and linker, which use Sun's naming convention.
+# gcc's -m64 is equivalent to Workshop's v9
ifeq ($(USE_64), 1)
ifdef NS_USE_GCC
@@ -66,17 +65,9 @@ ifeq ($(USE_64), 1)
else
ifneq ($(OS_TEST),i86pc)
ifdef NS_USE_GCC
- ifdef USE_HYBRID
- ARCHFLAG=-mcpu=v9 -Wa,-xarch=v8plus
- else
- ARCHFLAG=-mcpu=v8
- endif
+ ARCHFLAG=-mcpu=v8
else
- ifdef USE_HYBRID
- ARCHFLAG=-xarch=v8plus
- else
- ARCHFLAG=-xarch=v8
- endif
+ ARCHFLAG=-xarch=v8
endif
endif
endif
@@ -113,6 +104,8 @@ ifdef NS_USE_GCC
endif
ifdef BUILD_OPT
OPTIMIZER = -O2
+ # Enable this for accurate dtrace profiling
+ # OPTIMIZER += -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer
endif
else
CC = cc
@@ -157,7 +150,7 @@ else
MKSHLIB += -M $(MAPFILE)
endif
endif
-PROCESS_MAP_FILE = grep -v ';-' $(LIBRARY_NAME).def | \
+PROCESS_MAP_FILE = grep -v ';-' $< | \
sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
@@ -181,6 +174,7 @@ ifeq ($(USE_64), 1)
endif
DSO_LDOPTS += -G -h $(notdir $@)
endif
+DSO_LDOPTS += -z combreloc -z defs -z ignore
# -KPIC generates position independent code for use in shared libraries.
# (Similarly for -fPIC in case of gcc.)
diff --git a/security/coreconf/UNIXWARE2.1.mk b/security/coreconf/UNIXWARE2.1.mk
index e0a9ef901..7edcb1f58 100644
--- a/security/coreconf/UNIXWARE2.1.mk
+++ b/security/coreconf/UNIXWARE2.1.mk
@@ -57,5 +57,5 @@ ifdef MAPFILE
# Add LD options to restrict exported symbols to those in the map file
endif
# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = cp $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = cp $< $@
diff --git a/security/coreconf/WIN16.mk b/security/coreconf/WIN16.mk
index 9c1eefb29..e5d4b1816 100644
--- a/security/coreconf/WIN16.mk
+++ b/security/coreconf/WIN16.mk
@@ -117,7 +117,7 @@ ifdef MAPFILE
# Add LD options to restrict exported symbols to those in the map file
endif
# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = copy $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = copy $< $@
#
diff --git a/security/coreconf/WIN32.mk b/security/coreconf/WIN32.mk
index 10e046888..423105414 100644
--- a/security/coreconf/WIN32.mk
+++ b/security/coreconf/WIN32.mk
@@ -157,7 +157,7 @@ DLLFLAGS += -DEF:$(MAPFILE)
endif
endif
# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = cp $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = cp $< $@
#
diff --git a/security/coreconf/WINCE.mk b/security/coreconf/WINCE.mk
index 39d73c92f..86d868674 100644
--- a/security/coreconf/WINCE.mk
+++ b/security/coreconf/WINCE.mk
@@ -111,7 +111,7 @@ ifdef MAPFILE
endif
# Change PROCESS to put the mapfile in the correct format for this platform
-PROCESS_MAP_FILE = cp $(LIBRARY_NAME).def $@
+PROCESS_MAP_FILE = cp $< $@
#
# The following is NOT needed for the NSPR 2.0 library.
diff --git a/security/nss/cmd/lib/makefile.win b/security/coreconf/WINNT5.2.mk
index b12bbcee6..7423692b6 100644
--- a/security/nss/cmd/lib/makefile.win
+++ b/security/coreconf/WINNT5.2.mk
@@ -35,36 +35,39 @@
#
# ***** END LICENSE BLOCK *****
-include <manifest.mn>
-
-include <$(DEPTH)\config\config.mak>
-
-# include files are aought in LINCS and INCS.
-# LINCS are generated from REQUIRES in manigest.mn
-INCS = $(INCS) \
- -I..\include \
- -I..\..\lib\cert \
- $(NULL)
-
-IGNORE_ME = \
- -I$(DEPTH)\dist\public\security \
- -I$(DEPTH)\dist\public\nspr \
- -I$(DEPTH)\cmd\winfe \
- $(NULL)
-
-LCFLAGS = -DUSE_SSL -DEXPORT_VERSION
-
-PDBFILE = $(LIBNAME).pdb
+#
+# Config stuff for WINNT 5.2 (Windows Server 2003)
+#
+# This makefile defines the following variables:
+# OS_CFLAGS and OS_DLLFLAGS.
-# work around a bug in rules.mak
-LIBRARY_SUFFIX = $(MOZ_BITS)
+include $(CORE_DEPTH)/coreconf/WIN32.mk
-include <$(DEPTH)\config\rules.mak>
+ifeq ($(CPU_ARCH), x386)
+ OS_CFLAGS += -W3 -nologo
+ DEFINES += -D_X86_
+else
+ ifeq ($(CPU_ARCH), MIPS)
+ #OS_CFLAGS += -W3 -nologo
+ #DEFINES += -D_MIPS_
+ OS_CFLAGS += -W3 -nologo
+ else
+ ifeq ($(CPU_ARCH), ALPHA)
+ OS_CFLAGS += -W3 -nologo
+ DEFINES += -D_ALPHA_=1
+ endif
+ endif
+endif
-install:: $(LIBRARY)
-# $(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
+OS_DLLFLAGS += -nologo -DLL -SUBSYSTEM:WINDOWS
+ifndef MOZ_DEBUG_SYMBOLS
+ OS_DLLFLAGS += -PDB:NONE
+endif
+#
+# Win NT needs -GT so that fibers can work
+#
+OS_CFLAGS += -GT
+DEFINES += -DWINNT
-symbols::
- @echo "LIBRARY_NAME is $(LIBRARY_NAME)"
- @echo "LIBRARY is $(LIBRARY)"
+NSPR31_LIB_PREFIX = lib
diff --git a/security/coreconf/arch.mk b/security/coreconf/arch.mk
index aaf812175..f53847445 100644
--- a/security/coreconf/arch.mk
+++ b/security/coreconf/arch.mk
@@ -20,6 +20,7 @@
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
+# Howard Chu <hyc@symas.com>
#
# 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
@@ -267,6 +268,24 @@ ifeq (CYGWIN_NT,$(findstring CYGWIN_NT,$(OS_ARCH)))
endif
endif
endif
+#
+# If uname -s returns "MINGW32_NT-5.1", we assume that we are using
+# the uname.exe in the MSYS toolkit.
+#
+ifeq (MINGW32_NT,$(findstring MINGW32_NT,$(OS_ARCH)))
+ OS_RELEASE := $(patsubst MINGW32_NT-%,%,$(OS_ARCH))
+ OS_ARCH = WINNT
+ USE_MSYS = 1
+ ifndef CPU_ARCH
+ CPU_ARCH := $(shell uname -m)
+ #
+ # MSYS's uname -m returns "i686" on a Pentium Pro machine.
+ #
+ ifneq (,$(findstring 86,$(CPU_ARCH)))
+ CPU_ARCH = x386
+ endif
+ endif
+endif
ifndef OS_TARGET
OS_TARGET = $(OS_ARCH)
diff --git a/security/coreconf/command.mk b/security/coreconf/command.mk
index b2033d237..f231f1c5c 100644
--- a/security/coreconf/command.mk
+++ b/security/coreconf/command.mk
@@ -45,7 +45,6 @@ ASFLAGS += $(CFLAGS)
CCF = $(CC) $(CFLAGS)
LINK_DLL = $(LINK) $(OS_DLLFLAGS) $(DLLFLAGS)
LINK_EXE = $(LINK) $(OS_LFLAGS) $(LFLAGS)
-NFSPWD = $(NSINSTALL_DIR)/nfspwd
CFLAGS = $(OPTIMIZER) $(OS_CFLAGS) $(XP_DEFINE) $(DEFINES) $(INCLUDES) \
$(XCFLAGS)
RANLIB = echo
diff --git a/security/coreconf/import.pl b/security/coreconf/import.pl
index f3fa979c0..bc50077c9 100755
--- a/security/coreconf/import.pl
+++ b/security/coreconf/import.pl
@@ -46,7 +46,6 @@ $returncode =0;
#######-- read in variables on command line into %var
-$var{ZIP} = "zip";
$var{UNZIP} = "unzip -o";
&parse_argv;
diff --git a/security/coreconf/jdk.mk b/security/coreconf/jdk.mk
index dd6a09657..2bc7336e1 100644
--- a/security/coreconf/jdk.mk
+++ b/security/coreconf/jdk.mk
@@ -86,14 +86,14 @@ endif
# set [Microsoft Windows] platforms
ifeq ($(OS_ARCH), WINNT)
- JAVA_CLASSES = $(JAVA_HOME)/lib/classes.zip
+ JAVA_CLASSES = $(JAVA_HOME)/jre/lib/rt.jar
ifeq ($(JRE_HOME),)
JRE_HOME = $(JAVA_HOME)
JRE_CLASSES = $(JAVA_CLASSES)
else
ifeq ($(JRE_CLASSES),)
- JRE_CLASSES = $(JRE_HOME)/lib/classes.zip
+ JRE_CLASSES = $(JRE_HOME)/lib/rt.jar
endif
endif
@@ -105,32 +105,20 @@ ifeq ($(OS_ARCH), WINNT)
INCLUDES += -I$(JAVA_HOME)/include
INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH)
- # (3) specify "linker" information
- JAVA_CPU =
-
- JAVA_LIBDIR = lib
-
- JAVA_CLIBS =
-
- JAVA_LIBS = -LIBPATH:$(JAVA_HOME)/$(JAVA_LIBDIR) jvm.lib
- JAVA_LIBS += $(JAVA_CLIBS)
-
- LDFLAGS += $(JAVA_LIBS)
-
# currently, disable JIT option on this platform
JDK_JIT_OPT = -nojit
endif
# set [Sun Solaris] platforms
ifeq ($(OS_ARCH), SunOS)
- JAVA_CLASSES = $(JAVA_HOME)/lib/classes.zip
+ JAVA_CLASSES = $(JAVA_HOME)/jre/lib/rt.jar
ifeq ($(JRE_HOME),)
JRE_HOME = $(JAVA_HOME)
JRE_CLASSES = $(JAVA_CLASSES)
else
ifeq ($(JRE_CLASSES),)
- JRE_CLASSES = $(JRE_HOME)/lib/classes.zip
+ JRE_CLASSES = $(JRE_HOME)/lib/rt.jar
endif
endif
@@ -142,53 +130,20 @@ ifeq ($(OS_ARCH), SunOS)
INCLUDES += -I$(JAVA_HOME)/include
INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH)
- # (3) specify "linker" information
-ifeq ($(USE_64), 1)
- JAVA_CPU = $(shell uname -p)v9
-else
- JAVA_CPU = $(shell uname -p)
-endif
-
-ifeq ($(JDK_VERSION), 1.1)
- JAVA_LIBDIR = lib/$(JAVA_CPU)
-else
- JAVA_LIBDIR = jre/lib/$(JAVA_CPU)
-endif
-
- # ** IMPORTANT ** having -lthread before -lnspr is critical on solaris
- # when linking with -ljava as nspr redefines symbols in libthread that
- # cause JNI executables to fail with assert of bad thread stack values.
- JAVA_CLIBS = -lthread
-
-ifneq ($(JDK_VERSION), 1.1)
-ifeq ($(USE_64), 1)
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/server
-else
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/classic
-endif
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)
- JAVA_LIBS += -ljvm -ljava
-else
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/$(JDK_THREADING_MODEL) -ljava
-endif
- JAVA_LIBS += $(JAVA_CLIBS)
-
- LDFLAGS += $(JAVA_LIBS)
-
# currently, disable JIT option on this platform
JDK_JIT_OPT =
endif
# set [Hewlett Packard HP-UX] platforms
ifeq ($(OS_ARCH), HP-UX)
- JAVA_CLASSES = $(JAVA_HOME)/lib/classes.zip
+ JAVA_CLASSES = $(JAVA_HOME)/jre/lib/rt.jar
ifeq ($(JRE_HOME),)
JRE_HOME = $(JAVA_HOME)
JRE_CLASSES = $(JAVA_CLASSES)
else
ifeq ($(JRE_CLASSES),)
- JRE_CLASSES = $(JRE_HOME)/lib/classes.zip
+ JRE_CLASSES = $(JRE_HOME)/lib/rt.jar
endif
endif
@@ -200,34 +155,20 @@ ifeq ($(OS_ARCH), HP-UX)
INCLUDES += -I$(JAVA_HOME)/include
INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH)
- # (3) specify "linker" information
- JAVA_CPU = PA_RISC
-
- JAVA_LIBDIR = jre/lib/$(JAVA_CPU)
-
- JAVA_CLIBS =
-
- JAVA_LIBS = -L$(JAVA_HOME)/$(JAVA_LIBDIR)/$(JDK_THREADING_MODEL) -lhpi
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/classic -ljvm
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR) -ljava
- JAVA_LIBS += $(JAVA_CLIBS)
-
- LDFLAGS += $(JAVA_LIBS)
-
# no JIT option available on this platform
JDK_JIT_OPT =
endif
# set [Redhat Linux] platforms
ifeq ($(OS_ARCH), Linux)
- JAVA_CLASSES = $(JAVA_HOME)/lib/classes.zip
+ JAVA_CLASSES = $(JAVA_HOME)/jre/lib/rt.jar
ifeq ($(JRE_HOME),)
JRE_HOME = $(JAVA_HOME)
JRE_CLASSES = $(JAVA_CLASSES)
else
ifeq ($(JRE_CLASSES),)
- JRE_CLASSES = $(JRE_HOME)/lib/classes.zip
+ JRE_CLASSES = $(JRE_HOME)/lib/rt.jar
endif
endif
@@ -239,37 +180,20 @@ ifeq ($(OS_ARCH), Linux)
INCLUDES += -I$(JAVA_HOME)/include
INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH)
- # (3) specify "linker" information
- JAVA_CPU = i386
-
- JAVA_LIBDIR = jre/lib/$(JAVA_CPU)
-
- JAVA_CLIBS =
-
- ifeq ($(JDK_VERSION), 1.4)
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/server -ljvm
- else
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/classic -ljvm
- endif
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR) -ljava
- JAVA_LIBS += $(JAVA_CLIBS)
-
- LDFLAGS += $(JAVA_LIBS)
-
# no JIT option available on this platform
JDK_JIT_OPT =
endif
# set [IBM AIX] platforms
ifeq ($(OS_ARCH), AIX)
- JAVA_CLASSES = $(JAVA_HOME)/lib/classes.zip
+ JAVA_CLASSES = $(JAVA_HOME)/jre/lib/rt.jar
ifeq ($(JRE_HOME),)
JRE_HOME = $(JAVA_HOME)
JRE_CLASSES = $(JAVA_CLASSES)
else
ifeq ($(JRE_CLASSES),)
- JRE_CLASSES = $(JRE_HOME)/lib/classes.zip
+ JRE_CLASSES = $(JRE_HOME)/lib/rt.jar
endif
endif
@@ -281,34 +205,20 @@ ifeq ($(OS_ARCH), AIX)
INCLUDES += -I$(JAVA_HOME)/include
INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH)
- # (3) specify "linker" information
- JAVA_CPU = aix
-
- JAVA_LIBDIR = jre/bin
-
- JAVA_CLIBS =
-
- JAVA_LIBS = -L$(JAVA_HOME)/$(JAVA_LIBDIR) -lhpi
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/classic -ljvm
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR) -ljava
- JAVA_LIBS += $(JAVA_CLIBS)
-
- LDFLAGS += $(JAVA_LIBS)
-
# no JIT option available on this platform
JDK_JIT_OPT =
endif
# set [Digital UNIX] platforms
ifeq ($(OS_ARCH), OSF1)
- JAVA_CLASSES = $(JAVA_HOME)/lib/classes.zip
+ JAVA_CLASSES = $(JAVA_HOME)/jre/lib/rt.jar
ifeq ($(JRE_HOME),)
JRE_HOME = $(JAVA_HOME)
JRE_CLASSES = $(JAVA_CLASSES)
else
ifeq ($(JRE_CLASSES),)
- JRE_CLASSES = $(JRE_HOME)/lib/classes.zip
+ JRE_CLASSES = $(JRE_HOME)/lib/rt.jar
endif
endif
@@ -320,20 +230,6 @@ ifeq ($(OS_ARCH), OSF1)
INCLUDES += -I$(JAVA_HOME)/include
INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH)
- # (3) specify "linker" information
- JAVA_CPU = alpha
-
- JAVA_LIBDIR = jre/lib/$(JAVA_CPU)
-
- JAVA_CLIBS =
-
- JAVA_LIBS = -L$(JAVA_HOME)/$(JAVA_LIBDIR)/$(JDK_THREADING_MODEL) -lhpi
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/classic -ljvm
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR) -ljava
- JAVA_LIBS += $(JAVA_CLIBS)
-
- LDFLAGS += $(JAVA_LIBS)
-
# no JIT option available on this platform
JDK_JIT_OPT =
endif
@@ -359,21 +255,6 @@ ifeq ($(OS_ARCH), IRIX)
INCLUDES += -I$(JAVA_HOME)/include
INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH)
- # (3) specify "-n32 linker" information
- JAVA_CPU = sgi
-
- JAVA_LIBDIR = lib32/$(JAVA_CPU)
-
- JAVA_CLIBS =
-
- JAVA_LIBS = -L$(JAVA_HOME)/$(JAVA_LIBDIR)/$(JDK_THREADING_MODEL) -lhpi
- JAVA_LIBS += -lirixextra
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR)/classic -ljvm
- JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR) -ljava
- JAVA_LIBS += $(JAVA_CLIBS)
-
- LDFLAGS += $(JAVA_LIBS)
-
# no JIT option available on this platform
JDK_JIT_OPT =
endif
diff --git a/security/coreconf/location.mk b/security/coreconf/location.mk
index 77203e08b..2b3be6451 100644
--- a/security/coreconf/location.mk
+++ b/security/coreconf/location.mk
@@ -67,4 +67,12 @@ endif
GARBAGE += $(DEPENDENCIES) core $(wildcard core.[0-9]*)
+ifdef NSPR_INCLUDE_DIR
+ INCLUDES += -I$(NSPR_INCLUDE_DIR)
+endif
+
+ifndef NSPR_LIB_DIR
+ NSPR_LIB_DIR = $(DIST)/lib
+endif
+
MK_LOCATION = included
diff --git a/security/coreconf/makefile.win b/security/coreconf/makefile.win
deleted file mode 100644
index 6f3e244b4..000000000
--- a/security/coreconf/makefile.win
+++ /dev/null
@@ -1,104 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-#
-# An NMAKE file to set up and adjust coreconf's build system for
-# Client build. Client build should invoke NMAKE on this file
-# instead of invoking gmake directly.
-#
-
-NS_DEPTH = ..
-include <$(NS_DEPTH)\config\config.mak>
-#include <$(NS_DEPTH)\config\rules.mak>
-
-#
-# Backslashes are escape characters to gmake, so flip all backslashes
-# in $(MOZ_TOOLS) to forward slashes and pass that to gmake.
-#
-
-GMAKE = $(MOZ_TOOLS)\bin\gmake.exe MOZ_TOOLS_FLIPPED=$(MOZ_TOOLS:\=/)
-
-GMAKE = $(GMAKE) PR_CLIENT_BUILD=1 PR_CLIENT_BUILD_WINDOWS=1
-
-#
-# The Client's debug build uses MSVC's debug runtime library (/MDd).
-#
-
-!ifdef MOZ_DEBUG
-GMAKE = $(GMAKE) USE_DEBUG_RTL=1
-!else
-GMAKE = $(GMAKE) BUILD_OPT=1
-!endif
-
-!if "$(MOZ_BITS)" == "16"
-GMAKE = $(GMAKE) OS_TARGET=WIN16
-!else
-
-GMAKE = $(GMAKE) OS_TARGET=WIN95
-!ifdef MOZ_DEBUG
-PR_OBJDIR = WIN954.0_DBG.OBJD
-!else
-PR_OBJDIR = WIN954.0_OPT.OBJ
-!endif
-
-!endif
-
-#
-# The rules. Simply invoke gmake with the same target
-# for Win16, use the watcom compiler with the MSVC headers and libs
-#
-
-# this rule is needed so that nmake with no explicit target will only build
-# all, and not build all the targets named below in succession!
-default:: all
-
-# a rule like this one must only be used for explicitly named targets!
-all depend export libs install clobber clobber_all clean::
-!if "$(MOZ_BITS)" == "16"
- set PATH=%WATCPATH%
- set INCLUDE=%MSVC_INC%
- set LIB=%MSVC_LIB%
-!endif
- $(GMAKE) $@
-!if "$(MOZ_BITS)" == "16"
- set PATH=%MSVCPATH%
- set INCLUDE=%MSVC_INC%
- set LIB=%MSVC_LIB%
-!endif
-
-show:
- @echo "MAKEFLAGS = $(MAKEFLAGS)"
diff --git a/security/coreconf/nsinstall/Makefile b/security/coreconf/nsinstall/Makefile
index 0a28c6af4..c794890f5 100644
--- a/security/coreconf/nsinstall/Makefile
+++ b/security/coreconf/nsinstall/Makefile
@@ -42,8 +42,6 @@ MODULE = coreconf
CSRCS = nsinstall.c pathsub.c
-PLSRCS = nfspwd.pl
-
PROGRAM = nsinstall
# Indicate that this directory builds build tools.
@@ -55,7 +53,7 @@ include $(DEPTH)/coreconf/config.mk
ifeq (,$(filter-out OS2 WIN%,$(OS_TARGET)))
PROGRAM =
else
-TARGETS = $(PROGRAM) $(PLSRCS:.pl=)
+TARGETS = $(PROGRAM)
INSTALL = true
endif
diff --git a/security/coreconf/nsinstall/nfspwd.pl b/security/coreconf/nsinstall/nfspwd.pl
deleted file mode 100644
index 66345aa07..000000000
--- a/security/coreconf/nsinstall/nfspwd.pl
+++ /dev/null
@@ -1,50 +0,0 @@
-#! perl
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-require "fastcwd.pl";
-
-$_ = &fastcwd;
-if (m@^/[uh]/@o || s@^/tmp_mnt/@/@o) {
- print("$_\n");
-} elsif ((($user, $rest) = m@^/usr/people/(\w+)/(.*)@o)
- && readlink("/u/$user") eq "/usr/people/$user") {
- print("/u/$user/$rest\n");
-} else {
- chop($host = `hostname`);
- print("/h/$host$_\n");
-}
diff --git a/security/coreconf/release.pl b/security/coreconf/release.pl
index 42979fb77..286ec5cc5 100755
--- a/security/coreconf/release.pl
+++ b/security/coreconf/release.pl
@@ -41,7 +41,14 @@ require('coreconf.pl');
#######-- read in variables on command line into %var
-$var{ZIP} = "zip";
+$use_jar = 1;
+$ZIP = "$ENV{JAVA_HOME}/bin/jar";
+
+if ( $ENV{JAVA_HOME} eq "" ) {
+ $ZIP = "zip";
+ $use_jar = 0;
+}
+
&parse_argv;
@@ -56,11 +63,15 @@ foreach $jarfile (split(/ /,$var{FILES}) ) {
($jardir,$jaropts) = split(/\|/,$jarinfo);
- $zipoptions = "-T";
- if ($jaropts =~ /a/) {
- if ($var{OS_ARCH} eq 'WINNT') {
- $zipoptions .= ' -ll';
- }
+ if ( $use_jar ) {
+ $zipoptions = "-cvf";
+ } else {
+ $zipoptions = "-T -r";
+ if ($jaropts =~ /a/) {
+ if ($var{OS_ARCH} eq 'WINNT') {
+ $zipoptions .= ' -ll';
+ }
+ }
}
# just in case the directory ends in a /, remove it
@@ -117,8 +128,8 @@ foreach $jarfile (split(/ /,$var{FILES}) ) {
}
closedir(DIR);
- print STDERR "zip $zipoptions -r $jarfile $filelist\n";
- system("zip $zipoptions -r $jarfile $filelist");
+ print STDERR "$ZIP $zipoptions $jarfile $filelist\n";
+ system("$ZIP $zipoptions $jarfile $filelist");
rmdir("META-INF");
for $i (1 .. $dirdepth) {
chdir("..");
diff --git a/security/coreconf/rules.mk b/security/coreconf/rules.mk
index 7643672b2..0d0aaee1a 100644
--- a/security/coreconf/rules.mk
+++ b/security/coreconf/rules.mk
@@ -137,22 +137,6 @@ realclean clobber_all::
rm -rf $(wildcard *.OBJ) dist $(ALL_TRASH)
+$(LOOP_OVER_DIRS)
-#ifdef ALL_PLATFORMS
-#all_platforms:: $(NFSPWD)
-# @d=`$(NFSPWD)`; \
-# if test ! -d LOGS; then rm -rf LOGS; mkdir LOGS; fi; \
-# for h in $(PLATFORM_HOSTS); do \
-# echo "On $$h: $(MAKE) $(ALL_PLATFORMS) >& LOGS/$$h.log";\
-# rsh $$h -n "(chdir $$d; \
-# $(MAKE) $(ALL_PLATFORMS) >& LOGS/$$h.log; \
-# echo DONE) &" 2>&1 > LOGS/$$h.pid & \
-# sleep 1; \
-# done
-#
-#$(NFSPWD):
-# cd $(@D); $(MAKE) $(@F)
-#endif
-
#######################################################################
# Double-Colon rules for populating the binary release model. #
#######################################################################
@@ -348,9 +332,9 @@ else
endif
else
ifdef XP_OS2_VACPP
- $(MKSHLIB) $(DLLFLAGS) $(LDFLAGS) $(OBJS) $(SUB_SHLOBJS) $(LD_LIBS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS)
+ $(MKSHLIB) $(DLLFLAGS) $(LDFLAGS) $(OBJS) $(SUB_SHLOBJS) $(LD_LIBS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS)
else
- $(MKSHLIB) -o $@ $(OBJS) $(SUB_SHLOBJS) $(LD_LIBS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS)
+ $(MKSHLIB) -o $@ $(OBJS) $(SUB_SHLOBJS) $(LD_LIBS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS)
endif
chmod +x $@
ifeq ($(OS_TARGET),Darwin)
@@ -373,7 +357,7 @@ endif
@echo $(RES) finished
endif
-$(MAPFILE): $(LIBRARY_NAME).def
+$(MAPFILE): $(MAPFILE_SOURCE)
@$(MAKE_OBJDIR)
$(PROCESS_MAP_FILE)
@@ -402,10 +386,11 @@ endif
ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET)))
NEED_ABSOLUTE_PATH := 1
-ifeq (,$(findstring ;,$(PATH)))
-PWD := $(subst \,/,$(shell cygpath -w `pwd`))
-else
PWD := $(shell pwd)
+ifeq (,$(findstring ;,$(PATH)))
+ifndef USE_MSYS
+PWD := $(subst \,/,$(shell cygpath -w $(PWD)))
+endif
endif
endif
diff --git a/security/coreconf/ruleset.mk b/security/coreconf/ruleset.mk
index f4969ee5d..5ee77a78a 100644
--- a/security/coreconf/ruleset.mk
+++ b/security/coreconf/ruleset.mk
@@ -123,6 +123,9 @@ ifdef LIBRARY_NAME
ifndef SHARED_LIBRARY
SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(JDK_DEBUG_SUFFIX).$(DLL_SUFFIX)
endif
+ ifndef MAPFILE_SOURCE
+ MAPFILE_SOURCE = $(LIBRARY_NAME).def
+ endif
endif
#
diff --git a/security/nss/cmd/Makefile b/security/nss/cmd/Makefile
index 8e8342fd5..5369d8904 100644
--- a/security/nss/cmd/Makefile
+++ b/security/nss/cmd/Makefile
@@ -42,6 +42,10 @@ DEPTH = ../..
include manifest.mn
include $(CORE_DEPTH)/coreconf/config.mk
+ifndef USE_SYSTEM_ZLIB
+ZLIB_SRCDIR = zlib # Add the zlib directory to DIRS.
+endif
+
# These sources were once in this directory, but now are gone.
MISSING_SOURCES = \
addcert.c \
diff --git a/security/nss/cmd/SSLsample/Makefile.NSS b/security/nss/cmd/SSLsample/Makefile.NSS
deleted file mode 100644
index 75461e9de..000000000
--- a/security/nss/cmd/SSLsample/Makefile.NSS
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-ARCH := $(shell uname)
-
-ifeq ($(ARCH), SunOS)
- DEFINES = -KPIC -DSVR4 -DSOLARIS -DSYSV -D__svr4 -D__svr4__ \
- -D_REENTRANT -DSOLARIS2_5 -D_SVID_GETTOD -DXP_UNIX -UDEBUG -DNDEBUG \
- -DXP_UNIX
- INCPATH = -I. -I../include/dbm -I../include/nspr -I../include/security
- LIBPATH = -L../lib
- LIBS = -lnss -lssl -lpkcs7 -lpkcs12 -lsecmod -lcert -lkey \
- -lcrypto -lsecutil -lhash -ldbm -lplc4 -lplds4 -lnspr4 -lsocket -lnsl
- CFLAGS = -g
- CC = cc
-endif # SunOS
-
-# The rules to build the sample apps appear below.
-
-server:
- $(CC) $(CFLAGS) $@.c -o $@ $(DEFINES) $(INCPATH) $(LIBPATH) $(LIBS)
-
-client:
- $(CC) $(CFLAGS) $@.c -o $@ $(DEFINES) $(INCPATH) $(LIBPATH) $(LIBS)
-
-clean:
- rm -fr server client server.o client.o
-
diff --git a/security/nss/cmd/SSLsample/README b/security/nss/cmd/SSLsample/README
index 2c4c09110..5672cfac8 100644
--- a/security/nss/cmd/SSLsample/README
+++ b/security/nss/cmd/SSLsample/README
@@ -12,14 +12,6 @@ config.mk
make.client
make.server
-The following makefiles are used only when building in the NSS distribution.
-These files are part of the distribution.
-
-Makefile.NSS
-nmakefile95.nss
-nmakefilent.nss
-
-
The following source files are common to both build environments and are
part of the distribution.
diff --git a/security/nss/cmd/SSLsample/nmakefilent.nss b/security/nss/cmd/SSLsample/nmakefilent.nss
deleted file mode 100755
index 09cadd926..000000000
--- a/security/nss/cmd/SSLsample/nmakefilent.nss
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-# NSS 2.6.2 Sample NT Makefile
-#
-#
-# This nmake file will build server.c and client.c on Windows NT 4 SP3.
-#
-
-DEFINES=-D_X86_ -GT -DWINNT -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG -DWIN32 -D_WINDOWS
-INCPATH=-I. -I..\include\dbm -I..\include\nspr -I..\include\security
-
-LIBS=nss.lib ssl.lib pkcs7.lib pkcs12.lib secmod.lib cert.lib key.lib crypto.lib secutil.lib hash.lib dbm.lib libplc3.lib libplds3.lib libnspr3.lib wsock32.lib
-
-CFLAGS=-O2 -MD -W3 -nologo
-
-CC=cl
-
-LDOPTIONS=/link /LIBPATH:..\lib /nodefaultlib:libcd.lib /subsystem:console
-
-server:
- $(CC) $(CFLAGS) /Feserver server.c getopt.c $(LIBS) $(DEFINES) $(INCPATH) $(LDOPTIONS)
-
-client:
- $(CC) $(CFLAGS) /Feclient client.c getopt.c $(LIBS) $(DEFINES) $(INCPATH) $(LDOPTIONS)
-
-clean:
- del /S server.exe client.exe server.lib server.exp client.lib client.exp server.obj client.obj getopt.obj
-
diff --git a/security/nss/cmd/SSLsample/server.c b/security/nss/cmd/SSLsample/server.c
index ced32d287..5965d4723 100644
--- a/security/nss/cmd/SSLsample/server.c
+++ b/security/nss/cmd/SSLsample/server.c
@@ -102,14 +102,11 @@ Usage(const char *progName)
"E SSL2 DES 64 CBC WITH MD5\n"
"F SSL2 DES 192 EDE3 CBC WITH MD5\n"
"\n"
-"a SSL3 FORTEZZA DMS WITH FORTEZZA CBC SHA\n"
-"b SSL3 FORTEZZA DMS WITH RC4 128 SHA\n"
"c SSL3 RSA WITH RC4 128 MD5\n"
"d SSL3 RSA WITH 3DES EDE CBC SHA\n"
"e SSL3 RSA WITH DES CBC SHA\n"
"f SSL3 RSA EXPORT WITH RC4 40 MD5\n"
"g SSL3 RSA EXPORT WITH RC2 CBC 40 MD5\n"
-"h SSL3 FORTEZZA DMS WITH NULL SHA\n"
"i SSL3 RSA WITH NULL MD5\n"
"j SSL3 RSA FIPS WITH 3DES EDE CBC SHA\n"
"k SSL3 RSA FIPS WITH DES CBC SHA\n"
diff --git a/security/nss/cmd/SSLsample/sslsample.c b/security/nss/cmd/SSLsample/sslsample.c
index 85f5d523b..422d453de 100644
--- a/security/nss/cmd/SSLsample/sslsample.c
+++ b/security/nss/cmd/SSLsample/sslsample.c
@@ -50,14 +50,14 @@ int ssl2CipherSuites[] = {
};
int ssl3CipherSuites[] = {
- SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* a */
- SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, /* b */
+ -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA a */
+ -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA * b */
SSL_RSA_WITH_RC4_128_MD5, /* c */
SSL_RSA_WITH_3DES_EDE_CBC_SHA, /* d */
SSL_RSA_WITH_DES_CBC_SHA, /* e */
SSL_RSA_EXPORT_WITH_RC4_40_MD5, /* f */
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */
- SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* h */
+ -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA, * h */
SSL_RSA_WITH_NULL_MD5, /* i */
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */
SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */
diff --git a/security/nss/cmd/atob/makefile.win b/security/nss/cmd/atob/makefile.win
deleted file mode 100644
index f97e79275..000000000
--- a/security/nss/cmd/atob/makefile.win
+++ /dev/null
@@ -1,159 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-VERBOSE = 1
-include <manifest.mn>
-
-#cannot define PROGRAM in manifest compatibly with NT and UNIX
-PROGRAM = atob
-PROGRAM = ./$(OBJDIR)/$(PROGRAM).exe
-include <$(DEPTH)\config\config.mak>
-
-# let manifest generate C_OBJS, it will prepend ./$(OBJDIR)/
-# rules.mak will append C_OBJS onto OBJS.
-# OBJS = $(CSRCS:.c=.obj)
-
-# include files are looked for in $LINCS and $INCS.
-# $LINCS is in manifest.mnw, computed from REQUIRES=
-INCS = $(INCS) \
- -I$(DEPTH)/security/lib/cert \
- -I../include \
- $(NULL)
-
-IGNORE_ME = \
- -I$(DEPTH)/security/lib/key \
- -I$(DEPTH)/security/lib/util \
- $(NULL)
-
-
-WINFE = $(DEPTH)/cmd/winfe/mkfiles$(MOZ_BITS)/x86Dbg
-
-# these files are the content of libdbm
-DBM_LIB = \
- $(WINFE)/DB.obj \
- $(WINFE)/HASH.obj \
- $(WINFE)/H_BIGKEY.obj \
- $(WINFE)/H_PAGE.obj \
- $(WINFE)/H_LOG2.obj \
- $(WINFE)/H_FUNC.obj \
- $(WINFE)/HASH_BUF.obj \
- $(NULL)
-
-MOZ_LIBS = \
- $(WINFE)/ALLXPSTR.obj \
- $(WINFE)/XP_ERROR.obj \
- $(WINFE)/XPASSERT.obj \
- $(WINFE)/XP_REG.obj \
- $(WINFE)/XP_TRACE.obj \
- $(DBM_LIB) \
- $(WINFE)/XP_STR.obj \
- $(WINFE)/MKTEMP.obj \
- $(NULL)
-
-SEC_LIBS = \
- $(DIST)/lib/cert$(MOZ_BITS).lib \
- $(DIST)/lib/crypto$(MOZ_BITS).lib \
- $(DIST)/lib/hash$(MOZ_BITS).lib \
- $(DIST)/lib/key$(MOZ_BITS).lib \
- $(DIST)/lib/pkcs7$(MOZ_BITS).lib \
- $(DIST)/lib/secmod$(MOZ_BITS).lib \
- $(DIST)/lib/secutl$(MOZ_BITS).lib \
- $(DIST)/lib/ssl$(MOZ_BITS).lib \
- $(NULL)
-
-LLFLAGS = $(LLFLAGS) \
- ../lib/$(OBJDIR)/sectool$(MOZ_BITS).lib \
- $(SEC_LIBS) \
- $(MOZ_LIBS) \
- $(DEPTH)/nspr/src/$(OBJDIR)/getopt.obj \
- $(LIBNSPR) \
- $(NULL)
-
-
-# awt3240.lib # brpref32.lib # cert32.lib
-# crypto32.lib # dllcom.lib # editor32.lib
-# edpref32.lib # edtplug.lib # font.lib
-# hash32.lib # htmldg32.lib # img32.lib
-# javart32.lib # jbn3240.lib # jdb3240.lib
-# jmc.lib # jpeg3240.lib # jpw3240.lib
-# jrt3240.lib # js3240.lib # jsd3240.lib
-# key32.lib # libapplet32.lib # libnjs32.lib
-# libnsc32.lib # libreg32.lib # mm3240.lib
-# mnpref32.lib # netcst32.lib # nsdlg32.lib
-# nsldap32.lib # nsldaps32.lib # nsn32.lib
-# pkcs1232.lib # pkcs732.lib # pr3240.lib
-# prefui32.lib # prefuuid.lib # secmod32.lib
-# secnav32.lib # secutl32.lib # softup32.lib
-# sp3240.lib # ssl32.lib # uni3200.lib
-# unicvt32.lib # win32md.lib # winfont.lib
-# xppref32.lib # zlib32.lib
-
-include <$(DEPTH)\config\rules.mak>
-
-INSTALL = $(MAKE_INSTALL)
-
-objs: $(OBJS)
-
-$(PROGRAM)::
- $(INSTALL) $(DIST)/bin/pr3240.dll ./$(OBJDIR)
-
-programs: $(PROGRAM)
-
-install:: $(TARGETS)
- $(INSTALL) $(TARGETS) $(DIST)/bin
-
-# ALLXPSTR.obj XP_ALLOC.obj XP_HASH.obj XP_RGB.obj XP_WRAP.obj
-# CXPRINT.obj XP_C.cl XP_LIST.obj XP_SEC.obj netscape.exp
-# CXPRNDLG.obj XP_CNTXT.obj XP_MD5.obj XP_STR.obj xp.pch
-# EXPORT.obj XP_CORE.obj XP_MESG.obj XP_THRMO.obj xppref32.dll
-# XPASSERT.obj XP_ERROR.obj XP_RECT.obj XP_TIME.obj
-# XPLOCALE.obj XP_FILE.obj XP_REG.obj XP_TRACE.obj
-
-
-symbols:
- @echo "CSRCS = $(CSRCS)"
- @echo "INCS = $(INCS)"
- @echo "OBJS = $(OBJS)"
- @echo "LIBRARY = $(LIBRARY)"
- @echo "PROGRAM = $(PROGRAM)"
- @echo "TARGETS = $(TARGETS)"
- @echo "DIST = $(DIST)"
- @echo "VERSION_NUMBER = $(VERSION_NUMBER)"
- @echo "WINFE = $(WINFE)"
- @echo "DBM_LIB = $(DBM_LIB)"
- @echo "INSTALL = $(INSTALL)"
-
diff --git a/security/nss/cmd/bltest/blapitest.c b/security/nss/cmd/bltest/blapitest.c
index cce2d821f..72182a127 100644
--- a/security/nss/cmd/bltest/blapitest.c
+++ b/security/nss/cmd/bltest/blapitest.c
@@ -2789,8 +2789,11 @@ blapi_selftest(bltestCipherMode *modes, int numModes, int inoff, int outoff,
#endif
PR_Close(file);
/* loop over the tests in the directory */
- numtests = (int) (item.data[0] - '0');
- for (j=1; j<item.len - 1; j++) {
+ numtests = 0;
+ for (j=0; j<item.len; j++) {
+ if (!isdigit(item.data[j])) {
+ break;
+ }
numtests *= 10;
numtests += (int) (item.data[j] - '0');
}
diff --git a/security/nss/cmd/btoa/makefile.win b/security/nss/cmd/btoa/makefile.win
deleted file mode 100644
index 6d114d9fc..000000000
--- a/security/nss/cmd/btoa/makefile.win
+++ /dev/null
@@ -1,134 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-VERBOSE = 1
-include <manifest.mn>
-
-#cannot define PROGRAM in manifest compatibly with NT and UNIX
-PROGRAM = btoa
-PROGRAM = ./$(OBJDIR)/$(PROGRAM).exe
-include <$(DEPTH)\config\config.mak>
-
-# let manifest generate C_OBJS, it will prepend ./$(OBJDIR)/
-# rules.mak will append C_OBJS onto OBJS.
-# OBJS = $(CSRCS:.c=.obj)
-
-# include files are looked for in $LINCS and $INCS.
-# $LINCS is in manifest.mnw, computed from REQUIRES=
-INCS = $(INCS) \
- -I$(DEPTH)/security/lib/cert \
- -I../include \
- $(NULL)
-
-IGNORE_ME = \
- -I$(DEPTH)/security/lib/key \
- -I$(DEPTH)/security/lib/util \
- $(NULL)
-
-
-WINFE = $(DEPTH)/cmd/winfe/mkfiles$(MOZ_BITS)/x86Dbg
-
-# these files are the content of libdbm
-DBM_LIB = \
- $(WINFE)/DB.obj \
- $(WINFE)/HASH.obj \
- $(WINFE)/H_BIGKEY.obj \
- $(WINFE)/H_PAGE.obj \
- $(WINFE)/H_LOG2.obj \
- $(WINFE)/H_FUNC.obj \
- $(WINFE)/HASH_BUF.obj \
- $(NULL)
-
-MOZ_LIBS = \
- $(WINFE)/ALLXPSTR.obj \
- $(WINFE)/XP_ERROR.obj \
- $(WINFE)/XPASSERT.obj \
- $(WINFE)/XP_REG.obj \
- $(WINFE)/XP_TRACE.obj \
- $(DBM_LIB) \
- $(WINFE)/XP_STR.obj \
- $(WINFE)/MKTEMP.obj \
- $(NULL)
-
-SEC_LIBS = \
- $(DIST)/lib/cert$(MOZ_BITS).lib \
- $(DIST)/lib/crypto$(MOZ_BITS).lib \
- $(DIST)/lib/hash$(MOZ_BITS).lib \
- $(DIST)/lib/key$(MOZ_BITS).lib \
- $(DIST)/lib/pkcs7$(MOZ_BITS).lib \
- $(DIST)/lib/secmod$(MOZ_BITS).lib \
- $(DIST)/lib/secutl$(MOZ_BITS).lib \
- $(DIST)/lib/ssl$(MOZ_BITS).lib \
- $(NULL)
-
-LLFLAGS = $(LLFLAGS) \
- ../lib/$(OBJDIR)/sectool$(MOZ_BITS).lib \
- $(SEC_LIBS) \
- $(MOZ_LIBS) \
- $(DEPTH)/nspr/src/$(OBJDIR)/getopt.obj \
- $(LIBNSPR) \
- $(NULL)
-
-
-include <$(DEPTH)\config\rules.mak>
-
-INSTALL = $(MAKE_INSTALL)
-
-objs: $(OBJS)
-
-$(PROGRAM)::
- $(INSTALL) $(DIST)/bin/pr3240.dll ./$(OBJDIR)
-
-programs: $(PROGRAM)
-
-install:: $(TARGETS)
- $(INSTALL) $(TARGETS) $(DIST)/bin
-
-
-symbols:
- @echo "CSRCS = $(CSRCS)"
- @echo "INCS = $(INCS)"
- @echo "OBJS = $(OBJS)"
- @echo "LIBRARY = $(LIBRARY)"
- @echo "PROGRAM = $(PROGRAM)"
- @echo "TARGETS = $(TARGETS)"
- @echo "DIST = $(DIST)"
- @echo "VERSION_NUMBER = $(VERSION_NUMBER)"
- @echo "WINFE = $(WINFE)"
- @echo "DBM_LIB = $(DBM_LIB)"
- @echo "INSTALL = $(INSTALL)"
-
diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c
index fda08a9f5..d9a82bfd9 100644
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -87,6 +87,39 @@ extern SECKEYPrivateKey *CERTUTIL_GeneratePrivateKey(KeyType keytype,
static char *progName;
+static char *
+Gets_s(char *buff, size_t size) {
+ char *str;
+
+ if (buff == NULL || size < 1) {
+ PORT_Assert(0);
+ return NULL;
+ }
+ if ((str = fgets(buff, size, stdin)) != NULL) {
+ int len = PORT_Strlen(str);
+ /*
+ * fgets() automatically converts native text file
+ * line endings to '\n'. As defensive programming
+ * (just in case fgets has a bug or we put stdin in
+ * binary mode by mistake), we handle three native
+ * text file line endings here:
+ * '\n' Unix (including Linux and Mac OS X)
+ * '\r''\n' DOS/Windows & OS/2
+ * '\r' Mac OS Classic
+ * len can not be less then 1, since in case with
+ * empty string it has at least '\n' in the buffer
+ */
+ if (buff[len - 1] == '\n' || buff[len - 1] == '\r') {
+ buff[len - 1] = '\0';
+ if (len > 1 && buff[len - 2] == '\r')
+ buff[len - 2] = '\0';
+ }
+ } else {
+ buff[0] = '\0';
+ }
+ return str;
+}
+
static CERTGeneralName *
GetGeneralName (PRArenaPool *arena)
{
@@ -105,16 +138,17 @@ GetGeneralName (PRArenaPool *arena)
puts ("\t1 - instance of other name\n\t2 - rfc822Name\n\t3 - dnsName\n");
puts ("\t4 - x400Address\n\t5 - directoryName\n\t6 - ediPartyName\n");
puts ("\t7 - uniformResourceidentifier\n\t8 - ipAddress\n\t9 - registerID\n");
- puts ("\tOther - omit\n\t\tChoice:");
- if (scanf ("%d", &intValue) == EOF) {
+ puts ("\tAny other number to finish\n\t\tChoice:");
+ if (Gets_s (buffer, sizeof(buffer)) == NULL) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
- GEN_BREAK (SECFailure);
- }
+ GEN_BREAK (SECFailure);
+ }
+ intValue = PORT_Atoi (buffer);
/*
* Should use ZAlloc instead of Alloc to avoid problem with garbage
* initialized pointers in CERT_CopyName
*/
- if (intValue >= certOtherName || intValue <= certRegisterID) {
+ if (intValue >= certOtherName && intValue <= certRegisterID) {
if (namesList == NULL) {
namesList = current = tail = PORT_ArenaZNew(arena, CERTGeneralName);
} else {
@@ -129,10 +163,10 @@ GetGeneralName (PRArenaPool *arena)
current->type = intValue;
puts ("\nEnter data:");
fflush (stdout);
- if (gets (buffer) == NULL) {
+ if (Gets_s (buffer, sizeof(buffer)) == NULL) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
- GEN_BREAK (SECFailure);
- }
+ GEN_BREAK (SECFailure);
+ }
switch (current->type) {
case certURI:
case certDNSName:
@@ -199,13 +233,16 @@ static SECStatus
GetString(PRArenaPool *arena, char *prompt, SECItem *value)
{
char buffer[251];
+ char *buffPrt;
+ buffer[0] = '\0';
value->data = NULL;
value->len = 0;
puts (prompt);
- gets (buffer);
- if (strlen (buffer) > 0) {
+ buffPrt = Gets_s (buffer, sizeof(buffer));
+ /* returned NULL here treated the same way as empty string */
+ if (buffPrt && strlen (buffer) > 0) {
value->data = PORT_ArenaAlloc (arena, strlen (buffer));
if (value->data == NULL) {
PORT_SetError (SEC_ERROR_NO_MEMORY);
@@ -271,20 +308,12 @@ static PRBool
GetYesNo(char *prompt)
{
char buf[3];
+ char *buffPrt;
- PR_Sync(PR_STDIN);
- PR_Write(PR_STDOUT, prompt, strlen(prompt)+1);
- PR_Read(PR_STDIN, buf, sizeof(buf));
- return (buf[0] == 'y' || buf[0] == 'Y') ? PR_TRUE : PR_FALSE;
-#if 0
- char charValue;
-
- puts (prompt);
- scanf ("%c", &charValue);
- if (charValue != 'y' && charValue != 'Y')
- return (0);
- return (1);
-#endif
+ buf[0] = 'n';
+ puts(prompt);
+ buffPrt = Gets_s(buf, sizeof(buf));
+ return (buffPrt && (buf[0] == 'y' || buf[0] == 'Y')) ? PR_TRUE : PR_FALSE;
}
static SECStatus
@@ -1412,6 +1441,7 @@ AddKeyUsage (void *extHandle)
unsigned char keyUsage = 0x0;
char buffer[5];
int value;
+ PRBool yesNoAns;
while (1) {
fprintf(stdout, "%-25s 0 - Digital Signature\n", "");
@@ -1422,10 +1452,18 @@ AddKeyUsage (void *extHandle)
fprintf(stdout, "%-25s 5 - Cert signing key\n", "");
fprintf(stdout, "%-25s 6 - CRL signing key\n", "");
fprintf(stdout, "%-25s Other to finish\n", "");
- if (gets (buffer)) {
- value = atoi (buffer);
+ if (Gets_s (buffer, sizeof(buffer))) {
+ value = PORT_Atoi (buffer);
if (value < 0 || value > 6)
break;
+ if (value == 0) {
+ /* Checking that zero value of variable 'value'
+ * corresponds to '0' input made by user */
+ char *chPtr = strchr(buffer, '0');
+ if (chPtr == NULL) {
+ continue;
+ }
+ }
keyUsage |= (0x80 >> value);
}
else { /* gets() returns NULL on EOF or error */
@@ -1435,13 +1473,11 @@ AddKeyUsage (void *extHandle)
bitStringValue.data = &keyUsage;
bitStringValue.len = 1;
- buffer[0] = 'n';
- puts ("Is this a critical extension [y/n]? ");
- gets (buffer);
+ yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
return (CERT_EncodeAndAddBitStrExtension
(extHandle, SEC_OID_X509_KEY_USAGE, &bitStringValue,
- (buffer[0] == 'y' || buffer[0] == 'Y') ? PR_TRUE : PR_FALSE));
+ yesNoAns));
}
@@ -1562,6 +1598,7 @@ AddExtKeyUsage (void *extHandle)
CERTOidSequence *os;
SECStatus rv;
SECItem *item;
+ PRBool yesNoAns;
os = CreateOidSequence();
if( (CERTOidSequence *)NULL == os ) {
@@ -1578,12 +1615,21 @@ AddExtKeyUsage (void *extHandle)
fprintf(stdout, "%-25s 6 - Step-up\n", "");
fprintf(stdout, "%-25s Other to finish\n", "");
- if (gets(buffer) == NULL) {
+ if (Gets_s(buffer, sizeof(buffer)) == NULL) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
rv = SECFailure;
goto loser;
}
- value = atoi(buffer);
+ value = PORT_Atoi(buffer);
+
+ if (value == 0) {
+ /* Checking that zero value of variable 'value'
+ * corresponds to '0' input made by user */
+ char *chPtr = strchr(buffer, '0');
+ if (chPtr == NULL) {
+ continue;
+ }
+ }
switch( value ) {
case 0:
@@ -1617,13 +1663,10 @@ AddExtKeyUsage (void *extHandle)
endloop:;
item = EncodeOidSequence(os);
- buffer[0] = 'n';
- puts ("Is this a critical extension [y/n]? ");
- gets (buffer);
+ yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
rv = CERT_AddExtension(extHandle, SEC_OID_X509_EXT_KEY_USAGE, item,
- ((buffer[0] == 'y' || buffer[0] == 'Y')
- ? PR_TRUE : PR_FALSE), PR_TRUE);
+ yesNoAns, PR_TRUE);
/*FALLTHROUGH*/
loser:
DestroyOidSequence(os);
@@ -1637,6 +1680,7 @@ AddNscpCertType (void *extHandle)
unsigned char keyUsage = 0x0;
char buffer[5];
int value;
+ PRBool yesNoAns;
while (1) {
fprintf(stdout, "%-25s 0 - SSL Client\n", "");
@@ -1648,25 +1692,31 @@ AddNscpCertType (void *extHandle)
fprintf(stdout, "%-25s 6 - S/MIME CA\n", "");
fprintf(stdout, "%-25s 7 - Object Signing CA\n", "");
fprintf(stdout, "%-25s Other to finish\n", "");
- if (gets (buffer) == NULL) {
+ if (Gets_s (buffer, sizeof(buffer)) == NULL) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
- value = atoi (buffer);
+ return SECFailure;
+ }
+ value = PORT_Atoi (buffer);
if (value < 0 || value > 7)
break;
+ if (value == 0) {
+ /* Checking that zero value of variable 'value'
+ * corresponds to '0' input made by user */
+ char *chPtr = strchr(buffer, '0');
+ if (chPtr == NULL) {
+ continue;
+ }
+ }
keyUsage |= (0x80 >> value);
}
bitStringValue.data = &keyUsage;
bitStringValue.len = 1;
- buffer[0] = 'n';
- puts ("Is this a critical extension [y/n]? ");
- gets (buffer);
+ yesNoAns = GetYesNo("Is this a critical extension [y/N]?");
return (CERT_EncodeAndAddBitStrExtension
(extHandle, SEC_OID_NS_CERT_EXT_CERT_TYPE, &bitStringValue,
- (buffer[0] == 'y' || buffer[0] == 'Y') ? PR_TRUE : PR_FALSE));
+ yesNoAns));
}
@@ -1761,32 +1811,29 @@ AddBasicConstraint(void *extHandle)
SECItem encodedValue;
SECStatus rv;
char buffer[10];
+ PRBool yesNoAns;
encodedValue.data = NULL;
encodedValue.len = 0;
do {
basicConstraint.pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT;
- puts ("Is this a CA certificate [y/n]?");
- gets (buffer);
- basicConstraint.isCA = (buffer[0] == 'Y' || buffer[0] == 'y') ?
- PR_TRUE : PR_FALSE;
+ basicConstraint.isCA = GetYesNo ("Is this a CA certificate [y/N]?");
+ buffer[0] = '\0';
puts ("Enter the path length constraint, enter to skip [<0 for unlimited path]:");
- gets (buffer);
+ Gets_s (buffer, sizeof(buffer));
if (PORT_Strlen (buffer) > 0)
- basicConstraint.pathLenConstraint = atoi (buffer);
+ basicConstraint.pathLenConstraint = PORT_Atoi (buffer);
rv = CERT_EncodeBasicConstraintValue (NULL, &basicConstraint, &encodedValue);
if (rv)
return (rv);
- buffer[0] = 'n';
- puts ("Is this a critical extension [y/n]? ");
- gets (buffer);
+ yesNoAns = GetYesNo ("Is this a critical extension [y/N]?");
+
rv = CERT_AddExtension
(extHandle, SEC_OID_X509_BASIC_CONSTRAINTS,
- &encodedValue, (buffer[0] == 'y' || buffer[0] == 'Y') ?
- PR_TRUE : PR_FALSE ,PR_TRUE);
+ &encodedValue, yesNoAns, PR_TRUE);
} while (0);
PORT_Free (encodedValue.data);
return (rv);
@@ -1875,7 +1922,7 @@ AddAuthKeyID (void *extHandle)
CERTAuthKeyID *authKeyID = NULL;
PRArenaPool *arena = NULL;
SECStatus rv = SECSuccess;
- char buffer[512];
+ PRBool yesNoAns;
do {
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
@@ -1884,7 +1931,7 @@ AddAuthKeyID (void *extHandle)
GEN_BREAK (SECFailure);
}
- if (GetYesNo ("Enter value for the authKeyID extension [y/n]?\n") == 0)
+ if (GetYesNo ("Enter value for the authKeyID extension [y/N]?") == 0)
break;
authKeyID = PORT_ArenaZAlloc (arena, sizeof (CERTAuthKeyID));
@@ -1904,13 +1951,10 @@ AddAuthKeyID (void *extHandle)
rv = GetString (arena, "Enter value for the authCertSerial field, enter to omit:",
&authKeyID->authCertSerialNumber);
- buffer[0] = 'n';
- puts ("Is this a critical extension [y/n]? ");
- gets (buffer);
+ yesNoAns = GetYesNo ("Is this a critical extension [y/N]?");
rv = SECU_EncodeAndAddExtensionValue
- (arena, extHandle, authKeyID,
- (buffer[0] == 'y' || buffer[0] == 'Y') ? PR_TRUE : PR_FALSE,
+ (arena, extHandle, authKeyID, yesNoAns,
SEC_OID_X509_AUTH_KEY_ID,
(EXTEN_EXT_VALUE_ENCODER) CERT_EncodeAuthKeyID);
if (rv)
@@ -1930,7 +1974,7 @@ AddCrlDistPoint(void *extHandle)
CRLDistributionPoint *current;
SECStatus rv = SECSuccess;
int count = 0, intValue;
- char buffer[5];
+ char buffer[512];
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( !arena )
@@ -1945,8 +1989,12 @@ AddCrlDistPoint(void *extHandle)
/* Get the distributionPointName fields - this field is optional */
puts ("Enter the type of the distribution point name:\n");
- puts ("\t1 - Full Name\n\t2 - Relative Name\n\tOther - omit\n\t\tChoice: ");
- scanf ("%d", &intValue);
+ puts ("\t1 - Full Name\n\t2 - Relative Name\n\tAny other number to finish\n\t\tChoice: ");
+ if (Gets_s (buffer, sizeof(buffer)) == NULL) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ GEN_BREAK (SECFailure);
+ }
+ intValue = PORT_Atoi (buffer);
switch (intValue) {
case generalName:
current->distPointType = intValue;
@@ -1956,12 +2004,13 @@ AddCrlDistPoint(void *extHandle)
case relativeDistinguishedName: {
CERTName *name;
- char buffer[512];
current->distPointType = intValue;
puts ("Enter the relative name: ");
fflush (stdout);
- gets (buffer);
+ if (Gets_s (buffer, sizeof(buffer)) == NULL) {
+ GEN_BREAK (SECFailure);
+ }
/* For simplicity, use CERT_AsciiToName to converse from a string
to NAME, but we only interest in the first RDN */
name = CERT_AsciiToName (buffer);
@@ -1980,9 +2029,21 @@ AddCrlDistPoint(void *extHandle)
puts ("\nSelect one of the following for the reason flags\n");
puts ("\t0 - unused\n\t1 - keyCompromise\n\t2 - caCompromise\n\t3 - affiliationChanged\n");
puts ("\t4 - superseded\n\t5 - cessationOfOperation\n\t6 - certificateHold\n");
- puts ("\tother - omit\t\tChoice: ");
+ puts ("\tAny other number to finish\t\tChoice: ");
- scanf ("%d", &intValue);
+ if (Gets_s (buffer, sizeof(buffer)) == NULL) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ GEN_BREAK (SECFailure);
+ }
+ intValue = PORT_Atoi (buffer);
+ if (intValue == 0) {
+ /* Checking that zero value of variable 'value'
+ * corresponds to '0' input made by user */
+ char *chPtr = strchr(buffer, '0');
+ if (chPtr == NULL) {
+ intValue = -1;
+ }
+ }
if (intValue >= 0 && intValue <8) {
current->reasons.data = PORT_ArenaAlloc (arena, sizeof(char));
if (current->reasons.data == NULL) {
@@ -2013,7 +2074,7 @@ AddCrlDistPoint(void *extHandle)
crlDistPoints->distPoints[count] = current;
++count;
- if (GetYesNo ("Enter more value for the CRL distribution point extension [y/n]\n") == 0) {
+ if (GetYesNo ("Enter more value for the CRL distribution point extension [y/N]") == 0) {
/* Add null to the end of the crlDistPoints to mark end of data */
crlDistPoints->distPoints = PORT_ArenaGrow(arena,
crlDistPoints->distPoints,
@@ -2027,13 +2088,10 @@ AddCrlDistPoint(void *extHandle)
} while (1);
if (rv == SECSuccess) {
- buffer[0] = 'n';
- puts ("Is this a critical extension [y/n]? ");
- gets (buffer);
+ PRBool yesNoAns = GetYesNo ("Is this a critical extension [y/N]?");
rv = SECU_EncodeAndAddExtensionValue(arena, extHandle, crlDistPoints,
- (buffer[0] == 'Y' || buffer[0] == 'y') ? PR_TRUE : PR_FALSE,
- SEC_OID_X509_CRL_DIST_POINTS,
+ yesNoAns, SEC_OID_X509_CRL_DIST_POINTS,
(EXTEN_EXT_VALUE_ENCODER) CERT_EncodeCRLDistributionPoints);
}
if (arena)
@@ -2748,8 +2806,7 @@ secuCommandFlag certutil_options[] =
certHandle = CERT_GetDefaultCertDB();
if (certutil.commands[cmd_Version].activated) {
- int version = CERT_GetDBContentVersion(certHandle);
- printf("Certificate database content version: %d\n", version);
+ printf("Certificate database content version: command not implemented.\n");
}
if (PL_strcmp(slotname, "internal") == 0)
diff --git a/security/nss/cmd/certutil/makefile.win b/security/nss/cmd/certutil/makefile.win
deleted file mode 100644
index 6e17cbab5..000000000
--- a/security/nss/cmd/certutil/makefile.win
+++ /dev/null
@@ -1,159 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-VERBOSE = 1
-include <manifest.mn>
-
-PROGRAM = certutil
-PROGRAM = $(OBJDIR)\$(PROGRAM).exe
-
-include <$(DEPTH)\config\config.mak>
-
-
-# let manifest generate C_OBJS, it will prepend ./$(OBJDIR)/
-# rules.mak will append C_OBJS onto OBJS.
-# OBJS = $(CSRCS:.c=.obj)
-
-# include files are looked for in $LINCS and $INCS.
-# $LINCS is in manifest.mnw, computed from REQUIRES=
-INCS = $(INCS) \
- -I$(DEPTH)/security/lib/cert \
- -I../include \
- $(NULL)
-
-IGNORE_ME = \
- -I$(DEPTH)/security/lib/key \
- -I$(DEPTH)/security/lib/util \
-
-
-WINFE = $(DEPTH)/cmd/winfe/mkfiles$(MOZ_BITS)/x86Dbg
-
-# these files are the content of libdbm
-DBM_LIB = \
- $(WINFE)/DB.obj \
- $(WINFE)/HASH.obj \
- $(WINFE)/H_BIGKEY.obj \
- $(WINFE)/H_PAGE.obj \
- $(WINFE)/H_LOG2.obj \
- $(WINFE)/H_FUNC.obj \
- $(WINFE)/HASH_BUF.obj \
- $(NULL)
-
-MOZ_LIBS = \
- $(WINFE)/ALLXPSTR.obj \
- $(WINFE)/XP_ERROR.obj \
- $(WINFE)/XPASSERT.obj \
- $(WINFE)/XP_REG.obj \
- $(WINFE)/XP_TRACE.obj \
- $(DBM_LIB) \
- $(WINFE)/XP_STR.obj \
- $(WINFE)/MKTEMP.obj \
- $(NULL)
-
-SEC_LIBS = \
- $(DIST)/lib/cert$(MOZ_BITS).lib \
- $(DIST)/lib/crypto$(MOZ_BITS).lib \
- $(DIST)/lib/hash$(MOZ_BITS).lib \
- $(DIST)/lib/key$(MOZ_BITS).lib \
- $(DIST)/lib/pkcs7$(MOZ_BITS).lib \
- $(DIST)/lib/secmod$(MOZ_BITS).lib \
- $(DIST)/lib/secutl$(MOZ_BITS).lib \
- $(DIST)/lib/ssl$(MOZ_BITS).lib \
- $(NULL)
-
-LLFLAGS = $(LLFLAGS) \
- ../lib/$(OBJDIR)/sectool$(MOZ_BITS).lib \
- $(SEC_LIBS) \
- $(MOZ_LIBS) \
- $(DEPTH)/nspr/src/$(OBJDIR)/getopt.obj \
- $(LIBNSPR) \
- $(NULL)
-
-
-# awt3240.lib # brpref32.lib # cert32.lib
-# crypto32.lib # dllcom.lib # editor32.lib
-# edpref32.lib # edtplug.lib # font.lib
-# hash32.lib # htmldg32.lib # img32.lib
-# javart32.lib # jbn3240.lib # jdb3240.lib
-# jmc.lib # jpeg3240.lib # jpw3240.lib
-# jrt3240.lib # js3240.lib # jsd3240.lib
-# key32.lib # libapplet32.lib # libnjs32.lib
-# libnsc32.lib # libreg32.lib # mm3240.lib
-# mnpref32.lib # netcst32.lib # nsdlg32.lib
-# nsldap32.lib # nsldaps32.lib # nsn32.lib
-# pkcs1232.lib # pkcs732.lib # pr3240.lib
-# prefui32.lib # prefuuid.lib # secmod32.lib
-# secnav32.lib # secutl32.lib # softup32.lib
-# sp3240.lib # ssl32.lib # uni3200.lib
-# unicvt32.lib # win32md.lib # winfont.lib
-# xppref32.lib # zlib32.lib
-
-include <$(DEPTH)\config\rules.mak>
-
-
-INSTALL = $(MAKE_INSTALL)
-
-objs: $(OBJS)
-
-$(PROGRAM)::
- $(INSTALL) $(DIST)/bin/pr3240.dll ./$(OBJDIR)
-
-programs: $(PROGRAM)
-
-install:: $(TARGETS)
- $(INSTALL) $(TARGETS) $(DIST)/bin
-
-# ALLXPSTR.obj XP_ALLOC.obj XP_HASH.obj XP_RGB.obj XP_WRAP.obj
-# CXPRINT.obj XP_C.cl XP_LIST.obj XP_SEC.obj netscape.exp
-# CXPRNDLG.obj XP_CNTXT.obj XP_MD5.obj XP_STR.obj xp.pch
-# EXPORT.obj XP_CORE.obj XP_MESG.obj XP_THRMO.obj xppref32.dll
-# XPASSERT.obj XP_ERROR.obj XP_RECT.obj XP_TIME.obj
-# XPLOCALE.obj XP_FILE.obj XP_REG.obj XP_TRACE.obj
-
-symbols:
- @echo "CSRCS = $(CSRCS)"
- @echo "INCS = $(INCS)"
- @echo "OBJS = $(OBJS)"
- @echo "LIBRARY = $(LIBRARY)"
- @echo "PROGRAM = $(PROGRAM)"
- @echo "TARGETS = $(TARGETS)"
- @echo "DIST = $(DIST)"
- @echo "VERSION_NUMBER = $(VERSION_NUMBER)"
- @echo "WINFE = $(WINFE)"
- @echo "DBM_LIB = $(DBM_LIB)"
- @echo "INSTALL = $(INSTALL)"
-
diff --git a/security/nss/cmd/checkcert/makefile.win b/security/nss/cmd/checkcert/makefile.win
deleted file mode 100644
index 19e9cbc5a..000000000
--- a/security/nss/cmd/checkcert/makefile.win
+++ /dev/null
@@ -1,134 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-VERBOSE = 1
-include <manifest.mn>
-
-#cannot define PROGRAM in manifest compatibly with NT and UNIX
-PROGRAM = checkcert
-PROGRAM = ./$(OBJDIR)/$(PROGRAM).exe
-include <$(DEPTH)\config\config.mak>
-
-# let manifest generate C_OBJS, it will prepend ./$(OBJDIR)/
-# rules.mak will append C_OBJS onto OBJS.
-# OBJS = $(CSRCS:.c=.obj)
-
-# include files are looked for in $LINCS and $INCS.
-# $LINCS is in manifest.mnw, computed from REQUIRES=
-INCS = $(INCS) \
- -I$(DEPTH)/security/lib/cert \
- -I../include \
- $(NULL)
-
-IGNORE_ME = \
- -I$(DEPTH)/security/lib/key \
- -I$(DEPTH)/security/lib/util \
- $(NULL)
-
-
-WINFE = $(DEPTH)/cmd/winfe/mkfiles$(MOZ_BITS)/x86Dbg
-
-# these files are the content of libdbm
-DBM_LIB = \
- $(WINFE)/DB.obj \
- $(WINFE)/HASH.obj \
- $(WINFE)/H_BIGKEY.obj \
- $(WINFE)/H_PAGE.obj \
- $(WINFE)/H_LOG2.obj \
- $(WINFE)/H_FUNC.obj \
- $(WINFE)/HASH_BUF.obj \
- $(NULL)
-
-MOZ_LIBS = \
- $(WINFE)/ALLXPSTR.obj \
- $(WINFE)/XP_ERROR.obj \
- $(WINFE)/XPASSERT.obj \
- $(WINFE)/XP_REG.obj \
- $(WINFE)/XP_TRACE.obj \
- $(DBM_LIB) \
- $(WINFE)/XP_STR.obj \
- $(WINFE)/MKTEMP.obj \
- $(NULL)
-
-SEC_LIBS = \
- $(DIST)/lib/cert$(MOZ_BITS).lib \
- $(DIST)/lib/crypto$(MOZ_BITS).lib \
- $(DIST)/lib/hash$(MOZ_BITS).lib \
- $(DIST)/lib/key$(MOZ_BITS).lib \
- $(DIST)/lib/pkcs7$(MOZ_BITS).lib \
- $(DIST)/lib/secmod$(MOZ_BITS).lib \
- $(DIST)/lib/secutl$(MOZ_BITS).lib \
- $(DIST)/lib/ssl$(MOZ_BITS).lib \
- $(NULL)
-
-LLFLAGS = $(LLFLAGS) \
- ../lib/$(OBJDIR)/sectool$(MOZ_BITS).lib \
- $(SEC_LIBS) \
- $(MOZ_LIBS) \
- $(DEPTH)/nspr/src/$(OBJDIR)/getopt.obj \
- $(LIBNSPR) \
- $(NULL)
-
-
-include <$(DEPTH)\config\rules.mak>
-
-INSTALL = $(MAKE_INSTALL)
-
-objs: $(OBJS)
-
-$(PROGRAM)::
- $(INSTALL) $(DIST)/bin/pr3240.dll ./$(OBJDIR)
-
-programs: $(PROGRAM)
-
-install:: $(TARGETS)
- $(INSTALL) $(TARGETS) $(DIST)/bin
-
-
-symbols:
- @echo "CSRCS = $(CSRCS)"
- @echo "INCS = $(INCS)"
- @echo "OBJS = $(OBJS)"
- @echo "LIBRARY = $(LIBRARY)"
- @echo "PROGRAM = $(PROGRAM)"
- @echo "TARGETS = $(TARGETS)"
- @echo "DIST = $(DIST)"
- @echo "VERSION_NUMBER = $(VERSION_NUMBER)"
- @echo "WINFE = $(WINFE)"
- @echo "DBM_LIB = $(DBM_LIB)"
- @echo "INSTALL = $(INSTALL)"
-
diff --git a/security/nss/cmd/crlutil/makefile.win b/security/nss/cmd/crlutil/makefile.win
deleted file mode 100644
index b509d4bc7..000000000
--- a/security/nss/cmd/crlutil/makefile.win
+++ /dev/null
@@ -1,134 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-VERBOSE = 1
-include <manifest.mn>
-
-#cannot define PROGRAM in manifest compatibly with NT and UNIX
-PROGRAM = crlutil
-PROGRAM = ./$(OBJDIR)/$(PROGRAM).exe
-include <$(DEPTH)\config\config.mak>
-
-# let manifest generate C_OBJS, it will prepend ./$(OBJDIR)/
-# rules.mak will append C_OBJS onto OBJS.
-# OBJS = $(CSRCS:.c=.obj)
-
-# include files are looked for in $LINCS and $INCS.
-# $LINCS is in manifest.mnw, computed from REQUIRES=
-INCS = $(INCS) \
- -I$(DEPTH)/security/lib/cert \
- -I../include \
- $(NULL)
-
-IGNORE_ME = \
- -I$(DEPTH)/security/lib/key \
- -I$(DEPTH)/security/lib/util \
- $(NULL)
-
-
-WINFE = $(DEPTH)/cmd/winfe/mkfiles$(MOZ_BITS)/x86Dbg
-
-# these files are the content of libdbm
-DBM_LIB = \
- $(WINFE)/DB.obj \
- $(WINFE)/HASH.obj \
- $(WINFE)/H_BIGKEY.obj \
- $(WINFE)/H_PAGE.obj \
- $(WINFE)/H_LOG2.obj \
- $(WINFE)/H_FUNC.obj \
- $(WINFE)/HASH_BUF.obj \
- $(NULL)
-
-MOZ_LIBS = \
- $(WINFE)/ALLXPSTR.obj \
- $(WINFE)/XP_ERROR.obj \
- $(WINFE)/XPASSERT.obj \
- $(WINFE)/XP_REG.obj \
- $(WINFE)/XP_TRACE.obj \
- $(DBM_LIB) \
- $(WINFE)/XP_STR.obj \
- $(WINFE)/MKTEMP.obj \
- $(NULL)
-
-SEC_LIBS = \
- $(DIST)/lib/cert$(MOZ_BITS).lib \
- $(DIST)/lib/crypto$(MOZ_BITS).lib \
- $(DIST)/lib/hash$(MOZ_BITS).lib \
- $(DIST)/lib/key$(MOZ_BITS).lib \
- $(DIST)/lib/pkcs7$(MOZ_BITS).lib \
- $(DIST)/lib/secmod$(MOZ_BITS).lib \
- $(DIST)/lib/secutl$(MOZ_BITS).lib \
- $(DIST)/lib/ssl$(MOZ_BITS).lib \
- $(NULL)
-
-LLFLAGS = $(LLFLAGS) \
- ../lib/$(OBJDIR)/sectool$(MOZ_BITS).lib \
- $(SEC_LIBS) \
- $(MOZ_LIBS) \
- $(DEPTH)/nspr/src/$(OBJDIR)/getopt.obj \
- $(LIBNSPR) \
- $(NULL)
-
-
-include <$(DEPTH)\config\rules.mak>
-
-INSTALL = $(MAKE_INSTALL)
-
-objs: $(OBJS)
-
-$(PROGRAM)::
- $(INSTALL) $(DIST)/bin/pr3240.dll ./$(OBJDIR)
-
-programs: $(PROGRAM)
-
-install:: $(TARGETS)
- $(INSTALL) $(TARGETS) $(DIST)/bin
-
-
-symbols:
- @echo "CSRCS = $(CSRCS)"
- @echo "INCS = $(INCS)"
- @echo "OBJS = $(OBJS)"
- @echo "LIBRARY = $(LIBRARY)"
- @echo "PROGRAM = $(PROGRAM)"
- @echo "TARGETS = $(TARGETS)"
- @echo "DIST = $(DIST)"
- @echo "VERSION_NUMBER = $(VERSION_NUMBER)"
- @echo "WINFE = $(WINFE)"
- @echo "DBM_LIB = $(DBM_LIB)"
- @echo "INSTALL = $(INSTALL)"
-
diff --git a/security/nss/cmd/crmftest/Makefile b/security/nss/cmd/crmftest/Makefile
index fa074c984..66d334a7d 100644
--- a/security/nss/cmd/crmftest/Makefile
+++ b/security/nss/cmd/crmftest/Makefile
@@ -67,11 +67,7 @@ ifeq ($(OS_TARGET)$(OS_RELEASE), SunOS5.6)
OS_LIBS += -ldl -lxnet -lposix4 -lsocket -lnsl
endif
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-EXTRA_LIBS += $(DIST)/lib/crmf.lib
-else
-EXTRA_LIBS += $(DIST)/lib/libcrmf.$(LIB_SUFFIX)
-endif
+EXTRA_LIBS += $(DIST)/lib/$(LIB_PREFIX)crmf.$(LIB_SUFFIX)
include ../platlibs.mk
diff --git a/security/nss/cmd/crmftest/testcrmf.c b/security/nss/cmd/crmftest/testcrmf.c
index 42cae81e5..11f96ab75 100644
--- a/security/nss/cmd/crmftest/testcrmf.c
+++ b/security/nss/cmd/crmftest/testcrmf.c
@@ -128,6 +128,7 @@ PRTime notBefore;
char *personalCert = NULL;
char *recoveryEncrypter = NULL;
char *caCertName = NULL;
+static secuPWData pwdata = { PW_NONE, 0 };
char *configdir;
PRBool doingDSA = PR_FALSE;
@@ -171,23 +172,6 @@ get_serial_number(long *dest)
return SECSuccess;
}
-char *
-promptForPassword (PK11SlotInfo *slot, PRBool retry, void *cx)
-{
- char passWord[80];
- char *retPass = NULL;
-
- if (retry) {
- printf ("Incorrect password. Please re-enter the password.\n");
- }
- printf ("WARNING: Password will be echoed to the screen.\n");
- printf ("Please enter the password for slot \"%s\":",
- PK11_GetTokenName(slot));
- scanf ("%s", passWord);
- retPass = PORT_Strdup(passWord);
- return retPass;
-}
-
PK11RSAGenParams *
GetRSAParams(void)
{
@@ -205,20 +189,6 @@ GetRSAParams(void)
}
-SECStatus
-SetSlotPassword(PK11SlotInfo *slot)
-{
- char userPin[80];
-
- printf ("Initialization of PIN's for your Database.\n");
- printf ("------------------------------------------\n");
- printf ("Please enter the PIN's for your Database.\n");
- printf ("Warning: ALL PIN'S WILL BE ECHOED TO SCREEN!!!\n");
- printf ("Now enter the PIN for the user: ");
- scanf ("%s", userPin);
- return PK11_InitPin (slot, NULL, userPin);
-}
-
PQGParams*
GetDSAParams(void)
{
@@ -245,15 +215,10 @@ GetSubjectPubKeyInfo(TESTKeyPair *pair)
SECKEYPrivateKey *privKey = NULL;
SECKEYPublicKey *pubKey = NULL;
PK11SlotInfo *keySlot = NULL;
- PK11SlotInfo *cryptoSlot = NULL;
keySlot = PK11_GetInternalKeySlot();
- PK11_Authenticate(keySlot, PR_FALSE, NULL);
+ PK11_Authenticate(keySlot, PR_FALSE, &pwdata);
- /* the slot authentication logic in this program needs an OVERHAUL. */
- cryptoSlot = PK11_GetInternalSlot();
- PK11_Authenticate(cryptoSlot, PR_FALSE, NULL);
- PK11_FreeSlot(cryptoSlot);
if (!doingDSA) {
PK11RSAGenParams *rsaParams = GetRSAParams();
@@ -263,7 +228,7 @@ GetSubjectPubKeyInfo(TESTKeyPair *pair)
}
privKey = PK11_GenerateKeyPair(keySlot, CKM_RSA_PKCS_KEY_PAIR_GEN,
(void*)rsaParams, &pubKey, PR_FALSE,
- PR_FALSE, NULL);
+ PR_FALSE, &pwdata);
} else {
PQGParams *dsaParams = GetDSAParams();
if (dsaParams == NULL) {
@@ -272,7 +237,7 @@ GetSubjectPubKeyInfo(TESTKeyPair *pair)
}
privKey = PK11_GenerateKeyPair(keySlot, CKM_DSA_KEY_PAIR_GEN,
(void*)dsaParams, &pubKey, PR_FALSE,
- PR_FALSE, NULL);
+ PR_FALSE, &pwdata);
}
PK11_FreeSlot(keySlot);
if (privKey == NULL || pubKey == NULL) {
@@ -295,33 +260,20 @@ GetSubjectPubKeyInfo(TESTKeyPair *pair)
SECStatus
InitPKCS11(void)
{
-#if 1
- PK11_SetPasswordFunc(promptForPassword);
-#else
- PK11SlotInfo *cryptoSlot, *keySlot;
+ PK11SlotInfo *keySlot;
- PK11_SetPasswordFunc(promptForPassword);
+ PK11_SetPasswordFunc(SECU_GetModulePassword);
- cryptoSlot = PK11_GetInternalSlot();
keySlot = PK11_GetInternalKeySlot();
- if (PK11_NeedUserInit(cryptoSlot) && PK11_NeedLogin(cryptoSlot)) {
- if (SetSlotPassword (cryptoSlot) != SECSuccess) {
- printf ("Initializing the PINs failed.\n");
- return SECFailure;
- }
- }
-
if (PK11_NeedUserInit(keySlot) && PK11_NeedLogin(keySlot)) {
- if (SetSlotPassword (keySlot) != SECSuccess) {
+ if (SECU_ChangePW(keySlot, NULL, NULL) != SECSuccess) {
printf ("Initializing the PINs failed.\n");
return SECFailure;
}
}
- PK11_FreeSlot(cryptoSlot);
PK11_FreeSlot(keySlot);
-#endif
return SECSuccess;
}
@@ -341,13 +293,17 @@ GetExtensions(void)
{
unsigned char keyUsage[4] = { 0x03, 0x02, 0x07, KU_DIGITAL_SIGNATURE };
/* What are these magic numbers? */
- SECItem data = { 0, keyUsage, sizeof keyUsage };
-
- CRMFCertExtension *extension =
- CRMF_CreateCertExtension(SEC_OID_X509_KEY_USAGE, PR_FALSE, &data);
+ SECItem data = { 0, NULL, 0 };
+ CRMFCertExtension *extension;
CRMFCertExtCreationInfo *extInfo =
PORT_ZNew(CRMFCertExtCreationInfo);
+ data.data = keyUsage;
+ data.len = sizeof keyUsage;
+
+
+ extension =
+ CRMF_CreateCertExtension(SEC_OID_X509_KEY_USAGE, PR_FALSE, &data);
if (extension && extInfo) {
extInfo->numExtensions = 1;
extInfo->extensions = PORT_ZNewArray(CRMFCertExtension*, 1);
@@ -590,7 +546,7 @@ AddProofOfPossession(TESTKeyPair *pair,
switch(inPOPChoice){
case crmfSignature:
CRMF_CertReqMsgSetSignaturePOP(pair->certReqMsg, pair->privKey,
- pair->pubKey, NULL, NULL, NULL);
+ pair->pubKey, NULL, NULL, &pwdata);
break;
case crmfRAVerified:
CRMF_CertReqMsgSetRAVerifiedPOP(pair->certReqMsg);
@@ -865,7 +821,7 @@ EncodeCMMFRecoveryMessage(const char * filePath,
rv = 409;
goto finish;
}
- privKey = PK11_FindKeyByAnyCert(cert, NULL);
+ privKey = PK11_FindKeyByAnyCert(cert, &pwdata);
if (privKey == NULL) {
printf ("Could not get the private key associated with the\n"
"certificate %s\n", personalCert);
@@ -1190,7 +1146,7 @@ DoKeyRecovery( SECKEYPrivateKey *privKey)
PK11_FreeSlot(slot);
return 509;
}
- caPrivKey = PK11_FindKeyByAnyCert(caCert, NULL);
+ caPrivKey = PK11_FindKeyByAnyCert(caCert, &pwdata);
if (CMMF_KeyRecRepContentGetPKIStatusInfoStatus(keyRecRep) !=
cmmfGranted) {
PORT_Free(ciphertext);
@@ -1212,7 +1168,7 @@ DoKeyRecovery( SECKEYPrivateKey *privKey)
&nickname,
PK11_GetInternalKeySlot(),
db,
- &unwrappedPrivKey, NULL);
+ &unwrappedPrivKey, &pwdata);
CMMF_DestroyCertifiedKeyPair(certKeyPair);
if (rv != SECSuccess) {
printf ("Unwrapping the private key failed.\n");
@@ -1303,7 +1259,7 @@ DoChallengeResponse(SECKEYPrivateKey *privKey,
randomNums[i],
myGenName,
pubKey,
- NULL);
+ &pwdata);
if (rv != SECSuccess) {
printf ("Could not set the challenge in DoChallengeResponse\n");
return 903;
@@ -1352,7 +1308,7 @@ DoChallengeResponse(SECKEYPrivateKey *privKey,
printf ("Could not make the keyID from the public value\n");
return 909;
}
- foundPrivKey = PK11_FindKeyByKeyID(privKey->pkcs11Slot,keyID, NULL);
+ foundPrivKey = PK11_FindKeyByKeyID(privKey->pkcs11Slot, keyID, &pwdata);
if (foundPrivKey == NULL) {
printf ("Could not find the private key corresponding to the public"
" value.\n");
@@ -1535,7 +1491,7 @@ Usage (void)
{
printf ("Usage:\n"
"\tcrmftest -d [Database Directory] -p [Personal Cert]\n"
- "\t -e [Encrypter] -s [CA Certificate]\n\n"
+ "\t -e [Encrypter] -s [CA Certificate] [-P password]\n\n"
"\t [crmf] [dsa] [decode] [cmmf] [recover] [challenge]\n"
"Database Directory\n"
"\tThis is the directory where the key3.db, cert7.db, and\n"
@@ -1597,6 +1553,7 @@ main(int argc, char **argv)
TESTKeyPair signPair, cryptPair;
PLOptState *optstate;
PLOptStatus status;
+ char *password = NULL;
int irv = 0;
PRUint32 flags = 0;
SECStatus rv;
@@ -1604,11 +1561,12 @@ main(int argc, char **argv)
PRBool pArg = PR_FALSE;
PRBool eArg = PR_FALSE;
PRBool sArg = PR_FALSE;
+ PRBool PArg = PR_FALSE;
memset( &signPair, 0, sizeof signPair);
memset( &cryptPair, 0, sizeof cryptPair);
printf ("\ncrmftest v1.0\n");
- optstate = PL_CreateOptState(argc, argv, "d:p:e:s:");
+ optstate = PL_CreateOptState(argc, argv, "d:p:e:s:P:");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case 'd':
@@ -1644,6 +1602,14 @@ main(int argc, char **argv)
}
sArg = PR_TRUE;
break;
+ case 'P':
+ password = PORT_Strdup(optstate->value);
+ if (password == NULL) {
+ printf ("-P failed\n");
+ return 606;
+ }
+ PArg = PR_TRUE;
+ break;
case 0: /* positional parameter */
rv = parsePositionalParam(optstate->value, &flags);
if (rv) {
@@ -1665,6 +1631,10 @@ main(int argc, char **argv)
flags = ~ TEST_USE_DSA;
db = CERT_GetDefaultCertDB();
InitPKCS11();
+ if (password) {
+ pwdata.source = PW_PLAINTEXT;
+ pwdata.data = password;
+ }
if (flags & TEST_MAKE_CRMF_REQ) {
printf("Generating CRMF request\n");
diff --git a/security/nss/cmd/dbtest/makefile.win b/security/nss/cmd/dbtest/makefile.win
deleted file mode 100644
index a5e351621..000000000
--- a/security/nss/cmd/dbtest/makefile.win
+++ /dev/null
@@ -1,134 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-VERBOSE = 1
-include <manifest.mn>
-
-#cannot define PROGRAM in manifest compatibly with NT and UNIX
-PROGRAM = dbtest
-PROGRAM = ./$(OBJDIR)/$(PROGRAM).exe
-include <$(DEPTH)\config\config.mak>
-
-# let manifest generate C_OBJS, it will prepend ./$(OBJDIR)/
-# rules.mak will append C_OBJS onto OBJS.
-# OBJS = $(CSRCS:.c=.obj)
-
-# include files are looked for in $LINCS and $INCS.
-# $LINCS is in manifest.mnw, computed from REQUIRES=
-INCS = $(INCS) \
- -I$(DEPTH)/security/lib/cert \
- -I../include \
- $(NULL)
-
-IGNORE_ME = \
- -I$(DEPTH)/security/lib/key \
- -I$(DEPTH)/security/lib/util \
- $(NULL)
-
-
-WINFE = $(DEPTH)/cmd/winfe/mkfiles$(MOZ_BITS)/x86Dbg
-
-# these files are the content of libdbm
-DBM_LIB = \
- $(WINFE)/DB.obj \
- $(WINFE)/HASH.obj \
- $(WINFE)/H_BIGKEY.obj \
- $(WINFE)/H_PAGE.obj \
- $(WINFE)/H_LOG2.obj \
- $(WINFE)/H_FUNC.obj \
- $(WINFE)/HASH_BUF.obj \
- $(NULL)
-
-MOZ_LIBS = \
- $(WINFE)/ALLXPSTR.obj \
- $(WINFE)/XP_ERROR.obj \
- $(WINFE)/XPASSERT.obj \
- $(WINFE)/XP_REG.obj \
- $(WINFE)/XP_TRACE.obj \
- $(DBM_LIB) \
- $(WINFE)/XP_STR.obj \
- $(WINFE)/MKTEMP.obj \
- $(NULL)
-
-SEC_LIBS = \
- $(DIST)/lib/cert$(MOZ_BITS).lib \
- $(DIST)/lib/crypto$(MOZ_BITS).lib \
- $(DIST)/lib/hash$(MOZ_BITS).lib \
- $(DIST)/lib/key$(MOZ_BITS).lib \
- $(DIST)/lib/pkcs7$(MOZ_BITS).lib \
- $(DIST)/lib/secmod$(MOZ_BITS).lib \
- $(DIST)/lib/secutl$(MOZ_BITS).lib \
- $(DIST)/lib/ssl$(MOZ_BITS).lib \
- $(NULL)
-
-LLFLAGS = $(LLFLAGS) \
- ../lib/$(OBJDIR)/sectool$(MOZ_BITS).lib \
- $(SEC_LIBS) \
- $(MOZ_LIBS) \
- $(DEPTH)/nspr/src/$(OBJDIR)/getopt.obj \
- $(LIBNSPR) \
- $(NULL)
-
-
-include <$(DEPTH)\config\rules.mak>
-
-INSTALL = $(MAKE_INSTALL)
-
-objs: $(OBJS)
-
-$(PROGRAM)::
- $(INSTALL) $(DIST)/bin/pr3240.dll ./$(OBJDIR)
-
-programs: $(PROGRAM)
-
-install:: $(TARGETS)
- $(INSTALL) $(TARGETS) $(DIST)/bin
-
-
-symbols:
- @echo "CSRCS = $(CSRCS)"
- @echo "INCS = $(INCS)"
- @echo "OBJS = $(OBJS)"
- @echo "LIBRARY = $(LIBRARY)"
- @echo "PROGRAM = $(PROGRAM)"
- @echo "TARGETS = $(TARGETS)"
- @echo "DIST = $(DIST)"
- @echo "VERSION_NUMBER = $(VERSION_NUMBER)"
- @echo "WINFE = $(WINFE)"
- @echo "DBM_LIB = $(DBM_LIB)"
- @echo "INSTALL = $(INSTALL)"
-
diff --git a/security/nss/cmd/derdump/makefile.win b/security/nss/cmd/derdump/makefile.win
deleted file mode 100644
index 727feb587..000000000
--- a/security/nss/cmd/derdump/makefile.win
+++ /dev/null
@@ -1,134 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-VERBOSE = 1
-include <manifest.mn>
-
-#cannot define PROGRAM in manifest compatibly with NT and UNIX
-PROGRAM = derdump
-PROGRAM = ./$(OBJDIR)/$(PROGRAM).exe
-include <$(DEPTH)\config\config.mak>
-
-# let manifest generate C_OBJS, it will prepend ./$(OBJDIR)/
-# rules.mak will append C_OBJS onto OBJS.
-# OBJS = $(CSRCS:.c=.obj)
-
-# include files are looked for in $LINCS and $INCS.
-# $LINCS is in manifest.mnw, computed from REQUIRES=
-INCS = $(INCS) \
- -I$(DEPTH)/security/lib/cert \
- -I../include \
- $(NULL)
-
-IGNORE_ME = \
- -I$(DEPTH)/security/lib/key \
- -I$(DEPTH)/security/lib/util \
- $(NULL)
-
-
-WINFE = $(DEPTH)/cmd/winfe/mkfiles$(MOZ_BITS)/x86Dbg
-
-# these files are the content of libdbm
-DBM_LIB = \
- $(WINFE)/DB.obj \
- $(WINFE)/HASH.obj \
- $(WINFE)/H_BIGKEY.obj \
- $(WINFE)/H_PAGE.obj \
- $(WINFE)/H_LOG2.obj \
- $(WINFE)/H_FUNC.obj \
- $(WINFE)/HASH_BUF.obj \
- $(NULL)
-
-MOZ_LIBS = \
- $(WINFE)/ALLXPSTR.obj \
- $(WINFE)/XP_ERROR.obj \
- $(WINFE)/XPASSERT.obj \
- $(WINFE)/XP_REG.obj \
- $(WINFE)/XP_TRACE.obj \
- $(DBM_LIB) \
- $(WINFE)/XP_STR.obj \
- $(WINFE)/MKTEMP.obj \
- $(NULL)
-
-SEC_LIBS = \
- $(DIST)/lib/cert$(MOZ_BITS).lib \
- $(DIST)/lib/crypto$(MOZ_BITS).lib \
- $(DIST)/lib/hash$(MOZ_BITS).lib \
- $(DIST)/lib/key$(MOZ_BITS).lib \
- $(DIST)/lib/pkcs7$(MOZ_BITS).lib \
- $(DIST)/lib/secmod$(MOZ_BITS).lib \
- $(DIST)/lib/secutl$(MOZ_BITS).lib \
- $(DIST)/lib/ssl$(MOZ_BITS).lib \
- $(NULL)
-
-LLFLAGS = $(LLFLAGS) \
- ../lib/$(OBJDIR)/sectool$(MOZ_BITS).lib \
- $(SEC_LIBS) \
- $(MOZ_LIBS) \
- $(DEPTH)/nspr/src/$(OBJDIR)/getopt.obj \
- $(LIBNSPR) \
- $(NULL)
-
-
-include <$(DEPTH)\config\rules.mak>
-
-INSTALL = $(MAKE_INSTALL)
-
-objs: $(OBJS)
-
-$(PROGRAM)::
- $(INSTALL) $(DIST)/bin/pr3240.dll ./$(OBJDIR)
-
-programs: $(PROGRAM)
-
-install:: $(TARGETS)
- $(INSTALL) $(TARGETS) $(DIST)/bin
-
-
-symbols:
- @echo "CSRCS = $(CSRCS)"
- @echo "INCS = $(INCS)"
- @echo "OBJS = $(OBJS)"
- @echo "LIBRARY = $(LIBRARY)"
- @echo "PROGRAM = $(PROGRAM)"
- @echo "TARGETS = $(TARGETS)"
- @echo "DIST = $(DIST)"
- @echo "VERSION_NUMBER = $(VERSION_NUMBER)"
- @echo "WINFE = $(WINFE)"
- @echo "DBM_LIB = $(DBM_LIB)"
- @echo "INSTALL = $(INSTALL)"
-
diff --git a/security/nss/cmd/digest/makefile.win b/security/nss/cmd/digest/makefile.win
deleted file mode 100644
index d40214301..000000000
--- a/security/nss/cmd/digest/makefile.win
+++ /dev/null
@@ -1,134 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-VERBOSE = 1
-include <manifest.mn>
-
-#cannot define PROGRAM in manifest compatibly with NT and UNIX
-PROGRAM = digest
-PROGRAM = ./$(OBJDIR)/$(PROGRAM).exe
-include <$(DEPTH)\config\config.mak>
-
-# let manifest generate C_OBJS, it will prepend ./$(OBJDIR)/
-# rules.mak will append C_OBJS onto OBJS.
-# OBJS = $(CSRCS:.c=.obj)
-
-# include files are looked for in $LINCS and $INCS.
-# $LINCS is in manifest.mnw, computed from REQUIRES=
-INCS = $(INCS) \
- -I$(DEPTH)/security/lib/cert \
- -I../include \
- $(NULL)
-
-IGNORE_ME = \
- -I$(DEPTH)/security/lib/key \
- -I$(DEPTH)/security/lib/util \
- $(NULL)
-
-
-WINFE = $(DEPTH)/cmd/winfe/mkfiles$(MOZ_BITS)/x86Dbg
-
-# these files are the content of libdbm
-DBM_LIB = \
- $(WINFE)/DB.obj \
- $(WINFE)/HASH.obj \
- $(WINFE)/H_BIGKEY.obj \
- $(WINFE)/H_PAGE.obj \
- $(WINFE)/H_LOG2.obj \
- $(WINFE)/H_FUNC.obj \
- $(WINFE)/HASH_BUF.obj \
- $(NULL)
-
-MOZ_LIBS = \
- $(WINFE)/ALLXPSTR.obj \
- $(WINFE)/XP_ERROR.obj \
- $(WINFE)/XPASSERT.obj \
- $(WINFE)/XP_REG.obj \
- $(WINFE)/XP_TRACE.obj \
- $(DBM_LIB) \
- $(WINFE)/XP_STR.obj \
- $(WINFE)/MKTEMP.obj \
- $(NULL)
-
-SEC_LIBS = \
- $(DIST)/lib/cert$(MOZ_BITS).lib \
- $(DIST)/lib/crypto$(MOZ_BITS).lib \
- $(DIST)/lib/hash$(MOZ_BITS).lib \
- $(DIST)/lib/key$(MOZ_BITS).lib \
- $(DIST)/lib/pkcs7$(MOZ_BITS).lib \
- $(DIST)/lib/secmod$(MOZ_BITS).lib \
- $(DIST)/lib/secutl$(MOZ_BITS).lib \
- $(DIST)/lib/ssl$(MOZ_BITS).lib \
- $(NULL)
-
-LLFLAGS = $(LLFLAGS) \
- ../lib/$(OBJDIR)/sectool$(MOZ_BITS).lib \
- $(SEC_LIBS) \
- $(MOZ_LIBS) \
- $(DEPTH)/nspr/src/$(OBJDIR)/getopt.obj \
- $(LIBNSPR) \
- $(NULL)
-
-
-include <$(DEPTH)\config\rules.mak>
-
-INSTALL = $(MAKE_INSTALL)
-
-objs: $(OBJS)
-
-$(PROGRAM)::
- $(INSTALL) $(DIST)/bin/pr3240.dll ./$(OBJDIR)
-
-programs: $(PROGRAM)
-
-install:: $(TARGETS)
- $(INSTALL) $(TARGETS) $(DIST)/bin
-
-
-symbols:
- @echo "CSRCS = $(CSRCS)"
- @echo "INCS = $(INCS)"
- @echo "OBJS = $(OBJS)"
- @echo "LIBRARY = $(LIBRARY)"
- @echo "PROGRAM = $(PROGRAM)"
- @echo "TARGETS = $(TARGETS)"
- @echo "DIST = $(DIST)"
- @echo "VERSION_NUMBER = $(VERSION_NUMBER)"
- @echo "WINFE = $(WINFE)"
- @echo "DBM_LIB = $(DBM_LIB)"
- @echo "INSTALL = $(INSTALL)"
-
diff --git a/security/nss/cmd/fipstest/Makefile b/security/nss/cmd/fipstest/Makefile
index db7ac49ca..3b8ea808a 100755
--- a/security/nss/cmd/fipstest/Makefile
+++ b/security/nss/cmd/fipstest/Makefile
@@ -1,86 +1,85 @@
-#! gmake
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-#MKPROG = purify -cache-dir=/u/mcgreer/pcache -best-effort \
-# -always-use-cache-dir $(CC)
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include ../platlibs.mk
-
-#EXTRA_SHARED_LIBS += \
-# -L/usr/lib \
-# -lposix4 \
-# $(NULL)
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-include ../platrules.mk
+#! gmake
+#
+# ***** BEGIN LICENSE BLOCK *****
+# 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 Netscape security libraries.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1994-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# 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.
+#
+# ***** END LICENSE BLOCK *****
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+#MKPROG = purify -cache-dir=/u/mcgreer/pcache -best-effort \
+# -always-use-cache-dir $(CC)
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+ifdef NSS_ENABLE_ECC
+DEFINES += -DNSS_ENABLE_ECC
+endif
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+include ../platrules.mk
diff --git a/security/nss/cmd/fipstest/aes.sh b/security/nss/cmd/fipstest/aes.sh
new file mode 100644
index 000000000..09ed494bf
--- /dev/null
+++ b/security/nss/cmd/fipstest/aes.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST AES Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+cbc_kat_requests="
+CBCGFSbox128.req
+CBCGFSbox192.req
+CBCGFSbox256.req
+CBCKeySbox128.req
+CBCKeySbox192.req
+CBCKeySbox256.req
+CBCVarKey128.req
+CBCVarKey192.req
+CBCVarKey256.req
+CBCVarTxt128.req
+CBCVarTxt192.req
+CBCVarTxt256.req
+"
+
+cbc_mct_requests="
+CBCMCT128.req
+CBCMCT192.req
+CBCMCT256.req
+"
+
+cbc_mmt_requests="
+CBCMMT128.req
+CBCMMT192.req
+CBCMMT256.req
+"
+
+ecb_kat_requests="
+ECBGFSbox128.req
+ECBGFSbox192.req
+ECBGFSbox256.req
+ECBKeySbox128.req
+ECBKeySbox192.req
+ECBKeySbox256.req
+ECBVarKey128.req
+ECBVarKey192.req
+ECBVarKey256.req
+ECBVarTxt128.req
+ECBVarTxt192.req
+ECBVarTxt256.req
+"
+
+ecb_mct_requests="
+ECBMCT128.req
+ECBMCT192.req
+ECBMCT256.req
+"
+
+ecb_mmt_requests="
+ECBMMT128.req
+ECBMMT192.req
+ECBMMT256.req
+"
+
+for request in $ecb_kat_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes kat ecb $request > $response
+done
+for request in $ecb_mmt_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes mmt ecb $request > $response
+done
+for request in $ecb_mct_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes mct ecb $request > $response
+done
+for request in $cbc_kat_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes kat cbc $request > $response
+done
+for request in $cbc_mmt_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes mmt cbc $request > $response
+done
+for request in $cbc_mct_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest aes mct cbc $request > $response
+done
diff --git a/security/nss/cmd/fipstest/ecdsa.sh b/security/nss/cmd/fipstest/ecdsa.sh
new file mode 100644
index 000000000..306c8650f
--- /dev/null
+++ b/security/nss/cmd/fipstest/ecdsa.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST ECDSA Validation System
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+request=KeyPair.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest ecdsa keypair $request > $response
+
+request=PKV.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest ecdsa pkv $request > $response
+
+request=SigGen.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest ecdsa siggen $request > $response
+
+request=SigVer.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest ecdsa sigver $request > $response
diff --git a/security/nss/cmd/fipstest/fipstest.c b/security/nss/cmd/fipstest/fipstest.c
index cd657da6b..c602cbc2d 100644
--- a/security/nss/cmd/fipstest/fipstest.c
+++ b/security/nss/cmd/fipstest/fipstest.c
@@ -36,299 +36,30 @@
#include <stdio.h>
#include <stdlib.h>
+#include <ctype.h>
+#include "secitem.h"
#include "blapi.h"
#include "nss.h"
+#include "secerr.h"
+#include "secoidt.h"
+#include "keythi.h"
+#include "ec.h"
+#if 0
#include "../../lib/freebl/mpi/mpi.h"
+#endif
-static const unsigned char
-table3[32][8] = {
- { 0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31 },
- { 0x10, 0x07, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20 },
- { 0x10, 0x07, 0x10, 0x34, 0xc8, 0x98, 0x01, 0x20 },
- { 0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20 },
- { 0x10, 0x86, 0x91, 0x15, 0x19, 0x19, 0x01, 0x01 },
- { 0x10, 0x86, 0x91, 0x15, 0x19, 0x58, 0x01, 0x01 },
- { 0x51, 0x07, 0xb0, 0x15, 0x19, 0x58, 0x01, 0x01 },
- { 0x10, 0x07, 0xb0, 0x15, 0x19, 0x19, 0x01, 0x01 },
- { 0x31, 0x07, 0x91, 0x54, 0x98, 0x08, 0x01, 0x01 },
- { 0x31, 0x07, 0x91, 0x94, 0x98, 0x08, 0x01, 0x01 },
- { 0x10, 0x07, 0x91, 0x15, 0xb9, 0x08, 0x01, 0x40 },
- { 0x31, 0x07, 0x91, 0x15, 0x98, 0x08, 0x01, 0x40 },
- { 0x10, 0x07, 0xd0, 0x15, 0x89, 0x98, 0x01, 0x01 },
- { 0x91, 0x07, 0x91, 0x15, 0x89, 0x98, 0x01, 0x01 },
- { 0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01 },
- { 0x10, 0x07, 0xd0, 0x15, 0x98, 0x98, 0x01, 0x20 },
- { 0x10, 0x07, 0x94, 0x04, 0x98, 0x19, 0x01, 0x01 },
- { 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x04, 0x01 },
- { 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x01, 0x01 },
- { 0x01, 0x07, 0x94, 0x04, 0x91, 0x19, 0x04, 0x01 },
- { 0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01 },
- { 0x10, 0x07, 0x91, 0x19, 0x98, 0x19, 0x08, 0x01 },
- { 0x10, 0x07, 0x91, 0x19, 0x98, 0x1a, 0x08, 0x01 },
- { 0x10, 0x07, 0x92, 0x10, 0x98, 0x19, 0x01, 0x01 },
- { 0x10, 0x07, 0x91, 0x15, 0x98, 0x19, 0x01, 0x0b },
- { 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x01 },
- { 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x02 },
- { 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x08 },
- { 0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x01, 0x04 },
- { 0x10, 0x02, 0x91, 0x15, 0x98, 0x19, 0x01, 0x04 },
- { 0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x02, 0x01 },
- { 0x10, 0x02, 0x91, 0x16, 0x98, 0x10, 0x01, 0x01 }
-};
-
-static const unsigned char
-table4_key[19][8] = {
- { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 },
- { 0x01, 0x31, 0xd9, 0x61, 0x9d, 0xc1, 0x37, 0x6e },
- { 0x07, 0xa1, 0x13, 0x3e, 0x4a, 0x0b, 0x26, 0x86 },
- { 0x38, 0x49, 0x67, 0x4c, 0x26, 0x02, 0x31, 0x9e },
- { 0x04, 0xb9, 0x15, 0xba, 0x43, 0xfe, 0xb5, 0xb6 },
- { 0x01, 0x13, 0xb9, 0x70, 0xfd, 0x34, 0xf2, 0xce },
- { 0x01, 0x70, 0xf1, 0x75, 0x46, 0x8f, 0xb5, 0xe6 },
- { 0x43, 0x29, 0x7f, 0xad, 0x38, 0xe3, 0x73, 0xfe },
- { 0x07, 0xa7, 0x13, 0x70, 0x45, 0xda, 0x2a, 0x16 },
- { 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f },
- { 0x37, 0xd0, 0x6b, 0xb5, 0x16, 0xcb, 0x75, 0x46 },
- { 0x1f, 0x08, 0x26, 0x0d, 0x1a, 0xc2, 0x46, 0x5e },
- { 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76 },
- { 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xb0, 0x07 },
- { 0x49, 0x79, 0x3e, 0xbc, 0x79, 0xb3, 0x25, 0x8f },
- { 0x4f, 0xb0, 0x5e, 0x15, 0x15, 0xab, 0x73, 0xa7 },
- { 0x49, 0xe9, 0x5d, 0x6d, 0x4c, 0xa2, 0x29, 0xbf },
- { 0x01, 0x83, 0x10, 0xdc, 0x40, 0x9b, 0x26, 0xd6 },
- { 0x1c, 0x58, 0x7f, 0x1c, 0x13, 0x92, 0x4f, 0xef }
-};
-
-static const unsigned char
-table4_inp[19][8] = {
- { 0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42 },
- { 0x5c, 0xd5, 0x4c, 0xa8, 0x3d, 0xef, 0x57, 0xda },
- { 0x02, 0x48, 0xd4, 0x38, 0x06, 0xf6, 0x71, 0x72 },
- { 0x51, 0x45, 0x4b, 0x58, 0x2d, 0xdf, 0x44, 0x0a },
- { 0x42, 0xfd, 0x44, 0x30, 0x59, 0x57, 0x7f, 0xa2 },
- { 0x05, 0x9b, 0x5e, 0x08, 0x51, 0xcf, 0x14, 0x3a },
- { 0x07, 0x56, 0xd8, 0xe0, 0x77, 0x47, 0x61, 0xd2 },
- { 0x76, 0x25, 0x14, 0xb8, 0x29, 0xbf, 0x48, 0x6a },
- { 0x3b, 0xdd, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02 },
- { 0x26, 0x95, 0x5f, 0x68, 0x35, 0xaf, 0x60, 0x9a },
- { 0x16, 0x4d, 0x5e, 0x40, 0x4f, 0x27, 0x52, 0x32 },
- { 0x6b, 0x05, 0x6e, 0x18, 0x75, 0x9f, 0x5c, 0xca },
- { 0x00, 0x4b, 0xd6, 0xef, 0x09, 0x17, 0x60, 0x62 },
- { 0x48, 0x0d, 0x39, 0x00, 0x6e, 0xe7, 0x62, 0xf2 },
- { 0x43, 0x75, 0x40, 0xc8, 0x69, 0x8f, 0x3c, 0xfa },
- { 0x07, 0x2d, 0x43, 0xa0, 0x77, 0x07, 0x52, 0x92 },
- { 0x02, 0xfe, 0x55, 0x77, 0x81, 0x17, 0xf1, 0x2a },
- { 0x1d, 0x9d, 0x5c, 0x50, 0x18, 0xf7, 0x28, 0xc2 },
- { 0x30, 0x55, 0x32, 0x28, 0x6d, 0x6f, 0x29, 0x5a }
-};
+#ifdef NSS_ENABLE_ECC
+extern SECStatus
+EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams);
+#endif
-static const unsigned char
-des_ecb_enc_sample_key[8] = { 0x97, 0xae, 0x43, 0x08, 0xb6, 0xa8, 0x7a, 0x08 };
-static const unsigned char
-des_ecb_enc_sample_inp[8] = { 0xcf, 0xcd, 0x91, 0xf1, 0xb3, 0x40, 0xc9, 0x91 };
-
-static const unsigned char
-des_ecb_dec_sample_key[8] = { 0x0b, 0x8c, 0x38, 0xef, 0x52, 0x01, 0xda, 0x13 };
-static const unsigned char
-des_ecb_dec_sample_inp[8] = { 0x58, 0x0b, 0x39, 0x57, 0x3d, 0x9b, 0x8d, 0xdf };
-
-static const unsigned char
-des_cbc_enc_sample_key[8] = { 0x58, 0x62, 0xd3, 0xf8, 0x04, 0xe9, 0xb3, 0x98 };
-static const unsigned char
-des_cbc_enc_sample_iv[8] = { 0xac, 0xcf, 0x45, 0x4c, 0x1a, 0x28, 0x68, 0xcf };
-static const unsigned char
-des_cbc_enc_sample_inp[8] = { 0xf1, 0x55, 0x47, 0x63, 0x76, 0x0e, 0x43, 0xa9 };
-
-static const unsigned char
-des_cbc_dec_sample_key[8] = { 0x64, 0x6d, 0x02, 0x75, 0xe9, 0x34, 0xe6, 0x7a };
-static const unsigned char
-des_cbc_dec_sample_iv[8] = { 0xb4, 0x32, 0xa3, 0x8c, 0xd5, 0xe3, 0x20, 0x1a };
-static const unsigned char
-des_cbc_dec_sample_inp[8] = { 0x5a, 0xfe, 0xe8, 0xf2, 0xf6, 0x63, 0x4f, 0xb6 };
-
-static const unsigned char
-tdea_ecb_enc_sample_key[24] = {
- 0x0b, 0x62, 0x7f, 0x67, 0xea, 0xda, 0x0b, 0x34,
- 0x08, 0x07, 0x3b, 0xc8, 0x8c, 0x23, 0x1a, 0xb6,
- 0x75, 0x0b, 0x9e, 0x57, 0x83, 0xf4, 0xe6, 0xa4 };
-static const unsigned char
-tdea_ecb_enc_sample_inp[8] = { 0x44, 0x15, 0x7a, 0xb0, 0x0a, 0x78, 0x6d, 0xbf };
-
-static const unsigned char
-tdea_ecb_dec_sample_key[24] = {
- 0x91, 0xe5, 0x07, 0xba, 0x01, 0x01, 0xb6, 0xdc,
- 0x0e, 0x51, 0xf1, 0xd0, 0x25, 0xc2, 0xc2, 0x1c,
- 0x1f, 0x54, 0x2f, 0xa1, 0xf8, 0xce, 0xda, 0x89 };
-static const unsigned char
-tdea_ecb_dec_sample_inp[8] = { 0x66, 0xe8, 0x72, 0x0d, 0x42, 0x85, 0x4b, 0xba };
-
-static const unsigned char
-tdea_cbc_enc_sample_key[24] = {
- 0xd5, 0xe5, 0x61, 0x61, 0xb0, 0xc4, 0xa4, 0x25,
- 0x45, 0x1a, 0x15, 0x67, 0xa4, 0x89, 0x6b, 0xc4,
- 0x3b, 0x54, 0x1a, 0x4c, 0x1a, 0xb5, 0x49, 0x0d };
-static const unsigned char
-tdea_cbc_enc_sample_iv[8] = { 0x5a, 0xb2, 0xa7, 0x3e, 0xc4, 0x3c, 0xe7, 0x1e };
-static const unsigned char
-tdea_cbc_enc_sample_inp[8] = { 0x9e, 0x76, 0x87, 0x7c, 0x54, 0x14, 0xab, 0x50 };
-
-static const unsigned char
-tdea_cbc_dec_sample_key[24] = {
- 0xf8, 0x25, 0xcd, 0x02, 0xc7, 0x76, 0xe6, 0xce,
- 0x9e, 0x16, 0xe6, 0x40, 0x7f, 0xcd, 0x01, 0x80,
- 0x5b, 0x38, 0xc4, 0xe0, 0xb5, 0x6e, 0x94, 0x61 };
-static const unsigned char
-tdea_cbc_dec_sample_iv[8] = { 0x74, 0x3e, 0xdc, 0xc2, 0xc6, 0xc4, 0x18, 0xe3 };
-static const unsigned char
-tdea_cbc_dec_sample_inp[8] = { 0xbe, 0x47, 0xd1, 0x77, 0xa5, 0xe8, 0x29, 0xfb };
-
-
-static const unsigned char
-des_ecb_enc_key[8] = { 0x49, 0x45, 0xd9, 0x3d, 0x83, 0xcd, 0x61, 0x9b };
-static const unsigned char
-des_ecb_enc_inp[8] = { 0x81, 0xf2, 0x12, 0x0d, 0x99, 0x04, 0x5d, 0x16 };
-
-static const unsigned char
-des_ecb_dec_key[8] = { 0x7a, 0x6b, 0x61, 0x76, 0xc8, 0x85, 0x43, 0x31 };
-static const unsigned char
-des_ecb_dec_inp[8] = { 0xef, 0xe4, 0x6e, 0x4f, 0x4f, 0xc3, 0x28, 0xcc };
-
-static const unsigned char
-des_cbc_enc_key[8] = { 0xc8, 0x5e, 0xfd, 0xa7, 0xa7, 0xc2, 0xc4, 0x0d };
-static const unsigned char
-des_cbc_enc_iv[8] = { 0x4c, 0xb9, 0xcf, 0x46, 0xff, 0x7a, 0x3d, 0xff };
-static const unsigned char
-des_cbc_enc_inp[8] = { 0x80, 0x1b, 0x24, 0x9b, 0x24, 0x0e, 0xa5, 0x96 };
-
-static const unsigned char
-des_cbc_dec_key[8] = { 0x2c, 0x3d, 0xa1, 0x67, 0x4c, 0xfb, 0x85, 0x23 };
-static const unsigned char
-des_cbc_dec_iv[8] = { 0x7a, 0x0a, 0xc2, 0x15, 0x1d, 0x22, 0x98, 0x3a };
-static const unsigned char
-des_cbc_dec_inp[8] = { 0x2d, 0x5d, 0x02, 0x04, 0x98, 0x5d, 0x5e, 0x28 };
-
-static const unsigned char
-tdea1_ecb_enc_key[24] = {
- 0x89, 0xcd, 0xd3, 0xf1, 0x01, 0xc1, 0x1a, 0xf4,
- 0x89, 0xcd, 0xd3, 0xf1, 0x01, 0xc1, 0x1a, 0xf4,
- 0x89, 0xcd, 0xd3, 0xf1, 0x01, 0xc1, 0x1a, 0xf4 };
-
-static const unsigned char
-tdea1_ecb_enc_inp[8] = { 0xe5, 0x8c, 0x48, 0xf0, 0x91, 0x4e, 0xeb, 0x87 };
-
-static const unsigned char
-tdea1_ecb_dec_key[24] = {
- 0xbf, 0x86, 0x94, 0xe0, 0x83, 0x46, 0x70, 0x37,
- 0xbf, 0x86, 0x94, 0xe0, 0x83, 0x46, 0x70, 0x37,
- 0xbf, 0x86, 0x94, 0xe0, 0x83, 0x46, 0x70, 0x37 };
-
-static const unsigned char
-tdea1_ecb_dec_inp[8] = { 0x35, 0x7a, 0x6c, 0x05, 0xe0, 0x8c, 0x3d, 0xb7 };
-
-static const unsigned char
-tdea1_cbc_enc_key[24] = {
- 0x46, 0xf1, 0x6d, 0xbf, 0xe3, 0xd5, 0xd3, 0x94,
- 0x46, 0xf1, 0x6d, 0xbf, 0xe3, 0xd5, 0xd3, 0x94,
- 0x46, 0xf1, 0x6d, 0xbf, 0xe3, 0xd5, 0xd3, 0x94 };
-
-
-static const unsigned char
-tdea1_cbc_enc_iv[8] = { 0xf7, 0x3e, 0x14, 0x05, 0x88, 0xeb, 0x2e, 0x96 };
-static const unsigned char
-tdea1_cbc_enc_inp[8] = { 0x18, 0x1b, 0xdf, 0x18, 0x10, 0xb2, 0xe0, 0x05 };
-
-static const unsigned char
-tdea1_cbc_dec_key[24] = {
- 0x83, 0xd0, 0x54, 0xa2, 0x92, 0xe9, 0x6e, 0x7c,
- 0x83, 0xd0, 0x54, 0xa2, 0x92, 0xe9, 0x6e, 0x7c,
- 0x83, 0xd0, 0x54, 0xa2, 0x92, 0xe9, 0x6e, 0x7c };
-
-
-static const unsigned char
-tdea1_cbc_dec_iv[8] = { 0xb9, 0x65, 0x4a, 0x94, 0xba, 0x6a, 0x66, 0xf9 };
-static const unsigned char
-tdea1_cbc_dec_inp[8] = { 0xce, 0xb8, 0x30, 0x95, 0xac, 0x82, 0xdf, 0x9b };
-
-static const unsigned char
-tdea2_ecb_enc_key[24] = {
- 0x79, 0x98, 0x4a, 0xe9, 0x23, 0xad, 0x10, 0xda,
- 0x16, 0x3e, 0xb5, 0xfe, 0xcd, 0x52, 0x20, 0x01,
- 0x79, 0x98, 0x4a, 0xe9, 0x23, 0xad, 0x10, 0xda };
-static const unsigned char
-tdea2_ecb_enc_inp[8] = { 0x99, 0xd2, 0xca, 0xe8, 0xa7, 0x90, 0x13, 0xc2 };
-
-static const unsigned char
-tdea2_ecb_dec_key[24] = {
- 0x98, 0xcd, 0x29, 0x52, 0x85, 0x91, 0x75, 0xe3,
- 0xab, 0x29, 0xe3, 0x10, 0xa2, 0x10, 0x04, 0x58,
- 0x98, 0xcd, 0x29, 0x52, 0x85, 0x91, 0x75, 0xe3 };
-
-static const unsigned char
-tdea2_ecb_dec_inp[8] = { 0xc0, 0x35, 0x24, 0x1f, 0xc9, 0x29, 0x5c, 0x7a };
-
-static const unsigned char
-tdea2_cbc_enc_key[24] = {
- 0xba, 0x5d, 0x70, 0xf8, 0x08, 0x13, 0xb0, 0x4c,
- 0xf8, 0x46, 0xa8, 0xce, 0xe6, 0xb3, 0x08, 0x02,
- 0xba, 0x5d, 0x70, 0xf8, 0x08, 0x13, 0xb0, 0x4c };
-
-
-static const unsigned char
-tdea2_cbc_enc_iv[8] = { 0xe8, 0x39, 0xd7, 0x3a, 0x8d, 0x8c, 0x59, 0x8a };
-static const unsigned char
-tdea2_cbc_enc_inp[8] = { 0x6e, 0x85, 0x0a, 0x4c, 0x86, 0x86, 0x70, 0x23 };
-
-static const unsigned char
-tdea2_cbc_dec_key[24] = {
- 0x25, 0xf8, 0x9e, 0x7a, 0xef, 0x26, 0xb5, 0x9e,
- 0x46, 0x32, 0x19, 0x9b, 0xea, 0x1c, 0x19, 0xad,
- 0x25, 0xf8, 0x9e, 0x7a, 0xef, 0x26, 0xb5, 0x9e };
-
-
-static const unsigned char
-tdea2_cbc_dec_iv[8] = { 0x48, 0x07, 0x6f, 0xf9, 0x05, 0x14, 0xc1, 0xdc };
-static const unsigned char
-tdea2_cbc_dec_inp[8] = { 0x9e, 0xf4, 0x10, 0x55, 0xe8, 0x7e, 0x7e, 0x25 };
-
-static const unsigned char
-tdea3_ecb_enc_key[24] = {
- 0x6d, 0x37, 0x16, 0x31, 0x6e, 0x02, 0x83, 0xb6,
- 0xf7, 0x16, 0xa2, 0x64, 0x57, 0x8c, 0xae, 0x34,
- 0xd0, 0xce, 0x38, 0xb6, 0x31, 0x5e, 0xae, 0x1a };
-static const unsigned char
-tdea3_ecb_enc_inp[8] = { 0x28, 0x8a, 0x45, 0x22, 0x53, 0x95, 0xba, 0x3c };
-
-static const unsigned char
-tdea3_ecb_dec_key[24] = {
- 0xb0, 0x75, 0x92, 0x2c, 0xfd, 0x67, 0x8a, 0x26,
- 0xc8, 0xba, 0xad, 0x68, 0xb6, 0xba, 0x92, 0x49,
- 0xe3, 0x2c, 0xec, 0x83, 0x34, 0xe6, 0xda, 0x98 };
-static const unsigned char
-tdea3_ecb_dec_inp[8] = { 0x03, 0xcc, 0xe6, 0x65, 0xf6, 0xc5, 0xc3, 0xba };
-
-static const unsigned char
-tdea3_cbc_enc_key[24] = {
- 0x01, 0x32, 0x73, 0xe9, 0xcb, 0x8a, 0x89, 0x80,
- 0x02, 0x7a, 0xc1, 0x5d, 0xf4, 0xd5, 0x6b, 0x76,
- 0x2f, 0xef, 0xfd, 0x58, 0x57, 0x1a, 0xce, 0x29 };
-static const unsigned char
-tdea3_cbc_enc_iv[8] = { 0x93, 0x98, 0x7c, 0x66, 0x98, 0x21, 0x5b, 0x9e };
-static const unsigned char
-tdea3_cbc_enc_inp[8] = { 0x16, 0x54, 0x09, 0xd2, 0x2c, 0xad, 0x6d, 0x99 };
-
-static const unsigned char
-tdea3_cbc_dec_key[24] = {
- 0x57, 0x70, 0x3b, 0x4f, 0xae, 0xe6, 0x9d, 0x0e,
- 0x4c, 0x3b, 0x23, 0xcd, 0x54, 0x20, 0xbc, 0x58,
- 0x3b, 0x8a, 0x4a, 0xf1, 0x73, 0xf8, 0xf8, 0x38 };
-static const unsigned char
-tdea3_cbc_dec_iv[8] = { 0x5f, 0x62, 0xe4, 0xea, 0xa7, 0xb2, 0xb5, 0x70 };
-static const unsigned char
-tdea3_cbc_dec_inp[8] = { 0x44, 0xb3, 0xe6, 0x3b, 0x1f, 0xbb, 0x43, 0x02 };
+#define ENCRYPT 1
+#define DECRYPT 0
+#define BYTE unsigned char
SECStatus
-hex_from_2char(unsigned char *c2, unsigned char *byteval)
+hex_from_2char(const unsigned char *c2, unsigned char *byteval)
{
int i;
unsigned char offset;
@@ -367,9 +98,9 @@ char2_from_hex(unsigned char byteval, unsigned char *c2, char a)
}
void
-to_hex_str(char *str, unsigned char *buf, unsigned int len)
+to_hex_str(char *str, const unsigned char *buf, unsigned int len)
{
- int i;
+ unsigned int i;
for (i=0; i<len; i++) {
char2_from_hex(buf[i], &str[2*i], 'a');
}
@@ -377,466 +108,1703 @@ to_hex_str(char *str, unsigned char *buf, unsigned int len)
}
void
-to_hex_str_cap(char *str, unsigned char *buf, unsigned int len)
+to_hex_str_cap(char *str, const unsigned char *buf, unsigned int len)
{
- int i;
+ unsigned int i;
for (i=0; i<len; i++) {
char2_from_hex(buf[i], &str[2*i], 'A');
}
+ str[2*len] = '\0';
}
-void
-des_var_pt_kat(int mode, PRBool encrypt, unsigned int len,
- unsigned char *key, unsigned char *iv,
- unsigned char *inp)
+/*
+ * Convert a string of hex digits (str) to an array (buf) of len bytes.
+ * Return PR_TRUE if the hex string can fit in the byte array. Return
+ * PR_FALSE if the hex string is empty or is too long.
+ */
+PRBool
+from_hex_str(unsigned char *buf, unsigned int len, const char *str)
{
- int i;
- unsigned int olen, mbnum = 0;
- unsigned char mod_byte = 0x80;
- unsigned char in[8];
- unsigned char out[8];
- char keystr[17], ivstr[17], instr[17], outstr[17];
- char *ptty = (len == 8) ? "PT" : "PLAINTEXT";
- char *ctty = (len == 8) ? "CT" : "CIPHERTEXT";
- char tchar = (len == 8) ? '\t' : '\n';
- DESContext *cx1 = NULL, *cx2 = NULL;
- memset(in, 0, sizeof in);
- memset(keystr, 0, sizeof keystr);
- memset(ivstr, 0, sizeof ivstr);
- memset(instr, 0, sizeof instr);
- memset(outstr, 0, sizeof outstr);
- in[mbnum] = mod_byte;
- for (i=1; i<=64; i++) {
- cx1 = DES_CreateContext(key, iv, mode, PR_TRUE);
- if (!encrypt) {
- cx2 = DES_CreateContext(key, iv, mode, PR_FALSE);
- }
- if (len > 8) {
- printf("COUNT = %d\n", i);
- to_hex_str(keystr, key, 8);
- printf("KEY1=%s\n", keystr);
- to_hex_str(keystr, key+8, 8);
- printf("KEY2=%s\n", keystr);
- to_hex_str(keystr, key+16, 8);
- printf("KEY3=%s\n", keystr);
- } else {
- to_hex_str(keystr, key, 8);
- printf("%ld\tKEY=%s\t", i, keystr);
- }
- if (iv) {
- to_hex_str(ivstr, iv, 8);
- printf("IV=%s%c", ivstr, tchar);
- }
- DES_Encrypt(cx1, out, &olen, 8, in, 8);
- if (encrypt) {
- to_hex_str(instr, in, 8);
- to_hex_str(outstr, out, 8);
- printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr);
- } else {
- unsigned char inv[8];
- DES_Decrypt(cx2, inv, &olen, 8, out, 8);
- to_hex_str(instr, out, 8);
- to_hex_str(outstr, inv, 8);
- printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr);
+ unsigned int nxdigit; /* number of hex digits in str */
+ unsigned int i; /* index into buf */
+ unsigned int j; /* index into str */
+
+ /* count the hex digits */
+ nxdigit = 0;
+ for (nxdigit = 0; isxdigit(str[nxdigit]); nxdigit++) {
+ /* empty body */
+ }
+ if (nxdigit == 0) {
+ return PR_FALSE;
+ }
+ if (nxdigit > 2*len) {
+ /*
+ * The input hex string is too long, but we allow it if the
+ * extra digits are leading 0's.
+ */
+ for (j = 0; j < nxdigit-2*len; j++) {
+ if (str[j] != '0') {
+ return PR_FALSE;
+ }
}
- if (mod_byte > 0x01) {
- mod_byte >>= 1;
+ /* skip leading 0's */
+ str += nxdigit-2*len;
+ nxdigit = 2*len;
+ }
+ for (i=0, j=0; i< len; i++) {
+ if (2*i < 2*len-nxdigit) {
+ /* Handle a short input as if we padded it with leading 0's. */
+ if (2*i+1 < 2*len-nxdigit) {
+ buf[i] = 0;
+ } else {
+ char tmp[2];
+ tmp[0] = '0';
+ tmp[1] = str[j];
+ hex_from_2char(tmp, &buf[i]);
+ j++;
+ }
} else {
- in[mbnum] = 0x00;
- mod_byte = 0x80;
- mbnum++;
- }
- in[mbnum] = mod_byte;
- DES_DestroyContext(cx1, PR_TRUE);
- if (cx2) {
- DES_DestroyContext(cx2, PR_TRUE);
+ hex_from_2char(&str[j], &buf[i]);
+ j += 2;
}
}
+ return PR_TRUE;
+}
+
+SECStatus
+tdea_encrypt_buf(
+ int mode,
+ const unsigned char *key,
+ const unsigned char *iv,
+ unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
+ const unsigned char *input, unsigned int inputlen)
+{
+ SECStatus rv = SECFailure;
+ DESContext *cx;
+ unsigned char doublecheck[8*20]; /* 1 to 20 blocks */
+ unsigned int doublechecklen = 0;
+
+ cx = DES_CreateContext(key, iv, mode, PR_TRUE);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = DES_Encrypt(cx, output, outputlen, maxoutputlen, input, inputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (*outputlen != inputlen) {
+ goto loser;
+ }
+ DES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+
+ /*
+ * Doublecheck our result by decrypting the ciphertext and
+ * compare the output with the input plaintext.
+ */
+ cx = DES_CreateContext(key, iv, mode, PR_FALSE);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = DES_Decrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
+ output, *outputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (doublechecklen != *outputlen) {
+ goto loser;
+ }
+ DES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ if (memcmp(doublecheck, input, inputlen) != 0) {
+ goto loser;
+ }
+ rv = SECSuccess;
+
+loser:
+ if (cx != NULL) {
+ DES_DestroyContext(cx, PR_TRUE);
+ }
+ return rv;
+}
+
+SECStatus
+tdea_decrypt_buf(
+ int mode,
+ const unsigned char *key,
+ const unsigned char *iv,
+ unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
+ const unsigned char *input, unsigned int inputlen)
+{
+ SECStatus rv = SECFailure;
+ DESContext *cx;
+ unsigned char doublecheck[8*20]; /* 1 to 20 blocks */
+ unsigned int doublechecklen = 0;
+
+ cx = DES_CreateContext(key, iv, mode, PR_FALSE);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = DES_Decrypt(cx, output, outputlen, maxoutputlen,
+ input, inputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (*outputlen != inputlen) {
+ goto loser;
+ }
+ DES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+
+ /*
+ * Doublecheck our result by encrypting the plaintext and
+ * compare the output with the input ciphertext.
+ */
+ cx = DES_CreateContext(key, iv, mode, PR_TRUE);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = DES_Encrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
+ output, *outputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (doublechecklen != *outputlen) {
+ goto loser;
+ }
+ DES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ if (memcmp(doublecheck, input, inputlen) != 0) {
+ goto loser;
+ }
+ rv = SECSuccess;
+
+loser:
+ if (cx != NULL) {
+ DES_DestroyContext(cx, PR_TRUE);
+ }
+ return rv;
}
+/*
+ * Perform the TDEA Known Answer Test (KAT) or Multi-block Message
+ * Test (MMT) in ECB or CBC mode. The KAT (there are five types)
+ * and MMT have the same structure: given the key and IV (CBC mode
+ * only), encrypt the given plaintext or decrypt the given ciphertext.
+ * So we can handle them the same way.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
void
-des_inv_perm_kat(int mode, PRBool encrypt, unsigned int len,
- unsigned char *key, unsigned char *iv,
- unsigned char *inp)
+tdea_kat_mmt(char *reqfn)
{
- int i;
- unsigned int olen, mbnum = 0;
- unsigned char mod_byte = 0x80;
- unsigned char in[8];
- unsigned char out[8];
- char keystr[17], ivstr[17], instr[17], outstr[17];
- char *ptty = (len == 8) ? "PT" : "PLAINTEXT";
- char *ctty = (len == 8) ? "CT" : "CIPHERTEXT";
- char tchar = (len == 8) ? '\t' : '\n';
- DESContext *cx1 = NULL, *cx2 = NULL;
- memset(in, 0, sizeof in);
- memset(keystr, 0, sizeof keystr);
- memset(ivstr, 0, sizeof ivstr);
- memset(instr, 0, sizeof instr);
- memset(outstr, 0, sizeof outstr);
- in[mbnum] = mod_byte;
- for (i=1; i<=64; i++) {
- if (encrypt) {
- cx1 = DES_CreateContext(key, iv, mode, PR_TRUE);
- cx2 = DES_CreateContext(key, iv, mode, PR_TRUE);
- } else {
- cx1 = DES_CreateContext(key, iv, mode, PR_FALSE);
- }
- if (len > 8) {
- printf("COUNT = %d\n", i);
- to_hex_str(keystr, key, 8);
- printf("KEY1=%s\n", keystr);
- to_hex_str(keystr, key+8, 8);
- printf("KEY2=%s\n", keystr);
- to_hex_str(keystr, key+16, 8);
- printf("KEY3=%s\n", keystr);
- } else {
- to_hex_str(keystr, key, 8);
- printf("%ld\tKEY=%s\t", i, keystr);
- }
- if (iv) {
- to_hex_str(ivstr, iv, 8);
- printf("IV=%s%c", ivstr, tchar);
- }
- if (encrypt) {
- unsigned char inv[8];
- DES_Encrypt(cx1, out, &olen, 8, in, 8);
- DES_Encrypt(cx2, inv, &olen, 8, out, 8);
- to_hex_str(instr, out, 8);
- to_hex_str(outstr, inv, 8);
- printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr);
- } else {
- DES_Decrypt(cx1, out, &olen, 8, in, 8);
- to_hex_str(instr, in, 8);
- to_hex_str(outstr, out, 8);
- printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr);
- }
- if (mod_byte > 0x01) {
- mod_byte >>= 1;
- } else {
- in[mbnum] = 0x00;
- mod_byte = 0x80;
- mbnum++;
- }
- in[mbnum] = mod_byte;
- DES_DestroyContext(cx1, PR_TRUE);
- if (cx2) {
- DES_DestroyContext(cx2, PR_TRUE);
- }
+ char buf[180]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "CIPHERTEXT = <180 hex digits>\n".
+ */
+ FILE *req; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+ int i, j;
+ int mode; /* NSS_DES_EDE3 (ECB) or NSS_DES_EDE3_CBC */
+ int crypt = DECRYPT; /* 1 means encrypt, 0 means decrypt */
+ unsigned char key[24]; /* TDEA 3 key bundle */
+ unsigned int numKeys = 0;
+ unsigned char iv[8]; /* for all modes except ECB */
+ unsigned char plaintext[8*20]; /* 1 to 20 blocks */
+ unsigned int plaintextlen;
+ unsigned char ciphertext[8*20]; /* 1 to 20 blocks */
+ unsigned int ciphertextlen;
+ SECStatus rv;
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ while (fgets(buf, sizeof buf, req) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, resp);
+ continue;
+ }
+ /* [ENCRYPT] or [DECRYPT] */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+ crypt = ENCRYPT;
+ } else {
+ crypt = DECRYPT;
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ /* NumKeys */
+ if (strncmp(&buf[0], "NumKeys", 7) == 0) {
+ i = 7;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ numKeys = buf[i];
+ fputs(buf, resp);
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* mode defaults to ECB, if dataset has IV mode will be set CBC */
+ mode = NSS_DES_EDE3;
+ /* zeroize the variables for the test with this data set */
+ memset(key, 0, sizeof key);
+ memset(iv, 0, sizeof iv);
+ memset(plaintext, 0, sizeof plaintext);
+ plaintextlen = 0;
+ memset(ciphertext, 0, sizeof ciphertext);
+ ciphertextlen = 0;
+ fputs(buf, resp);
+ continue;
+ }
+ if (numKeys == 0) {
+ if (strncmp(buf, "KEYs", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ key[j+8] = key[j];
+ key[j+16] = key[j];
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ } else {
+ /* KEY1 = ... */
+ if (strncmp(buf, "KEY1", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ /* KEY2 = ... */
+ if (strncmp(buf, "KEY2", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=8; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ /* KEY3 = ... */
+ if (strncmp(buf, "KEY3", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=16; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ }
+
+ /* IV = ... */
+ if (strncmp(buf, "IV", 2) == 0) {
+ mode = NSS_DES_EDE3_CBC;
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof iv; i+=2,j++) {
+ hex_from_2char(&buf[i], &iv[j]);
+ }
+ fputs(buf, resp);
+ continue;
+ }
+
+ /* PLAINTEXT = ... */
+ if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+ /* sanity check */
+ if (crypt != ENCRYPT) {
+ goto loser;
+ }
+ i = 9;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &plaintext[j]);
+ }
+ plaintextlen = j;
+ rv = tdea_encrypt_buf(mode, key,
+ (mode == NSS_DES_EDE3) ? NULL : iv,
+ ciphertext, &ciphertextlen, sizeof ciphertext,
+ plaintext, plaintextlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ fputs(buf, resp);
+ fputs("CIPHERTEXT = ", resp);
+ to_hex_str(buf, ciphertext, ciphertextlen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ continue;
+ }
+ /* CIPHERTEXT = ... */
+ if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+ /* sanity check */
+ if (crypt != DECRYPT) {
+ goto loser;
+ }
+
+ i = 10;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &ciphertext[j]);
+ }
+ ciphertextlen = j;
+
+ rv = tdea_decrypt_buf(mode, key,
+ (mode == NSS_DES_EDE3) ? NULL : iv,
+ plaintext, &plaintextlen, sizeof plaintext,
+ ciphertext, ciphertextlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ fputs(buf, resp);
+ fputs("PLAINTEXT = ", resp);
+ to_hex_str(buf, plaintext, plaintextlen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ continue;
+ }
}
+
+loser:
+ fclose(req);
}
+/*
+* Set the parity bit for the given byte
+*/
+BYTE odd_parity( BYTE in)
+{
+ BYTE out = in;
+ in ^= in >> 4;
+ in ^= in >> 2;
+ in ^= in >> 1;
+ return (BYTE)(out ^ !(in & 1));
+}
+
+/*
+ * Generate Keys [i+1] from Key[i], PT/CT[j-2], PT/CT[j-1], and PT/CT[j]
+ * for TDEA Monte Carlo Test (MCT) in ECB and CBC modes.
+ */
void
-des_var_key_kat(int mode, PRBool encrypt, unsigned int len,
- unsigned char *key, unsigned char *iv,
- unsigned char *inp)
+tdea_mct_next_keys(unsigned char *key,
+ const unsigned char *text_2, const unsigned char *text_1,
+ const unsigned char *text, unsigned int numKeys)
{
- int i;
- unsigned int olen, mbnum = 0;
- unsigned char mod_byte = 0x80;
- unsigned char keyin[24];
- unsigned char out[8];
- char keystr[17], ivstr[17], instr[17], outstr[17];
- char *ptty = (len == 8) ? "PT" : "PLAINTEXT";
- char *ctty = (len == 8) ? "CT" : "CIPHERTEXT";
- char tchar = (len == 8) ? '\t' : '\n';
- DESContext *cx1 = NULL, *cx2 = NULL;
- memset(keyin, 1, sizeof keyin);
- memset(keystr, 0, sizeof keystr);
- memset(ivstr, 0, sizeof ivstr);
- memset(instr, 0, sizeof instr);
- memset(outstr, 0, sizeof outstr);
- keyin[mbnum] = mod_byte;
- keyin[mbnum+8] = mod_byte;
- keyin[mbnum+16] = mod_byte;
- for (i=1; i<=56; i++) {
- cx1 = DES_CreateContext(keyin, iv, mode, PR_TRUE);
- if (!encrypt) {
- cx2 = DES_CreateContext(keyin, iv, mode, PR_FALSE);
+ int k;
+
+ /* key1[i+1] = key1[i] xor PT/CT[j] */
+ for (k=0; k<8; k++) {
+ key[k] ^= text[k];
+ }
+ /* key2 */
+ if (numKeys == 2 || numKeys == 3) {
+ /* key2 independent */
+ for (k=8; k<16; k++) {
+ /* key2[i+1] = KEY2[i] xor PT/CT[j-1] */
+ key[k] ^= text_1[k-8];
+ }
+ } else {
+ /* key2 == key 1 */
+ for (k=8; k<16; k++) {
+ /* key2[i+1] = KEY2[i] xor PT/CT[j] */
+ key[k] = key[k-8];
+ }
+ }
+ /* key3 */
+ if (numKeys == 1 || numKeys == 2) {
+ /* key3 == key 1 */
+ for (k=16; k<24; k++) {
+ /* key3[i+1] = KEY3[i] xor PT/CT[j] */
+ key[k] = key[k-16];
+ }
+ } else {
+ /* key3 independent */
+ for (k=16; k<24; k++) {
+ /* key3[i+1] = KEY3[i] xor PT/CT[j-2] */
+ key[k] ^= text_2[k-16];
+ }
+ }
+ /* set the parity bits */
+ for (k=0; k<24; k++) {
+ key[k] = odd_parity(key[k]);
+ }
+}
+
+/*
+ * Perform the Monte Carlo Test
+ *
+ * mode = NSS_DES_EDE3 or NSS_DES_EDE3_CBC
+ * crypt = ENCRYPT || DECRYPT
+ * inputtext = plaintext or Cyphertext depending on the value of crypt
+ * inputlength is expected to be size 8 bytes
+ * iv = needs to be set for NSS_DES_EDE3_CBC mode
+ * resp = is the output response file.
+ */
+ void
+tdea_mct_test(int mode, unsigned char* key, unsigned int numKeys,
+ unsigned int crypt, unsigned char* inputtext,
+ unsigned int inputlength, unsigned char* iv, FILE *resp) {
+
+ int i, j;
+ unsigned char outputtext_1[8]; /* PT/CT[j-1] */
+ unsigned char outputtext_2[8]; /* PT/CT[j-2] */
+ char buf[80]; /* holds one line from the input REQUEST file. */
+ unsigned int outputlen;
+ unsigned char outputtext[8];
+
+
+ SECStatus rv;
+
+ if (mode == NSS_DES_EDE3 && iv != NULL) {
+ printf("IV must be NULL for NSS_DES_EDE3 mode");
+ goto loser;
+ } else if (mode == NSS_DES_EDE3_CBC && iv == NULL) {
+ printf("IV must not be NULL for NSS_DES_EDE3_CBC mode");
+ goto loser;
+ }
+
+ /* loop 400 times */
+ for (i=0; i<400; i++) {
+ /* if i == 0 CV[0] = IV not necessary */
+ /* record the count and key values and plainText */
+ sprintf(buf, "COUNT = %d\n", i);
+ fputs(buf, resp);
+ /* Output KEY1[i] */
+ fputs("KEY1 = ", resp);
+ to_hex_str(buf, key, 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ /* Output KEY2[i] */
+ fputs("KEY2 = ", resp);
+ to_hex_str(buf, &key[8], 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ /* Output KEY3[i] */
+ fputs("KEY3 = ", resp);
+ to_hex_str(buf, &key[16], 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ if (mode == NSS_DES_EDE3_CBC) {
+ /* Output CV[i] */
+ fputs("IV = ", resp);
+ to_hex_str(buf, iv, 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ }
+ if (crypt == ENCRYPT) {
+ /* Output PT[0] */
+ fputs("PLAINTEXT = ", resp);
+ } else {
+ /* Output CT[0] */
+ fputs("CIPHERTEXT = ", resp);
+ }
+
+ to_hex_str(buf, inputtext, inputlength);
+ fputs(buf, resp);
+ fputc('\n', resp);
+
+ /* loop 10,000 times */
+ for (j=0; j<10000; j++) {
+
+ outputlen = 0;
+ if (crypt == ENCRYPT) {
+ /* inputtext == ciphertext outputtext == plaintext*/
+ rv = tdea_encrypt_buf(mode, key,
+ (mode == NSS_DES_EDE3) ? NULL : iv,
+ outputtext, &outputlen, 8,
+ inputtext, 8);
+ } else {
+ /* inputtext == plaintext outputtext == ciphertext */
+ rv = tdea_decrypt_buf(mode, key,
+ (mode == NSS_DES_EDE3) ? NULL : iv,
+ outputtext, &outputlen, 8,
+ inputtext, 8);
+ }
+
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != inputlength) {
+ goto loser;
+ }
+
+ if (mode == NSS_DES_EDE3_CBC) {
+ if (crypt == ENCRYPT) {
+ if (j == 0) {
+ /*P[j+1] = CV[0] */
+ memcpy(inputtext, iv, 8);
+ } else {
+ /* p[j+1] = C[j-1] */
+ memcpy(inputtext, outputtext_1, 8);
+ }
+ /* CV[j+1] = C[j] */
+ memcpy(iv, outputtext, 8);
+ if (j != 9999) {
+ /* save C[j-1] */
+ memcpy(outputtext_1, outputtext, 8);
+ }
+ } else { /* DECRYPT */
+ /* CV[j+1] = C[j] */
+ memcpy(iv, inputtext, 8);
+ /* C[j+1] = P[j] */
+ memcpy(inputtext, outputtext, 8);
+ }
+ } else {
+ /* ECB mode PT/CT[j+1] = CT/PT[j] */
+ memcpy(inputtext, outputtext, 8);
+ }
+
+ /* Save PT/CT[j-2] and PT/CT[j-1] */
+ if (j==9997) memcpy(outputtext_2, outputtext, 8);
+ if (j==9998) memcpy(outputtext_1, outputtext, 8);
+ /* done at the end of the for(j) loop */
+ }
+
+
+ if (crypt == ENCRYPT) {
+ /* Output CT[j] */
+ fputs("CIPHERTEXT = ", resp);
+ } else {
+ /* Output PT[j] */
+ fputs("PLAINTEXT = ", resp);
+ }
+ to_hex_str(buf, outputtext, 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+
+ /* Key[i+1] = Key[i] xor ... outputtext_2 == PT/CT[j-2]
+ * outputtext_1 == PT/CT[j-1] outputtext == PT/CT[j]
+ */
+ tdea_mct_next_keys(key, outputtext_2,
+ outputtext_1, outputtext, numKeys);
+
+ if (mode == NSS_DES_EDE3_CBC) {
+ /* taken care of in the j=9999 iteration */
+ if (crypt == ENCRYPT) {
+ /* P[i] = C[j-1] */
+ /* CV[i] = C[j] */
+ } else {
+ /* taken care of in the j=9999 iteration */
+ /* CV[i] = C[j] */
+ /* C[i] = P[j] */
+ }
+ } else {
+ /* ECB PT/CT[i] = PT/CT[j] */
+ memcpy(inputtext, outputtext, 8);
+ }
+ /* done at the end of the for(i) loop */
+ fputc('\n', resp);
+ }
+
+loser:
+ return;
+}
+
+/*
+ * Perform the TDEA Monte Carlo Test (MCT) in ECB/CBC modes.
+ * by gathering the input from the request file, and then
+ * calling tdea_mct_test.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+tdea_mct(int mode, char *reqfn)
+{
+ int i, j;
+ char buf[80]; /* holds one line from the input REQUEST file. */
+ FILE *req; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+ unsigned int crypt = 0; /* 1 means encrypt, 0 means decrypt */
+ unsigned char key[24]; /* TDEA 3 key bundle */
+ unsigned int numKeys = 0;
+ unsigned char plaintext[8]; /* PT[j] */
+ unsigned char ciphertext[8]; /* CT[j] */
+ unsigned char iv[8];
+
+ /* zeroize the variables for the test with this data set */
+ memset(key, 0, sizeof key);
+ memset(plaintext, 0, sizeof plaintext);
+ memset(ciphertext, 0, sizeof ciphertext);
+ memset(iv, 0, sizeof iv);
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ while (fgets(buf, sizeof buf, req) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, resp);
+ continue;
+ }
+ /* [ENCRYPT] or [DECRYPT] */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+ crypt = ENCRYPT;
+ } else {
+ crypt = DECRYPT;
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ /* NumKeys */
+ if (strncmp(&buf[0], "NumKeys", 7) == 0) {
+ i = 7;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ numKeys = atoi(&buf[i]);
+ continue;
+ }
+ /* KEY1 = ... */
+ if (strncmp(buf, "KEY1", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ continue;
+ }
+ /* KEY2 = ... */
+ if (strncmp(buf, "KEY2", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=8; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ continue;
+ }
+ /* KEY3 = ... */
+ if (strncmp(buf, "KEY3", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=16; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ continue;
+ }
+
+ /* IV = ... */
+ if (strncmp(buf, "IV", 2) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof iv; i+=2,j++) {
+ hex_from_2char(&buf[i], &iv[j]);
+ }
+ continue;
+ }
+
+ /* PLAINTEXT = ... */
+ if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+
+ /* sanity check */
+ if (crypt != ENCRYPT) {
+ goto loser;
+ }
+ /* PT[0] = PT */
+ i = 9;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof plaintext; i+=2,j++) {
+ hex_from_2char(&buf[i], &plaintext[j]);
+ }
+
+ /* do the Monte Carlo test */
+ if (mode==NSS_DES_EDE3) {
+ tdea_mct_test(NSS_DES_EDE3, key, numKeys, crypt, plaintext, sizeof plaintext, NULL, resp);
+ } else {
+ tdea_mct_test(NSS_DES_EDE3_CBC, key, numKeys, crypt, plaintext, sizeof plaintext, iv, resp);
+ }
+ continue;
+ }
+ /* CIPHERTEXT = ... */
+ if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+ /* sanity check */
+ if (crypt != DECRYPT) {
+ goto loser;
+ }
+ /* CT[0] = CT */
+ i = 10;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &ciphertext[j]);
+ }
+
+ /* do the Monte Carlo test */
+ if (mode==NSS_DES_EDE3) {
+ tdea_mct_test(NSS_DES_EDE3, key, numKeys, crypt, ciphertext, sizeof ciphertext, NULL, resp);
+ } else {
+ tdea_mct_test(NSS_DES_EDE3_CBC, key, numKeys, crypt, ciphertext, sizeof ciphertext, iv, resp);
+ }
+ continue;
+ }
+ }
+
+loser:
+ fclose(req);
+}
+
+
+SECStatus
+aes_encrypt_buf(
+ int mode,
+ const unsigned char *key, unsigned int keysize,
+ const unsigned char *iv,
+ unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
+ const unsigned char *input, unsigned int inputlen)
+{
+ SECStatus rv = SECFailure;
+ AESContext *cx;
+ unsigned char doublecheck[10*16]; /* 1 to 10 blocks */
+ unsigned int doublechecklen = 0;
+
+ cx = AES_CreateContext(key, iv, mode, PR_TRUE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = AES_Encrypt(cx, output, outputlen, maxoutputlen, input, inputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (*outputlen != inputlen) {
+ goto loser;
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+
+ /*
+ * Doublecheck our result by decrypting the ciphertext and
+ * compare the output with the input plaintext.
+ */
+ cx = AES_CreateContext(key, iv, mode, PR_FALSE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = AES_Decrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
+ output, *outputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (doublechecklen != *outputlen) {
+ goto loser;
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ if (memcmp(doublecheck, input, inputlen) != 0) {
+ goto loser;
+ }
+ rv = SECSuccess;
+
+loser:
+ if (cx != NULL) {
+ AES_DestroyContext(cx, PR_TRUE);
+ }
+ return rv;
+}
+
+SECStatus
+aes_decrypt_buf(
+ int mode,
+ const unsigned char *key, unsigned int keysize,
+ const unsigned char *iv,
+ unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
+ const unsigned char *input, unsigned int inputlen)
+{
+ SECStatus rv = SECFailure;
+ AESContext *cx;
+ unsigned char doublecheck[10*16]; /* 1 to 10 blocks */
+ unsigned int doublechecklen = 0;
+
+ cx = AES_CreateContext(key, iv, mode, PR_FALSE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = AES_Decrypt(cx, output, outputlen, maxoutputlen,
+ input, inputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (*outputlen != inputlen) {
+ goto loser;
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+
+ /*
+ * Doublecheck our result by encrypting the plaintext and
+ * compare the output with the input ciphertext.
+ */
+ cx = AES_CreateContext(key, iv, mode, PR_TRUE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = AES_Encrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
+ output, *outputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (doublechecklen != *outputlen) {
+ goto loser;
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ if (memcmp(doublecheck, input, inputlen) != 0) {
+ goto loser;
+ }
+ rv = SECSuccess;
+
+loser:
+ if (cx != NULL) {
+ AES_DestroyContext(cx, PR_TRUE);
+ }
+ return rv;
+}
+
+/*
+ * Perform the AES Known Answer Test (KAT) or Multi-block Message
+ * Test (MMT) in ECB or CBC mode. The KAT (there are four types)
+ * and MMT have the same structure: given the key and IV (CBC mode
+ * only), encrypt the given plaintext or decrypt the given ciphertext.
+ * So we can handle them the same way.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+aes_kat_mmt(char *reqfn)
+{
+ char buf[512]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "CIPHERTEXT = <320 hex digits>\n".
+ */
+ FILE *aesreq; /* input stream from the REQUEST file */
+ FILE *aesresp; /* output stream to the RESPONSE file */
+ int i, j;
+ int mode; /* NSS_AES (ECB) or NSS_AES_CBC */
+ int encrypt = 0; /* 1 means encrypt, 0 means decrypt */
+ unsigned char key[32]; /* 128, 192, or 256 bits */
+ unsigned int keysize;
+ unsigned char iv[16]; /* for all modes except ECB */
+ unsigned char plaintext[10*16]; /* 1 to 10 blocks */
+ unsigned int plaintextlen;
+ unsigned char ciphertext[10*16]; /* 1 to 10 blocks */
+ unsigned int ciphertextlen;
+ SECStatus rv;
+
+ aesreq = fopen(reqfn, "r");
+ aesresp = stdout;
+ while (fgets(buf, sizeof buf, aesreq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, aesresp);
+ continue;
}
- if (len > 8) {
- printf("COUNT = %d\n", i);
- to_hex_str(keystr, keyin, 8);
- printf("KEY1=%s\n", keystr);
- to_hex_str(keystr, keyin+8, 8);
- printf("KEY2=%s\n", keystr);
- to_hex_str(keystr, keyin+16, 8);
- printf("KEY3=%s\n", keystr);
- } else {
- to_hex_str(keystr, keyin, 8);
- printf("%ld\tKEY=%s\t", i, keystr);
+ /* [ENCRYPT] or [DECRYPT] */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+ encrypt = 1;
+ } else {
+ encrypt = 0;
+ }
+ fputs(buf, aesresp);
+ continue;
}
- if (iv) {
- to_hex_str(ivstr, iv, 8);
- printf("IV=%s%c", ivstr, tchar);
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ mode = NSS_AES;
+ /* zeroize the variables for the test with this data set */
+ memset(key, 0, sizeof key);
+ keysize = 0;
+ memset(iv, 0, sizeof iv);
+ memset(plaintext, 0, sizeof plaintext);
+ plaintextlen = 0;
+ memset(ciphertext, 0, sizeof ciphertext);
+ ciphertextlen = 0;
+ fputs(buf, aesresp);
+ continue;
}
- DES_Encrypt(cx1, out, &olen, 8, inp, 8);
- if (encrypt) {
- to_hex_str(instr, inp, 8);
- to_hex_str(outstr, out, 8);
- printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr);
- } else {
- unsigned char inv[8];
- DES_Decrypt(cx2, inv, &olen, 8, out, 8);
- to_hex_str(instr, out, 8);
- to_hex_str(outstr, inv, 8);
- printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr);
+ /* KEY = ... */
+ if (strncmp(buf, "KEY", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ keysize = j;
+ fputs(buf, aesresp);
+ continue;
}
- if (mod_byte > 0x02) {
- mod_byte >>= 1;
- } else {
- keyin[mbnum] = 0x01;
- keyin[mbnum+8] = 0x01;
- keyin[mbnum+16] = 0x01;
- mod_byte = 0x80;
- mbnum++;
+ /* IV = ... */
+ if (strncmp(buf, "IV", 2) == 0) {
+ mode = NSS_AES_CBC;
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof iv; i+=2,j++) {
+ hex_from_2char(&buf[i], &iv[j]);
+ }
+ fputs(buf, aesresp);
+ continue;
}
- keyin[mbnum] = mod_byte;
- keyin[mbnum+8] = mod_byte;
- keyin[mbnum+16] = mod_byte;
- DES_DestroyContext(cx1, PR_TRUE);
- if (cx2) {
- DES_DestroyContext(cx2, PR_TRUE);
+ /* PLAINTEXT = ... */
+ if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+ /* sanity check */
+ if (!encrypt) {
+ goto loser;
+ }
+
+ i = 9;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &plaintext[j]);
+ }
+ plaintextlen = j;
+
+ rv = aes_encrypt_buf(mode, key, keysize,
+ (mode == NSS_AES) ? NULL : iv,
+ ciphertext, &ciphertextlen, sizeof ciphertext,
+ plaintext, plaintextlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ fputs(buf, aesresp);
+ fputs("CIPHERTEXT = ", aesresp);
+ to_hex_str(buf, ciphertext, ciphertextlen);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ continue;
+ }
+ /* CIPHERTEXT = ... */
+ if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+ /* sanity check */
+ if (encrypt) {
+ goto loser;
+ }
+
+ i = 10;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &ciphertext[j]);
+ }
+ ciphertextlen = j;
+
+ rv = aes_decrypt_buf(mode, key, keysize,
+ (mode == NSS_AES) ? NULL : iv,
+ plaintext, &plaintextlen, sizeof plaintext,
+ ciphertext, ciphertextlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ fputs(buf, aesresp);
+ fputs("PLAINTEXT = ", aesresp);
+ to_hex_str(buf, plaintext, plaintextlen);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ continue;
}
}
+loser:
+ fclose(aesreq);
}
+/*
+ * Generate Key[i+1] from Key[i], CT[j-1], and CT[j] for AES Monte Carlo
+ * Test (MCT) in ECB and CBC modes.
+ */
void
-des_perm_op_kat(int mode, PRBool encrypt, unsigned int len,
- unsigned char *key, unsigned char *iv,
- unsigned char *inp)
+aes_mct_next_key(unsigned char *key, unsigned int keysize,
+ const unsigned char *ciphertext_1, const unsigned char *ciphertext)
{
- int i;
- unsigned int olen;
- unsigned char keyin[24];
- unsigned char out[8];
- char keystr[17], ivstr[17], instr[17], outstr[17];
- char *ptty = (len == 8) ? "PT" : "PLAINTEXT";
- char *ctty = (len == 8) ? "CT" : "CIPHERTEXT";
- char tchar = (len == 8) ? '\t' : '\n';
- DESContext *cx1 = NULL, *cx2 = NULL;
- memset(keyin, 0, sizeof keyin);
- memset(keystr, 0, sizeof keystr);
- memset(ivstr, 0, sizeof ivstr);
- memset(instr, 0, sizeof instr);
- memset(outstr, 0, sizeof outstr);
- for (i=0; i<32; i++) {
- memcpy(keyin, table3[i], 8);
- memcpy(keyin+8, table3[i], 8);
- memcpy(keyin+16, table3[i], 8);
- cx1 = DES_CreateContext(keyin, iv, mode, PR_TRUE);
- if (!encrypt) {
- cx2 = DES_CreateContext(keyin, iv, mode, PR_FALSE);
+ int k;
+
+ switch (keysize) {
+ case 16: /* 128-bit key */
+ /* Key[i+1] = Key[i] xor CT[j] */
+ for (k=0; k<16; k++) {
+ key[k] ^= ciphertext[k];
}
- if (len > 8) {
- printf("COUNT = %d\n", i);
- to_hex_str(keystr, keyin, 8);
- printf("KEY1=%s\n", keystr);
- to_hex_str(keystr, keyin+8, 8);
- printf("KEY2=%s\n", keystr);
- to_hex_str(keystr, keyin+16, 8);
- printf("KEY3=%s\n", keystr);
- } else {
- to_hex_str(keystr, keyin, 8);
- printf("%ld\tKEY=%s\t", i, keystr);
+ break;
+ case 24: /* 192-bit key */
+ /*
+ * Key[i+1] = Key[i] xor (last 64-bits of
+ * CT[j-1] || CT[j])
+ */
+ for (k=0; k<8; k++) {
+ key[k] ^= ciphertext_1[k+8];
}
- if (iv) {
- to_hex_str(ivstr, iv, 8);
- printf("IV=%s%c", ivstr, tchar);
+ for (k=8; k<24; k++) {
+ key[k] ^= ciphertext[k-8];
}
- DES_Encrypt(cx1, out, &olen, 8, inp, 8);
- if (encrypt) {
- to_hex_str(instr, inp, 8);
- to_hex_str(outstr, out, 8);
- printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr);
- } else {
- unsigned char inv[8];
- DES_Decrypt(cx2, inv, &olen, 8, out, 8);
- to_hex_str(instr, out, 8);
- to_hex_str(outstr, inv, 8);
- printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr);
+ break;
+ case 32: /* 256-bit key */
+ /* Key[i+1] = Key[i] xor (CT[j-1] || CT[j]) */
+ for (k=0; k<16; k++) {
+ key[k] ^= ciphertext_1[k];
}
- DES_DestroyContext(cx1, PR_TRUE);
- if (cx2) {
- DES_DestroyContext(cx2, PR_TRUE);
+ for (k=16; k<32; k++) {
+ key[k] ^= ciphertext[k-16];
}
+ break;
}
}
+/*
+ * Perform the AES Monte Carlo Test (MCT) in ECB mode. MCT exercises
+ * our AES code in streaming mode because the plaintext or ciphertext
+ * is generated block by block as we go, so we can't collect all the
+ * plaintext or ciphertext in one buffer and encrypt or decrypt it in
+ * one shot.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
void
-des_sub_tbl_kat(int mode, PRBool encrypt, unsigned int len,
- unsigned char *key, unsigned char *iv,
- unsigned char *inp)
+aes_ecb_mct(char *reqfn)
{
- int i;
- unsigned int olen;
- unsigned char keyin[24];
- unsigned char out[8];
- char keystr[17], ivstr[17], instr[17], outstr[17];
- char *ptty = (len == 8) ? "PT" : "PLAINTEXT";
- char *ctty = (len == 8) ? "CT" : "CIPHERTEXT";
- char tchar = (len == 8) ? '\t' : '\n';
- DESContext *cx1 = NULL, *cx2 = NULL;
- memset(keyin, 0, sizeof keyin);
- memset(keystr, 0, sizeof keystr);
- memset(ivstr, 0, sizeof ivstr);
- memset(instr, 0, sizeof instr);
- memset(outstr, 0, sizeof outstr);
- for (i=0; i<19; i++) {
- memcpy(keyin, table4_key[i], 8);
- memcpy(keyin+8, table4_key[i], 8);
- memcpy(keyin+16, table4_key[i], 8);
- cx1 = DES_CreateContext(keyin, iv, mode, PR_TRUE);
- if (!encrypt) {
- cx2 = DES_CreateContext(keyin, iv, mode, PR_FALSE);
+ char buf[80]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "KEY = <64 hex digits>\n".
+ */
+ FILE *aesreq; /* input stream from the REQUEST file */
+ FILE *aesresp; /* output stream to the RESPONSE file */
+ int i, j;
+ int encrypt = 0; /* 1 means encrypt, 0 means decrypt */
+ unsigned char key[32]; /* 128, 192, or 256 bits */
+ unsigned int keysize;
+ unsigned char plaintext[16]; /* PT[j] */
+ unsigned char plaintext_1[16]; /* PT[j-1] */
+ unsigned char ciphertext[16]; /* CT[j] */
+ unsigned char ciphertext_1[16]; /* CT[j-1] */
+ unsigned char doublecheck[16];
+ unsigned int outputlen;
+ AESContext *cx = NULL; /* the operation being tested */
+ AESContext *cx2 = NULL; /* the inverse operation done in parallel
+ * to doublecheck our result.
+ */
+ SECStatus rv;
+
+ aesreq = fopen(reqfn, "r");
+ aesresp = stdout;
+ while (fgets(buf, sizeof buf, aesreq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, aesresp);
+ continue;
}
- if (len > 8) {
- printf("COUNT = %d\n", i);
- to_hex_str(keystr, keyin, 8);
- printf("KEY1=%s\n", keystr);
- to_hex_str(keystr, keyin+8, 8);
- printf("KEY2=%s\n", keystr);
- to_hex_str(keystr, keyin+16, 8);
- printf("KEY3=%s\n", keystr);
- } else {
- to_hex_str(keystr, keyin, 8);
- printf("%ld\tKEY=%s\t", i, keystr);
+ /* [ENCRYPT] or [DECRYPT] */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+ encrypt = 1;
+ } else {
+ encrypt = 0;
+ }
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ memset(key, 0, sizeof key);
+ keysize = 0;
+ memset(plaintext, 0, sizeof plaintext);
+ memset(ciphertext, 0, sizeof ciphertext);
+ continue;
}
- if (iv) {
- to_hex_str(ivstr, iv, 8);
- printf("IV=%s%c", ivstr, tchar);
+ /* KEY = ... */
+ if (strncmp(buf, "KEY", 3) == 0) {
+ /* Key[0] = Key */
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ keysize = j;
+ continue;
}
- DES_Encrypt(cx1, out, &olen, 8, table4_inp[i], 8);
- if (encrypt) {
- to_hex_str(instr, table4_inp[i], 8);
- to_hex_str(outstr, out, 8);
- printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr);
- } else {
- unsigned char inv[8];
- DES_Decrypt(cx2, inv, &olen, 8, out, 8);
- to_hex_str(instr, out, 8);
- to_hex_str(outstr, inv, 8);
- printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr);
+ /* PLAINTEXT = ... */
+ if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+ /* sanity check */
+ if (!encrypt) {
+ goto loser;
+ }
+ /* PT[0] = PT */
+ i = 9;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof plaintext; i+=2,j++) {
+ hex_from_2char(&buf[i], &plaintext[j]);
+ }
+
+ for (i=0; i<100; i++) {
+ sprintf(buf, "COUNT = %d\n", i);
+ fputs(buf, aesresp);
+ /* Output Key[i] */
+ fputs("KEY = ", aesresp);
+ to_hex_str(buf, key, keysize);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ /* Output PT[0] */
+ fputs("PLAINTEXT = ", aesresp);
+ to_hex_str(buf, plaintext, sizeof plaintext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ cx = AES_CreateContext(key, NULL, NSS_AES,
+ PR_TRUE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ /*
+ * doublecheck our result by decrypting the result
+ * and comparing the output with the plaintext.
+ */
+ cx2 = AES_CreateContext(key, NULL, NSS_AES,
+ PR_FALSE, keysize, 16);
+ if (cx2 == NULL) {
+ goto loser;
+ }
+ for (j=0; j<1000; j++) {
+ /* Save CT[j-1] */
+ memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
+
+ /* CT[j] = AES(Key[i], PT[j]) */
+ outputlen = 0;
+ rv = AES_Encrypt(cx,
+ ciphertext, &outputlen, sizeof ciphertext,
+ plaintext, sizeof plaintext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof plaintext) {
+ goto loser;
+ }
+
+ /* doublecheck our result */
+ outputlen = 0;
+ rv = AES_Decrypt(cx2,
+ doublecheck, &outputlen, sizeof doublecheck,
+ ciphertext, sizeof ciphertext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof ciphertext) {
+ goto loser;
+ }
+ if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
+ goto loser;
+ }
+
+ /* PT[j+1] = CT[j] */
+ memcpy(plaintext, ciphertext, sizeof plaintext);
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ AES_DestroyContext(cx2, PR_TRUE);
+ cx2 = NULL;
+
+ /* Output CT[j] */
+ fputs("CIPHERTEXT = ", aesresp);
+ to_hex_str(buf, ciphertext, sizeof ciphertext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ /* Key[i+1] = Key[i] xor ... */
+ aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
+ /* PT[0] = CT[j] */
+ /* done at the end of the for(j) loop */
+
+ fputc('\n', aesresp);
+ }
+
+ continue;
}
- DES_DestroyContext(cx1, PR_TRUE);
- if (cx2) {
- DES_DestroyContext(cx2, PR_TRUE);
+ /* CIPHERTEXT = ... */
+ if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+ /* sanity check */
+ if (encrypt) {
+ goto loser;
+ }
+ /* CT[0] = CT */
+ i = 10;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &ciphertext[j]);
+ }
+
+ for (i=0; i<100; i++) {
+ sprintf(buf, "COUNT = %d\n", i);
+ fputs(buf, aesresp);
+ /* Output Key[i] */
+ fputs("KEY = ", aesresp);
+ to_hex_str(buf, key, keysize);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ /* Output CT[0] */
+ fputs("CIPHERTEXT = ", aesresp);
+ to_hex_str(buf, ciphertext, sizeof ciphertext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ cx = AES_CreateContext(key, NULL, NSS_AES,
+ PR_FALSE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ /*
+ * doublecheck our result by encrypting the result
+ * and comparing the output with the ciphertext.
+ */
+ cx2 = AES_CreateContext(key, NULL, NSS_AES,
+ PR_TRUE, keysize, 16);
+ if (cx2 == NULL) {
+ goto loser;
+ }
+ for (j=0; j<1000; j++) {
+ /* Save PT[j-1] */
+ memcpy(plaintext_1, plaintext, sizeof plaintext);
+
+ /* PT[j] = AES(Key[i], CT[j]) */
+ outputlen = 0;
+ rv = AES_Decrypt(cx,
+ plaintext, &outputlen, sizeof plaintext,
+ ciphertext, sizeof ciphertext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof ciphertext) {
+ goto loser;
+ }
+
+ /* doublecheck our result */
+ outputlen = 0;
+ rv = AES_Encrypt(cx2,
+ doublecheck, &outputlen, sizeof doublecheck,
+ plaintext, sizeof plaintext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof plaintext) {
+ goto loser;
+ }
+ if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
+ goto loser;
+ }
+
+ /* CT[j+1] = PT[j] */
+ memcpy(ciphertext, plaintext, sizeof ciphertext);
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ AES_DestroyContext(cx2, PR_TRUE);
+ cx2 = NULL;
+
+ /* Output PT[j] */
+ fputs("PLAINTEXT = ", aesresp);
+ to_hex_str(buf, plaintext, sizeof plaintext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ /* Key[i+1] = Key[i] xor ... */
+ aes_mct_next_key(key, keysize, plaintext_1, plaintext);
+ /* CT[0] = PT[j] */
+ /* done at the end of the for(j) loop */
+
+ fputc('\n', aesresp);
+ }
+
+ continue;
}
}
-}
-
-unsigned char make_odd_parity(unsigned char b)
-{
- int i;
- int sum = 0;
- for (i=1; i<8; i++) {
- sum += (b & (1 << i)) ? 1 : 0;
+loser:
+ if (cx != NULL) {
+ AES_DestroyContext(cx, PR_TRUE);
}
- if (sum & 0x01) {
- return (b & 0xfe);
- } else {
- return (b | 0x01);
+ if (cx2 != NULL) {
+ AES_DestroyContext(cx2, PR_TRUE);
}
+ fclose(aesreq);
}
+/*
+ * Perform the AES Monte Carlo Test (MCT) in CBC mode. MCT exercises
+ * our AES code in streaming mode because the plaintext or ciphertext
+ * is generated block by block as we go, so we can't collect all the
+ * plaintext or ciphertext in one buffer and encrypt or decrypt it in
+ * one shot.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
void
-des_modes(int mode, PRBool encrypt, unsigned int len,
- const unsigned char *key, const unsigned char *iv,
- const unsigned char *inp, int keymode)
+aes_cbc_mct(char *reqfn)
{
+ char buf[80]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "KEY = <64 hex digits>\n".
+ */
+ FILE *aesreq; /* input stream from the REQUEST file */
+ FILE *aesresp; /* output stream to the RESPONSE file */
int i, j;
- unsigned int olen;
- unsigned char keyin[24];
- unsigned char in[8];
- unsigned char cv[8];
- unsigned char cv0[8];
- unsigned char in0[8];
- unsigned char out[8];
- unsigned char cj9998[8], cj9997[8];
- char keystr[17], ivstr[17], instr[17], outstr[17];
- char *ptty = (len == 8) ? "PT" : "PLAINTEXT";
- char *ctty = (len == 8) ? "CT" : "CIPHERTEXT";
- char tchar = (len == 8) ? '\t' : '\n';
- DESContext *cx1 = NULL;
- memset(keystr, 0, sizeof keystr);
- memset(ivstr, 0, sizeof ivstr);
- memset(instr, 0, sizeof instr);
- memset(outstr, 0, sizeof outstr);
- memcpy(in, inp, 8);
- if (iv) memcpy(cv, iv, 8);
- memcpy(keyin, key, len);
- for (i=0; i<400; i++) {
- if (iv) memcpy(cv0, cv, 8);
- memcpy(in0, in, 8);
- for (j=0; j<10000; j++) {
- if (encrypt) {
- cx1 = DES_CreateContext(keyin, cv, mode, PR_TRUE);
- DES_Encrypt(cx1, out, &olen, 8, in, 8);
- } else {
- cx1 = DES_CreateContext(keyin, cv, mode, PR_FALSE);
- DES_Decrypt(cx1, out, &olen, 8, in, 8);
- }
- if (j==9997) memcpy(cj9997, out, 8);
- if (j==9998) memcpy(cj9998, out, 8);
- if (iv) {
- if (encrypt) {
- memcpy(in, cv, 8);
- memcpy(cv, out, 8);
- } else {
- memcpy(cv, in, 8);
- memcpy(in, out, 8);
- }
+ int encrypt = 0; /* 1 means encrypt, 0 means decrypt */
+ unsigned char key[32]; /* 128, 192, or 256 bits */
+ unsigned int keysize;
+ unsigned char iv[16];
+ unsigned char plaintext[16]; /* PT[j] */
+ unsigned char plaintext_1[16]; /* PT[j-1] */
+ unsigned char ciphertext[16]; /* CT[j] */
+ unsigned char ciphertext_1[16]; /* CT[j-1] */
+ unsigned char doublecheck[16];
+ unsigned int outputlen;
+ AESContext *cx = NULL; /* the operation being tested */
+ AESContext *cx2 = NULL; /* the inverse operation done in parallel
+ * to doublecheck our result.
+ */
+ SECStatus rv;
+
+ aesreq = fopen(reqfn, "r");
+ aesresp = stdout;
+ while (fgets(buf, sizeof buf, aesreq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, aesresp);
+ continue;
+ }
+ /* [ENCRYPT] or [DECRYPT] */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+ encrypt = 1;
} else {
- memcpy(in, out, 8);
+ encrypt = 0;
}
- DES_DestroyContext(cx1, PR_TRUE);
+ fputs(buf, aesresp);
+ continue;
}
- if (keymode > 0) {
- printf("COUNT = %d\n", i);
- to_hex_str(keystr, keyin, 8);
- printf("KEY1=%s\n", keystr);
- to_hex_str(keystr, keyin+8, 8);
- printf("KEY2=%s\n", keystr);
- to_hex_str(keystr, keyin+16, 8);
- printf("KEY3=%s\n", keystr);
- } else {
- to_hex_str(keystr, keyin, 8);
- printf("%ld\tKEY=%s\t", i, keystr);
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ memset(key, 0, sizeof key);
+ keysize = 0;
+ memset(iv, 0, sizeof iv);
+ memset(plaintext, 0, sizeof plaintext);
+ memset(ciphertext, 0, sizeof ciphertext);
+ continue;
}
- if (iv) {
- to_hex_str(ivstr, cv0, 8);
- printf("CV=%s%c", ivstr, tchar);
+ /* KEY = ... */
+ if (strncmp(buf, "KEY", 3) == 0) {
+ /* Key[0] = Key */
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ keysize = j;
+ continue;
}
- to_hex_str(instr, in0, 8);
- to_hex_str(outstr, out, 8);
- if (encrypt) {
- printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr);
- } else {
- printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr);
+ /* IV = ... */
+ if (strncmp(buf, "IV", 2) == 0) {
+ /* IV[0] = IV */
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof iv; i+=2,j++) {
+ hex_from_2char(&buf[i], &iv[j]);
+ }
+ continue;
}
- for (j=0; j<8; j++) {
- keyin[j] ^= out[j];
- keyin[j] = make_odd_parity(keyin[j]);
- if (keymode == 0) continue;
- if (keymode > 1) {
- keyin[j+8] ^= cj9998[j];
- keyin[j+8] = make_odd_parity(keyin[j+8]);
- } else {
- keyin[j+8] = keyin[j];
+ /* PLAINTEXT = ... */
+ if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+ /* sanity check */
+ if (!encrypt) {
+ goto loser;
}
- if (keymode > 2) {
- keyin[j+16] ^= cj9997[j];
- keyin[j+16] = make_odd_parity(keyin[j+16]);
- } else {
- keyin[j+16] = keyin[j];
+ /* PT[0] = PT */
+ i = 9;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof plaintext; i+=2,j++) {
+ hex_from_2char(&buf[i], &plaintext[j]);
+ }
+
+ for (i=0; i<100; i++) {
+ sprintf(buf, "COUNT = %d\n", i);
+ fputs(buf, aesresp);
+ /* Output Key[i] */
+ fputs("KEY = ", aesresp);
+ to_hex_str(buf, key, keysize);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ /* Output IV[i] */
+ fputs("IV = ", aesresp);
+ to_hex_str(buf, iv, sizeof iv);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ /* Output PT[0] */
+ fputs("PLAINTEXT = ", aesresp);
+ to_hex_str(buf, plaintext, sizeof plaintext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ cx = AES_CreateContext(key, iv, NSS_AES_CBC,
+ PR_TRUE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ /*
+ * doublecheck our result by decrypting the result
+ * and comparing the output with the plaintext.
+ */
+ cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
+ PR_FALSE, keysize, 16);
+ if (cx2 == NULL) {
+ goto loser;
+ }
+ /* CT[-1] = IV[i] */
+ memcpy(ciphertext, iv, sizeof ciphertext);
+ for (j=0; j<1000; j++) {
+ /* Save CT[j-1] */
+ memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
+ /*
+ * If ( j=0 )
+ * CT[j] = AES(Key[i], IV[i], PT[j])
+ * PT[j+1] = IV[i] (= CT[j-1])
+ * Else
+ * CT[j] = AES(Key[i], PT[j])
+ * PT[j+1] = CT[j-1]
+ */
+ outputlen = 0;
+ rv = AES_Encrypt(cx,
+ ciphertext, &outputlen, sizeof ciphertext,
+ plaintext, sizeof plaintext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof plaintext) {
+ goto loser;
+ }
+
+ /* doublecheck our result */
+ outputlen = 0;
+ rv = AES_Decrypt(cx2,
+ doublecheck, &outputlen, sizeof doublecheck,
+ ciphertext, sizeof ciphertext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof ciphertext) {
+ goto loser;
+ }
+ if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
+ goto loser;
+ }
+
+ memcpy(plaintext, ciphertext_1, sizeof plaintext);
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ AES_DestroyContext(cx2, PR_TRUE);
+ cx2 = NULL;
+
+ /* Output CT[j] */
+ fputs("CIPHERTEXT = ", aesresp);
+ to_hex_str(buf, ciphertext, sizeof ciphertext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ /* Key[i+1] = Key[i] xor ... */
+ aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
+ /* IV[i+1] = CT[j] */
+ memcpy(iv, ciphertext, sizeof iv);
+ /* PT[0] = CT[j-1] */
+ /* done at the end of the for(j) loop */
+
+ fputc('\n', aesresp);
+ }
+
+ continue;
+ }
+ /* CIPHERTEXT = ... */
+ if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+ /* sanity check */
+ if (encrypt) {
+ goto loser;
+ }
+ /* CT[0] = CT */
+ i = 10;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &ciphertext[j]);
}
+
+ for (i=0; i<100; i++) {
+ sprintf(buf, "COUNT = %d\n", i);
+ fputs(buf, aesresp);
+ /* Output Key[i] */
+ fputs("KEY = ", aesresp);
+ to_hex_str(buf, key, keysize);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ /* Output IV[i] */
+ fputs("IV = ", aesresp);
+ to_hex_str(buf, iv, sizeof iv);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+ /* Output CT[0] */
+ fputs("CIPHERTEXT = ", aesresp);
+ to_hex_str(buf, ciphertext, sizeof ciphertext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ cx = AES_CreateContext(key, iv, NSS_AES_CBC,
+ PR_FALSE, keysize, 16);
+ if (cx == NULL) {
+ goto loser;
+ }
+ /*
+ * doublecheck our result by encrypting the result
+ * and comparing the output with the ciphertext.
+ */
+ cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
+ PR_TRUE, keysize, 16);
+ if (cx2 == NULL) {
+ goto loser;
+ }
+ /* PT[-1] = IV[i] */
+ memcpy(plaintext, iv, sizeof plaintext);
+ for (j=0; j<1000; j++) {
+ /* Save PT[j-1] */
+ memcpy(plaintext_1, plaintext, sizeof plaintext);
+ /*
+ * If ( j=0 )
+ * PT[j] = AES(Key[i], IV[i], CT[j])
+ * CT[j+1] = IV[i] (= PT[j-1])
+ * Else
+ * PT[j] = AES(Key[i], CT[j])
+ * CT[j+1] = PT[j-1]
+ */
+ outputlen = 0;
+ rv = AES_Decrypt(cx,
+ plaintext, &outputlen, sizeof plaintext,
+ ciphertext, sizeof ciphertext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof ciphertext) {
+ goto loser;
+ }
+
+ /* doublecheck our result */
+ outputlen = 0;
+ rv = AES_Encrypt(cx2,
+ doublecheck, &outputlen, sizeof doublecheck,
+ plaintext, sizeof plaintext);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != sizeof plaintext) {
+ goto loser;
+ }
+ if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
+ goto loser;
+ }
+
+ memcpy(ciphertext, plaintext_1, sizeof ciphertext);
+ }
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ AES_DestroyContext(cx2, PR_TRUE);
+ cx2 = NULL;
+
+ /* Output PT[j] */
+ fputs("PLAINTEXT = ", aesresp);
+ to_hex_str(buf, plaintext, sizeof plaintext);
+ fputs(buf, aesresp);
+ fputc('\n', aesresp);
+
+ /* Key[i+1] = Key[i] xor ... */
+ aes_mct_next_key(key, keysize, plaintext_1, plaintext);
+ /* IV[i+1] = PT[j] */
+ memcpy(iv, plaintext, sizeof iv);
+ /* CT[0] = PT[j-1] */
+ /* done at the end of the for(j) loop */
+
+ fputc('\n', aesresp);
+ }
+
+ continue;
}
}
+loser:
+ if (cx != NULL) {
+ AES_DestroyContext(cx, PR_TRUE);
+ }
+ if (cx2 != NULL) {
+ AES_DestroyContext(cx2, PR_TRUE);
+ }
+ fclose(aesreq);
}
void write_compact_string(FILE *out, unsigned char *hash, unsigned int len)
{
- int i, j, count = 0, last = -1, z = 0;
+ unsigned int i;
+ int j, count = 0, last = -1, z = 0;
long start = ftell(out);
for (i=0; i<len; i++) {
for (j=7; j>=0; j--) {
@@ -871,152 +1839,6 @@ void write_compact_string(FILE *out, unsigned char *hash, unsigned int len)
fseek(out, 0, SEEK_END);
}
-void do_shs_type3(FILE *out, unsigned char *M, unsigned int len)
-{
- int i, j, a;
- unsigned char zero[30];
- unsigned char iword[4];
- unsigned int l = len;
- char hashstr[41];
- SHA1Context *cx;
- memset(zero, 0, sizeof zero);
- for (j=0; j<100; j++) {
- cx = SHA1_NewContext();
- for (i=1; i<=50000; i++) {
- SHA1_Begin(cx);
- SHA1_Update(cx, M, l);
- a = j/4 + 3;
- SHA1_Update(cx, zero, a);
- iword[3] = (char)i;
- iword[2] = (char)(i >> 8);
- iword[1] = (char)(i >> 16);
- iword[0] = (char)(i >> 24);
- SHA1_Update(cx, iword, 4);
- SHA1_End(cx, M, &l, 20);
- }
- SHA1_DestroyContext(cx, PR_TRUE);
- to_hex_str_cap(hashstr, M, l);
- hashstr[40] = '\0';
- fprintf(out, "%s ^", hashstr);
- if (j<99) fprintf(out, "\n");
- }
-}
-
-void
-shs_test(char *reqfn)
-{
- char buf[80];
- FILE *shareq, *sharesp;
- char readbuf[64];
- int i, nr;
- int newline, skip, r_z, r_b, r_n, r, b, z, n, reading;
- unsigned char hash[20];
- char hashstr[41];
- unsigned char input[13000];
- int next_bit = 0;
- int shs_type = 0;
- shareq = fopen(reqfn, "r");
- sharesp = stdout;
- newline = 1;
- reading = skip = r_z = r_b = r_n = z = r = n = 0;
- while ((nr = fread(buf, 1, sizeof buf, shareq)) > 0) {
- for (i=0; i<nr; i++) {
- if (newline) {
- if (buf[i] == '#' || buf[i] == 'D' || buf[i] == '<') {
- skip = 1;
- } else if (buf[i] == 'H') {
- skip = 0;
- shs_type++;
- fprintf(sharesp, "H>SHS Type %d Hashes<H", shs_type);
- } else if (isdigit(buf[i])) {
- r_z = 1;
- readbuf[r++] = buf[i];
- }
- newline = (buf[i] == '\n') ? 1 : 0;
- } else {
- if (buf[i] == '\n' && !r_n) {
- skip = r_z = r_n = 0;
- newline = 1;
- } else if (r_z) {
- if (buf[i] == ' ') {
- r_z = 0;
- readbuf[r] = '\0';
- z = atoi(readbuf);
- r_b = 1;
- r = 0;
- } else if (isdigit(buf[i])) {
- readbuf[r++] = buf[i];
- }
- } else if (r_b) {
- if (buf[i] == ' ') {
- r_b = 0;
- readbuf[r] = '\0';
- b = atoi(readbuf);
- r_n = 1;
- r = 0;
- } else if (isdigit(buf[i])) {
- readbuf[r++] = buf[i];
- }
- } else if (r_n) {
- if (buf[i] == ' ') {
- readbuf[r++] = '\0';
- n = atoi(readbuf);
- if (b == 0) {
- next_bit += n;
- b = 1;
- } else {
- int next_byte = next_bit / 8;
- int shift = next_bit % 8;
- unsigned char m = 0xff;
- if (n < 8 - shift) {
- m <<= (8 - n);
- m >>= shift;
- input[next_byte] |= m;
- next_bit += n;
- } else {
- m >>= shift;
- input[next_byte++] |= m;
- next_bit += 8 - shift;
- n -= (8 - shift);
- while (n > 8) {
- m = 0xff;
- input[next_byte++] |= m;
- next_bit += 8;
- n -= 8;
- }
- if (n > 0) {
- m = 0xff << (8 - n);
- input[next_byte] |= m;
- next_bit += n;
- }
- }
- b = 0;
- }
- r = 0;
- } else if (buf[i] == '^') {
- r_n = 0;
- if (shs_type < 3) {
- SHA1_HashBuf(hash, input, next_bit/8);
- to_hex_str_cap(hashstr, hash, sizeof hash);
- hashstr[40] = '\0';
- fprintf(sharesp, "%s ^", hashstr);
- memset(input, 0, sizeof input);
- next_bit = 0;
- } else {
- do_shs_type3(sharesp, input, next_bit/8);
- }
- } else if (isdigit(buf[i])) {
- readbuf[r++] = buf[i];
- }
- }
- }
- if (skip || newline) {
- fprintf(sharesp, "%c", buf[i]);
- }
- }
- }
-}
-
int get_next_line(FILE *req, char *key, char *val, FILE *rsp)
{
int ignore = 0;
@@ -1058,8 +1880,10 @@ dss_test(char *reqdir, char *rspdir)
DSAPrivateKey privkey = { 0 };
PQGParams params;
PQGVerify verify;
- int i, j, rv;
+ unsigned int i;
+ int j, rv;
goto do_pqggen;
+#if 0
/* primality test */
do_prime:
sprintf(filename, "%s/prime.req", reqdir);
@@ -1090,6 +1914,7 @@ do_prime:
}
fclose(req);
fclose(rsp);
+#endif
do_pqggen:
/* PQG Gen */
sprintf(filename, "%s/pqg.req", reqdir);
@@ -1103,7 +1928,7 @@ do_pqggen:
fprintf(rsp, "[mod=%d]\n", mod);
} else if (strcmp(key, "N") == 0) {
char str[264];
- int jj;
+ unsigned int jj;
int N = atoi(val);
for (i=0; i<N; i++) {
PQGParams *pqg;
@@ -1225,7 +2050,7 @@ do_keygen:
PQGParams *pqg;
PQGVerify *vfy;
fprintf(rsp, "[mod=%d]\n", 512 + j*64);
- PQG_ParamGenSeedLen(j, &pqg, &vfy);
+ PQG_ParamGen(j, &pqg, &vfy);
to_hex_str(str, pqg->prime.data, pqg->prime.len);
fprintf(rsp, "P= %s\n", str);
to_hex_str(str, pqg->subPrime.data, pqg->subPrime.len);
@@ -1402,6 +2227,686 @@ do_sigver:
fclose(rsp);
}
+#ifdef NSS_ENABLE_ECC
+typedef struct curveNameTagPairStr {
+ char *curveName;
+ SECOidTag curveOidTag;
+} CurveNameTagPair;
+
+#define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP192R1
+/* #define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP160R1 */
+
+static CurveNameTagPair nameTagPair[] =
+{
+ { "sect163k1", SEC_OID_SECG_EC_SECT163K1},
+ { "nistk163", SEC_OID_SECG_EC_SECT163K1},
+ { "sect163r1", SEC_OID_SECG_EC_SECT163R1},
+ { "sect163r2", SEC_OID_SECG_EC_SECT163R2},
+ { "nistb163", SEC_OID_SECG_EC_SECT163R2},
+ { "sect193r1", SEC_OID_SECG_EC_SECT193R1},
+ { "sect193r2", SEC_OID_SECG_EC_SECT193R2},
+ { "sect233k1", SEC_OID_SECG_EC_SECT233K1},
+ { "nistk233", SEC_OID_SECG_EC_SECT233K1},
+ { "sect233r1", SEC_OID_SECG_EC_SECT233R1},
+ { "nistb233", SEC_OID_SECG_EC_SECT233R1},
+ { "sect239k1", SEC_OID_SECG_EC_SECT239K1},
+ { "sect283k1", SEC_OID_SECG_EC_SECT283K1},
+ { "nistk283", SEC_OID_SECG_EC_SECT283K1},
+ { "sect283r1", SEC_OID_SECG_EC_SECT283R1},
+ { "nistb283", SEC_OID_SECG_EC_SECT283R1},
+ { "sect409k1", SEC_OID_SECG_EC_SECT409K1},
+ { "nistk409", SEC_OID_SECG_EC_SECT409K1},
+ { "sect409r1", SEC_OID_SECG_EC_SECT409R1},
+ { "nistb409", SEC_OID_SECG_EC_SECT409R1},
+ { "sect571k1", SEC_OID_SECG_EC_SECT571K1},
+ { "nistk571", SEC_OID_SECG_EC_SECT571K1},
+ { "sect571r1", SEC_OID_SECG_EC_SECT571R1},
+ { "nistb571", SEC_OID_SECG_EC_SECT571R1},
+ { "secp160k1", SEC_OID_SECG_EC_SECP160K1},
+ { "secp160r1", SEC_OID_SECG_EC_SECP160R1},
+ { "secp160r2", SEC_OID_SECG_EC_SECP160R2},
+ { "secp192k1", SEC_OID_SECG_EC_SECP192K1},
+ { "secp192r1", SEC_OID_SECG_EC_SECP192R1},
+ { "nistp192", SEC_OID_SECG_EC_SECP192R1},
+ { "secp224k1", SEC_OID_SECG_EC_SECP224K1},
+ { "secp224r1", SEC_OID_SECG_EC_SECP224R1},
+ { "nistp224", SEC_OID_SECG_EC_SECP224R1},
+ { "secp256k1", SEC_OID_SECG_EC_SECP256K1},
+ { "secp256r1", SEC_OID_SECG_EC_SECP256R1},
+ { "nistp256", SEC_OID_SECG_EC_SECP256R1},
+ { "secp384r1", SEC_OID_SECG_EC_SECP384R1},
+ { "nistp384", SEC_OID_SECG_EC_SECP384R1},
+ { "secp521r1", SEC_OID_SECG_EC_SECP521R1},
+ { "nistp521", SEC_OID_SECG_EC_SECP521R1},
+
+ { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
+ { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
+ { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
+ { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
+ { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
+ { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
+
+ { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
+ { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
+ { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
+ { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
+ { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
+ { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
+ { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
+ { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
+ { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
+ { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
+ { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
+ { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
+ { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
+ { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
+ { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
+ { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
+ { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
+ { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
+ { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
+ { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
+
+ { "secp112r1", SEC_OID_SECG_EC_SECP112R1},
+ { "secp112r2", SEC_OID_SECG_EC_SECP112R2},
+ { "secp128r1", SEC_OID_SECG_EC_SECP128R1},
+ { "secp128r2", SEC_OID_SECG_EC_SECP128R2},
+
+ { "sect113r1", SEC_OID_SECG_EC_SECT113R1},
+ { "sect113r2", SEC_OID_SECG_EC_SECT113R2},
+ { "sect131r1", SEC_OID_SECG_EC_SECT131R1},
+ { "sect131r2", SEC_OID_SECG_EC_SECT131R2},
+};
+
+static SECKEYECParams *
+getECParams(const char *curve)
+{
+ SECKEYECParams *ecparams;
+ SECOidData *oidData = NULL;
+ SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
+ int i, numCurves;
+
+ if (curve != NULL) {
+ numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
+ for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
+ i++) {
+ if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
+ curveOidTag = nameTagPair[i].curveOidTag;
+ }
+ }
+
+ /* Return NULL if curve name is not recognized */
+ if ((curveOidTag == SEC_OID_UNKNOWN) ||
+ (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
+ fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
+ return NULL;
+ }
+
+ ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
+
+ /*
+ * ecparams->data needs to contain the ASN encoding of an object ID (OID)
+ * representing the named curve. The actual OID is in
+ * oidData->oid.data so we simply prepend 0x06 and OID length
+ */
+ ecparams->data[0] = SEC_ASN1_OBJECT_ID;
+ ecparams->data[1] = oidData->oid.len;
+ memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
+
+ return ecparams;
+}
+
+/*
+ * Perform the ECDSA Key Pair Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+ecdsa_keypair_test(char *reqfn)
+{
+ char buf[256]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * needs to be large enough to hold the longest
+ * line "Qx = <144 hex digits>\n".
+ */
+ FILE *ecdsareq; /* input stream from the REQUEST file */
+ FILE *ecdsaresp; /* output stream to the RESPONSE file */
+ char curve[16]; /* "nistxddd" */
+ ECParams *ecparams;
+ int N;
+ int i;
+ unsigned int len;
+
+ ecdsareq = fopen(reqfn, "r");
+ ecdsaresp = stdout;
+ strcpy(curve, "nist");
+ while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* [X-ddd] */
+ if (buf[0] == '[') {
+ const char *src;
+ char *dst;
+ SECKEYECParams *encodedparams;
+
+ src = &buf[1];
+ dst = &curve[4];
+ *dst++ = tolower(*src);
+ src += 2; /* skip the hyphen */
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst = '\0';
+ encodedparams = getECParams(curve);
+ if (encodedparams == NULL) {
+ goto loser;
+ }
+ if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+ goto loser;
+ }
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* N = x */
+ if (buf[0] == 'N') {
+ if (sscanf(buf, "N = %d", &N) != 1) {
+ goto loser;
+ }
+ for (i = 0; i < N; i++) {
+ ECPrivateKey *ecpriv;
+
+ if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
+ goto loser;
+ }
+ fputs("d = ", ecdsaresp);
+ to_hex_str(buf, ecpriv->privateValue.data,
+ ecpriv->privateValue.len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
+ != SECSuccess) {
+ goto loser;
+ }
+ len = ecpriv->publicValue.len;
+ if (len%2 == 0) {
+ goto loser;
+ }
+ len = (len-1)/2;
+ if (ecpriv->publicValue.data[0]
+ != EC_POINT_FORM_UNCOMPRESSED) {
+ goto loser;
+ }
+ fputs("Qx = ", ecdsaresp);
+ to_hex_str(buf, &ecpriv->publicValue.data[1], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ fputs("Qy = ", ecdsaresp);
+ to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ fputc('\n', ecdsaresp);
+ PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
+ }
+ PORT_FreeArena(ecparams->arena, PR_TRUE);
+ continue;
+ }
+ }
+loser:
+ fclose(ecdsareq);
+}
+
+/*
+ * Perform the ECDSA Public Key Validation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+ecdsa_pkv_test(char *reqfn)
+{
+ char buf[256]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "Qx = <144 hex digits>\n".
+ */
+ FILE *ecdsareq; /* input stream from the REQUEST file */
+ FILE *ecdsaresp; /* output stream to the RESPONSE file */
+ char curve[16]; /* "nistxddd" */
+ ECParams *ecparams = NULL;
+ SECItem pubkey;
+ unsigned int i;
+ unsigned int len;
+ PRBool keyvalid = PR_TRUE;
+
+ ecdsareq = fopen(reqfn, "r");
+ ecdsaresp = stdout;
+ strcpy(curve, "nist");
+ pubkey.data = NULL;
+ while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* [X-ddd] */
+ if (buf[0] == '[') {
+ const char *src;
+ char *dst;
+ SECKEYECParams *encodedparams;
+
+ src = &buf[1];
+ dst = &curve[4];
+ *dst++ = tolower(*src);
+ src += 2; /* skip the hyphen */
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst = '\0';
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_TRUE);
+ ecparams = NULL;
+ }
+ encodedparams = getECParams(curve);
+ if (encodedparams == NULL) {
+ goto loser;
+ }
+ if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+ goto loser;
+ }
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
+ len = (ecparams->fieldID.size + 7) >> 3;
+ if (pubkey.data != NULL) {
+ PORT_Free(pubkey.data);
+ pubkey.data = NULL;
+ }
+ SECITEM_AllocItem(NULL, &pubkey, 2*len+1);
+ if (pubkey.data == NULL) {
+ goto loser;
+ }
+ pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED;
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* Qx = ... */
+ if (strncmp(buf, "Qx", 2) == 0) {
+ fputs(buf, ecdsaresp);
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&pubkey.data[1], len, &buf[i]);
+ continue;
+ }
+ /* Qy = ... */
+ if (strncmp(buf, "Qy", 2) == 0) {
+ fputs(buf, ecdsaresp);
+ if (!keyvalid) {
+ fputs("Result = F\n", ecdsaresp);
+ continue;
+ }
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&pubkey.data[1+len], len, &buf[i]);
+ if (!keyvalid) {
+ fputs("Result = F\n", ecdsaresp);
+ continue;
+ }
+ if (EC_ValidatePublicKey(ecparams, &pubkey) == SECSuccess) {
+ fputs("Result = P\n", ecdsaresp);
+ } else if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
+ fputs("Result = F\n", ecdsaresp);
+ } else {
+ goto loser;
+ }
+ continue;
+ }
+ }
+loser:
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_TRUE);
+ }
+ if (pubkey.data != NULL) {
+ PORT_Free(pubkey.data);
+ }
+ fclose(ecdsareq);
+}
+
+/*
+ * Perform the ECDSA Signature Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+ecdsa_siggen_test(char *reqfn)
+{
+ char buf[1024]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * needs to be large enough to hold the longest
+ * line "Msg = <256 hex digits>\n".
+ */
+ FILE *ecdsareq; /* input stream from the REQUEST file */
+ FILE *ecdsaresp; /* output stream to the RESPONSE file */
+ char curve[16]; /* "nistxddd" */
+ ECParams *ecparams = NULL;
+ int i, j;
+ unsigned int len;
+ unsigned char msg[512]; /* message to be signed (<= 128 bytes) */
+ unsigned int msglen;
+ unsigned char sha1[20]; /* SHA-1 hash (160 bits) */
+ unsigned char sig[2*MAX_ECKEY_LEN];
+ SECItem signature, digest;
+
+ ecdsareq = fopen(reqfn, "r");
+ ecdsaresp = stdout;
+ strcpy(curve, "nist");
+ while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* [X-ddd] */
+ if (buf[0] == '[') {
+ const char *src;
+ char *dst;
+ SECKEYECParams *encodedparams;
+
+ src = &buf[1];
+ dst = &curve[4];
+ *dst++ = tolower(*src);
+ src += 2; /* skip the hyphen */
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst = '\0';
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_TRUE);
+ ecparams = NULL;
+ }
+ encodedparams = getECParams(curve);
+ if (encodedparams == NULL) {
+ goto loser;
+ }
+ if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+ goto loser;
+ }
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ ECPrivateKey *ecpriv;
+
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &msg[j]);
+ }
+ msglen = j;
+ if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) {
+ goto loser;
+ }
+ fputs(buf, ecdsaresp);
+
+ if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
+ goto loser;
+ }
+ if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
+ != SECSuccess) {
+ goto loser;
+ }
+ len = ecpriv->publicValue.len;
+ if (len%2 == 0) {
+ goto loser;
+ }
+ len = (len-1)/2;
+ if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
+ goto loser;
+ }
+ fputs("Qx = ", ecdsaresp);
+ to_hex_str(buf, &ecpriv->publicValue.data[1], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ fputs("Qy = ", ecdsaresp);
+ to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+
+ digest.type = siBuffer;
+ digest.data = sha1;
+ digest.len = sizeof sha1;
+ signature.type = siBuffer;
+ signature.data = sig;
+ signature.len = sizeof sig;
+ if (ECDSA_SignDigest(ecpriv, &signature, &digest) != SECSuccess) {
+ goto loser;
+ }
+ len = signature.len;
+ if (len%2 != 0) {
+ goto loser;
+ }
+ len = len/2;
+ fputs("R = ", ecdsaresp);
+ to_hex_str(buf, &signature.data[0], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ fputs("S = ", ecdsaresp);
+ to_hex_str(buf, &signature.data[len], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+
+ PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
+ continue;
+ }
+ }
+loser:
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_TRUE);
+ }
+ fclose(ecdsareq);
+}
+
+/*
+ * Perform the ECDSA Signature Verification Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+ecdsa_sigver_test(char *reqfn)
+{
+ char buf[1024]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "Msg = <256 hex digits>\n".
+ */
+ FILE *ecdsareq; /* input stream from the REQUEST file */
+ FILE *ecdsaresp; /* output stream to the RESPONSE file */
+ char curve[16]; /* "nistxddd" */
+ ECParams *ecparams = NULL;
+ ECPublicKey ecpub;
+ unsigned int i, j;
+ unsigned int flen; /* length in bytes of the field size */
+ unsigned int olen; /* length in bytes of the base point order */
+ unsigned char msg[512]; /* message that was signed (<= 128 bytes) */
+ unsigned int msglen;
+ unsigned char sha1[20]; /* SHA-1 hash (160 bits) */
+ unsigned char sig[2*MAX_ECKEY_LEN];
+ SECItem signature, digest;
+ PRBool keyvalid = PR_TRUE;
+ PRBool sigvalid = PR_TRUE;
+
+ ecdsareq = fopen(reqfn, "r");
+ ecdsaresp = stdout;
+ ecpub.publicValue.type = siBuffer;
+ ecpub.publicValue.data = NULL;
+ ecpub.publicValue.len = 0;
+ strcpy(curve, "nist");
+ while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* [X-ddd] */
+ if (buf[0] == '[') {
+ const char *src;
+ char *dst;
+ SECKEYECParams *encodedparams;
+
+ src = &buf[1];
+ dst = &curve[4];
+ *dst++ = tolower(*src);
+ src += 2; /* skip the hyphen */
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst = '\0';
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_TRUE);
+ ecparams = NULL;
+ }
+ encodedparams = getECParams(curve);
+ if (encodedparams == NULL) {
+ goto loser;
+ }
+ if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+ goto loser;
+ }
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
+ ecpub.ecParams = *ecparams;
+ flen = (ecparams->fieldID.size + 7) >> 3;
+ olen = ecparams->order.len;
+ if (2*olen > sizeof sig) {
+ goto loser;
+ }
+ if (ecpub.publicValue.data != NULL) {
+ SECITEM_FreeItem(&ecpub.publicValue, PR_FALSE);
+ }
+ SECITEM_AllocItem(NULL, &ecpub.publicValue, 2*flen+1);
+ if (ecpub.publicValue.data == NULL) {
+ goto loser;
+ }
+ ecpub.publicValue.data[0] = EC_POINT_FORM_UNCOMPRESSED;
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &msg[j]);
+ }
+ msglen = j;
+ if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) {
+ goto loser;
+ }
+ fputs(buf, ecdsaresp);
+
+ digest.type = siBuffer;
+ digest.data = sha1;
+ digest.len = sizeof sha1;
+
+ continue;
+ }
+ /* Qx = ... */
+ if (strncmp(buf, "Qx", 2) == 0) {
+ fputs(buf, ecdsaresp);
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&ecpub.publicValue.data[1], flen,
+ &buf[i]);
+ continue;
+ }
+ /* Qy = ... */
+ if (strncmp(buf, "Qy", 2) == 0) {
+ fputs(buf, ecdsaresp);
+ if (!keyvalid) {
+ continue;
+ }
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&ecpub.publicValue.data[1+flen], flen,
+ &buf[i]);
+ if (!keyvalid) {
+ continue;
+ }
+ if (EC_ValidatePublicKey(ecparams, &ecpub.publicValue)
+ != SECSuccess) {
+ if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
+ keyvalid = PR_FALSE;
+ } else {
+ goto loser;
+ }
+ }
+ continue;
+ }
+ /* R = ... */
+ if (buf[0] == 'R') {
+ fputs(buf, ecdsaresp);
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ sigvalid = from_hex_str(sig, olen, &buf[i]);
+ continue;
+ }
+ /* S = ... */
+ if (buf[0] == 'S') {
+ fputs(buf, ecdsaresp);
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ if (sigvalid) {
+ sigvalid = from_hex_str(&sig[olen], olen, &buf[i]);
+ }
+ signature.type = siBuffer;
+ signature.data = sig;
+ signature.len = 2*olen;
+
+ if (!keyvalid || !sigvalid) {
+ fputs("Result = F\n", ecdsaresp);
+ } else if (ECDSA_VerifyDigest(&ecpub, &signature, &digest)
+ == SECSuccess) {
+ fputs("Result = P\n", ecdsaresp);
+ } else {
+ fputs("Result = F\n", ecdsaresp);
+ }
+ continue;
+ }
+ }
+loser:
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_TRUE);
+ }
+ if (ecpub.publicValue.data != NULL) {
+ SECITEM_FreeItem(&ecpub.publicValue, PR_FALSE);
+ }
+ fclose(ecdsareq);
+}
+#endif /* NSS_ENABLE_ECC */
+
void do_random()
{
int i, j, k = 0;
@@ -1415,282 +2920,483 @@ void do_random()
}
}
+/*
+ * Calculate the SHA Message Digest
+ *
+ * MD = Message digest
+ * MDLen = length of Message Digest and SHA_Type
+ * msg = message to digest
+ * msgLen = length of message to digest
+ */
+SECStatus sha_calcMD(unsigned char *MD, unsigned int MDLen, unsigned char *msg, unsigned int msgLen)
+{
+ SECStatus sha_status = SECFailure;
+
+ if (MDLen == SHA1_LENGTH) {
+ sha_status = SHA1_HashBuf(MD, msg, msgLen);
+ } else if (MDLen == SHA256_LENGTH) {
+ sha_status = SHA256_HashBuf(MD, msg, msgLen);
+ } else if (MDLen == SHA384_LENGTH) {
+ sha_status = SHA384_HashBuf(MD, msg, msgLen);
+ } else if (MDLen == SHA512_LENGTH) {
+ sha_status = SHA512_HashBuf(MD, msg, msgLen);
+ }
+
+ return sha_status;
+}
+
+/*
+ * Perform the SHA Monte Carlo Test
+ *
+ * MDLen = length of Message Digest and SHA_Type
+ * seed = input seed value
+ * resp = is the output response file.
+ */
+SECStatus sha_mct_test(unsigned int MDLen, unsigned char *seed, FILE *resp)
+{
+ int i, j;
+ unsigned int msgLen = MDLen*3;
+ unsigned char MD_i3[HASH_LENGTH_MAX]; /* MD[i-3] */
+ unsigned char MD_i2[HASH_LENGTH_MAX]; /* MD[i-2] */
+ unsigned char MD_i1[HASH_LENGTH_MAX]; /* MD[i-1] */
+ unsigned char MD_i[HASH_LENGTH_MAX]; /* MD[i] */
+ unsigned char msg[HASH_LENGTH_MAX*3];
+ char buf[HASH_LENGTH_MAX*2 + 1]; /* MAX buf MD_i as a hex string */
+
+ for (j=0; j<100; j++) {
+ /* MD_0 = MD_1 = MD_2 = seed */
+ memcpy(MD_i3, seed, MDLen);
+ memcpy(MD_i2, seed, MDLen);
+ memcpy(MD_i1, seed, MDLen);
+
+ for (i=3; i < 1003; i++) {
+ /* Mi = MD[i-3] || MD [i-2] || MD [i-1] */
+ memcpy(msg, MD_i3, MDLen);
+ memcpy(&msg[MDLen], MD_i2, MDLen);
+ memcpy(&msg[MDLen*2], MD_i1,MDLen);
+
+ /* MDi = SHA(Msg) */
+ if (sha_calcMD(MD_i, MDLen,
+ msg, msgLen) != SECSuccess) {
+ return SECFailure;
+ }
+
+ /* save MD[i-3] MD[i-2] MD[i-1] */
+ memcpy(MD_i3, MD_i2, MDLen);
+ memcpy(MD_i2, MD_i1, MDLen);
+ memcpy(MD_i1, MD_i, MDLen);
+
+ }
+
+ /* seed = MD_i */
+ memcpy(seed, MD_i, MDLen);
+
+ sprintf(buf, "COUNT = %d\n", j);
+ fputs(buf, resp);
+
+ /* output MD_i */
+ fputs("MD = ", resp);
+ to_hex_str(buf, MD_i, MDLen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ }
+
+ return SECSuccess;
+}
+
+/*
+ * Perform the SHA Tests.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void sha_test(char *reqfn)
+{
+ int i, j;
+ unsigned int MDlen; /* the length of the Message Digest in Bytes */
+ unsigned int msgLen; /* the length of the input Message in Bytes */
+ char *msg = NULL; /* holds the message to digest.*/
+ size_t bufSize = 25608; /*MAX buffer size */
+ char *buf = NULL; /* holds one line from the input REQUEST file.*/
+ unsigned char seed[HASH_LENGTH_MAX]; /* max size of seed 64 bytes */
+ unsigned char MD[HASH_LENGTH_MAX]; /* message digest */
+
+ FILE *req; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+
+ buf = PORT_ZAlloc(bufSize);
+ if (buf == NULL) {
+ goto loser;
+ }
+
+ /* zeroize the variables for the test with this data set */
+ memset(seed, 0, sizeof seed);
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ while (fgets(buf, bufSize, req) != NULL) {
+
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, resp);
+ continue;
+ }
+ /* [L = Length of the Message Digest and sha_type */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "L ", 1) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ MDlen = atoi(&buf[i]);
+ fputs(buf, resp);
+ continue;
+ }
+ }
+ /* Len = Length of the Input Message Length ... */
+ if (strncmp(buf, "Len", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ if (msg) {
+ PORT_ZFree(msg,msgLen);
+ msg = NULL;
+ }
+ msgLen = atoi(&buf[i]); /* in bits */
+ msgLen = msgLen/8; /* convert to bytes */
+ fputs(buf, resp);
+ msg = PORT_ZAlloc(msgLen);
+ if (msg == NULL && msgLen != 0) {
+ goto loser;
+ }
+ continue;
+ }
+ /* MSG = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j< msgLen; i+=2,j++) {
+ hex_from_2char(&buf[i], &msg[j]);
+ }
+ fputs(buf, resp);
+ /* calculate the Message Digest */
+ memset(MD, 0, sizeof MD);
+ if (sha_calcMD(MD, MDlen,
+ msg, msgLen) != SECSuccess) {
+ goto loser;
+ }
+
+ fputs("MD = ", resp);
+ to_hex_str(buf, MD, MDlen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+
+ continue;
+ }
+ /* Seed = ... */
+ if (strncmp(buf, "Seed", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof seed; i+=2,j++) {
+ hex_from_2char(&buf[i], &seed[j]);
+ }
+
+ fputs(buf, resp);
+ fputc('\n', resp);
+
+ /* do the Monte Carlo test */
+ if (sha_mct_test(MDlen, seed, resp) != SECSuccess) {
+ goto loser;
+ }
+
+ continue;
+ }
+ }
+loser:
+ fclose(req);
+ if (buf) {
+ PORT_ZFree(buf, bufSize);
+ }
+ if (msg) {
+ PORT_ZFree(msg, msgLen);
+ }
+}
+
+/****************************************************/
+/* HMAC SHA-X calc */
+/* hmac_computed - the computed HMAC */
+/* hmac_length - the length of the computed HMAC */
+/* secret_key - secret key to HMAC */
+/* secret_key_length - length of secret key, */
+/* message - message to HMAC */
+/* message_length - length ofthe message */
+/****************************************************/
+static SECStatus
+hmac_calc(unsigned char *hmac_computed,
+ const unsigned int hmac_length,
+ const char *secret_key,
+ const unsigned int secret_key_length,
+ const char *message,
+ const unsigned int message_length,
+ const HASH_HashType hashAlg )
+{
+ SECStatus hmac_status = SECFailure;
+ HMACContext *cx = NULL;
+ SECHashObject *hashObj = NULL;
+ unsigned int bytes_hashed = 0;
+
+ hashObj = (SECHashObject *) HASH_GetRawHashObject(hashAlg);
+
+ if (!hashObj)
+ return( SECFailure );
+
+ cx = HMAC_Create(hashObj, secret_key,
+ secret_key_length,
+ PR_TRUE); /* PR_TRUE for in FIPS mode */
+
+ if (cx == NULL)
+ return( SECFailure );
+
+ HMAC_Begin(cx);
+ HMAC_Update(cx, message, message_length);
+ hmac_status = HMAC_Finish(cx, hmac_computed, &bytes_hashed,
+ hmac_length);
+
+ HMAC_Destroy(cx, PR_TRUE);
+
+ return( hmac_status );
+}
+
+/*
+ * Perform the HMAC Tests.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void hmac_test(char *reqfn)
+{
+ int i, j;
+ size_t bufSize = 288; /* MAX buffer size */
+ char *buf = NULL; /* holds one line from the input REQUEST file.*/
+ unsigned int keyLen; /* Key Length */
+ char key[140]; /* key MAX size = 140 */
+ unsigned int msgLen = 128; /* the length of the input */
+ /* Message is always 128 Bytes */
+ char *msg = NULL; /* holds the message to digest.*/
+ unsigned int HMACLen; /* the length of the HMAC Bytes */
+ unsigned char HMAC[HASH_LENGTH_MAX]; /* computed HMAC */
+ HASH_HashType hash_alg; /* HMAC type */
+
+ FILE *req; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+
+ buf = PORT_ZAlloc(bufSize);
+ if (buf == NULL) {
+ goto loser;
+ }
+ msg = PORT_ZAlloc(msgLen);
+ memset(msg, 0, msgLen);
+ if (msg == NULL) {
+ goto loser;
+ }
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ while (fgets(buf, bufSize, req) != NULL) {
+
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, resp);
+ continue;
+ }
+ /* [L = Length of the MAC and HASH_type */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "L ", 1) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ /* HMACLen will get reused for Tlen */
+ HMACLen = atoi(&buf[i]);
+ /* set the HASH algorithm for HMAC */
+ if (HMACLen == SHA1_LENGTH) {
+ hash_alg = HASH_AlgSHA1;
+ } else if (HMACLen == SHA256_LENGTH) {
+ hash_alg = HASH_AlgSHA256;
+ } else if (HMACLen == SHA384_LENGTH) {
+ hash_alg = HASH_AlgSHA384;
+ } else if (HMACLen == SHA512_LENGTH) {
+ hash_alg = HASH_AlgSHA512;
+ } else {
+ goto loser;
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ }
+ /* Count = test iteration number*/
+ if (strncmp(buf, "Count ", 5) == 0) {
+ /* count can just be put into resp file */
+ fputs(buf, resp);
+ /* zeroize the variables for the test with this data set */
+ keyLen = 0;
+ HMACLen = 0;
+ memset(key, 0, sizeof key);
+ memset(msg, 0, sizeof msg);
+ memset(HMAC, 0, sizeof HMAC);
+ continue;
+ }
+ /* KLen = Length of the Input Secret Key ... */
+ if (strncmp(buf, "Klen", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyLen = atoi(&buf[i]); /* in bytes */
+ fputs(buf, resp);
+ continue;
+ }
+ /* key = the secret key for the key to MAC */
+ if (strncmp(buf, "Key", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j< keyLen; i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ fputs(buf, resp);
+ }
+ /* TLen = Length of the calculated HMAC */
+ if (strncmp(buf, "Tlen", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ HMACLen = atoi(&buf[i]); /* in bytes */
+ fputs(buf, resp);
+ continue;
+ }
+ /* MSG = to HMAC always 128 bytes for these tests */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j< msgLen; i+=2,j++) {
+ hex_from_2char(&buf[i], &msg[j]);
+ }
+ fputs(buf, resp);
+ /* calculate the HMAC and output */
+ if (hmac_calc(HMAC, HMACLen, key, keyLen,
+ msg, msgLen, hash_alg) != SECSuccess) {
+ goto loser;
+ }
+ fputs("MAC = ", resp);
+ to_hex_str(buf, HMAC, HMACLen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ continue;
+ }
+ }
+loser:
+ fclose(req);
+ if (buf) {
+ PORT_ZFree(buf, bufSize);
+ }
+ if (msg) {
+ PORT_ZFree(msg, msgLen);
+ }
+}
+
int main(int argc, char **argv)
{
- unsigned char key[24];
- unsigned char inp[24];
- unsigned char iv[8];
if (argc < 2) exit (-1);
NSS_NoDB_Init(NULL);
- memset(inp, 0, sizeof inp);
/*************/
- /* DES */
+ /* TDEA */
/*************/
- /**** ECB ****/
- /* encrypt */
- if ( strcmp(argv[1], "des_5_1_1_1") == 0) {
- printf("Variable Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- des_var_pt_kat(NSS_DES, PR_TRUE, 8, key, NULL, NULL);
- } else if (strcmp(argv[1], "des_5_1_1_2") == 0) {
- printf("Inverse Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- des_inv_perm_kat(NSS_DES, PR_TRUE, 8, key, NULL, NULL);
- } else if (strcmp(argv[1], "des_5_1_1_3") == 0) {
- printf("Variable Key Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- des_var_key_kat(NSS_DES, PR_TRUE, 8, key, NULL, inp);
- } else if (strcmp(argv[1], "des_5_1_1_4") == 0) {
- printf("Permutation Operation Known Answer Test - Encryption\n\n");
- des_perm_op_kat(NSS_DES, PR_TRUE, 8, NULL, NULL, inp);
- } else if (strcmp(argv[1], "des_5_1_1_5") == 0) {
- printf("Substitution Table Known Answer Test - Encryption\n\n");
- des_sub_tbl_kat(NSS_DES, PR_TRUE, 8, NULL, NULL, NULL);
- } else if (strcmp(argv[1], "des_5_1_1_6") == 0) {
- printf("Modes Test for the Encryption Process\n\n");
- des_modes(NSS_DES, PR_TRUE, 8, des_ecb_enc_key,
- NULL, des_ecb_enc_inp, 0);
- /* decrypt */
- } else if (strcmp(argv[1], "des_5_1_2_1") == 0) {
- printf("Variable Ciphertext Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- des_var_pt_kat(NSS_DES, PR_FALSE, 8, key, NULL, NULL);
- } else if (strcmp(argv[1], "des_5_1_2_2") == 0) {
- printf("Inverse Permutation Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- des_inv_perm_kat(NSS_DES, PR_FALSE, 8, key, NULL, NULL);
- } else if (strcmp(argv[1], "des_5_1_2_3") == 0) {
- printf("Variable Key Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- des_var_key_kat(NSS_DES, PR_FALSE, 8, key, NULL, inp);
- } else if (strcmp(argv[1], "des_5_1_2_4") == 0) {
- printf("Permutation Operation Known Answer Test - Decryption\n\n");
- des_perm_op_kat(NSS_DES, PR_FALSE, 8, NULL, NULL, inp);
- } else if (strcmp(argv[1], "des_5_1_2_5") == 0) {
- printf("Substitution Table Known Answer Test - Decryption\n\n");
- des_sub_tbl_kat(NSS_DES, PR_FALSE, 8, NULL, NULL, NULL);
- } else if (strcmp(argv[1], "des_5_1_2_6") == 0) {
- printf("Modes Test for the Decryption Process\n\n");
- des_modes(NSS_DES, PR_FALSE, 8, des_ecb_dec_key,
- NULL, des_ecb_dec_inp, 0);
- /**** CBC ****/
- /* encrypt */
- } else if (strcmp(argv[1], "des_5_2_1_1") == 0) {
- printf("Variable Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_pt_kat(NSS_DES_CBC, PR_TRUE, 8, key, iv, NULL);
- } else if (strcmp(argv[1], "des_5_2_1_2") == 0) {
- printf("Inverse Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_inv_perm_kat(NSS_DES_CBC, PR_TRUE, 8, key, iv, NULL);
- } else if (strcmp(argv[1], "des_5_2_1_3") == 0) {
- printf("Variable Key Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_key_kat(NSS_DES_CBC, PR_TRUE, 8, key, iv, inp);
- } else if (strcmp(argv[1], "des_5_2_1_4") == 0) {
- printf("Permutation Operation Known Answer Test - Encryption\n\n");
- memset(iv, 0, sizeof iv);
- des_perm_op_kat(NSS_DES_CBC, PR_TRUE, 8, NULL, iv, inp);
- } else if (strcmp(argv[1], "des_5_2_1_5") == 0) {
- printf("Substitution Table Known Answer Test - Encryption\n\n");
- memset(iv, 0, sizeof iv);
- des_sub_tbl_kat(NSS_DES_CBC, PR_TRUE, 8, NULL, iv, NULL);
- } else if (strcmp(argv[1], "des_5_2_1_6") == 0) {
- printf("Modes Test for the Encryption Process\n\n");
- des_modes(NSS_DES_CBC, PR_TRUE, 8, des_cbc_enc_key,
- des_cbc_enc_iv, des_cbc_enc_inp, 0);
- /* decrypt */
- } else if (strcmp(argv[1], "des_5_2_2_1") == 0) {
- printf("Variable Ciphertext Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_pt_kat(NSS_DES_CBC, PR_FALSE, 8, key, iv, NULL);
- } else if (strcmp(argv[1], "des_5_2_2_2") == 0) {
- printf("Inverse Permutation Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_inv_perm_kat(NSS_DES_CBC, PR_FALSE, 8, key, iv, NULL);
- } else if (strcmp(argv[1], "des_5_2_2_3") == 0) {
- printf("Variable Key Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_key_kat(NSS_DES_CBC, PR_FALSE, 8, key, iv, inp);
- } else if (strcmp(argv[1], "des_5_2_2_4") == 0) {
- printf("Permutation Operation Known Answer Test - Decryption\n\n");
- memset(iv, 0, sizeof iv);
- des_perm_op_kat(NSS_DES_CBC, PR_FALSE, 8, NULL, iv, inp);
- } else if (strcmp(argv[1], "des_5_2_2_5") == 0) {
- printf("Substitution Table Known Answer Test - Decryption\n\n");
- memset(iv, 0, sizeof iv);
- des_sub_tbl_kat(NSS_DES_CBC, PR_FALSE, 8, NULL, iv, NULL);
- } else if (strcmp(argv[1], "des_5_2_2_6") == 0) {
- printf("Modes Test for the Decryption Process\n\n");
- des_modes(NSS_DES_CBC, PR_FALSE, 8, des_cbc_dec_key,
- des_cbc_dec_iv, des_cbc_dec_inp, 0);
+ if (strcmp(argv[1], "tdea") == 0) {
+ /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */
+ if (strcmp(argv[2], "kat") == 0) {
+ /* Known Answer Test (KAT) */
+ tdea_kat_mmt(argv[4]);
+ } else if (strcmp(argv[2], "mmt") == 0) {
+ /* Multi-block Message Test (MMT) */
+ tdea_kat_mmt(argv[4]);
+ } else if (strcmp(argv[2], "mct") == 0) {
+ /* Monte Carlo Test (MCT) */
+ if (strcmp(argv[3], "ecb") == 0) {
+ /* ECB mode */
+ tdea_mct(NSS_DES_EDE3, argv[4]);
+ } else if (strcmp(argv[3], "cbc") == 0) {
+ /* CBC mode */
+ tdea_mct(NSS_DES_EDE3_CBC, argv[4]);
+ }
+ }
/*************/
- /* TDEA */
+ /* AES */
+ /*************/
+ } else if (strcmp(argv[1], "aes") == 0) {
+ /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */
+ if ( strcmp(argv[2], "kat") == 0) {
+ /* Known Answer Test (KAT) */
+ aes_kat_mmt(argv[4]);
+ } else if (strcmp(argv[2], "mmt") == 0) {
+ /* Multi-block Message Test (MMT) */
+ aes_kat_mmt(argv[4]);
+ } else if (strcmp(argv[2], "mct") == 0) {
+ /* Monte Carlo Test (MCT) */
+ if ( strcmp(argv[3], "ecb") == 0) {
+ /* ECB mode */
+ aes_ecb_mct(argv[4]);
+ } else if (strcmp(argv[3], "cbc") == 0) {
+ /* CBC mode */
+ aes_cbc_mct(argv[4]);
+ }
+ }
/*************/
- /**** ECB ****/
- /* encrypt */
- } else if (strcmp(argv[1], "tdea_5_1_1_1") == 0) {
- printf("Variable Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- des_var_pt_kat(NSS_DES_EDE3, PR_TRUE, 24, key, NULL, NULL);
- } else if (strcmp(argv[1], "tdea_5_1_1_2") == 0) {
- printf("Inverse Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- des_inv_perm_kat(NSS_DES_EDE3, PR_TRUE, 24, key, NULL, NULL);
- } else if (strcmp(argv[1], "tdea_5_1_1_3") == 0) {
- printf("Variable Key Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- des_var_key_kat(NSS_DES_EDE3, PR_TRUE, 24, key, NULL, inp);
- } else if (strcmp(argv[1], "tdea_5_1_1_4") == 0) {
- printf("Permutation Operation Known Answer Test - Encryption\n\n");
- des_perm_op_kat(NSS_DES_EDE3, PR_TRUE, 24, NULL, NULL, inp);
- } else if (strcmp(argv[1], "tdea_5_1_1_5") == 0) {
- printf("Substitution Table Known Answer Test - Encryption\n\n");
- des_sub_tbl_kat(NSS_DES_EDE3, PR_TRUE, 24, NULL, NULL, NULL);
- } else if (strcmp(argv[1], "tdea_5_1_1_6_3") == 0) {
- printf("Modes Test for the Encryption Process\n");
- printf("DATA FILE UTILIZED: datecbmontee1\n\n");
- des_modes(NSS_DES_EDE3, PR_TRUE, 24, tdea1_ecb_enc_key,
- NULL, tdea1_ecb_enc_inp, 1);
- } else if (strcmp(argv[1], "tdea_5_1_1_6_2") == 0) {
- printf("Modes Test for the Encryption Process\n");
- printf("DATA FILE UTILIZED: datecbmontee2\n\n");
- des_modes(NSS_DES_EDE3, PR_TRUE, 24, tdea2_ecb_enc_key,
- NULL, tdea2_ecb_enc_inp, 2);
- } else if (strcmp(argv[1], "tdea_5_1_1_6_1") == 0) {
- printf("Modes Test for the Encryption Process\n");
- printf("DATA FILE UTILIZED: datecbmontee3\n\n");
- des_modes(NSS_DES_EDE3, PR_TRUE, 24, tdea3_ecb_enc_key,
- NULL, tdea3_ecb_enc_inp, 3);
- /* decrypt */
- } else if (strcmp(argv[1], "tdea_5_1_2_1") == 0) {
- printf("Variable Ciphertext Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- des_var_pt_kat(NSS_DES_EDE3, PR_FALSE, 24, key, NULL, NULL);
- } else if (strcmp(argv[1], "tdea_5_1_2_2") == 0) {
- printf("Inverse Permutation Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- des_inv_perm_kat(NSS_DES_EDE3, PR_FALSE, 24, key, NULL, NULL);
- } else if (strcmp(argv[1], "tdea_5_1_2_3") == 0) {
- printf("Variable Key Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- des_var_key_kat(NSS_DES_EDE3, PR_FALSE, 24, key, NULL, inp);
- } else if (strcmp(argv[1], "tdea_5_1_2_4") == 0) {
- printf("Permutation Operation Known Answer Test - Decryption\n\n");
- des_perm_op_kat(NSS_DES_EDE3, PR_FALSE, 24, NULL, NULL, inp);
- } else if (strcmp(argv[1], "tdea_5_1_2_5") == 0) {
- printf("Substitution Table Known Answer Test - Decryption\n\n");
- des_sub_tbl_kat(NSS_DES_EDE3, PR_FALSE, 24, NULL, NULL, NULL);
- } else if (strcmp(argv[1], "tdea_5_1_2_6_3") == 0) {
- printf("Modes Test for the Decryption Process\n");
- printf("DATA FILE UTILIZED: datecbmonted1\n\n");
- des_modes(NSS_DES_EDE3, PR_FALSE, 24, tdea1_ecb_dec_key,
- NULL, tdea1_ecb_dec_inp, 1);
- } else if (strcmp(argv[1], "tdea_5_1_2_6_2") == 0) {
- printf("Modes Test for the Decryption Process\n");
- printf("DATA FILE UTILIZED: datecbmonted2\n\n");
- des_modes(NSS_DES_EDE3, PR_FALSE, 24, tdea2_ecb_dec_key,
- NULL, tdea2_ecb_dec_inp, 2);
- } else if (strcmp(argv[1], "tdea_5_1_2_6_1") == 0) {
- printf("Modes Test for the Decryption Process\n");
- printf("DATA FILE UTILIZED: datecbmonted3\n\n");
- des_modes(NSS_DES_EDE3, PR_FALSE, 24, tdea3_ecb_dec_key,
- NULL, tdea3_ecb_dec_inp, 3);
- /**** CBC ****/
- /* encrypt */
- } else if (strcmp(argv[1], "tdea_5_2_1_1") == 0) {
- printf("Variable Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_pt_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, key, iv, NULL);
- } else if (strcmp(argv[1], "tdea_5_2_1_2") == 0) {
- printf("Inverse Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_inv_perm_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, key, iv, NULL);
- } else if (strcmp(argv[1], "tdea_5_2_1_3") == 0) {
- printf("Variable Key Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_key_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, key, iv, inp);
- } else if (strcmp(argv[1], "tdea_5_2_1_4") == 0) {
- printf("Permutation Operation Known Answer Test - Encryption\n\n");
- memset(iv, 0, sizeof iv);
- des_perm_op_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, NULL, iv, inp);
- } else if (strcmp(argv[1], "tdea_5_2_1_5") == 0) {
- memset(iv, 0, sizeof iv);
- printf("Substitution Table Known Answer Test - Encryption\n\n");
- des_sub_tbl_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, NULL, iv, NULL);
- } else if (strcmp(argv[1], "tdea_5_2_1_6_3") == 0) {
- printf("Modes Test for the Encryption Process\n");
- printf("DATA FILE UTILIZED: datcbcmontee1\n\n");
- des_modes(NSS_DES_EDE3_CBC, PR_TRUE, 24, tdea1_cbc_enc_key,
- tdea1_cbc_enc_iv, tdea1_cbc_enc_inp, 1);
- } else if (strcmp(argv[1], "tdea_5_2_1_6_2") == 0) {
- printf("Modes Test for the Encryption Process\n");
- printf("DATA FILE UTILIZED: datcbcmontee2\n\n");
- des_modes(NSS_DES_EDE3_CBC, PR_TRUE, 24, tdea2_cbc_enc_key,
- tdea2_cbc_enc_iv, tdea2_cbc_enc_inp, 2);
- } else if (strcmp(argv[1], "tdea_5_2_1_6_1") == 0) {
- printf("Modes Test for the Encryption Process\n");
- printf("DATA FILE UTILIZED: datcbcmontee3\n\n");
- des_modes(NSS_DES_EDE3_CBC, PR_TRUE, 24, tdea3_cbc_enc_key,
- tdea3_cbc_enc_iv, tdea3_cbc_enc_inp, 3);
- /* decrypt */
- } else if (strcmp(argv[1], "tdea_5_2_2_1") == 0) {
- printf("Variable Ciphertext Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_pt_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, key, iv, NULL);
- } else if (strcmp(argv[1], "tdea_5_2_2_2") == 0) {
- printf("Inverse Permutation Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_inv_perm_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, key, iv, NULL);
- } else if (strcmp(argv[1], "tdea_5_2_2_3") == 0) {
- printf("Variable Key Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_key_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, key, iv, inp);
- } else if (strcmp(argv[1], "tdea_5_2_2_4") == 0) {
- printf("Permutation Operation Known Answer Test - Decryption\n\n");
- memset(iv, 0, sizeof iv);
- des_perm_op_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, NULL, iv, inp);
- } else if (strcmp(argv[1], "tdea_5_2_2_5") == 0) {
- printf("Substitution Table Known Answer Test - Decryption\n\n");
- memset(iv, 0, sizeof iv);
- des_sub_tbl_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, NULL, iv, NULL);
- } else if (strcmp(argv[1], "tdea_5_2_2_6_3") == 0) {
- printf("Modes Test for the Decryption Process\n");
- printf("DATA FILE UTILIZED: datcbcmonted1\n\n");
- des_modes(NSS_DES_EDE3_CBC, PR_FALSE, 24, tdea1_cbc_dec_key,
- tdea1_cbc_dec_iv, tdea1_cbc_dec_inp, 1);
- } else if (strcmp(argv[1], "tdea_5_2_2_6_2") == 0) {
- printf("Modes Test for the Decryption Process\n");
- printf("DATA FILE UTILIZED: datcbcmonted2\n\n");
- des_modes(NSS_DES_EDE3_CBC, PR_FALSE, 24, tdea2_cbc_dec_key,
- tdea2_cbc_dec_iv, tdea2_cbc_dec_inp, 2);
- } else if (strcmp(argv[1], "tdea_5_2_2_6_1") == 0) {
- printf("Modes Test for the Decryption Process\n");
- printf("DATA FILE UTILIZED: datcbcmonted3\n\n");
- des_modes(NSS_DES_EDE3_CBC, PR_FALSE, 24, tdea3_cbc_dec_key,
- tdea3_cbc_dec_iv, tdea3_cbc_dec_inp, 3);
+ /* SHA */
/*************/
- /* SHS */
+ } else if (strcmp(argv[1], "sha") == 0) {
+ sha_test(argv[2]);
/*************/
- } else if (strcmp(argv[1], "shs") == 0) {
- shs_test(argv[2]);
+ /* HMAC */
+ /*************/
+ } else if (strcmp(argv[1], "hmac") == 0) {
+ hmac_test(argv[2]);
/*************/
/* DSS */
/*************/
} else if (strcmp(argv[1], "dss") == 0) {
dss_test(argv[2], argv[3]);
+#ifdef NSS_ENABLE_ECC
+ /*************/
+ /* ECDSA */
+ /*************/
+ } else if (strcmp(argv[1], "ecdsa") == 0) {
+ /* argv[2]=keypair|pkv|siggen|sigver argv[3]=<test name>.req */
+ if ( strcmp(argv[2], "keypair") == 0) {
+ /* Key Pair Generation Test */
+ ecdsa_keypair_test(argv[3]);
+ } else if (strcmp(argv[2], "pkv") == 0) {
+ /* Public Key Validation Test */
+ ecdsa_pkv_test(argv[3]);
+ } else if (strcmp(argv[2], "siggen") == 0) {
+ /* Signature Generation Test */
+ ecdsa_siggen_test(argv[3]);
+ } else if (strcmp(argv[2], "sigver") == 0) {
+ /* Signature Verification Test */
+ ecdsa_sigver_test(argv[3]);
+ }
+#endif /* NSS_ENABLE_ECC */
/*************/
/* RNG */
/*************/
diff --git a/security/nss/cmd/fipstest/hmac.sh b/security/nss/cmd/fipstest/hmac.sh
new file mode 100755
index 000000000..ace988c7f
--- /dev/null
+++ b/security/nss/cmd/fipstest/hmac.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST HMAC Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+hmac_requests="
+HMAC.req
+"
+
+for request in $hmac_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest hmac $request > $response
+done
+
diff --git a/security/nss/cmd/fipstest/manifest.mn b/security/nss/cmd/fipstest/manifest.mn
index ce64d59ba..ba3b1a448 100644
--- a/security/nss/cmd/fipstest/manifest.mn
+++ b/security/nss/cmd/fipstest/manifest.mn
@@ -1,57 +1,55 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-CORE_DEPTH = ../../..
-
-MODULE = security
-
-REQUIRES = seccmd
-
-PROGRAM = fipstest
-
- USE_STATIC_LIBS = 1
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- $(NULL)
-
-CSRCS = \
- fipstest.c \
- $(NULL)
-
+#
+# ***** BEGIN LICENSE BLOCK *****
+# 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 Netscape security libraries.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1994-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# 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.
+#
+# ***** END LICENSE BLOCK *****
+
+CORE_DEPTH = ../../..
+
+MODULE = nss
+
+PROGRAM = fipstest
+
+USE_STATIC_LIBS = 1
+
+EXPORTS = \
+ $(NULL)
+
+PRIVATE_EXPORTS = \
+ $(NULL)
+
+CSRCS = \
+ fipstest.c \
+ $(NULL)
+
diff --git a/security/nss/cmd/fipstest/sha.sh b/security/nss/cmd/fipstest/sha.sh
new file mode 100644
index 000000000..685a41b00
--- /dev/null
+++ b/security/nss/cmd/fipstest/sha.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST SHA Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+sha_ShortMsg_requests="
+SHA1ShortMsg.req
+SHA256ShortMsg.req
+SHA384ShortMsg.req
+SHA512ShortMsg.req
+"
+
+sha_LongMsg_requests="
+SHA1LongMsg.req
+SHA256LongMsg.req
+SHA384LongMsg.req
+SHA512LongMsg.req
+"
+
+sha_Monte_requests="
+SHA1Monte.req
+SHA256Monte.req
+SHA384Monte.req
+SHA512Monte.req
+"
+for request in $sha_ShortMsg_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest sha $request > $response
+done
+for request in $sha_LongMsg_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest sha $request > $response
+done
+for request in $sha_Monte_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest sha $request > $response
+done
+
diff --git a/security/nss/cmd/fipstest/tdea.sh b/security/nss/cmd/fipstest/tdea.sh
new file mode 100644
index 000000000..505478039
--- /dev/null
+++ b/security/nss/cmd/fipstest/tdea.sh
@@ -0,0 +1,87 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST tdea Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+#CBC_Known_Answer_tests
+#Initial Permutation KAT
+#Permutation Operation KAT
+#Subsitution Table KAT
+#Variable Key KAT
+#Variable PlainText KAT
+cbc_kat_requests="
+TCBCinvperm.req
+TCBCpermop.req
+TCBCsubtab.req
+TCBCvarkey.req
+TCBCvartext.req
+"
+
+#CBC Monte Carlo KATs
+cbc_monte_requests="
+TCBCMonte1.req
+TCBCMonte2.req
+TCBCMonte3.req
+"
+#Multi-block Message KATs
+cbc_mmt_requests="
+TCBCMMT1.req
+TCBCMMT2.req
+TCBCMMT3.req
+"
+
+ecb_kat_requests="
+TECBinvperm.req
+TECBpermop.req
+TECBsubtab.req
+TECBvarkey.req
+TECBvartext.req
+"
+
+ecb_monte_requests="
+TECBMonte1.req
+TECBMonte2.req
+TECBMonte3.req
+"
+
+ecb_mmt_requests="
+TECBMMT1.req
+TECBMMT2.req
+TECBMMT3.req
+"
+
+for request in $ecb_mmt_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea mmt ecb $request > $response
+done
+for request in $ecb_kat_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea kat ecb $request > $response
+done
+for request in $ecb_monte_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea mct ecb $request > $response
+done
+for request in $cbc_mmt_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea mmt cbc $request > $response
+done
+for request in $cbc_kat_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea kat cbc $request > $response
+done
+for request in $cbc_monte_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea mct cbc $request > $response
+done
diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c
index 04236540d..1f41e938d 100644
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -1318,7 +1318,11 @@ secu_PrintUniversal(FILE *out, SECItem *i, char *m, int level)
SECU_PrintUTCTime(out, i, m, level);
break;
case SEC_ASN1_NULL:
- SECU_Indent(out, level); fprintf(out, "%s: NULL\n", m);
+ SECU_Indent(out, level);
+ if (m && m[0])
+ fprintf(out, "%s: NULL\n", m);
+ else
+ fprintf(out, "NULL\n");
break;
case SEC_ASN1_SET:
case SEC_ASN1_SEQUENCE:
@@ -3078,7 +3082,9 @@ SECU_ParseCommandLine(int argc, char **argv, char *progName, secuCommand *cmd)
cmd->options[i].activated = PR_TRUE;
if (optstate->value) {
cmd->options[i].arg = (char *)optstate->value;
- }
+ } else if (cmd->options[i].needsArg) {
+ return SECFailure;
+ }
found = PR_TRUE;
break;
}
diff --git a/security/nss/cmd/makefile.inc b/security/nss/cmd/makefile.inc
deleted file mode 100644
index 54c54e73c..000000000
--- a/security/nss/cmd/makefile.inc
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-INCLUDES += \
- -I$(DEPTH)/security/lib/cert \
- -I$(DEPTH)/security/lib/key \
- -I$(DEPTH)/security/lib/util \
- -I../include \
- $(NULL)
-
-
-# For the time being, sec stuff is export only
-# US_FLAGS = -DEXPORT_VERSION -DUS_VERSION
-
-US_FLAGS = -DEXPORT_VERSION
-EXPORT_FLAGS = -DEXPORT_VERSION
-
-BASE_LIBS = \
- $(DIST)/lib/libdbm.a \
- $(DIST)/lib/libxp.a \
- $(DIST)/lib/libnspr21.a \
- $(NULL)
-
-
-#There is a circular dependancy in security/lib, and here is a gross fix
-SEC_LIBS = \
- $(DIST)/lib/libsecnav.a \
- $(DIST)/lib/libssl.a \
- $(DIST)/lib/libpkcs7.a \
- $(DIST)/lib/libcert.a \
- $(DIST)/lib/libkey.a \
- $(DIST)/lib/libsecmod.a \
- $(DIST)/lib/libcrypto.a \
- $(DIST)/lib/libsecutil.a \
- $(DIST)/lib/libssl.a \
- $(DIST)/lib/libpkcs7.a \
- $(DIST)/lib/libcert.a \
- $(DIST)/lib/libkey.a \
- $(DIST)/lib/libsecmod.a \
- $(DIST)/lib/libcrypto.a \
- $(DIST)/lib/libsecutil.a \
- $(DIST)/lib/libhash.a \
- $(NULL)
-
-MYLIBDIR= ../lib/$(OBJDIR)
-MYLIB = $(MYLIBDIR)/libsectool.a
-
-US_LIBS = $(MYLIB) $(SEC_LIBS) $(BASE_LIBS) $(MYLIB) $(BASE_LIBS)
-EX_LIBS = $(MYLIB) $(SEC_LIBS) $(BASE_LIBS) $(MYLIB) $(BASE_LIBS)
-
-# this hack is necessary because rules.mk doesn't put anything like $(LIBS)
-# on the link command line (!?!?!?!)
-LDFLAGS += $(EX_LIBS)
-
diff --git a/security/nss/cmd/makepqg/makefile.win b/security/nss/cmd/makepqg/makefile.win
deleted file mode 100644
index e3b676a4b..000000000
--- a/security/nss/cmd/makepqg/makefile.win
+++ /dev/null
@@ -1,160 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-VERBOSE = 1
-include <manifest.mn>
-
-PROGRAM = makepqg
-PROGRAM = $(OBJDIR)\$(PROGRAM).exe
-
-include <$(DEPTH)\config\config.mak>
-
-
-# let manifest generate C_OBJS, it will prepend ./$(OBJDIR)/
-# rules.mak will append C_OBJS onto OBJS.
-# OBJS = $(CSRCS:.c=.obj)
-
-# include files are looked for in $LINCS and $INCS.
-# $LINCS is in manifest.mnw, computed from REQUIRES=
-INCS = $(INCS) \
- -I$(DEPTH)/security/lib/cert \
- -I$(DEPTH)/security/lib/crypto \
- -I../include \
- $(NULL)
-
-IGNORE_ME = \
- -I$(DEPTH)/security/lib/key \
- -I$(DEPTH)/security/lib/util \
-
-
-WINFE = $(DEPTH)/cmd/winfe/mkfiles$(MOZ_BITS)/x86Dbg
-
-# these files are the content of libdbm
-DBM_LIB = \
- $(WINFE)/DB.obj \
- $(WINFE)/HASH.obj \
- $(WINFE)/H_BIGKEY.obj \
- $(WINFE)/H_PAGE.obj \
- $(WINFE)/H_LOG2.obj \
- $(WINFE)/H_FUNC.obj \
- $(WINFE)/HASH_BUF.obj \
- $(NULL)
-
-MOZ_LIBS = \
- $(WINFE)/ALLXPSTR.obj \
- $(WINFE)/XP_ERROR.obj \
- $(WINFE)/XPASSERT.obj \
- $(WINFE)/XP_REG.obj \
- $(WINFE)/XP_TRACE.obj \
- $(DBM_LIB) \
- $(WINFE)/XP_STR.obj \
- $(WINFE)/MKTEMP.obj \
- $(NULL)
-
-SEC_LIBS = \
- $(DIST)/lib/cert$(MOZ_BITS).lib \
- $(DIST)/lib/crypto$(MOZ_BITS).lib \
- $(DIST)/lib/hash$(MOZ_BITS).lib \
- $(DIST)/lib/key$(MOZ_BITS).lib \
- $(DIST)/lib/pkcs7$(MOZ_BITS).lib \
- $(DIST)/lib/secmod$(MOZ_BITS).lib \
- $(DIST)/lib/secutl$(MOZ_BITS).lib \
- $(DIST)/lib/ssl$(MOZ_BITS).lib \
- $(NULL)
-
-LLFLAGS = $(LLFLAGS) \
- ../lib/$(OBJDIR)/sectool$(MOZ_BITS).lib \
- $(SEC_LIBS) \
- $(MOZ_LIBS) \
- $(DEPTH)/nspr/src/$(OBJDIR)/getopt.obj \
- $(LIBNSPR) \
- $(NULL)
-
-
-# awt3240.lib # brpref32.lib # cert32.lib
-# crypto32.lib # dllcom.lib # editor32.lib
-# edpref32.lib # edtplug.lib # font.lib
-# hash32.lib # htmldg32.lib # img32.lib
-# javart32.lib # jbn3240.lib # jdb3240.lib
-# jmc.lib # jpeg3240.lib # jpw3240.lib
-# jrt3240.lib # js3240.lib # jsd3240.lib
-# key32.lib # libapplet32.lib # libnjs32.lib
-# libnsc32.lib # libreg32.lib # mm3240.lib
-# mnpref32.lib # netcst32.lib # nsdlg32.lib
-# nsldap32.lib # nsldaps32.lib # nsn32.lib
-# pkcs1232.lib # pkcs732.lib # pr3240.lib
-# prefui32.lib # prefuuid.lib # secmod32.lib
-# secnav32.lib # secutl32.lib # softup32.lib
-# sp3240.lib # ssl32.lib # uni3200.lib
-# unicvt32.lib # win32md.lib # winfont.lib
-# xppref32.lib # zlib32.lib
-
-include <$(DEPTH)\config\rules.mak>
-
-
-INSTALL = $(MAKE_INSTALL)
-
-objs: $(OBJS)
-
-$(PROGRAM)::
- $(INSTALL) $(DIST)/bin/pr3240.dll ./$(OBJDIR)
-
-programs: $(PROGRAM)
-
-install:: $(TARGETS)
- $(INSTALL) $(TARGETS) $(DIST)/bin
-
-# ALLXPSTR.obj XP_ALLOC.obj XP_HASH.obj XP_RGB.obj XP_WRAP.obj
-# CXPRINT.obj XP_C.cl XP_LIST.obj XP_SEC.obj netscape.exp
-# CXPRNDLG.obj XP_CNTXT.obj XP_MD5.obj XP_STR.obj xp.pch
-# EXPORT.obj XP_CORE.obj XP_MESG.obj XP_THRMO.obj xppref32.dll
-# XPASSERT.obj XP_ERROR.obj XP_RECT.obj XP_TIME.obj
-# XPLOCALE.obj XP_FILE.obj XP_REG.obj XP_TRACE.obj
-
-symbols:
- @echo "CSRCS = $(CSRCS)"
- @echo "INCS = $(INCS)"
- @echo "OBJS = $(OBJS)"
- @echo "LIBRARY = $(LIBRARY)"
- @echo "PROGRAM = $(PROGRAM)"
- @echo "TARGETS = $(TARGETS)"
- @echo "DIST = $(DIST)"
- @echo "VERSION_NUMBER = $(VERSION_NUMBER)"
- @echo "WINFE = $(WINFE)"
- @echo "DBM_LIB = $(DBM_LIB)"
- @echo "INSTALL = $(INSTALL)"
-
diff --git a/security/nss/cmd/manifest.mn b/security/nss/cmd/manifest.mn
index de58f84c1..0428314a4 100644
--- a/security/nss/cmd/manifest.mn
+++ b/security/nss/cmd/manifest.mn
@@ -41,7 +41,7 @@ DEPTH = ../..
REQUIRES = nss nspr libdbm
DIRS = lib \
- zlib \
+ $(ZLIB_SRCDIR) \
addbuiltin \
atob \
bltest \
@@ -50,9 +50,11 @@ DIRS = lib \
certutil \
checkcert \
crlutil \
+ crmftest \
dbtest \
derdump \
digest \
+ fipstest \
makepqg \
ocspclnt \
oidcalc \
@@ -72,7 +74,6 @@ DIRS = lib \
SSLsample \
ssltap \
strsclnt \
- swfort \
symkeyutil \
tstclnt \
vfychain \
diff --git a/security/nss/cmd/modutil/modutil.c b/security/nss/cmd/modutil/modutil.c
index 77c91a31e..d277fea05 100644
--- a/security/nss/cmd/modutil/modutil.c
+++ b/security/nss/cmd/modutil/modutil.c
@@ -749,11 +749,10 @@ usage()
"---------------------------------------------------------------------------\n"
"\n"
"Mechanism lists are colon-separated. The following mechanisms are recognized:\n"
-"RSA, DSA, RC2, RC4, RC5, DES, DH, FORTEZZA, SHA1, MD5, MD2, SSL, TLS, RANDOM,\n"
-" FRIENDLY\n"
+"RSA, DSA, RC2, RC4, RC5, DES, DH, SHA1, MD5, MD2, SSL, TLS, RANDOM, FRIENDLY\n"
"\n"
"Cipher lists are colon-separated. The following ciphers are recognized:\n"
-"FORTEZZA\n"
+"\n"
"\nQuestions or bug reports should be sent to modutil-support@netscape.com.\n"
);
diff --git a/security/nss/cmd/pk11util/pk11table.c b/security/nss/cmd/pk11util/pk11table.c
index 52ff7fa14..1f1406a65 100644
--- a/security/nss/cmd/pk11util/pk11table.c
+++ b/security/nss/cmd/pk11util/pk11table.c
@@ -302,7 +302,6 @@ const Constant _consts[] = {
mkEntry(CKM_DSA_SHA1, Mechanism),
mkEntry(CKM_DH_PKCS_KEY_PAIR_GEN, Mechanism),
mkEntry(CKM_DH_PKCS_DERIVE, Mechanism),
- mkEntry(CKM_X9_42_DH_PKCS_KEY_PAIR_GEN, Mechanism),
mkEntry(CKM_X9_42_DH_DERIVE, Mechanism),
mkEntry(CKM_X9_42_DH_HYBRID_DERIVE, Mechanism),
mkEntry(CKM_X9_42_MQV_DERIVE, Mechanism),
@@ -479,7 +478,6 @@ const Constant _consts[] = {
mkEntry(CKM_AES_CBC_PAD, Mechanism),
mkEntry(CKM_DSA_PARAMETER_GEN, Mechanism),
mkEntry(CKM_DH_PKCS_PARAMETER_GEN, Mechanism),
- mkEntry(CKM_DH_X9_42_PARAMETER_GEN, Mechanism),
mkEntry(CKM_NETSCAPE_AES_KEY_WRAP, Mechanism),
mkEntry(CKM_NETSCAPE_AES_KEY_WRAP_PAD, Mechanism),
mkEntry(CKM_NETSCAPE_PBE_SHA1_DES_CBC, Mechanism),
@@ -1223,6 +1221,13 @@ const Commands _commands[] = {
" size number of elements in the array\n",
{ArgVar|ArgNew, ArgVar, ArgULong, ArgNone, ArgNone,
ArgNone, ArgNone, ArgNone, ArgNone, ArgNone }},
+ {"NewInitArg", F_NewInitializeArgs,
+"NewInitArg varName string\n\n"
+"Creates a new init variable.\n"
+" varName variable name of the new initArg\n"
+" string string parameter for init arg\n",
+ {ArgVar|ArgNew, ArgULong, ArgVar|ArgNew, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone, ArgNone }},
{"NewTemplate", F_NewTemplate,
"NewTemplate varName attributeList\n\n"
"Create a new empty template and populate the attribute list\n"
@@ -1293,11 +1298,21 @@ const Commands _commands[] = {
ArgNone, ArgNone, ArgNone, ArgNone, ArgNone }},
{"Restore", F_RestoreVar,
"Restore filename variable\n\n"
-"Restors a variable from a file\n"
+"Restores a variable from a file\n"
" fileName target file to restore the variable from\n"
" variable variable to restore\n",
{ArgVar|ArgNew, ArgVar, ArgNone, ArgNone, ArgNone,
ArgNone, ArgNone, ArgNone, ArgNone, ArgNone }},
+ {"Increment", F_Increment,
+"Increment variable value\n\n"
+"Increment a variable by value\n",
+ {ArgVar, ArgULong, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone, ArgNone }},
+ {"Decrement", F_Decrement,
+"Decrement variable value\n\n"
+"Decrement a variable by value\n",
+ {ArgVar, ArgULong, ArgNone, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone, ArgNone }},
{"List", F_List,
"List all the variables\n",
{ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
@@ -1317,14 +1332,31 @@ const Commands _commands[] = {
{ArgVar|ArgFull, ArgNone, ArgNone, ArgNone, ArgNone,
ArgNone, ArgNone, ArgNone, ArgNone, ArgNone }},
{"System", F_System,
- "Fix Me... ",
+ "Set System Flag",
{ArgULong, ArgNone, ArgNone, ArgNone, ArgNone,
ArgNone, ArgNone, ArgNone, ArgNone, ArgNone }},
+ {"LoopRun", F_Loop,
+"LoopRun filename var start end step\n\n"
+"Run in a loop. Loop exit if scrip does and explicit quit (Quit QuitIf etc.)",
+ {ArgVar|ArgNew, ArgVar|ArgNew, ArgULong, ArgULong, ArgULong,
+ ArgNone, ArgNone, ArgNone, ArgNone, ArgNone }},
{"Help", F_Help,
"Help [command]\n\n"
"print general help, or help for a specific command\n",
{ArgVar|ArgOpt, ArgNone, ArgNone, ArgNone, ArgNone,
ArgNone, ArgNone, ArgNone, ArgNone, ArgNone }},
+ {"QuitIf", F_QuitIf,
+"QuitIf arg1 comparator arg2\n\n"
+"Exit from this program if Condition is valid, valid comparators:\n"
+" < > <= >= = !=\n",
+ {ArgULong, ArgVar|ArgNew, ArgULong, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone, ArgNone }},
+ {"QuitIfString", F_QuitIfString,
+"QuitIfString arg1 comparator arg2\n\n"
+"Exit from this program if Condition is valid, valid comparators:\n"
+" = !=\n",
+ {ArgVar|ArgNew, ArgVar|ArgNew, ArgVar|ArgNew, ArgNone, ArgNone,
+ ArgNone, ArgNone, ArgNone, ArgNone, ArgNone }},
{"Quit", F_Quit,
"Exit from this program",
{ArgNone, ArgNone, ArgNone, ArgNone, ArgNone,
diff --git a/security/nss/cmd/pk11util/pk11util.c b/security/nss/cmd/pk11util/pk11util.c
index ef5e2db12..3c8a1894f 100644
--- a/security/nss/cmd/pk11util/pk11util.c
+++ b/security/nss/cmd/pk11util/pk11util.c
@@ -220,6 +220,12 @@ argFreeData(Value *arg)
free(template[i].pValue);
}
}
+ if ((arg->type & ArgMask) == ArgInitializeArgs) {
+ CK_C_INITIALIZE_ARGS *init = (CK_C_INITIALIZE_ARGS *)arg->data;
+ if (init->LibraryParameters) {
+ free(init->LibraryParameters);
+ }
+ }
free(arg->data);
}
arg->type &= ~ArgStatic;
@@ -345,7 +351,7 @@ NewValue(ArgType type, CK_ULONG arraySize)
return NULL;
}
value->reference = 1;
- value->arraySize = arraySize;
+ value->arraySize = (type == ArgChar) ? 1: arraySize;
memset(value->data, 0, value->size);
return value;
@@ -735,6 +741,22 @@ NewMechanism(const char *bp, CK_ULONG mechType)
return CKR_OK;
}
+CK_RV
+NewInitializeArgs(const char *bp, CK_ULONG flags, const char *param)
+{
+ Value *value; /* new Value */
+ CK_C_INITIALIZE_ARGS *init;
+
+ value = NewValue(ArgInitializeArgs, 1);
+ init = (CK_C_INITIALIZE_ARGS *)value->data;
+ init->flags = flags;
+ if (strcmp(param, "null") != 0) {
+ init->LibraryParameters = (CK_CHAR_PTR *)strdup(param);
+ }
+ (void) AddVariable(bp, &value);
+ return CKR_OK;
+}
+
/*
* add a new variable to the chain
*/
@@ -933,6 +955,26 @@ save(const char *filename,Value *ptr)
return CKR_OK;
}
+static CK_RV
+increment(Value *ptr, CK_ULONG value)
+{
+ if ((ptr->type & ArgMask) != ArgULong) {
+ return CKR_ARGUMENTS_BAD;
+ }
+ *(CK_ULONG *)ptr->data += value;
+ return CKR_OK;
+}
+
+static CK_RV
+decrement(Value *ptr, CK_ULONG value)
+{
+ if ((ptr->type & ArgMask) != ArgULong) {
+ return CKR_ARGUMENTS_BAD;
+ }
+ *(CK_ULONG *)ptr->data -= value;
+ return CKR_OK;
+}
+
CK_RV
printArg(Value *ptr,int arg_number)
{
@@ -1104,6 +1146,9 @@ printArg(Value *ptr,int arg_number)
case ArgInitializeArgs:
initArgs = (CK_C_INITIALIZE_ARGS *)ptr->data;
printFlags(" Flags: ", initArgs->flags, ConstInitializeFlags);
+ if (initArgs->LibraryParameters) {
+ printf("Params: %s\n",initArgs->LibraryParameters);
+ }
case ArgFunctionList:
functionList = (CK_FUNCTION_LIST *)ptr->data;
printf(" Version: %d.%02d\n", VERSION(functionList->version));
@@ -1494,8 +1539,43 @@ printGeneralHelp(void)
return CKR_OK;
}
+static CK_RV
+quitIf(CK_ULONG a, const char *cmp, CK_ULONG b)
+{
+ if (strcmp(cmp, "<") == 0) {
+ return (a < b) ? CKR_QUIT : CKR_OK;
+ } else if (strcmp(cmp, ">") == 0) {
+ return (a > b) ? CKR_QUIT : CKR_OK;
+ } else if (strcmp(cmp, "<=") == 0) {
+ return (a <= b) ? CKR_QUIT : CKR_OK;
+ } else if (strcmp(cmp, ">=") == 0) {
+ return (a >= b) ? CKR_QUIT : CKR_OK;
+ } else if (strcmp(cmp, "=") == 0) {
+ return (a == b) ? CKR_QUIT : CKR_OK;
+ } else if (strcmp(cmp, "!=") == 0) {
+ return (a != b) ? CKR_QUIT : CKR_OK;
+ }
+ printf("Unkown integer comparator: '%s'\n", cmp);
+ return CKR_ARGUMENTS_BAD;
+}
+
+static CK_RV
+quitIfString(const char *a, const char *cmp, const char *b)
+{
+
+ if (strcmp(cmp, "=") == 0) {
+ return (strcmp(a,b) == 0) ? CKR_QUIT : CKR_OK;
+ } else if (strcmp(cmp, "!=") == 0) {
+ return (strcmp(a,b) != 0) ? CKR_QUIT : CKR_OK;
+ }
+ printf("Unkown string comparator: '%s'\n", cmp);
+ return CKR_ARGUMENTS_BAD;
+}
+
CK_RV run(const char *);
CK_RV timeCommand(const char *);
+CK_RV loop(const char *filename, const char *var,
+ CK_ULONG start, CK_ULONG end, CK_ULONG step) ;
/*
* Actually dispatch the function... Bad things happen
@@ -1901,6 +1981,10 @@ do_func(int index, Value **a)
return restore(a[0]->data,a[1]);
case F_Delete:
return DeleteVariable(a[0]->data);
+ case F_Increment:
+ return increment(a[0], *(CK_ULONG *)a[1]->data);
+ case F_Decrement:
+ return decrement(a[0], *(CK_ULONG *)a[1]->data);
case F_List:
return list();
case F_Run:
@@ -1926,6 +2010,9 @@ do_func(int index, Value **a)
case F_NewMechanism:
(void) DeleteVariable(a[0]->data);
return NewMechanism(a[0]->data,*(CK_ULONG *)a[1]->data);
+ case F_NewInitializeArgs:
+ (void) DeleteVariable(a[0]->data);
+ return NewInitializeArgs(a[0]->data,*(CK_ULONG *)a[1]->data,a[2]->data);
case F_System:
value = *(int *)a[0]->data;
if (value & 0x80000000) {
@@ -1934,6 +2021,9 @@ do_func(int index, Value **a)
systemFlags |= value;
}
return CKR_OK;
+ case F_Loop:
+ return loop(a[0]->data,a[1]->data,*(CK_ULONG *)a[2]->data,
+ *(CK_ULONG *)a[3]->data,*(CK_ULONG *)a[4]->data);
case F_Help:
if (a[0]) {
helpIndex = lookup(a[0]->data);
@@ -1944,6 +2034,10 @@ do_func(int index, Value **a)
return CKR_OK;
}
return printGeneralHelp();
+ case F_QuitIfString:
+ return quitIfString(a[0]->data,a[1]->data,a[2]->data);
+ case F_QuitIf:
+ return quitIf(*(CK_ULONG *)a[0]->data,a[1]->data,*(CK_ULONG *)a[2]->data);
case F_Quit:
return CKR_QUIT;
default:
@@ -1992,7 +2086,8 @@ processCommand(const char * buf)
return error;
}
-CK_RV timeCommand(const char *command)
+CK_RV
+timeCommand(const char *command)
{
CK_RV ckrv;
PRIntervalTime startTime = PR_IntervalNow();
@@ -2036,7 +2131,8 @@ process(FILE *inFile,int user)
return ckrv;
}
-CK_RV run(const char *filename)
+CK_RV
+run(const char *filename)
{
FILE *infile;
CK_RV ckrv;
@@ -2054,6 +2150,29 @@ CK_RV run(const char *filename)
return ckrv;
}
+CK_RV
+loop(const char *filename, const char *var,
+ CK_ULONG start, CK_ULONG end, CK_ULONG step)
+{
+ CK_ULONG i = 0;
+ Value *value = 0;
+ CK_RV ckrv;
+
+ for (i=start; i < end; i += step)
+ {
+ value = NewValue(ArgULong, 1);
+ *(CK_ULONG *)value->data = i;
+ DeleteVariable(var);
+ AddVariable(var, &value);
+ ckrv = run(filename);
+ argFree(value);
+ if (ckrv == CKR_QUIT) {
+ break;
+ }
+ }
+ return ckrv;
+}
+
int
main(int argc, char **argv)
{
diff --git a/security/nss/cmd/pk11util/pk11util.h b/security/nss/cmd/pk11util/pk11util.h
index aed07c325..8a2f4d592 100644
--- a/security/nss/cmd/pk11util/pk11util.h
+++ b/security/nss/cmd/pk11util/pk11util.h
@@ -16,6 +16,7 @@ typedef enum {
F_SetVar,
F_SetStringVar,
F_NewArray,
+ F_NewInitializeArgs,
F_NewTemplate,
F_NewMechanism,
F_BuildTemplate,
@@ -23,15 +24,20 @@ typedef enum {
F_Print,
F_SaveVar,
F_RestoreVar,
+ F_Increment,
+ F_Decrement,
F_Delete,
F_List,
F_Run,
F_Load,
F_Unload,
F_System,
+ F_Loop,
F_Time,
F_Help,
F_Quit,
+ F_QuitIf,
+ F_QuitIfString,
} FunctionType;
/*
diff --git a/security/nss/cmd/pk11util/scripts/dosign b/security/nss/cmd/pk11util/scripts/dosign
new file mode 100644
index 000000000..33e761f0b
--- /dev/null
+++ b/security/nss/cmd/pk11util/scripts/dosign
@@ -0,0 +1,162 @@
+Load nsscapi.dll
+C_Initialize NULL
+C_GetSlotList false NULL slotCount
+NewArray slotList CK_ULONG slotCount
+C_GetSlotList false slotList slotCount
+#change the following to the appropriate slot id
+set slotID 1
+#set slotID slotList[0]
+C_GetSlotInfo slotID slotInfo
+C_GetTokenInfo slotID tokenInfo
+C_OpenSession slotID CKF_SERIAL_SESSION session
+#
+#uncomment the following line and include the correct password
+#C_Login session CKU_USER 0000 4
+#
+# build the search template
+#
+NewTemplate search CKA_CLASS
+SetTemplate search 0 CKO_CERTIFICATE
+NewArray certID CK_ULONG 10
+C_FindObjectsInit session search 1
+C_FindObjects session certID sizeA(certID) count
+C_FindObjectsFinal session
+#
+# now read the cert out
+#
+#NewTemplate derCert CKA_VALUE
+#NewTemplate certName CKA_LABEL,CKA_VALUE
+#C_GetAttributeValue session certID[0] certName sizeA(certName)
+#BuildTemplate certName
+#C_GetAttributeValue session certID[0] certName sizeA(certName)
+#print certName[0]
+Set countm1 count
+Decrement countm1 1
+LoopRun pLabel1 i 0 countm1 1
+Set i 1
+run pLabel1
+NewTemplate id CKA_CLASS,CKA_ID
+C_GetAttributeValue session certID[i] id sizeA(id)
+BuildTemplate id
+C_GetAttributeValue session certID[i] id sizeA(id)
+SetTemplate id 0 CKO_PRIVATE_KEY
+NewArray keyID CK_ULONG 10
+C_FindObjectsInit session id sizeA(id)
+C_FindObjects session keyID sizeA(keyID) count
+C_FindObjectsFinal session
+
+NewMechanism rsaParams CKM_RSA_PKCS
+NewArray sign data 256
+NewArray sdata data 36
+C_SignInit session rsaParams keyID[0]
+print sdata
+C_Sign session sdata sizeof(sdata) sign sizeof(sign)
+save signature sign
+save hash sdata
+NewTemplate privValue CKA_MODULUS,CKA_PUBLIC_EXPONENT
+C_GetAttributeValue session keyID[0] privValue sizeA(privValue)
+BuildTemplate privValue
+C_GetAttributeValue session keyID[0] privValue sizeA(privValue)
+print privValue[0]
+print privValue[1]
+
+# save the public key
+SetTemplate id 0 CKO_PUBLIC_KEY
+NewArray pubkeyID CK_ULONG 10
+C_FindObjectsInit session id sizeA(id)
+C_FindObjects session pubkeyID sizeA(pubkeyID) count
+C_FindObjectsFinal session
+NewTemplate pubkeyValue CKA_MODULUS,CKA_PUBLIC_EXPONENT
+C_GetAttributeValue session pubkeyID[0] pubkeyValue sizeA(pubkeyValue)
+BuildTemplate pubkeyValue
+C_GetAttributeValue session pubkeyID[0] pubkeyValue sizeA(pubkeyValue)
+print pubkeyValue[0]
+print pubkeyValue[1]
+
+
+C_Finalize null
+unload
+
+#
+# Now do the same for using softoken
+#
+load softokn3.dll
+NewInitArg init CKF_OS_LOCKING_OK configdir=./db
+C_Initialize init
+C_GetSlotList false NULL slotCount
+NewArray slotList CK_ULONG slotCount
+C_GetSlotList false slotList slotCount
+#change the following to the appropriate slot id
+set slotID slotList[1]
+#set slotID slotList[0]
+C_GetSlotInfo slotID slotInfo
+C_GetTokenInfo slotID tokenInfo
+C_OpenSession slotID CKF_SERIAL_SESSION session
+NewTemplate search CKA_CLASS
+SetTemplate search 0 CKO_CERTIFICATE
+NewArray certID CK_ULONG 10
+C_FindObjectsInit session search 1
+C_FindObjects session certID sizeA(certID) count
+C_FindObjectsFinal session
+#
+# now read the cert out
+#
+#NewTemplate derCert CKA_VALUE
+#NewTemplate certName CKA_LABEL,CKA_VALUE
+#C_GetAttributeValue session certID[0] certName sizeA(certName)
+#BuildTemplate certName
+#C_GetAttributeValue session certID[0] certName sizeA(certName)
+#print certName[0]
+#Set countm1 count
+#Decrement countm1 1
+#LoopRun pLabel1 i 0 countm1 1
+Set i 0
+run pLabel1
+NewTemplate id CKA_CLASS,CKA_ID
+C_GetAttributeValue session certID[i] id sizeA(id)
+BuildTemplate id
+C_GetAttributeValue session certID[i] id sizeA(id)
+SetTemplate id 0 CKO_PRIVATE_KEY
+NewArray keyID CK_ULONG 10
+C_FindObjectsInit session id sizeA(id)
+C_FindObjects session keyID sizeA(keyID) count
+C_FindObjectsFinal session
+
+NewMechanism rsaParams CKM_RSA_PKCS
+NewArray sign data 256
+NewArray sdata data 36
+C_SignInit session rsaParams keyID[0]
+C_Sign session sdata sizeof(sdata) sign sizeof(sign)
+save signature2 sign
+save hash2 sdata
+
+SetTemplate id 0 CKO_PUBLIC_KEY
+NewArray pubkeyID CK_ULONG 10
+C_FindObjectsInit session id sizeA(id)
+C_FindObjects session pubkeyID sizeA(pubkeyID) count
+C_FindObjectsFinal session
+
+#
+# OK now we use raw unwrap and see what we have...
+#
+NewMechanism rawRsaParams CKM_RSA_X_509
+NewArray vdata data 256
+C_VerifyRecoverInit session rawRsaParams pubkeyID[0]
+C_VerifyRecover session sign sizeof(sign) vdata sizeof(vdata)
+save verify2 vdata
+restore signature sign
+C_VerifyRecoverInit session rawRsaParams pubkeyID[0]
+C_VerifyRecover session sign sizeof(sign) vdata sizeof(vdata)
+save verify vdata
+
+NewTemplate pubkeyValue CKA_MODULUS,CKA_PUBLIC_EXPONENT
+C_GetAttributeValue session pubkeyID[0] pubkeyValue sizeA(pubkeyValue)
+BuildTemplate pubkeyValue
+C_GetAttributeValue session pubkeyID[0] pubkeyValue sizeA(pubkeyValue)
+print pubkeyValue[0]
+print pubkeyValue[1]
+
+
+C_Finalize null
+
+unload
diff --git a/security/nss/cmd/pk11util/scripts/lcert b/security/nss/cmd/pk11util/scripts/lcert
new file mode 100644
index 000000000..0f249c3b5
--- /dev/null
+++ b/security/nss/cmd/pk11util/scripts/lcert
@@ -0,0 +1,35 @@
+Load nsscapi.dll
+C_Initialize NULL
+C_GetSlotList false NULL slotCount
+NewArray slotList CK_ULONG slotCount
+C_GetSlotList false slotList slotCount
+#change the following to the appropriate slot id
+set slotID 1
+#set slotID slotList[0]
+C_GetSlotInfo slotID slotInfo
+C_GetTokenInfo slotID tokenInfo
+C_OpenSession slotID CKF_SERIAL_SESSION session
+#
+#uncomment the following line and include the correct password
+#C_Login session CKU_USER 0000 4
+#
+# build the search template
+#
+NewTemplate search CKA_CLASS
+SetTemplate search 0 CKO_CERTIFICATE
+NewArray certID CK_ULONG 10
+C_FindObjectsInit session search 1
+C_FindObjects session certID sizeA(certID) count
+C_FindObjectsFinal session
+#
+# now read the cert out
+#
+#NewTemplate derCert CKA_VALUE
+#NewTemplate certName CKA_LABEL,CKA_VALUE
+#C_GetAttributeValue session certID[0] certName sizeA(certName)
+#BuildTemplate certName
+#C_GetAttributeValue session certID[0] certName sizeA(certName)
+#print certName[0]
+Set countm1 count
+Decrement countm1 1
+LoopRun pLabel1 i 0 countm1 1
diff --git a/security/nss/cmd/pk11util/scripts/mechanisms b/security/nss/cmd/pk11util/scripts/mechanisms
new file mode 100644
index 000000000..d103a9c4f
--- /dev/null
+++ b/security/nss/cmd/pk11util/scripts/mechanisms
@@ -0,0 +1,11 @@
+Load nsscapi.dll
+C_Initialize NULL
+C_GetSlotList false NULL slotCount
+NewArray slotList CK_ULONG slotCount
+C_GetSlotList false slotList slotCount
+
+LoopRun pMechanisms i 0 slotCount 1
+
+#C_Finalize
+#Unload
+
diff --git a/security/nss/cmd/pk11util/scripts/pLabel1 b/security/nss/cmd/pk11util/scripts/pLabel1
new file mode 100644
index 000000000..0be909bb4
--- /dev/null
+++ b/security/nss/cmd/pk11util/scripts/pLabel1
@@ -0,0 +1,6 @@
+NewTemplate certName CKA_LABEL,CKA_VALUE
+C_GetAttributeValue session certID[i] certName sizeA(certName)
+BuildTemplate certName
+C_GetAttributeValue session certID[i] certName sizeA(certName)
+print i
+print certName[0]
diff --git a/security/nss/cmd/pk11util/scripts/pMechanisms b/security/nss/cmd/pk11util/scripts/pMechanisms
new file mode 100644
index 000000000..82e860258
--- /dev/null
+++ b/security/nss/cmd/pk11util/scripts/pMechanisms
@@ -0,0 +1,8 @@
+#
+# print the mechanism list for a given token
+#
+set slotID slotList[i]
+C_GetMechanismList slotID NULL mechCount
+NewArray mechanismList CK_ULONG mechcount
+C_GetMechanismList slotID mechanismList mechCount
+print mechanismList
diff --git a/security/nss/cmd/pk11util/scripts/pcert b/security/nss/cmd/pk11util/scripts/pcert
new file mode 100644
index 000000000..c322a8bfe
--- /dev/null
+++ b/security/nss/cmd/pk11util/scripts/pcert
@@ -0,0 +1,30 @@
+Load aolkeypk11.dll
+C_Initialize NULL
+C_GetSlotList false NULL slotCount
+NewArray slotList CK_ULONG slotCount
+C_GetSlotList false slotList slotCount
+#change the following to the appropriate slot id
+set slotID 1
+#set slotID slotList[0]
+C_GetSlotInfo slotID slotInfo
+C_GetTokenInfo slotID tokenInfo
+C_OpenSession slotID CK_SESSION_SERIAL session
+#
+#uncomment the following line and include the correct password
+#C_Login session CKU_USER 0000 4
+#
+# build the search template
+#
+NewTemplate search CKA_CLASS
+SetTemplate search 0 CKO_CERTIFICATE
+NewArray certID CK_ULONG 1
+C_FindObjectsInit session search 1
+C_FindObjects session certID 1 count
+C_FindObjectsFinal session
+#
+# now read the cert out
+#
+NewTemplate derCert CKA_VALUE
+C_GetAttributeValue session certID derCert 1
+BuildTemplate derCert
+C_GetAttributeValue session certID derCert 1
diff --git a/security/nss/cmd/pk12util/pk12util.c b/security/nss/cmd/pk12util/pk12util.c
index 69fa49e82..1d15f1663 100644
--- a/security/nss/cmd/pk12util/pk12util.c
+++ b/security/nss/cmd/pk12util/pk12util.c
@@ -301,6 +301,9 @@ P12U_GetP12FilePassword(PRBool confirmPw, secuPWData *p12FilePw)
p0 = p12FilePw->data;
}
+ if (p0 == NULL) {
+ return NULL;
+ }
pwItem = SECITEM_AllocItem(NULL, NULL, PL_strlen(p0) + 1);
memcpy(pwItem->data, p0, pwItem->len);
diff --git a/security/nss/cmd/platlibs.mk b/security/nss/cmd/platlibs.mk
index 92269a250..57872e48b 100644
--- a/security/nss/cmd/platlibs.mk
+++ b/security/nss/cmd/platlibs.mk
@@ -66,15 +66,14 @@ EXTRA_LIBS += \
$(DIST)/lib/$(LIB_PREFIX)certdb.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)softokn.$(LIB_SUFFIX) \
$(CRYPTOLIB) \
- $(DIST)/lib/$(LIB_PREFIX)swfci.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)dbm.$(LIB_SUFFIX) \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4.$(LIB_SUFFIX) \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4.$(LIB_SUFFIX) \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)nspr4.$(LIB_SUFFIX) \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.$(LIB_SUFFIX) \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.$(LIB_SUFFIX) \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.$(LIB_SUFFIX) \
$(NULL)
# $(PROGRAM) has NO explicit dependencies on $(OS_LIBS)
@@ -82,10 +81,6 @@ EXTRA_LIBS += \
wsock32.lib \
winmm.lib \
$(NULL)
-
-JAR_LIBS = $(DIST)/lib/$(LIB_PREFIX)jar.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)zlib.$(LIB_SUFFIX) \
- $(NULL)
else
# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
@@ -116,7 +111,6 @@ EXTRA_LIBS += \
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)swfci.$(LIB_SUFFIX) \
$(CRYPTOLIB) \
$(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)dbm.$(LIB_SUFFIX) \
@@ -130,13 +124,13 @@ endif
# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
ifdef XP_OS2_VACPP
EXTRA_SHARED_LIBS += \
- $(DIST)/lib/plc4.lib \
- $(DIST)/lib/plds4.lib \
- $(DIST)/lib/nspr4.lib \
+ $(NSPR_LIB_DIR)/plc4.lib \
+ $(NSPR_LIB_DIR)/plds4.lib \
+ $(NSPR_LIB_DIR)/nspr4.lib \
$(NULL)
else
EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
+ -L$(NSPR_LIB_DIR) \
-lplc4 \
-lplds4 \
-lnspr4 \
@@ -144,10 +138,6 @@ EXTRA_SHARED_LIBS += \
endif
endif
-JAR_LIBS = $(DIST)/lib/$(LIB_PREFIX)jar.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)zlib.$(LIB_SUFFIX) \
- $(NULL)
-
else # USE_STATIC_LIBS
# can't do this in manifest.mn because OS_ARCH isn't defined there.
ifeq ($(OS_ARCH), WINNT)
@@ -158,9 +148,9 @@ EXTRA_LIBS += \
$(DIST)/lib/$(IMPORT_LIB_PREFIX)smime3$(IMPORT_LIB_SUFFIX) \
$(DIST)/lib/$(IMPORT_LIB_PREFIX)ssl3$(IMPORT_LIB_SUFFIX) \
$(DIST)/lib/$(IMPORT_LIB_PREFIX)nss3$(IMPORT_LIB_SUFFIX) \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4.$(LIB_SUFFIX) \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4.$(LIB_SUFFIX) \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)nspr4.$(LIB_SUFFIX) \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.$(LIB_SUFFIX) \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.$(LIB_SUFFIX) \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.$(LIB_SUFFIX) \
$(NULL)
# $(PROGRAM) has NO explicit dependencies on $(OS_LIBS)
@@ -168,10 +158,6 @@ EXTRA_LIBS += \
wsock32.lib \
winmm.lib \
$(NULL)
-
-JAR_LIBS = $(DIST)/lib/$(LIB_PREFIX)jar.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)zlib.$(LIB_SUFFIX) \
- $(NULL)
else
# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
@@ -210,6 +196,12 @@ EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib'
endif
endif
+ifeq ($(OS_ARCH), HP-UX)
+ifeq ($(OS_TEST), ia64)
+EXTRA_SHARED_LIBS += -Wl,+b,'$$ORIGIN/../lib'
+endif
+endif
+
ifeq ($(OS_ARCH), Darwin)
EXTRA_SHARED_LIBS += -dylib_file @executable_path/libsoftokn3.dylib:$(DIST)/lib/libsoftokn3.dylib
endif
@@ -222,14 +214,22 @@ EXTRA_SHARED_LIBS += \
-lssl3 \
-lsmime3 \
-lnss3 \
+ -L$(NSPR_LIB_DIR) \
-lplc4 \
-lplds4 \
-lnspr4 \
$(NULL)
-
-JAR_LIBS = $(DIST)/lib/$(LIB_PREFIX)jar.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)zlib.$(LIB_SUFFIX) \
- $(NULL)
endif
endif # USE_STATIC_LIBS
+
+# If a platform has a system zlib, set USE_SYSTEM_ZLIB to 1 and
+# ZLIB_LIBS to the linker command-line arguments for the system zlib
+# (for example, -lz) in the platform's config file in coreconf.
+ifndef USE_SYSTEM_ZLIB
+ZLIB_LIBS = $(DIST)/lib/$(LIB_PREFIX)zlib.$(LIB_SUFFIX)
+endif
+
+JAR_LIBS = $(DIST)/lib/$(LIB_PREFIX)jar.$(LIB_SUFFIX) \
+ $(ZLIB_LIBS) \
+ $(NULL)
diff --git a/security/nss/cmd/pwdecrypt/pwdecrypt.c b/security/nss/cmd/pwdecrypt/pwdecrypt.c
index febb91a0f..5d96ba210 100644
--- a/security/nss/cmd/pwdecrypt/pwdecrypt.c
+++ b/security/nss/cmd/pwdecrypt/pwdecrypt.c
@@ -317,8 +317,8 @@ main (int argc, char **argv)
free(dataString);
continue;
}
- result.data = malloc(inText->len+1);
- result.len = inText->len+1;
+ result.data = NULL;
+ result.len = 0;
rv = PK11SDR_Decrypt(inText, &result, NULL);
SECITEM_FreeItem(inText, PR_TRUE);
if (rv != SECSuccess) {
@@ -330,12 +330,12 @@ main (int argc, char **argv)
}
fputs(dataString,outFile);
free(dataString);
- free(result.data);
+ SECITEM_ZfreeItem(&result, PR_FALSE);
continue;
}
- result.data[result.len] = 0;
- fputs(result.data,outFile);
- free(result.data);
+ /* result buffer has no extra space for a NULL */
+ fprintf(outFile, "%.*s", result.len, result.data);
+ SECITEM_ZfreeItem(&result, PR_FALSE);
} else {
putc(c,outFile);
}
@@ -356,18 +356,3 @@ prdone:
PR_Cleanup ();
return retval;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/security/nss/cmd/rsaperf/rsaperf.c b/security/nss/cmd/rsaperf/rsaperf.c
index 12a74f64b..635f6c0b6 100644
--- a/security/nss/cmd/rsaperf/rsaperf.c
+++ b/security/nss/cmd/rsaperf/rsaperf.c
@@ -463,7 +463,7 @@ main(int argc, char **argv)
CERTCertDBHandle* certdb = NULL;
certdb = CERT_GetDefaultCertDB();
- cert = CERT_FindCertByNickname(certdb, nickname);
+ cert = PK11_FindCertFromNickname(nickname, &pwData);
if (cert == NULL) {
fprintf(stderr,
"Can't find certificate by name \"%s\"\n", nickname);
diff --git a/security/nss/cmd/selfserv/makefile.win b/security/nss/cmd/selfserv/makefile.win
deleted file mode 100644
index a277e4347..000000000
--- a/security/nss/cmd/selfserv/makefile.win
+++ /dev/null
@@ -1,140 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-VERBOSE = 1
-include <manifest.mn>
-
-#cannot define PROGRAM in manifest compatibly with NT and UNIX
-PROGRAM = selfserv
-PROGRAM = ./$(OBJDIR)/$(PROGRAM).exe
-include <$(DEPTH)\config\config.mak>
-
-# let manifest generate C_OBJS, it will prepend ./$(OBJDIR)/
-# rules.mak will append C_OBJS onto OBJS.
-# OBJS = $(CSRCS:.c=.obj)
-
-# include files are looked for in $LINCS and $INCS.
-# $LINCS is in manifest.mnw, computed from REQUIRES=
-INCS = $(INCS) \
- -I$(DEPTH)/security/lib/cert \
- -I../include \
- $(NULL)
-
-IGNORE_ME = \
- -I$(DEPTH)/security/lib/key \
- -I$(DEPTH)/security/lib/util \
- $(NULL)
-
-
-WINFE = $(DEPTH)/cmd/winfe/mkfiles$(MOZ_BITS)/x86Dbg
-
-# these files are the content of libdbm
-DBM_LIB = \
- $(WINFE)/DB.obj \
- $(WINFE)/HASH.obj \
- $(WINFE)/H_BIGKEY.obj \
- $(WINFE)/H_PAGE.obj \
- $(WINFE)/H_LOG2.obj \
- $(WINFE)/H_FUNC.obj \
- $(WINFE)/HASH_BUF.obj \
- $(NULL)
-
-MOZ_LIBS = \
- $(WINFE)/ALLXPSTR.obj \
- $(WINFE)/XP_ERROR.obj \
- $(WINFE)/XPASSERT.obj \
- $(WINFE)/XP_REG.obj \
- $(WINFE)/XP_TRACE.obj \
- $(DBM_LIB) \
- $(WINFE)/XP_STR.obj \
- $(WINFE)/MKTEMP.obj \
- $(NULL)
-
-IGNORE_ME2 = \
- $(WINFE)/feutil.obj \
- $(WINFE)/fenet.obj \
- $(WINFE)/fegui.obj \
- $(NULL)
-
-SEC_LIBS = \
- $(DIST)/lib/cert$(MOZ_BITS).lib \
- $(DIST)/lib/crypto$(MOZ_BITS).lib \
- $(DIST)/lib/hash$(MOZ_BITS).lib \
- $(DIST)/lib/key$(MOZ_BITS).lib \
- $(DIST)/lib/pkcs7$(MOZ_BITS).lib \
- $(DIST)/lib/secmod$(MOZ_BITS).lib \
- $(DIST)/lib/secutl$(MOZ_BITS).lib \
- $(DIST)/lib/ssl$(MOZ_BITS).lib \
- $(NULL)
-
-LLFLAGS = $(LLFLAGS) \
- $(SEC_LIBS) \
- ../lib/$(OBJDIR)/sectool$(MOZ_BITS).lib \
- $(MOZ_LIBS) \
- $(DEPTH)/nspr/src/$(OBJDIR)/getopt.obj \
- $(LIBNSPR) \
- $(NULL)
-
-
-include <$(DEPTH)\config\rules.mak>
-
-INSTALL = $(MAKE_INSTALL)
-
-objs: $(OBJS)
-
-$(PROGRAM)::
- $(INSTALL) $(DIST)/bin/pr3240.dll ./$(OBJDIR)
-
-programs: $(PROGRAM)
-
-install:: $(TARGETS)
- $(INSTALL) $(TARGETS) $(DIST)/bin
-
-
-symbols:
- @echo "CSRCS = $(CSRCS)"
- @echo "INCS = $(INCS)"
- @echo "OBJS = $(OBJS)"
- @echo "LIBRARY = $(LIBRARY)"
- @echo "PROGRAM = $(PROGRAM)"
- @echo "TARGETS = $(TARGETS)"
- @echo "DIST = $(DIST)"
- @echo "VERSION_NUMBER = $(VERSION_NUMBER)"
- @echo "WINFE = $(WINFE)"
- @echo "DBM_LIB = $(DBM_LIB)"
- @echo "INSTALL = $(INSTALL)"
-
diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c
index d5469ebc1..f4a3e6525 100644
--- a/security/nss/cmd/selfserv/selfserv.c
+++ b/security/nss/cmd/selfserv/selfserv.c
@@ -89,7 +89,7 @@
#define PORT_Malloc PR_Malloc
#endif
-#define NUM_SID_CACHE_ENTRIES 1024
+int NumSidCacheEntries = 1024;
static int handle_connection( PRFileDesc *, PRFileDesc *, int );
@@ -133,14 +133,14 @@ const int ssl2CipherSuites[] = {
};
const int ssl3CipherSuites[] = {
- SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* a */
- SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, /* b */
+ -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
+ -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA * b */
SSL_RSA_WITH_RC4_128_MD5, /* c */
SSL_RSA_WITH_3DES_EDE_CBC_SHA, /* d */
SSL_RSA_WITH_DES_CBC_SHA, /* e */
SSL_RSA_EXPORT_WITH_RC4_40_MD5, /* f */
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */
- SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* h */
+ -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA, * h */
SSL_RSA_WITH_NULL_MD5, /* i */
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */
SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */
@@ -200,16 +200,17 @@ Usage(const char *progName)
{
fprintf(stderr,
-"Usage: %s -n rsa_nickname -p port [-3DNRSTbmrvx] [-w password] [-t threads]\n"
+"Usage: %s -n rsa_nickname -p port [-3BDENRSTblmrsvx] [-w password] [-t threads]\n"
#ifdef NSS_ENABLE_ECC
" [-i pid_file] [-c ciphers] [-d dbdir] [-e ec_nickname] \n"
-" [-f fortezza_nickname] [-L [seconds]] [-M maxProcs] [-l] [-P dbprefix]\n"
+" [-f fortezza_nickname] [-L [seconds]] [-M maxProcs] [-P dbprefix]\n"
#else
" [-i pid_file] [-c ciphers] [-d dbdir] [-f fortezza_nickname] \n"
-" [-L [seconds]] [-M maxProcs] [-l] [-P dbprefix]\n"
+" [-L [seconds]] [-M maxProcs] [-P dbprefix] [-C SSLCacheEntries]\n"
#endif /* NSS_ENABLE_ECC */
"-S means disable SSL v2\n"
"-3 means disable SSL v3\n"
+"-B bypasses the PKCS11 layer for SSL encryption and MACing\n"
"-D means disable Nagle delays in TCP\n"
"-E means disable export ciphersuites and SSL step down key gen\n"
"-T means disable TLS\n"
@@ -221,6 +222,7 @@ Usage(const char *progName)
" 2 -r's mean request and require, cert on initial handshake.\n"
" 3 -r's mean request, not require, cert on second handshake.\n"
" 4 -r's mean request and require, cert on second handshake.\n"
+"-s means disable SSL socket locking for performance\n"
"-v means verbose output\n"
"-x means use export policy.\n"
"-L seconds means log statistics every 'seconds' seconds (default=30).\n"
@@ -230,6 +232,7 @@ Usage(const char *progName)
"-i pid_file file to write the process id of selfserve\n"
"-c ciphers Letter(s) chosen from the following list\n"
"-l means use local threads instead of global threads\n"
+"-C SSLCacheEntries sets the maximum number of entries in the SSL session cache\n"
"A SSL2 RC4 128 WITH MD5\n"
"B SSL2 RC4 128 EXPORT40 WITH MD5\n"
"C SSL2 RC2 128 CBC WITH MD5\n"
@@ -253,14 +256,11 @@ Usage(const char *progName)
"T TLS ECDHE RSA WITH AES 128 CBC SHA\n"
#endif /* NSS_ENABLE_ECC */
"\n"
-"a SSL3 FORTEZZA DMS WITH FORTEZZA CBC SHA\n"
-"b SSL3 FORTEZZA DMS WITH RC4 128 SHA\n"
"c SSL3 RSA WITH RC4 128 MD5\n"
"d SSL3 RSA WITH 3DES EDE CBC SHA\n"
"e SSL3 RSA WITH DES CBC SHA\n"
"f SSL3 RSA EXPORT WITH RC4 40 MD5\n"
"g SSL3 RSA EXPORT WITH RC2 CBC 40 MD5\n"
-"h SSL3 FORTEZZA DMS WITH NULL SHA\n"
"i SSL3 RSA WITH NULL MD5\n"
"j SSL3 RSA FIPS WITH 3DES EDE CBC SHA\n"
"k SSL3 RSA FIPS WITH DES CBC SHA\n"
@@ -690,6 +690,8 @@ PRBool disableRollBack = PR_FALSE;
PRBool NoReuse = PR_FALSE;
PRBool hasSidCache = PR_FALSE;
PRBool disableStepDown = PR_FALSE;
+PRBool bypassPKCS11 = PR_FALSE;
+PRBool disableLocking = PR_FALSE;
static const char stopCmd[] = { "GET /stop " };
static const char getCmd[] = { "GET " };
@@ -1408,6 +1410,18 @@ server_main(
errExit("error disabling SSL StepDown ");
}
}
+ if (bypassPKCS11) {
+ rv = SSL_OptionSet(model_sock, SSL_BYPASS_PKCS11, PR_TRUE);
+ if (rv != SECSuccess) {
+ errExit("error enabling PKCS11 bypass ");
+ }
+ }
+ if (disableLocking) {
+ rv = SSL_OptionSet(model_sock, SSL_NO_LOCKS, PR_TRUE);
+ if (rv != SECSuccess) {
+ errExit("error disabling SSL socket locking ");
+ }
+ }
for (kea = kt_rsa; kea < kt_kea_size; kea++) {
if (cert[kea] != NULL) {
@@ -1650,7 +1664,7 @@ main(int argc, char **argv)
** numbers, then capital letters, then lower case, alphabetical.
*/
optstate = PL_CreateOptState(argc, argv,
- "2:3DEL:M:NP:RSTbc:d:e:f:hi:lmn:op:rt:vw:xy");
+ "2:3BC:DEL:M:NP:RSTbc:d:e:f:hi:lmn:op:rst:vw:xy");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
++optionsFound;
switch(optstate->option) {
@@ -1658,6 +1672,10 @@ main(int argc, char **argv)
case '3': disableSSL3 = PR_TRUE; break;
+ case 'B': bypassPKCS11 = PR_TRUE; break;
+
+ case 'C': if (optstate->value) NumSidCacheEntries = PORT_Atoi(optstate->value); break;
+
case 'D': noDelay = PR_TRUE; break;
case 'E': disableStepDown = PR_TRUE; break;
@@ -1715,6 +1733,8 @@ main(int argc, char **argv)
case 'r': ++requestCert; break;
+ case 's': disableLocking = PR_TRUE; break;
+
case 't':
maxThreads = PORT_Atoi(optstate->value);
if ( maxThreads > MAX_THREADS ) maxThreads = MAX_THREADS;
@@ -1822,7 +1842,7 @@ main(int argc, char **argv)
} else if (maxProcs > 1) {
/* we're going to be the parent in a multi-process server. */
listen_sock = getBoundListenSocket(port);
- rv = SSL_ConfigMPServerSIDCache(NUM_SID_CACHE_ENTRIES, 0, 0, tmp);
+ rv = SSL_ConfigMPServerSIDCache(NumSidCacheEntries, 0, 0, tmp);
if (rv != SECSuccess)
errExit("SSL_ConfigMPServerSIDCache");
hasSidCache = PR_TRUE;
@@ -1835,7 +1855,7 @@ main(int argc, char **argv)
if (prStatus != PR_SUCCESS)
errExit("PR_SetFDInheritable");
if (!NoReuse) {
- rv = SSL_ConfigServerSessionIDCache(NUM_SID_CACHE_ENTRIES,
+ rv = SSL_ConfigServerSessionIDCache(NumSidCacheEntries,
0, 0, tmp);
if (rv != SECSuccess)
errExit("SSL_ConfigServerSessionIDCache");
@@ -1895,7 +1915,7 @@ main(int argc, char **argv)
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
/* do nothing */;
- if (cipher) {
+ if (cipher > 0) {
SECStatus status;
status = SSL_CipherPrefSetDefault(cipher, SSL_ALLOWED);
if (status != SECSuccess)
diff --git a/security/nss/cmd/shlibsign/Makefile b/security/nss/cmd/shlibsign/Makefile
index 83a3cada1..e6c47da24 100644
--- a/security/nss/cmd/shlibsign/Makefile
+++ b/security/nss/cmd/shlibsign/Makefile
@@ -58,28 +58,11 @@ include $(CORE_DEPTH)/coreconf/config.mk
include ../platlibs.mk
-#
-# we really should have this driven from a list file made during the normal
-# NSS build prodecure.
-#
-ifndef USE_64
-ifeq ($(OS_TARGET), HP-UX)
- ifneq ($(OS_TEST), ia64)
- LOADABLE_FREEBL= 1
- endif
-endif
-ifeq ($(OS_TARGET), SunOS)
- ifeq ($(CPU_ARCH), sparc)
- LOADABLE_FREEBL = 1
- endif
-endif
-endif
-
-ifdef LOADABLE_FREEBL
- CHECKFILES += freebl_pure32_3.chk freebl_hybrid_3.chk
-endif
+# sign any and all shared libraries that contain the word freebl
-CHECKLOC=$(addprefix $(DIST)/lib/$(DLL_PREFIX), $(CHECKFILES))
+CHECKLIBS = $(DIST)/lib/$(DLL_PREFIX)softokn3.$(DLL_SUFFIX)
+CHECKLIBS += $(wildcard $(DIST)/lib/$(DLL_PREFIX)freebl*3.$(DLL_SUFFIX))
+CHECKLOC = $(CHECKLIBS:.$(DLL_SUFFIX)=.chk)
MD_LIB_RELEASE_FILES = $(CHECKLOC)
ALL_TRASH += $(CHECKLOC)
@@ -105,9 +88,9 @@ include ../platrules.mk
%.chk: %.$(DLL_SUFFIX)
ifeq ($(OS_TARGET), OS2)
- @cmd.exe /c sign.cmd $(DIST) $(OBJDIR) $(OS_TARGET) $<
+ cmd.exe /c sign.cmd $(DIST) $(OBJDIR) $(OS_TARGET) $(NSPR_LIB_DIR) $<
else
- @sh ./sign.sh $(DIST) $(OBJDIR) $(OS_TARGET) $<
+ sh ./sign.sh $(DIST) $(OBJDIR) $(OS_TARGET) $(NSPR_LIB_DIR) $<
endif
libs install :: $(CHECKLOC)
diff --git a/security/nss/cmd/shlibsign/manifest.mn b/security/nss/cmd/shlibsign/manifest.mn
index 7d03279ea..ca460771f 100644
--- a/security/nss/cmd/shlibsign/manifest.mn
+++ b/security/nss/cmd/shlibsign/manifest.mn
@@ -46,8 +46,6 @@ CSRCS = \
shlibsign.c \
$(NULL)
-CHECKFILES = softokn3.chk
-
# headers for the MODULE (defined above) are implicitly required.
REQUIRES = dbm seccmd
diff --git a/security/nss/cmd/shlibsign/shlibsign.c b/security/nss/cmd/shlibsign/shlibsign.c
index 28d7c7f8a..701803def 100644
--- a/security/nss/cmd/shlibsign/shlibsign.c
+++ b/security/nss/cmd/shlibsign/shlibsign.c
@@ -155,6 +155,7 @@ main (int argc, char **argv)
int keySize = 1024;
PQGParams *pqgParams = NULL;
PQGVerify *pqgVerify = NULL;
+ char* nssDir = NULL;
#ifdef USES_LINKS
int ret;
struct stat stat_buf;
@@ -187,7 +188,7 @@ main (int argc, char **argv)
#endif
case 'd':
- SECU_ConfigDirectory(optstate->value);
+ nssDir = optstate->value;
break;
case 'i':
@@ -214,10 +215,15 @@ main (int argc, char **argv)
*/
PK11_SetPasswordFunc(SECU_GetModulePassword);
- rv = NSS_Init(SECU_ConfigDirectory(NULL));
- if (rv != SECSuccess) {
- rv = NSS_NoDB_Init("");
+ if (nssDir) {
+ rv = NSS_Init(nssDir);
+ if (rv != SECSuccess) {
+ rv = NSS_NoDB_Init("");
+ }
+ } else {
+ rv = NSS_NoDB_Init("");
}
+
if (rv != SECSuccess) {
lperror("NSS_Init failed");
goto prdone;
diff --git a/security/nss/cmd/shlibsign/sign.cmd b/security/nss/cmd/shlibsign/sign.cmd
index 612609de9..92414538e 100644
--- a/security/nss/cmd/shlibsign/sign.cmd
+++ b/security/nss/cmd/shlibsign/sign.cmd
@@ -1,10 +1,12 @@
/* Equivalent to sign.sh for OS/2 */
-PARSE ARG dist objdir os_target therest
+PARSE ARG dist objdir os_target nspr_lib_dir therest
dist=forwardtoback(dist);
objdir=forwardtoback(objdir);
+nspr_lib_dir=forwardtoback(nspr_lib_dir);
'echo 'dist
'echo 'objdir
-'set BEGINLIBPATH='dist'\lib;%BEGINLIBPATH%'
+'echo 'nspr_lib_dir
+'set BEGINLIBPATH='dist'\lib;'nspr_lib_dir';%BEGINLIBPATH%'
'set LIBPATHSTRICT=T'
objdir'\shlibsign -v -i 'therest
exit
diff --git a/security/nss/cmd/shlibsign/sign.sh b/security/nss/cmd/shlibsign/sign.sh
index 33be43150..764012d7b 100644
--- a/security/nss/cmd/shlibsign/sign.sh
+++ b/security/nss/cmd/shlibsign/sign.sh
@@ -2,7 +2,7 @@
case "${3}" in
WIN*)
if echo "${PATH}" | grep -c \; >/dev/null; then
- PATH=${1}/bin\;${1}/lib\;${PATH}
+ PATH=${1}/lib\;${1}/bin\;${4}\;${PATH}
else
# ARG1 is ${1} with the drive letter escaped.
if echo "${1}" | grep -c : >/dev/null; then
@@ -10,11 +10,16 @@ WIN*)
else
ARG1=${1}
fi
- PATH=${ARG1}/bin:${ARG1}/lib:${PATH}
+ if echo "${4}" | grep -c : >/dev/null; then
+ ARG4=`(cd ${4}; pwd)`
+ else
+ ARG4=${4}
+ fi
+ PATH=${ARG1}/lib:${ARG1}/bin:${ARG4}:${PATH}
fi
export PATH
- echo ${2}/shlibsign -v -i ${4}
- ${2}/shlibsign -v -i ${4}
+ echo ${2}/shlibsign -v -i ${5}
+ ${2}/shlibsign -v -i ${5}
;;
OpenVMS)
temp="tmp$$.tmp"
@@ -26,8 +31,8 @@ OpenVMS)
echo '$ define/job getipnodebyname xxx' >> $temp2
echo '$ define/job vms_null_dl_name sys$share:decc$shr' >> $temp2
dcl @$temp2
- echo ${2}/shlibsign -v -i ${4}
- ${2}/shlibsign -v -i ${4}
+ echo ${2}/shlibsign -v -i ${5}
+ ${2}/shlibsign -v -i ${5}
sed -e "s/\([^\.]*\)\.so/\$ deass\/job \1/" $temp > $temp2
echo '$ deass/job getipnodebyname' >> $temp2
echo '$ deass/job vms_null_dl_name' >> $temp2
@@ -35,17 +40,19 @@ OpenVMS)
rm $temp $temp2
;;
*)
- LIBPATH=`(cd ${1}/lib; pwd)`:$LIBPATH
+ LIBPATH=`(cd ${1}/lib; pwd)`:`(cd ${4}; pwd)`:$LIBPATH
export LIBPATH
- SHLIB_PATH=${1}/lib:$SHLIB_PATH
+ SHLIB_PATH=${1}/lib:${4}:$SHLIB_PATH
export SHLIB_PATH
- LD_LIBRARY_PATH=${1}/lib:$LD_LIBRARY_PATH
+ LD_LIBRARY_PATH=${1}/lib:${4}:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
- DYLD_LIBRARY_PATH=${1}/lib:$DYLD_LIBRARY_PATH
+ DYLD_LIBRARY_PATH=${1}/lib:${4}:$DYLD_LIBRARY_PATH
export DYLD_LIBRARY_PATH
- LIBRARY_PATH=${1}/lib:$LIBRARY_PATH
+ LIBRARY_PATH=${1}/lib:${4}:$LIBRARY_PATH
export LIBRARY_PATH
- echo ${2}/shlibsign -v -i ${4}
- ${2}/shlibsign -v -i ${4}
+ ADDON_PATH=${1}/lib:${4}:$ADDON_PATH
+ export ADDON_PATH
+ echo ${2}/shlibsign -v -i ${5}
+ ${2}/shlibsign -v -i ${5}
;;
esac
diff --git a/security/nss/cmd/signtool/javascript.c b/security/nss/cmd/signtool/javascript.c
index 976cd7460..add76db03 100644
--- a/security/nss/cmd/signtool/javascript.c
+++ b/security/nss/cmd/signtool/javascript.c
@@ -321,7 +321,7 @@ CreateTagItem(TagItem*ti, unsigned int startline, unsigned int endline)
static PRBool
-isAttChar(char c)
+isAttChar(int c)
{
return (isalnum(c) || c == '/' || c == '-');
}
@@ -737,7 +737,7 @@ FB_GetChar(FileBuffer *fb)
storedOffset = PR_Seek(fb->fd, 0, PR_SEEK_CUR);
- retval = fb->buf[fb->curIndex++];
+ retval = (unsigned char) fb->buf[fb->curIndex++];
if (retval == '\n')
fb->lineNum++;
diff --git a/security/nss/cmd/signver/signver.c b/security/nss/cmd/signver/signver.c
index 49b8cbbf8..b7b40cfd7 100644
--- a/security/nss/cmd/signver/signver.c
+++ b/security/nss/cmd/signver/signver.c
@@ -56,25 +56,11 @@ static char *usageInfo[] = {
" -a signature file is ASCII",
" -d certdir directory containing cert database",
" -i dataFileName input file name containing data,",
- " leave filename blank to use stdin",
+ " use - for stdin",
" -s signatureFileName input file name containing signature,",
- " leave filename blank to use stdin",
+ " use - for stdin",
" -o outputFileName output file name, default stdout",
" -A display all information from pkcs #7",
- " -C display all information from all certs",
- " -C -n display number of certificates",
- " -C -n certNum display all information from the certNum",
- " certificate in pkcs #7 signed object",
- " -C -n certNum f1 ... fN display information about specified",
- " fields from the certNum certificate in",
- " the pkcs #7 signed object",
- " -S display signer information list",
- " -S -n display number of signer information blocks",
- " -S -n signerNum display all information from the signerNum",
- " signer information block in pkcs #7",
- " -S -n signerNum f1 ... fN display information about specified",
- " fields from the signerNum signer",
- " information block in pkcs #7 object",
" -V verify the signed object and display result",
" -V -v verify the signed object and display",
" result and reason for failure",
@@ -159,8 +145,6 @@ enum {
static secuCommandFlag signver_commands[] =
{
{ /* cmd_DisplayAllPCKS7Info*/ 'A', PR_FALSE, 0, PR_FALSE },
- { /* cmd_DisplayCertInfo */ 'C', PR_FALSE, 0, PR_FALSE },
- { /* cmd_DisplaySignerInfo */ 'S', PR_FALSE, 0, PR_FALSE },
{ /* cmd_VerifySignedObj */ 'V', PR_FALSE, 0, PR_FALSE }
};
@@ -169,7 +153,6 @@ static secuCommandFlag signver_options[] =
{ /* opt_ASCII */ 'a', PR_FALSE, 0, PR_FALSE },
{ /* opt_CertDir */ 'd', PR_TRUE, 0, PR_FALSE },
{ /* opt_InputDataFile */ 'i', PR_TRUE, 0, PR_FALSE },
- { /* opt_ItemNumber */ 'n', PR_FALSE, 0, PR_FALSE },
{ /* opt_OutputFile */ 'o', PR_TRUE, 0, PR_FALSE },
{ /* opt_InputSigFile */ 's', PR_TRUE, 0, PR_FALSE },
{ /* opt_TypeTag */ 't', PR_TRUE, 0, PR_FALSE },
@@ -186,8 +169,6 @@ int main(int argc, char **argv)
PRFileDesc *signFile = 0;
FILE *outFile = stdout;
char *typeTag = 0;
- PRBool displayAllCerts = PR_FALSE;
- PRBool displayAllSigners = PR_FALSE;
SECStatus secstatus;
secuCommand signver;
@@ -215,7 +196,11 @@ int main(int argc, char **argv)
}
#endif
- SECU_ParseCommandLine(argc, argv, progName, &signver);
+ rv = SECU_ParseCommandLine(argc, argv, progName, &signver);
+
+ if (SECSuccess != rv) {
+ Usage(progName, outFile);
+ }
/* Set the certdb directory (default is ~/.{browser}) */
SECU_ConfigDirectory(signver.options[opt_CertDir].arg);
@@ -226,15 +211,15 @@ int main(int argc, char **argv)
/* -i and -s without filenames */
if (signver.options[opt_InputDataFile].activated &&
signver.options[opt_InputSigFile].activated &&
- !signver.options[opt_InputDataFile].arg &&
- !signver.options[opt_InputSigFile].arg)
+ !PL_strcmp("-", signver.options[opt_InputDataFile].arg) &&
+ !PL_strcmp("-", signver.options[opt_InputSigFile].arg))
PR_fprintf(PR_STDERR,
"%s: Only data or signature file can use stdin (not both).\n",
progName);
/* Open the input data file (no arg == use stdin). */
if (signver.options[opt_InputDataFile].activated) {
- if (signver.options[opt_InputDataFile].arg)
+ if (PL_strcmp("-", signver.options[opt_InputDataFile].arg))
dataFile = PR_Open(signver.options[opt_InputDataFile].arg,
PR_RDONLY, 0);
else
@@ -248,7 +233,7 @@ int main(int argc, char **argv)
/* Open the input signature file (no arg == use stdin). */
if (signver.options[opt_InputSigFile].activated) {
- if (signver.options[opt_InputSigFile].arg)
+ if (PL_strcmp("-", signver.options[opt_InputSigFile].arg))
signFile = PR_Open(signver.options[opt_InputSigFile].arg,
PR_RDONLY, 0);
else
@@ -278,20 +263,6 @@ int main(int argc, char **argv)
}
}
- if (signver.commands[cmd_DisplayCertInfo].activated &&
- !signver.options[opt_ItemNumber].arg)
- displayAllCerts = PR_TRUE;
-
- if (signver.commands[cmd_DisplaySignerInfo].activated &&
- !signver.options[opt_ItemNumber].arg)
- displayAllSigners = PR_TRUE;
-
-#if 0
- case 'W':
- debugInfo = 1;
- break;
-#endif
-
if (!signFile && !dataFile && !typeTag)
Usage(progName, outFile);
@@ -413,12 +384,6 @@ int main(int argc, char **argv)
if (signver.commands[cmd_DisplayAllPCKS7Info].activated)
SV_PrintPKCS7ContentInfo(outFile, &data);
- if (displayAllCerts)
- PR_fprintf(PR_STDERR, "-C option is not implemented in this version\n");
-
- if (displayAllSigners)
- PR_fprintf(PR_STDERR, "-S option is not implemented in this version\n");
-
/* Pretty print it */
} else if (PL_strcmp(typeTag, SEC_CT_CERTIFICATE) == 0) {
rv = SECU_PrintSignedData(outFile, &data, "Certificate", 0,
diff --git a/security/nss/cmd/ssltap/config.mk b/security/nss/cmd/ssltap/config.mk
deleted file mode 100644
index d68b4651d..000000000
--- a/security/nss/cmd/ssltap/config.mk
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-#######################################################################
-# Set the LDFLAGS value to encompass all normal link options, all #
-# library names, and all special system linking options #
-#######################################################################
-
-LDFLAGS = \
- $(DYNAMIC_LIB_PATH) \
- $(LDOPTS) \
- $(LIBPLC) \
- $(LIBPR) \
- $(DLLSYSTEM)
-
-#######################################################################
-# Adjust specific variables for all platforms #
-#######################################################################
-
-OS_CFLAGS += -DNSPR20=1
-
-
diff --git a/security/nss/cmd/ssltap/ssltap.c b/security/nss/cmd/ssltap/ssltap.c
index bc5ab401c..9352d063b 100644
--- a/security/nss/cmd/ssltap/ssltap.c
+++ b/security/nss/cmd/ssltap/ssltap.c
@@ -333,6 +333,13 @@ const char * V2CipherString(int cs_int) {
case 0x000039: cs_str = "TLS/DHE-RSA/AES256-CBC/SHA"; break;
case 0x00003A: cs_str = "TLS/DH-ANON/AES256-CBC/SHA"; break;
+ case 0x000041: cs_str = "TLS/RSA/CAMELLIA128-CBC/SHA"; break;
+ case 0x000042: cs_str = "TLS/DH-DSS/CAMELLIA128-CBC/SHA"; break;
+ case 0x000043: cs_str = "TLS/DH-RSA/CAMELLIA128-CBC/SHA"; break;
+ case 0x000044: cs_str = "TLS/DHE-DSS/CAMELLIA128-CBC/SHA"; break;
+ case 0x000045: cs_str = "TLS/DHE-RSA/CAMELLIA128-CBC/SHA"; break;
+ case 0x000046: cs_str = "TLS/DH-ANON/CAMELLIA128-CBC/SHA"; break;
+
case 0x000047: cs_str = "TLS/ECDH-ECDSA/NULL/SHA"; break;
case 0x000048: cs_str = "TLS/ECDH-ECDSA/RC4-128/SHA"; break;
case 0x000049: cs_str = "TLS/ECDH-ECDSA/DES-CBC/SHA"; break;
@@ -347,15 +354,57 @@ const char * V2CipherString(int cs_int) {
case 0x000051: cs_str = "TLS/ECDH-RSA/AES128-CBC/SHA"; break;
case 0x000052: cs_str = "TLS/ECDH-RSA/AES256-CBC/SHA"; break;
+ case 0x000060: cs_str = "TLS/RSA-EXPORT1024/RC4-56/MD5"; break;
+ case 0x000061: cs_str = "TLS/RSA-EXPORT1024/RC2CBC56/MD5"; break;
case 0x000062: cs_str = "TLS/RSA-EXPORT1024/DES56-CBC/SHA"; break;
case 0x000064: cs_str = "TLS/RSA-EXPORT1024/RC4-56/SHA"; break;
case 0x000063: cs_str = "TLS/DHE-DSS_EXPORT1024/DES56-CBC/SHA"; break;
case 0x000065: cs_str = "TLS/DHE-DSS_EXPORT1024/RC4-56/SHA"; break;
case 0x000066: cs_str = "TLS/DHE-DSS/RC4-128/SHA"; break;
+ case 0x000072: cs_str = "TLS/DHE-DSS/3DESEDE-CBC/RMD160"; break;
+ case 0x000073: cs_str = "TLS/DHE-DSS/AES128-CBC/RMD160"; break;
+ case 0x000074: cs_str = "TLS/DHE-DSS/AES256-CBC/RMD160"; break;
+
case 0x000077: cs_str = "TLS/ECDHE-ECDSA/AES128-CBC/SHA"; break;
case 0x000078: cs_str = "TLS/ECDHE-RSA/AES128-CBC/SHA"; break;
+ case 0x000079: cs_str = "TLS/DHE-RSA/AES256-CBC/RMD160"; break;
+
+ case 0x00007C: cs_str = "TLS/RSA/3DESEDE-CBC/RMD160"; break;
+ case 0x00007D: cs_str = "TLS/RSA/AES128-CBC/RMD160"; break;
+ case 0x00007E: cs_str = "TLS/RSA/AES256-CBC/RMD160"; break;
+
+ case 0x000080: cs_str = "TLS/GOST341094/GOST28147-OFB/GOST28147"; break;
+ case 0x000081: cs_str = "TLS/GOST34102001/GOST28147-OFB/GOST28147"; break;
+ case 0x000082: cs_str = "TLS/GOST341094/NULL/GOSTR3411"; break;
+ case 0x000083: cs_str = "TLS/GOST34102001/NULL/GOSTR3411"; break;
+
+ case 0x000084: cs_str = "TLS/RSA/CAMELLIA256-CBC/SHA"; break;
+ case 0x000085: cs_str = "TLS/DH-DSS/CAMELLIA256-CBC/SHA"; break;
+ case 0x000086: cs_str = "TLS/DH-RSA/CAMELLIA256-CBC/SHA"; break;
+ case 0x000087: cs_str = "TLS/DHE-DSS/CAMELLIA256-CBC/SHA"; break;
+ case 0x000088: cs_str = "TLS/DHE-RSA/CAMELLIA256-CBC/SHA"; break;
+ case 0x000089: cs_str = "TLS/DH-ANON/CAMELLIA256-CBC/SHA"; break;
+ case 0x00008A: cs_str = "TLS/PSK/RC4-128/SHA"; break;
+ case 0x00008B: cs_str = "TLS/PSK/3DES-EDE-CBC/SHA"; break;
+ case 0x00008C: cs_str = "TLS/PSK/AES128-CBC/SHA"; break;
+ case 0x00008D: cs_str = "TLS/PSK/AES256-CBC/SHA"; break;
+ case 0x00008E: cs_str = "TLS/DHE-PSK/RC4-128/SHA"; break;
+ case 0x00008F: cs_str = "TLS/DHE-PSK/3DES-EDE-CBC/SHA"; break;
+ case 0x000090: cs_str = "TLS/DHE-PSK/AES128-CBC/SHA"; break;
+ case 0x000091: cs_str = "TLS/DHE-PSK/AES256-CBC/SHA"; break;
+ case 0x000092: cs_str = "TLS/RSA-PSK/RC4-128/SHA"; break;
+ case 0x000093: cs_str = "TLS/RSA-PSK/3DES-EDE-CBC/SHA"; break;
+ case 0x000094: cs_str = "TLS/RSA-PSK/AES128-CBC/SHA"; break;
+ case 0x000095: cs_str = "TLS/RSA-PSK/AES256-CBC/SHA"; break;
+ case 0x000096: cs_str = "TLS/RSA/SEED-CBC/SHA"; break;
+ case 0x000097: cs_str = "TLS/DH-DSS/SEED-CBC/SHA"; break;
+ case 0x000098: cs_str = "TLS/DH-RSA/SEED-CBC/SHA"; break;
+ case 0x000099: cs_str = "TLS/DHE-DSS/SEED-CBC/SHA"; break;
+ case 0x00009A: cs_str = "TLS/DHE-RSA/SEED-CBC/SHA"; break;
+ case 0x00009B: cs_str = "TLS/DH-ANON/SEED-CBC/SHA"; break;
+
case 0x00feff: cs_str = "SSL3/RSA-FIPS/3DESEDE-CBC/SHA"; break;
case 0x00fefe: cs_str = "SSL3/RSA-FIPS/DES-CBC/SHA"; break;
case 0x00ffe1: cs_str = "SSL3/RSA-FIPS/DES56-CBC/SHA"; break;
diff --git a/security/nss/cmd/strsclnt/strsclnt.c b/security/nss/cmd/strsclnt/strsclnt.c
index 35ed739d6..d0c91d551 100644
--- a/security/nss/cmd/strsclnt/strsclnt.c
+++ b/security/nss/cmd/strsclnt/strsclnt.c
@@ -111,14 +111,14 @@ int ssl2CipherSuites[] = {
};
int ssl3CipherSuites[] = {
- SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* a */
- SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, /* b */
+ -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
+ -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA * b */
SSL_RSA_WITH_RC4_128_MD5, /* c */
SSL_RSA_WITH_3DES_EDE_CBC_SHA, /* d */
SSL_RSA_WITH_DES_CBC_SHA, /* e */
SSL_RSA_EXPORT_WITH_RC4_40_MD5, /* f */
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */
- SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* h */
+ -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA * h */
SSL_RSA_WITH_NULL_MD5, /* i */
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */
SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */
@@ -139,6 +139,8 @@ int ssl3CipherSuites[] = {
0
};
+#define NO_FULLHS_PERCENTAGE -1
+
/* This global string is so that client main can see
* which ciphers to use.
*/
@@ -148,14 +150,34 @@ static const char *cipherString;
static int certsTested;
static int MakeCertOK;
static int NoReuse;
+static int fullhs = NO_FULLHS_PERCENTAGE; /* percentage of full handshakes to
+ ** perform */
+static PRInt32 globalconid = 0; /* atomically set */
+static int total_connections; /* total number of connections to perform */
+static int total_connections_rounded_down_to_hundreds;
+static int total_connections_modulo_100;
+
static PRBool NoDelay;
static PRBool QuitOnTimeout = PR_FALSE;
+static PRBool ThrottleUp = PR_FALSE;
+
+static PRLock * threadLock; /* protects the global variables below */
+static PRTime lastConnectFailure;
+static PRTime lastConnectSuccess;
+static PRTime lastThrottleUp;
+static int remaining_connections; /* number of connections left */
+static int active_threads = 8; /* number of threads currently trying to
+ ** connect */
+static int numUsed;
+/* end of variables protected by threadLock */
static SSL3Statistics * ssl3stats;
static int failed_already = 0;
static PRBool disableSSL3 = PR_FALSE;
static PRBool disableTLS = PR_FALSE;
+static PRBool bypassPKCS11 = PR_FALSE;
+static PRBool disableLocking = PR_FALSE;
char * ownPasswd( PK11SlotInfo *slot, PRBool retry, void *arg)
@@ -181,7 +203,7 @@ Usage(const char *progName)
{
fprintf(stderr,
"Usage: %s [-n nickname] [-p port] [-d dbdir] [-c connections]\n"
- " [-3DNTovq] [-2 filename]\n"
+ " [-3BDNTovqs] [-2 filename] [-P fullhandshakespercentage | -N]\n"
" [-w dbpasswd] [-C cipher(s)] [-t threads] hostname\n"
" where -v means verbose\n"
" -o flag is interpreted as follows:\n"
@@ -189,7 +211,13 @@ Usage(const char *progName)
" 2 -o's mean skip server certificate validation altogether.\n"
" -D means no TCP delays\n"
" -q means quit when server gone (timeout rather than retry forever)\n"
- " -N means no session reuse\n",
+ " -s means disable SSL socket locking\n"
+ " -N means no session reuse\n"
+ " -P means do a specified percentage of full handshakes (0-100)\n"
+ " -3 means disable SSL3\n"
+ " -T means disable TLS\n"
+ " -U means enable throttling up threads\n"
+ " -B bypasses the PKCS11 layer for SSL encryption and MACing\n",
progName);
exit(1);
}
@@ -355,26 +383,18 @@ printSecurityInfo(PRFileDesc *fd)
typedef int startFn(void *a, void *b, int c);
-PRLock * threadLock;
-PRCondVar * threadStartQ;
-PRCondVar * threadEndQ;
-
-int numUsed;
-int numRunning;
-PRInt32 numConnected;
-int max_threads = 8; /* default much less than max. */
-typedef enum { rs_idle = 0, rs_running = 1, rs_zombie = 2 } runState;
+static PRInt32 numConnected;
+static int max_threads; /* peak threads allowed */
typedef struct perThreadStr {
void * a;
void * b;
- int c;
+ int tid;
int rv;
startFn * startFunc;
PRThread * prThread;
PRBool inUse;
- runState running;
} perThread;
perThread threads[MAX_THREADS];
@@ -383,25 +403,61 @@ void
thread_wrapper(void * arg)
{
perThread * slot = (perThread *)arg;
-
- /* wait for parent to finish launching us before proceeding. */
- PR_Lock(threadLock);
- PR_Unlock(threadLock);
-
- slot->rv = (* slot->startFunc)(slot->a, slot->b, slot->c);
-
- /* Handle cleanup of thread here. */
- PRINTF("strsclnt: Thread in slot %d returned %d\n",
- slot - threads, slot->rv);
-
- PR_Lock(threadLock);
- slot->running = rs_idle;
- --numRunning;
-
- /* notify the thread launcher. */
- PR_NotifyCondVar(threadStartQ);
-
- PR_Unlock(threadLock);
+ PRBool die = PR_FALSE;
+
+ do {
+ PRBool doop = PR_FALSE;
+ PRBool dosleep = PR_FALSE;
+ PRTime now = PR_Now();
+
+ PR_Lock(threadLock);
+ if (! (slot->tid < active_threads)) {
+ /* this thread isn't supposed to be running */
+ if (!ThrottleUp) {
+ /* we'll never need this thread again, so abort it */
+ die = PR_TRUE;
+ } else if (remaining_connections > 0) {
+ /* we may still need this thread, so just sleep for 1s */
+ dosleep = PR_TRUE;
+ /* the conditions to trigger a throttle up are :
+ ** 1. last PR_Connect failure must have happened more than
+ ** 10s ago
+ ** 2. last throttling up must have happened more than 0.5s ago
+ ** 3. there must be a more recent PR_Connect success than
+ ** failure
+ */
+ if ( (now - lastConnectFailure > 10 * PR_USEC_PER_SEC) &&
+ ( (!lastThrottleUp) || ( (now - lastThrottleUp) >=
+ (PR_USEC_PER_SEC/2)) ) &&
+ (lastConnectSuccess > lastConnectFailure) ) {
+ /* try throttling up by one thread */
+ active_threads = PR_MIN(max_threads, active_threads+1);
+ fprintf(stderr,"active_threads set up to %d\n",
+ active_threads);
+ lastThrottleUp = PR_MAX(now, lastThrottleUp);
+ }
+ } else {
+ /* no more connections left, we are done */
+ die = PR_TRUE;
+ }
+ } else {
+ /* this thread should run */
+ if (--remaining_connections >= 0) {
+ doop = PR_TRUE;
+ } else {
+ die = PR_TRUE;
+ }
+ }
+ PR_Unlock(threadLock);
+ if (doop) {
+ slot->rv = (* slot->startFunc)(slot->a, slot->b, slot->tid);
+ PRINTF("strsclnt: Thread in slot %d returned %d\n",
+ slot->tid, slot->rv);
+ }
+ if (dosleep) {
+ PR_Sleep(PR_SecondsToInterval(1));
+ }
+ } while (!die);
}
SECStatus
@@ -409,46 +465,30 @@ launch_thread(
startFn * startFunc,
void * a,
void * b,
- int c)
+ int tid)
{
perThread * slot;
int i;
- if (!threadStartQ) {
- threadLock = PR_NewLock();
- threadStartQ = PR_NewCondVar(threadLock);
- threadEndQ = PR_NewCondVar(threadLock);
- }
PR_Lock(threadLock);
- while (numRunning >= max_threads) {
- PR_WaitCondVar(threadStartQ, PR_INTERVAL_NO_TIMEOUT);
- }
- for (i = 0; i < numUsed; ++i) {
- if (threads[i].running == rs_idle)
- break;
- }
- if (i >= numUsed) {
- if (i >= MAX_THREADS) {
- /* something's really wrong here. */
- PORT_Assert(i < MAX_THREADS);
- PR_Unlock(threadLock);
- return SECFailure;
- }
- ++numUsed;
- PORT_Assert(numUsed == i + 1);
+
+ PORT_Assert(numUsed < MAX_THREADS);
+ if (! (numUsed < MAX_THREADS)) {
+ PR_Unlock(threadLock);
+ return SECFailure;
}
- slot = threads + i;
+ slot = &threads[numUsed++];
slot->a = a;
slot->b = b;
- slot->c = c;
+ slot->tid = tid;
slot->startFunc = startFunc;
slot->prThread = PR_CreateThread(PR_USER_THREAD,
thread_wrapper, slot,
PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
- PR_UNJOINABLE_THREAD, 0);
+ PR_JOINABLE_THREAD, 0);
if (slot->prThread == NULL) {
PR_Unlock(threadLock);
printf("strsclnt: Failed to launch thread!\n");
@@ -456,37 +496,25 @@ launch_thread(
}
slot->inUse = 1;
- slot->running = 1;
- ++numRunning;
PR_Unlock(threadLock);
PRINTF("strsclnt: Launched thread in slot %d \n", i);
return SECSuccess;
}
-/* Wait until numRunning == 0 */
+/* join all the threads */
int
reap_threads(void)
{
perThread * slot;
int i;
- if (!threadLock)
- return 0;
- PR_Lock(threadLock);
- while (numRunning > 0) {
- PR_WaitCondVar(threadStartQ, PR_INTERVAL_NO_TIMEOUT);
- }
-
- /* Safety Sam sez: make sure count is right. */
- for (i = 0; i < numUsed; ++i) {
- slot = threads + i;
- if (slot->running != rs_idle) {
- FPRINTF(stderr, "strsclnt: Thread in slot %d is in state %d!\n",
- i, slot->running);
- }
+ for (i = 0; i < MAX_THREADS; ++i) {
+ if (threads[i].prThread) {
+ PR_JoinThread(threads[i].prThread);
+ threads[i].prThread = NULL;
+ }
}
- PR_Unlock(threadLock);
return 0;
}
@@ -495,20 +523,18 @@ destroy_thread_data(void)
{
PORT_Memset(threads, 0, sizeof threads);
- if (threadEndQ) {
- PR_DestroyCondVar(threadEndQ);
- threadEndQ = NULL;
- }
- if (threadStartQ) {
- PR_DestroyCondVar(threadStartQ);
- threadStartQ = NULL;
- }
if (threadLock) {
PR_DestroyLock(threadLock);
threadLock = NULL;
}
}
+void
+init_thread_data(void)
+{
+ threadLock = PR_NewLock();
+}
+
/**************************************************************************
** End thread management routines.
**************************************************************************/
@@ -668,7 +694,7 @@ cleanup:
const char request[] = {"GET /abc HTTP/1.0\r\n\r\n" };
SECStatus
-handle_connection( PRFileDesc *ssl_sock, int connection)
+handle_connection( PRFileDesc *ssl_sock, int tid)
{
int countRead = 0;
PRInt32 rv;
@@ -702,8 +728,9 @@ handle_connection( PRFileDesc *ssl_sock, int connection)
}
countRead += rv;
- FPRINTF(stderr, "strsclnt: connection %d read %d bytes (%d total).\n",
- connection, rv, countRead );
+ FPRINTF(stderr,
+ "strsclnt: connection on thread %d read %d bytes (%d total).\n",
+ tid, rv, countRead );
}
PR_Free(buf);
buf = 0;
@@ -711,12 +738,27 @@ handle_connection( PRFileDesc *ssl_sock, int connection)
/* Caller closes the socket. */
FPRINTF(stderr,
- "strsclnt: connection %d read %d bytes total. -----------------------\n",
- connection, countRead);
+ "strsclnt: connection on thread %d read %d bytes total. ---------\n",
+ tid, countRead);
return SECSuccess; /* success */
}
+#define USE_SOCK_PEER_ID 1
+
+#ifdef USE_SOCK_PEER_ID
+
+PRInt32 lastFullHandshakePeerID;
+
+SECStatus
+myHandshakeCallback(PRFileDesc *socket, void *arg)
+{
+ PR_AtomicSet(&lastFullHandshakePeerID, (PRInt32) arg);
+ return SECSuccess;
+}
+
+#endif
+
/* one copy of this function is launched in a separate thread for each
** connection to be made.
*/
@@ -724,7 +766,7 @@ int
do_connects(
void * a,
void * b,
- int connection)
+ int tid)
{
PRNetAddr * addr = (PRNetAddr *) a;
PRFileDesc * model_sock = (PRFileDesc *) b;
@@ -765,16 +807,26 @@ retry:
prStatus = PR_Connect(tcp_sock, addr, PR_INTERVAL_NO_TIMEOUT);
if (prStatus != PR_SUCCESS) {
- PRErrorCode err = PR_GetError();
- if ((err == PR_CONNECT_REFUSED_ERROR) ||
+ PRErrorCode err = PR_GetError(); /* save error code */
+ if (ThrottleUp) {
+ PRTime now = PR_Now();
+ PR_Lock(threadLock);
+ lastConnectFailure = PR_MAX(now, lastConnectFailure);
+ PR_Unlock(threadLock);
+ }
+ if ((err == PR_CONNECT_REFUSED_ERROR) ||
(err == PR_CONNECT_RESET_ERROR) ) {
int connections = numConnected;
PR_Close(tcp_sock);
- if (connections > 2 && max_threads >= connections) {
- max_threads = connections - 1;
- fprintf(stderr,"max_threads set down to %d\n", max_threads);
- }
+ PR_Lock(threadLock);
+ if (connections > 2 && active_threads >= connections) {
+ active_threads = connections - 1;
+ fprintf(stderr,"active_threads set down to %d\n",
+ active_threads);
+ }
+ PR_Unlock(threadLock);
+
if (QuitOnTimeout && sleepInterval > 40000) {
fprintf(stderr,
"strsclnt: Client timed out waiting for connection to server.\n");
@@ -787,6 +839,13 @@ retry:
errWarn("PR_Connect");
rv = SECFailure;
goto done;
+ } else {
+ if (ThrottleUp) {
+ PRTime now;
+ PR_Lock(threadLock);
+ lastConnectSuccess = PR_MAX(now, lastConnectSuccess);
+ PR_Unlock(threadLock);
+ }
}
ssl_sock = SSL_ImportFD(model_sock, tcp_sock);
@@ -795,7 +854,37 @@ retry:
PR_Close(tcp_sock);
return SECSuccess;
}
-
+ if (fullhs != NO_FULLHS_PERCENTAGE) {
+#ifdef USE_SOCK_PEER_ID
+ char sockPeerIDString[512];
+ static PRInt32 sockPeerID = 0; /* atomically incremented */
+ PRInt32 thisPeerID;
+#endif
+ PRInt32 savid = PR_AtomicIncrement(&globalconid);
+ PRInt32 conid = 1 + (savid - 1) % 100;
+ /* don't change peer ID on the very first handshake, which is always
+ a full, so the session gets stored into the client cache */
+ if ( (savid != 1) &&
+ ( ( (savid <= total_connections_rounded_down_to_hundreds) &&
+ (conid <= fullhs) ) ||
+ (conid*100 <= total_connections_modulo_100*fullhs ) ) ) {
+#ifdef USE_SOCK_PEER_ID
+ /* force a full handshake by changing the socket peer ID */
+ thisPeerID = PR_AtomicIncrement(&sockPeerID);
+ } else {
+ /* reuse previous sockPeerID for restart handhsake */
+ thisPeerID = lastFullHandshakePeerID;
+ }
+ PR_snprintf(sockPeerIDString, sizeof(sockPeerIDString), "ID%d",
+ thisPeerID);
+ SSL_SetSockPeerID(ssl_sock, sockPeerIDString);
+ SSL_HandshakeCallback(ssl_sock, myHandshakeCallback, (void*)thisPeerID);
+#else
+ /* force a full handshake by setting the no cache option */
+ SSL_OptionSet(ssl_sock, SSL_NO_CACHE, 1);
+ }
+#endif
+ }
rv = SSL_ResetHandshake(ssl_sock, /* asServer */ 0);
if (rv != SECSuccess) {
errWarn("SSL_ResetHandshake");
@@ -805,9 +894,9 @@ retry:
PR_AtomicIncrement(&numConnected);
if (bigBuf.data != NULL) {
- result = handle_fdx_connection( ssl_sock, connection);
+ result = handle_fdx_connection( ssl_sock, tid);
} else {
- result = handle_connection( ssl_sock, connection);
+ result = handle_connection( ssl_sock, tid);
}
PR_AtomicDecrement(&numConnected);
@@ -918,7 +1007,7 @@ StressClient_GetClientAuthData(void * arg,
PR_Unlock(Cert_And_Key->lock);
if (!*pRetCert || !*pRetKey) {
/* one or both of them failed to copy. Either the source was NULL, or there was
- an out of memory condition. Free any allocated copy and fail */
+ ** an out of memory condition. Free any allocated copy and fail */
if (*pRetCert) {
CERT_DestroyCertificate(*pRetCert);
*pRetCert = NULL;
@@ -1058,7 +1147,7 @@ client_main(
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
/* do nothing */;
- if (cipher) {
+ if (cipher > 0) {
SECStatus rv;
rv = SSL_CipherPrefSetDefault(cipher, PR_TRUE);
if (rv != SECSuccess) {
@@ -1114,6 +1203,20 @@ client_main(
}
}
+ if (bypassPKCS11) {
+ rv = SSL_OptionSet(model_sock, SSL_BYPASS_PKCS11, 1);
+ if (rv < 0) {
+ errExit("SSL_OptionSet SSL_BYPASS_PKCS11");
+ }
+ }
+
+ if (disableLocking) {
+ rv = SSL_OptionSet(model_sock, SSL_NO_LOCKS, 1);
+ if (rv < 0) {
+ errExit("SSL_OptionSet SSL_NO_LOCKS");
+ }
+ }
+
SSL_SetURL(model_sock, hostName);
SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate,
@@ -1126,20 +1229,26 @@ client_main(
/* end of ssl configuration. */
- i = 1;
+ init_thread_data();
+
+ remaining_connections = total_connections = connections;
+ total_connections_modulo_100 = total_connections % 100;
+ total_connections_rounded_down_to_hundreds =
+ total_connections - total_connections_modulo_100;
+
if (!NoReuse) {
- rv = launch_thread(do_connects, &addr, model_sock, i);
- --connections;
- ++i;
+ remaining_connections = 1;
+ rv = launch_thread(do_connects, &addr, model_sock, 0);
/* wait for the first connection to terminate, then launch the rest. */
reap_threads();
+ remaining_connections = total_connections - 1 ;
}
- if (connections > 0) {
- /* Start up the connections */
- do {
+ if (remaining_connections > 0) {
+ active_threads = PR_MIN(active_threads, remaining_connections);
+ /* Start up the threads */
+ for (i=0;i<active_threads;i++) {
rv = launch_thread(do_connects, &addr, model_sock, i);
- ++i;
- } while (--connections > 0);
+ }
reap_threads();
}
destroy_thread_data();
@@ -1214,7 +1323,7 @@ main(int argc, char **argv)
progName = progName ? progName + 1 : tmp;
- optstate = PL_CreateOptState(argc, argv, "2:3C:DNTc:d:n:op:qt:vw:");
+ optstate = PL_CreateOptState(argc, argv, "2:3BC:DNP:TUc:d:n:op:qst:vw:");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch(optstate->option) {
@@ -1222,13 +1331,19 @@ main(int argc, char **argv)
case '3': disableSSL3 = PR_TRUE; break;
+ case 'B': bypassPKCS11 = PR_TRUE; break;
+
case 'C': cipherString = optstate->value; break;
case 'D': NoDelay = PR_TRUE; break;
case 'N': NoReuse = 1; break;
+
+ case 'P': fullhs = PORT_Atoi(optstate->value); break;
case 'T': disableTLS = PR_TRUE; break;
+
+ case 'U': ThrottleUp = PR_TRUE; break;
case 'c': connections = PORT_Atoi(optstate->value); break;
@@ -1242,10 +1357,12 @@ main(int argc, char **argv)
case 'q': QuitOnTimeout = PR_TRUE; break;
+ case 's': disableLocking = PR_TRUE; break;
+
case 't':
tmpInt = PORT_Atoi(optstate->value);
if (tmpInt > 0 && tmpInt < MAX_THREADS)
- max_threads = tmpInt;
+ max_threads = active_threads = tmpInt;
break;
case 'v': verbose++; break;
@@ -1269,6 +1386,9 @@ main(int argc, char **argv)
if (!hostName || status == PL_OPT_BAD)
Usage(progName);
+ if (fullhs!= NO_FULLHS_PERCENTAGE && (fullhs < 0 || fullhs>100 || NoReuse) )
+ Usage(progName);
+
if (port == 0)
Usage(progName);
diff --git a/security/nss/cmd/tstclnt/makefile.win b/security/nss/cmd/tstclnt/makefile.win
deleted file mode 100644
index 7f0fdcf04..000000000
--- a/security/nss/cmd/tstclnt/makefile.win
+++ /dev/null
@@ -1,134 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-VERBOSE = 1
-include <manifest.mn>
-
-#cannot define PROGRAM in manifest compatibly with NT and UNIX
-PROGRAM = tstclnt
-PROGRAM = ./$(OBJDIR)/$(PROGRAM).exe
-include <$(DEPTH)\config\config.mak>
-
-# let manifest generate C_OBJS, it will prepend ./$(OBJDIR)/
-# rules.mak will append C_OBJS onto OBJS.
-# OBJS = $(CSRCS:.c=.obj)
-
-# include files are looked for in $LINCS and $INCS.
-# $LINCS is in manifest.mnw, computed from REQUIRES=
-INCS = $(INCS) \
- -I$(DEPTH)/security/lib/cert \
- -I../include \
- $(NULL)
-
-IGNORE_ME = \
- -I$(DEPTH)/security/lib/key \
- -I$(DEPTH)/security/lib/util \
- $(NULL)
-
-
-WINFE = $(DEPTH)/cmd/winfe/mkfiles$(MOZ_BITS)/x86Dbg
-
-# these files are the content of libdbm
-DBM_LIB = \
- $(WINFE)/DB.obj \
- $(WINFE)/HASH.obj \
- $(WINFE)/H_BIGKEY.obj \
- $(WINFE)/H_PAGE.obj \
- $(WINFE)/H_LOG2.obj \
- $(WINFE)/H_FUNC.obj \
- $(WINFE)/HASH_BUF.obj \
- $(NULL)
-
-MOZ_LIBS = \
- $(WINFE)/ALLXPSTR.obj \
- $(WINFE)/XP_ERROR.obj \
- $(WINFE)/XPASSERT.obj \
- $(WINFE)/XP_REG.obj \
- $(WINFE)/XP_TRACE.obj \
- $(DBM_LIB) \
- $(WINFE)/XP_STR.obj \
- $(WINFE)/MKTEMP.obj \
- $(NULL)
-
-SEC_LIBS = \
- $(DIST)/lib/cert$(MOZ_BITS).lib \
- $(DIST)/lib/crypto$(MOZ_BITS).lib \
- $(DIST)/lib/hash$(MOZ_BITS).lib \
- $(DIST)/lib/key$(MOZ_BITS).lib \
- $(DIST)/lib/pkcs7$(MOZ_BITS).lib \
- $(DIST)/lib/secmod$(MOZ_BITS).lib \
- $(DIST)/lib/secutl$(MOZ_BITS).lib \
- $(DIST)/lib/ssl$(MOZ_BITS).lib \
- $(NULL)
-
-LLFLAGS = $(LLFLAGS) \
- ../lib/$(OBJDIR)/sectool$(MOZ_BITS).lib \
- $(SEC_LIBS) \
- $(MOZ_LIBS) \
- $(DEPTH)/nspr/src/$(OBJDIR)/getopt.obj \
- $(LIBNSPR) \
- $(NULL)
-
-
-include <$(DEPTH)\config\rules.mak>
-
-INSTALL = $(MAKE_INSTALL)
-
-objs: $(OBJS)
-
-$(PROGRAM)::
- $(INSTALL) $(DIST)/bin/pr3240.dll ./$(OBJDIR)
-
-programs: $(PROGRAM)
-
-install:: $(TARGETS)
- $(INSTALL) $(TARGETS) $(DIST)/bin
-
-
-symbols:
- @echo "CSRCS = $(CSRCS)"
- @echo "INCS = $(INCS)"
- @echo "OBJS = $(OBJS)"
- @echo "LIBRARY = $(LIBRARY)"
- @echo "PROGRAM = $(PROGRAM)"
- @echo "TARGETS = $(TARGETS)"
- @echo "DIST = $(DIST)"
- @echo "VERSION_NUMBER = $(VERSION_NUMBER)"
- @echo "WINFE = $(WINFE)"
- @echo "DBM_LIB = $(DBM_LIB)"
- @echo "INSTALL = $(INSTALL)"
-
diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c
index 2e0cdbcd9..f4e337a48 100644
--- a/security/nss/cmd/tstclnt/tstclnt.c
+++ b/security/nss/cmd/tstclnt/tstclnt.c
@@ -108,14 +108,14 @@ int ssl2CipherSuites[] = {
};
int ssl3CipherSuites[] = {
- SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* a */
- SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, /* b */
+ -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
+ -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, * b */
SSL_RSA_WITH_RC4_128_MD5, /* c */
SSL_RSA_WITH_3DES_EDE_CBC_SHA, /* d */
SSL_RSA_WITH_DES_CBC_SHA, /* e */
SSL_RSA_EXPORT_WITH_RC4_40_MD5, /* f */
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */
- SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* h */
+ -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA, * h */
SSL_RSA_WITH_NULL_MD5, /* i */
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */
SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */
@@ -214,7 +214,7 @@ handshakeCallback(PRFileDesc *fd, void *client_data)
static void Usage(const char *progName)
{
fprintf(stderr,
-"Usage: %s -h host [-p port] [-d certdir] [-n nickname] [-23Tfovx] \n"
+"Usage: %s -h host [-p port] [-d certdir] [-n nickname] [-23BTfosvx] \n"
" [-c ciphers] [-w passwd] [-q]\n", progName);
fprintf(stderr, "%-20s Hostname to connect with\n", "-h host");
fprintf(stderr, "%-20s Port number for SSL server\n", "-p port");
@@ -223,11 +223,14 @@ static void Usage(const char *progName)
"-d certdir");
fprintf(stderr, "%-20s Nickname of key and cert for client auth\n",
"-n nickname");
+ fprintf(stderr,
+ "%-20s Bypass PKCS11 layer for SSL encryption and MACing.\n", "-B");
fprintf(stderr, "%-20s Disable SSL v2.\n", "-2");
fprintf(stderr, "%-20s Disable SSL v3.\n", "-3");
fprintf(stderr, "%-20s Disable TLS (SSL v3.1).\n", "-T");
fprintf(stderr, "%-20s Client speaks first. \n", "-f");
fprintf(stderr, "%-20s Override bad server cert. Make it OK.\n", "-o");
+ fprintf(stderr, "%-20s Disable SSL socket locking.\n", "-s");
fprintf(stderr, "%-20s Verbose progress reporting.\n", "-v");
fprintf(stderr, "%-20s Use export policy.\n", "-x");
fprintf(stderr, "%-20s Ping the server and then exit.\n", "-q");
@@ -257,14 +260,11 @@ static void Usage(const char *progName)
"T TLS ECDHE RSA WITH AES 128 CBC SHA\n"
#endif /* NSS_ENABLE_ECC */
"\n"
-"a SSL3 FORTEZZA DMS WITH FORTEZZA CBC SHA\n"
-"b SSL3 FORTEZZA DMS WITH RC4 128 SHA\n"
"c SSL3 RSA WITH RC4 128 MD5\n"
"d SSL3 RSA WITH 3DES EDE CBC SHA\n"
"e SSL3 RSA WITH DES CBC SHA\n"
"f SSL3 RSA EXPORT WITH RC4 40 MD5\n"
"g SSL3 RSA EXPORT WITH RC2 CBC 40 MD5\n"
-"h SSL3 FORTEZZA DMS WITH NULL SHA\n"
"i SSL3 RSA WITH NULL MD5\n"
"j SSL3 RSA FIPS WITH 3DES EDE CBC SHA\n"
"k SSL3 RSA FIPS WITH DES CBC SHA\n"
@@ -451,6 +451,8 @@ int main(int argc, char **argv)
int disableSSL2 = 0;
int disableSSL3 = 0;
int disableTLS = 0;
+ int bypassPKCS11 = 0;
+ int disableLocking = 0;
int useExportPolicy = 0;
PRSocketOptionData opt;
PRNetAddr addr;
@@ -469,7 +471,7 @@ int main(int argc, char **argv)
progName = strrchr(argv[0], '\\');
progName = progName ? progName+1 : argv[0];
- optstate = PL_CreateOptState(argc, argv, "23Tfc:h:p:d:m:n:oqvw:x");
+ optstate = PL_CreateOptState(argc, argv, "23BTfc:h:p:d:m:n:oqsvw:x");
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case '?':
@@ -479,6 +481,8 @@ int main(int argc, char **argv)
case '3': disableSSL3 = 1; break;
+ case 'B': bypassPKCS11 = 1; break;
+
case 'T': disableTLS = 1; break;
case 'c': cipherString = strdup(optstate->value); break;
@@ -506,6 +510,8 @@ int main(int argc, char **argv)
case 'q': pingServerFirst = PR_TRUE; break;
+ case 's': disableLocking = 1; break;
+
case 'v': verbose++; break;
case 'w':
@@ -672,7 +678,7 @@ int main(int argc, char **argv)
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
/* do nothing */;
- if (cipher) {
+ if (cipher > 0) {
SECStatus status;
status = SSL_CipherPrefSet(s, cipher, SSL_ALLOWED);
if (status != SECSuccess)
@@ -706,6 +712,21 @@ int main(int argc, char **argv)
return 1;
}
+ /* enable PKCS11 bypass */
+ rv = SSL_OptionSet(s, SSL_BYPASS_PKCS11, bypassPKCS11);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "error enabling PKCS11 bypass");
+ return 1;
+ }
+
+ /* disable SSL socket locking */
+ rv = SSL_OptionSet(s, SSL_NO_LOCKS, disableLocking);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "error disabling SSL socket locking");
+ return 1;
+ }
+
+
if (useCommandLinePassword) {
SSL_SetPKCS11PinArg(s, password);
}
diff --git a/security/nss/cmd/vfyserv/makefile.win b/security/nss/cmd/vfyserv/makefile.win
deleted file mode 100644
index 7f0fdcf04..000000000
--- a/security/nss/cmd/vfyserv/makefile.win
+++ /dev/null
@@ -1,134 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-VERBOSE = 1
-include <manifest.mn>
-
-#cannot define PROGRAM in manifest compatibly with NT and UNIX
-PROGRAM = tstclnt
-PROGRAM = ./$(OBJDIR)/$(PROGRAM).exe
-include <$(DEPTH)\config\config.mak>
-
-# let manifest generate C_OBJS, it will prepend ./$(OBJDIR)/
-# rules.mak will append C_OBJS onto OBJS.
-# OBJS = $(CSRCS:.c=.obj)
-
-# include files are looked for in $LINCS and $INCS.
-# $LINCS is in manifest.mnw, computed from REQUIRES=
-INCS = $(INCS) \
- -I$(DEPTH)/security/lib/cert \
- -I../include \
- $(NULL)
-
-IGNORE_ME = \
- -I$(DEPTH)/security/lib/key \
- -I$(DEPTH)/security/lib/util \
- $(NULL)
-
-
-WINFE = $(DEPTH)/cmd/winfe/mkfiles$(MOZ_BITS)/x86Dbg
-
-# these files are the content of libdbm
-DBM_LIB = \
- $(WINFE)/DB.obj \
- $(WINFE)/HASH.obj \
- $(WINFE)/H_BIGKEY.obj \
- $(WINFE)/H_PAGE.obj \
- $(WINFE)/H_LOG2.obj \
- $(WINFE)/H_FUNC.obj \
- $(WINFE)/HASH_BUF.obj \
- $(NULL)
-
-MOZ_LIBS = \
- $(WINFE)/ALLXPSTR.obj \
- $(WINFE)/XP_ERROR.obj \
- $(WINFE)/XPASSERT.obj \
- $(WINFE)/XP_REG.obj \
- $(WINFE)/XP_TRACE.obj \
- $(DBM_LIB) \
- $(WINFE)/XP_STR.obj \
- $(WINFE)/MKTEMP.obj \
- $(NULL)
-
-SEC_LIBS = \
- $(DIST)/lib/cert$(MOZ_BITS).lib \
- $(DIST)/lib/crypto$(MOZ_BITS).lib \
- $(DIST)/lib/hash$(MOZ_BITS).lib \
- $(DIST)/lib/key$(MOZ_BITS).lib \
- $(DIST)/lib/pkcs7$(MOZ_BITS).lib \
- $(DIST)/lib/secmod$(MOZ_BITS).lib \
- $(DIST)/lib/secutl$(MOZ_BITS).lib \
- $(DIST)/lib/ssl$(MOZ_BITS).lib \
- $(NULL)
-
-LLFLAGS = $(LLFLAGS) \
- ../lib/$(OBJDIR)/sectool$(MOZ_BITS).lib \
- $(SEC_LIBS) \
- $(MOZ_LIBS) \
- $(DEPTH)/nspr/src/$(OBJDIR)/getopt.obj \
- $(LIBNSPR) \
- $(NULL)
-
-
-include <$(DEPTH)\config\rules.mak>
-
-INSTALL = $(MAKE_INSTALL)
-
-objs: $(OBJS)
-
-$(PROGRAM)::
- $(INSTALL) $(DIST)/bin/pr3240.dll ./$(OBJDIR)
-
-programs: $(PROGRAM)
-
-install:: $(TARGETS)
- $(INSTALL) $(TARGETS) $(DIST)/bin
-
-
-symbols:
- @echo "CSRCS = $(CSRCS)"
- @echo "INCS = $(INCS)"
- @echo "OBJS = $(OBJS)"
- @echo "LIBRARY = $(LIBRARY)"
- @echo "PROGRAM = $(PROGRAM)"
- @echo "TARGETS = $(TARGETS)"
- @echo "DIST = $(DIST)"
- @echo "VERSION_NUMBER = $(VERSION_NUMBER)"
- @echo "WINFE = $(WINFE)"
- @echo "DBM_LIB = $(DBM_LIB)"
- @echo "INSTALL = $(INSTALL)"
-
diff --git a/security/nss/cmd/vfyserv/vfyserv.c b/security/nss/cmd/vfyserv/vfyserv.c
index f1fd23825..4c31e4c70 100644
--- a/security/nss/cmd/vfyserv/vfyserv.c
+++ b/security/nss/cmd/vfyserv/vfyserv.c
@@ -444,7 +444,7 @@ main(int argc, char **argv)
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
/* do nothing */;
- if (cipher) {
+ if (cipher > 0) {
SSL_CipherPrefSetDefault(cipher, PR_TRUE);
}
}
diff --git a/security/nss/cmd/vfyserv/vfyutil.c b/security/nss/cmd/vfyserv/vfyutil.c
index b1d282f64..4741a22ad 100644
--- a/security/nss/cmd/vfyserv/vfyutil.c
+++ b/security/nss/cmd/vfyserv/vfyutil.c
@@ -53,14 +53,14 @@ int ssl2CipherSuites[] = {
};
int ssl3CipherSuites[] = {
- SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* a */
- SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, /* b */
+ -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
+ -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, * b */
SSL_RSA_WITH_RC4_128_MD5, /* c */
SSL_RSA_WITH_3DES_EDE_CBC_SHA, /* d */
SSL_RSA_WITH_DES_CBC_SHA, /* e */
SSL_RSA_EXPORT_WITH_RC4_40_MD5, /* f */
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */
- SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* h */
+ -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA, * h */
SSL_RSA_WITH_NULL_MD5, /* i */
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */
SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */
diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c
index d7742d83c..9c5c22f31 100644
--- a/security/nss/lib/certdb/certdb.c
+++ b/security/nss/lib/certdb/certdb.c
@@ -545,6 +545,7 @@ cert_GetCertType(CERTCertificate *cert)
tmpitem.data = NULL;
CERT_FindNSCertTypeExtension(cert, &tmpitem);
+ encodedExtKeyUsage.data = NULL;
rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE,
&encodedExtKeyUsage);
if (rv == SECSuccess) {
@@ -671,8 +672,10 @@ cert_GetCertType(CERTCertificate *cert)
}
}
- if (extKeyUsage != NULL) {
+ if (encodedExtKeyUsage.data != NULL) {
PORT_Free(encodedExtKeyUsage.data);
+ }
+ if (extKeyUsage != NULL) {
CERT_DestroyOidSequence(extKeyUsage);
}
/* Assert that it is safe to cast &cert->nsCertType to "PRInt32 *" */
@@ -1910,6 +1913,45 @@ CERT_IsRootDERCert(SECItem *derCert)
return isRoot;
}
+CERTCompareValidityStatus
+CERT_CompareValidityTimes(CERTValidity* val_a, CERTValidity* val_b)
+{
+ PRTime notBeforeA, notBeforeB, notAfterA, notAfterB;
+
+ if (!val_a || !val_b)
+ {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return certValidityUndetermined;
+ }
+
+ if ( SECSuccess != DER_DecodeTimeChoice(&notBeforeA, &val_a->notBefore) ||
+ SECSuccess != DER_DecodeTimeChoice(&notBeforeB, &val_b->notBefore) ||
+ SECSuccess != DER_DecodeTimeChoice(&notAfterA, &val_a->notAfter) ||
+ SECSuccess != DER_DecodeTimeChoice(&notAfterB, &val_b->notAfter) ) {
+ return certValidityUndetermined;
+ }
+
+ /* sanity check */
+ if (LL_CMP(notBeforeA,>,notAfterA) || LL_CMP(notBeforeB,>,notAfterB)) {
+ PORT_SetError(SEC_ERROR_INVALID_TIME);
+ return certValidityUndetermined;
+ }
+
+ if (LL_CMP(notAfterA,!=,notAfterB)) {
+ /* one cert validity goes farther into the future, select it */
+ return LL_CMP(notAfterA,<,notAfterB) ?
+ certValidityChooseB : certValidityChooseA;
+ }
+ /* the two certs have the same expiration date */
+ PORT_Assert(LL_CMP(notAfterA, == , notAfterB));
+ /* do they also have the same start date ? */
+ if (LL_CMP(notBeforeA,==,notBeforeB)) {
+ return certValidityEqual;
+ }
+ /* choose cert with the later start date */
+ return LL_CMP(notBeforeA,<,notBeforeB) ?
+ certValidityChooseB : certValidityChooseA;
+}
/*
* is certa newer than certb? If one is expired, pick the other one.
diff --git a/security/nss/lib/certdb/certdb.h b/security/nss/lib/certdb/certdb.h
index b24d470c4..f81fa93a7 100644
--- a/security/nss/lib/certdb/certdb.h
+++ b/security/nss/lib/certdb/certdb.h
@@ -157,6 +157,13 @@ SEC_CheckCRL(PCERTCertDBHandle *handle,PCERTCertificate *cert,
SECStatus
SEC_CrlReplaceUrl(PCERTSignedCrl *crl,char *url);
+
+/* Compare two certificate validity structures and return which cert should be
+** preferred, based first on newer notAfter, then on newer notBefore.
+*/
+CERTCompareValidityStatus
+CERT_CompareValidityTimes(CERTValidity* val_a, CERTValidity* val_b);
+
#endif
SEC_END_PROTOS
diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h
index a513092c6..8567ebbe4 100644
--- a/security/nss/lib/certdb/certt.h
+++ b/security/nss/lib/certdb/certt.h
@@ -523,6 +523,21 @@ typedef enum SECCertTimeValidityEnum {
} SECCertTimeValidity;
/*
+ * This is used as return status in functions that compare the validity
+ * periods of two certificates A and B, currently only
+ * CERT_CompareValidityTimes.
+ */
+
+typedef enum CERTCompareValidityStatusEnum
+{
+ certValidityUndetermined = 0, /* the function is unable to select one cert
+ over another */
+ certValidityChooseB = 1, /* cert B should be preferred */
+ certValidityEqual = 2, /* both certs have the same validity period */
+ certValidityChooseA = 3 /* cert A should be preferred */
+} CERTCompareValidityStatus;
+
+/*
* Interface for getting certificate nickname strings out of the database
*/
diff --git a/security/nss/lib/certdb/genname.c b/security/nss/lib/certdb/genname.c
index 9c8d1a801..a5ac86e75 100644
--- a/security/nss/lib/certdb/genname.c
+++ b/security/nss/lib/certdb/genname.c
@@ -1462,6 +1462,7 @@ CERT_CompareNameSpace(CERTCertificate *cert,
CERTNameConstraint *matchingConstraints;
CERTCertificate *badCert = NULL;
+ constraintsExtension.data = NULL;
rv = CERT_FindCertExtension(cert, SEC_OID_X509_NAME_CONSTRAINTS,
&constraintsExtension);
if (rv != SECSuccess) {
@@ -1474,6 +1475,7 @@ CERT_CompareNameSpace(CERTCertificate *cert,
}
/* TODO: mark arena */
constraints = cert_DecodeNameConstraints(arena, &constraintsExtension);
+ PORT_Free(constraintsExtension.data);
currentName = namesList;
if (constraints == NULL) { /* decode failed */
rv = SECFailure;
diff --git a/security/nss/lib/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c
index 56e9695cd..2c0ffe7cb 100644
--- a/security/nss/lib/certhigh/certhigh.c
+++ b/security/nss/lib/certhigh/certhigh.c
@@ -743,6 +743,7 @@ CERT_FindCRLDistributionPoints (CERTCertificate *cert)
{
SECItem encodedExtenValue;
SECStatus rv;
+ CERTCrlDistributionPoints *dps;
encodedExtenValue.data = NULL;
encodedExtenValue.len = 0;
@@ -753,8 +754,11 @@ CERT_FindCRLDistributionPoints (CERTCertificate *cert)
return (NULL);
}
- return (CERT_DecodeCRLDistributionPoints (cert->arena,
- &encodedExtenValue));
+ dps = CERT_DecodeCRLDistributionPoints(cert->arena, &encodedExtenValue);
+
+ PORT_Free(encodedExtenValue.data);
+
+ return dps;
}
/* From crl.c */
diff --git a/security/nss/lib/certhigh/certhtml.c b/security/nss/lib/certhigh/certhtml.c
index f5ca082f8..11ce4f6c8 100644
--- a/security/nss/lib/certhigh/certhtml.c
+++ b/security/nss/lib/certhigh/certhtml.c
@@ -407,7 +407,6 @@ CERT_HTMLCertInfo(CERTCertificate *cert, PRBool showImages, PRBool showIssuer)
char *notBefore, *notAfter;
char *ret;
char *nickname;
- SECItem dummyitem;
unsigned char fingerprint[16]; /* result of MD5, always 16 bytes */
char *fpstr;
SECItem fpitem;
@@ -435,12 +434,8 @@ CERT_HTMLCertInfo(CERTCertificate *cert, PRBool showImages, PRBool showIssuer)
showImages = PR_FALSE;
}
- dummyitem.data = NULL;
rv = CERT_FindCertExtension(cert, SEC_OID_NS_CERT_EXT_SUBJECT_LOGO,
- &dummyitem);
- if ( dummyitem.data ) {
- PORT_Free(dummyitem.data);
- }
+ NULL);
if ( rv || !showImages ) {
htmlcertstrings[1] = "";
@@ -468,13 +463,8 @@ CERT_HTMLCertInfo(CERTCertificate *cert, PRBool showImages, PRBool showIssuer)
htmlcertstrings[5] = subject;
- dummyitem.data = NULL;
-
rv = CERT_FindCertExtension(cert, SEC_OID_NS_CERT_EXT_ISSUER_LOGO,
- &dummyitem);
- if ( dummyitem.data ) {
- PORT_Free(dummyitem.data);
- }
+ NULL);
if ( rv || !showImages ) {
htmlcertstrings[7] = "";
@@ -500,6 +490,7 @@ CERT_HTMLCertInfo(CERTCertificate *cert, PRBool showImages, PRBool showIssuer)
pubk = CERT_ExtractPublicKey(cert);
DSSPriv = NULL;
if (pubk && (pubk->keyType == fortezzaKey)) {
+ SECItem dummyitem;
htmlcertstrings[18] = "</b><br><b>Clearance:</b>";
htmlcertstrings[19] = sec_FortezzaClearance(
&pubk->u.fortezza.clearance);
diff --git a/security/nss/lib/certhigh/certreq.c b/security/nss/lib/certhigh/certreq.c
index 924067780..148b71746 100644
--- a/security/nss/lib/certhigh/certreq.c
+++ b/security/nss/lib/certhigh/certreq.c
@@ -126,6 +126,23 @@ CERT_CreateCertificate(unsigned long serialNumber,
}
/************************************************************************/
+/* It's clear from the comments that the original author of this
+ * function expected the template for certificate requests to treat
+ * the attributes as a SET OF ANY. This function expected to be
+ * passed an array of SECItems each of which contained an already encoded
+ * Attribute. But the cert request template does not treat the
+ * Attributes as a SET OF ANY, and AFAIK never has. Instead the template
+ * encodes attributes as a SET OF xxxxxxx. That is, it expects to encode
+ * each of the Attributes, not have them pre-encoded. Consequently an
+ * array of SECItems containing encoded Attributes is of no value to this
+ * function. But we cannot change the signature of this public function.
+ * It must continue to take SECItems.
+ *
+ * I have recoded this function so that each SECItem contains an
+ * encoded cert extension. The encoded cert extensions form the list for the
+ * single attribute of the cert request. In this implementation there is at most
+ * one attribute and it is always of type SEC_OID_PKCS9_EXTENSION_REQUEST.
+ */
CERTCertificateRequest *
CERT_CreateCertificateRequest(CERTName *subject,
@@ -134,88 +151,94 @@ CERT_CreateCertificateRequest(CERTName *subject,
{
CERTCertificateRequest *certreq;
PRArenaPool *arena;
+ CERTAttribute * attribute;
+ SECOidData * oidData;
SECStatus rv;
+ int i = 0;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( arena == NULL ) {
return NULL;
}
- certreq = (CERTCertificateRequest *)
- PORT_ArenaZAlloc(arena, sizeof(CERTCertificateRequest));
-
- if (certreq != NULL) {
- certreq->arena = arena;
-
- rv = DER_SetUInteger(arena, &certreq->version,
- SEC_CERTIFICATE_REQUEST_VERSION);
- if (rv != SECSuccess)
- goto loser;
-
- rv = CERT_CopyName(arena, &certreq->subject, subject);
- if (rv != SECSuccess)
- goto loser;
+ certreq = PORT_ArenaZNew(arena, CERTCertificateRequest);
+ if (!certreq) {
+ PORT_FreeArena(arena, PR_FALSE);
+ return NULL;
+ }
+ /* below here it is safe to goto loser */
- rv = SECKEY_CopySubjectPublicKeyInfo(arena,
- &certreq->subjectPublicKeyInfo,
- spki);
- if (rv != SECSuccess)
+ certreq->arena = arena;
+
+ rv = DER_SetUInteger(arena, &certreq->version,
+ SEC_CERTIFICATE_REQUEST_VERSION);
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = CERT_CopyName(arena, &certreq->subject, subject);
+ if (rv != SECSuccess)
+ goto loser;
+
+ rv = SECKEY_CopySubjectPublicKeyInfo(arena,
+ &certreq->subjectPublicKeyInfo,
+ spki);
+ if (rv != SECSuccess)
+ goto loser;
+
+ certreq->attributes = PORT_ArenaZNewArray(arena, CERTAttribute*, 2);
+ if(!certreq->attributes)
+ goto loser;
+
+ /* Copy over attribute information */
+ if (!attributes || !attributes[0]) {
+ /*
+ ** Invent empty attribute information. According to the
+ ** pkcs#10 spec, attributes has this ASN.1 type:
+ **
+ ** attributes [0] IMPLICIT Attributes
+ **
+ ** Which means, we should create a NULL terminated list
+ ** with the first entry being NULL;
+ */
+ certreq->attributes[0] = NULL;
+ return certreq;
+ }
+
+ /* allocate space for attributes */
+ attribute = PORT_ArenaZNew(arena, CERTAttribute);
+ if (!attribute)
+ goto loser;
+
+ oidData = SECOID_FindOIDByTag( SEC_OID_PKCS9_EXTENSION_REQUEST );
+ PORT_Assert(oidData);
+ if (!oidData)
+ goto loser;
+ rv = SECITEM_CopyItem(arena, &attribute->attrType, &oidData->oid);
+ if (rv != SECSuccess)
+ goto loser;
+
+ for (i = 0; attributes[i] != NULL ; i++)
+ ;
+ attribute->attrValue = PORT_ArenaZNewArray(arena, SECItem *, i+1);
+ if (!attribute->attrValue)
+ goto loser;
+
+ /* copy attributes */
+ for (i = 0; attributes[i]; i++) {
+ /*
+ ** Attributes are a SetOf Attribute which implies
+ ** lexigraphical ordering. It is assumes that the
+ ** attributes are passed in sorted. If we need to
+ ** add functionality to sort them, there is an
+ ** example in the PKCS 7 code.
+ */
+ attribute->attrValue[i] = SECITEM_ArenaDupItem(arena, attributes[i]);
+ if(!attribute->attrValue[i])
goto loser;
-
- /* Copy over attribute information */
- if (attributes) {
- int i = 0;
-
- /* allocate space for attributes */
- while(attributes[i] != NULL) i++;
- certreq->attributes = PORT_ArenaZNewArray(arena,CERTAttribute*,i+1);
- if(!certreq->attributes) {
- goto loser;
- }
-
- /* copy attributes */
- i = 0;
- while(attributes[i]) {
- /*
- ** Attributes are a SetOf Attribute which implies
- ** lexigraphical ordering. It is assumes that the
- ** attributes are passed in sorted. If we need to
- ** add functionality to sort them, there is an
- ** example in the PKCS 7 code.
- */
- certreq->attributes[i] = (SECItem*)PORT_ArenaZAlloc(arena,
- sizeof(SECItem));
- if(!certreq->attributes[i]) {
- goto loser;
- };
- rv = SECITEM_CopyItem(arena, certreq->attributes[i],
- attributes[i]);
- if (rv != SECSuccess) {
- goto loser;
- }
- i++;
- }
- certreq->attributes[i] = NULL;
- } else {
- /*
- ** Invent empty attribute information. According to the
- ** pkcs#10 spec, attributes has this ASN.1 type:
- **
- ** attributes [0] IMPLICIT Attributes
- **
- ** Which means, we should create a NULL terminated list
- ** with the first entry being NULL;
- */
- certreq->attributes = (SECItem**)PORT_ArenaZAlloc(arena, sizeof(SECItem *));
- if(!certreq->attributes) {
- goto loser;
- }
- certreq->attributes[0] = NULL;
- }
- } else {
- PORT_FreeArena(arena, PR_FALSE);
}
+ certreq->attributes[0] = attribute;
+
return certreq;
loser:
diff --git a/security/nss/lib/certhigh/crlv2.c b/security/nss/lib/certhigh/crlv2.c
index 3e9e0e44e..b6d8c9182 100644
--- a/security/nss/lib/certhigh/crlv2.c
+++ b/security/nss/lib/certhigh/crlv2.c
@@ -133,9 +133,8 @@ SECStatus CERT_FindInvalidDateExten (CERTCrl *crl, int64 *value)
rv = SEC_ASN1DecodeItem (NULL, &decodedExtenValue,
SEC_GeneralizedTimeTemplate, &encodedExtenValue);
- if (rv != SECSuccess)
- return (rv);
- rv = DER_GeneralizedTimeToTime(value, &encodedExtenValue);
+ if (rv == SECSuccess)
+ rv = DER_GeneralizedTimeToTime(value, &encodedExtenValue);
PORT_Free (decodedExtenValue.data);
PORT_Free (encodedExtenValue.data);
return (rv);
diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c
index 54fa8ca24..9eda390b4 100644
--- a/security/nss/lib/certhigh/ocsp.c
+++ b/security/nss/lib/certhigh/ocsp.c
@@ -2296,14 +2296,9 @@ static PRBool
ocsp_CertHasNoCheckExtension(CERTCertificate *cert)
{
SECStatus rv;
- SECItem extItem;
- extItem.data = NULL;
rv = CERT_FindCertExtension(cert, SEC_OID_PKIX_OCSP_NO_CHECK,
- &extItem);
- if (extItem.data != NULL) {
- PORT_Free(extItem.data);
- }
+ NULL);
if (rv == SECSuccess) {
return PR_TRUE;
}
diff --git a/security/nss/lib/ckfw/builtins/Makefile b/security/nss/lib/ckfw/builtins/Makefile
index 6301cae8b..d1410119c 100644
--- a/security/nss/lib/ckfw/builtins/Makefile
+++ b/security/nss/lib/ckfw/builtins/Makefile
@@ -48,34 +48,31 @@ EXTRA_LIBS = \
# can't do this in manifest.mn because OS_TARGET isn't defined there.
ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-# Link with the real NSPR DLLs for MinGW because the NSPR stubs in
-# nsprstub.c can't resolve the references to the _imp__PR_XXX symbols.
-# This is merely an expedient hack and not the right solution.
ifdef NS_USE_GCC
EXTRA_LIBS += \
- -L$(DIST)/lib \
+ -L$(NSPR_LIB_DIR) \
-lplc4 \
-lplds4 \
-lnspr4 \
$(NULL)
-else
-EXTRA_LIBS += \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4_s.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4_s.lib \
- $(NULL)
-endif
-
+else
+EXTRA_SHARED_LIBS += \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
+ $(NULL)
+endif # NS_USE_GCC
else
EXTRA_LIBS += \
- $(DIST)/lib/$(LIB_PREFIX)plc4.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)plds4.$(LIB_SUFFIX) \
+ -L$(NSPR_LIB_DIR) \
+ -lplc4 \
+ -lplds4 \
+ -lnspr4 \
$(NULL)
-
endif
-
include $(CORE_DEPTH)/coreconf/rules.mk
# Generate certdata.c.
diff --git a/security/nss/lib/ckfw/builtins/nssckbi.h b/security/nss/lib/ckfw/builtins/nssckbi.h
index 951aa4365..b0378eea9 100644
--- a/security/nss/lib/ckfw/builtins/nssckbi.h
+++ b/security/nss/lib/ckfw/builtins/nssckbi.h
@@ -48,7 +48,7 @@
* to the PKCS #11 spec versions.
*/
#define NSS_BUILTINS_CRYPTOKI_VERSION_MAJOR 2
-#define NSS_BUILTINS_CRYPTOKI_VERSION_MINOR 1
+#define NSS_BUILTINS_CRYPTOKI_VERSION_MINOR 20
/* These version numbers detail the changes
* to the list of trusted certificates.
@@ -64,6 +64,7 @@
* - NSS 3.8 branch: 30-39
* - NSS 3.9 branch: 40-49
* - NSS 3.10 branch: 50-59
+ * - NSS 3.11 branch: 60-69
* ...
* - NSS 3.14 branch: 90-99
* ...
@@ -74,8 +75,8 @@
* of the comment in the CK_VERSION type definition.
*/
#define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 1
-#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 53
-#define NSS_BUILTINS_LIBRARY_VERSION "1.53"
+#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 60
+#define NSS_BUILTINS_LIBRARY_VERSION "1.60"
/* These version numbers detail the semantic changes to the ckfw engine. */
#define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1
diff --git a/security/nss/cmd/modutil/config.mk b/security/nss/lib/ckfw/capi/Makefile
index 3c94aa306..77afe8097 100644
--- a/security/nss/cmd/modutil/config.mk
+++ b/security/nss/lib/ckfw/capi/Makefile
@@ -34,48 +34,72 @@
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
+MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-#######################################################################
-# Set the LDFLAGS value to encompass all normal link options, all #
-# library names, and all special system linking options #
-#######################################################################
-
-LDFLAGS = \
- $(DYNAMIC_LIB_PATH) \
- $(LDOPTS) \
- $(LIBSECTOOLS) \
- $(LIBSECMOD) \
- $(LIBHASH) \
- $(LIBCERT) \
- $(LIBKEY) \
- $(LIBCRYPTO) \
- $(LIBSECUTIL) \
- $(LIBDBM) \
- $(LIBPLC3) \
- $(LIBPLDS3) \
- $(LIBPR3) \
- $(DLLSYSTEM) \
- $(LIBJAR) \
- $(LIBZLIB) \
- $(LIBPKCS7) \
- $(LIBPLC3)
-
-# Strip out the symbols
-ifdef BUILD_OPT
- ifneq (,$(filter-out WIN%,$(OS_TARGET)))
- LDFLAGS += -s
- endif
-endif
+include manifest.mn
+include $(CORE_DEPTH)/coreconf/config.mk
+include config.mk
-#######################################################################
-# Adjust specific variables for all platforms #
-#######################################################################
-
+EXTRA_LIBS = \
+ $(DIST)/lib/$(LIB_PREFIX)nssckfw.$(LIB_SUFFIX) \
+ $(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
+ $(NULL)
+# can't do this in manifest.mn because OS_TARGET isn't defined there.
ifeq (,$(filter-out WIN%,$(OS_TARGET)))
- PACKAGE_FILES = license.txt README.TXT specification.html pk11jar.html modutil.exe
+
+ifdef NS_USE_GCC
+EXTRA_LIBS += \
+ -L$(NSPR_LIB_DIR) \
+ -lplc4 \
+ -lplds4 \
+ -lnspr4 \
+ $(NULL)
+else
+EXTRA_SHARED_LIBS += \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
+ crypt32.lib \
+ advapi32.lib \
+ rpcrt4.lib \
+ $(NULL)
+endif # NS_USE_GCC
else
- PACKAGE_FILES = license.doc README specification.html pk11jar.html modutil
+
+EXTRA_LIBS += \
+ -L$(NSPR_LIB_DIR) \
+ -lplc4 \
+ -lplds4 \
+ -lnspr4 \
+ $(NULL)
+endif
+
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+# Generate certdata.c.
+generate:
+ perl certdata.perl < certdata.txt
+
+# This'll need some help from a build person.
+
+
+ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.1)
+DSO_LDOPTS = -bM:SRE -bh:4 -bnoentry
+EXTRA_DSO_LDOPTS = -lc
+MKSHLIB = xlC $(DSO_LDOPTS)
+
+$(SHARED_LIBRARY): $(OBJS)
+ @$(MAKE_OBJDIR)
+ rm -f $@
+ $(MKSHLIB) -o $@ $(OBJS) $(EXTRA_LIBS) $(EXTRA_DSO_LDOPTS)
+ chmod +x $@
+
endif
-ARCHIVE_NAME = modutil_$(OS_TARGET)$(OS_RELEASE)
+ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.2)
+LD += -G
+endif
+
+
diff --git a/security/nss/lib/ckfw/capi/README b/security/nss/lib/ckfw/capi/README
new file mode 100644
index 000000000..9fc5720a9
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/README
@@ -0,0 +1,7 @@
+This Cryptoki module provides acces to certs and keys stored in
+Microsofts CAPI certificate store.
+
+It does not import or export CA Root trust from the CAPI.
+It does not import or export CRLs from the CAPI.
+It does not handle S/MIME objects (pkcs #7 in capi terms?).
+It does not yet handle it's own PIN. (CAPI does all the pin prompting).
diff --git a/security/nss/lib/ckfw/capi/anchor.c b/security/nss/lib/ckfw/capi/anchor.c
new file mode 100644
index 000000000..e21006621
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/anchor.c
@@ -0,0 +1,55 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
+ *
+ * Contributor(s):
+ * Bob Relyea (rrelyea@redhat.com)
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
+#endif /* DEBUG */
+
+/*
+ * capi/canchor.c
+ *
+ * This file "anchors" the actual cryptoki entry points in this module's
+ * shared library, which is required for dynamic loading. See the
+ * comments in nssck.api for more information.
+ */
+
+#include "ckcapi.h"
+
+#define MODULE_NAME ckcapi
+#define INSTANCE_NAME (NSSCKMDInstance *)&nss_ckcapi_mdInstance
+#include "nssck.api"
diff --git a/security/nss/lib/ckfw/capi/cfind.c b/security/nss/lib/ckfw/capi/cfind.c
new file mode 100644
index 000000000..b685c0888
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/cfind.c
@@ -0,0 +1,595 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
+ *
+ * Contributor(s):
+ * Bob Relyea (rrelyea@redhat.com)
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
+#endif /* DEBUG */
+
+#ifndef CKCAPI_H
+#include "ckcapi.h"
+#endif /* CKCAPI_H */
+
+/*
+ * ckcapi/cfind.c
+ *
+ * This file implements the NSSCKMDFindObjects object for the
+ * "capi" cryptoki module.
+ */
+
+struct ckcapiFOStr {
+ NSSArena *arena;
+ CK_ULONG n;
+ CK_ULONG i;
+ ckcapiInternalObject **objs;
+};
+
+static void
+ckcapi_mdFindObjects_Final
+(
+ NSSCKMDFindObjects *mdFindObjects,
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ struct ckcapiFOStr *fo = (struct ckcapiFOStr *)mdFindObjects->etc;
+ NSSArena *arena = fo->arena;
+ PRUint32 i;
+
+ /* walk down an free the unused 'objs' */
+ for (i=fo->i; i < fo->n ; i++) {
+ nss_ckcapi_DestroyInternalObject(fo->objs[i]);
+ }
+
+ nss_ZFreeIf(fo->objs);
+ nss_ZFreeIf(fo);
+ nss_ZFreeIf(mdFindObjects);
+ if ((NSSArena *)NULL != arena) {
+ NSSArena_Destroy(arena);
+ }
+
+ return;
+}
+
+static NSSCKMDObject *
+ckcapi_mdFindObjects_Next
+(
+ NSSCKMDFindObjects *mdFindObjects,
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError
+)
+{
+ struct ckcapiFOStr *fo = (struct ckcapiFOStr *)mdFindObjects->etc;
+ ckcapiInternalObject *io;
+
+ if( fo->i == fo->n ) {
+ *pError = CKR_OK;
+ return (NSSCKMDObject *)NULL;
+ }
+
+ io = fo->objs[ fo->i ];
+ fo->i++;
+
+ return nss_ckcapi_CreateMDObject(arena, io, pError);
+}
+
+static CK_BBOOL
+ckcapi_attrmatch
+(
+ CK_ATTRIBUTE_PTR a,
+ ckcapiInternalObject *o
+)
+{
+ PRBool prb;
+ const NSSItem *b;
+
+ b = nss_ckcapi_FetchAttribute(o, a->type);
+ if (b == NULL) {
+ return CK_FALSE;
+ }
+
+ if( a->ulValueLen != b->size ) {
+ /* match a decoded serial number */
+ if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
+ int len;
+ unsigned char *data;
+
+ data = nss_ckcapi_DERUnwrap(b->data, b->size, &len, NULL);
+ if ((len == a->ulValueLen) &&
+ nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
+ return CK_TRUE;
+ }
+ }
+ return CK_FALSE;
+ }
+
+ prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
+
+ if( PR_TRUE == prb ) {
+ return CK_TRUE;
+ } else {
+ return CK_FALSE;
+ }
+}
+
+
+static CK_BBOOL
+ckcapi_match
+(
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ ckcapiInternalObject *o
+)
+{
+ CK_ULONG i;
+
+ for( i = 0; i < ulAttributeCount; i++ ) {
+ if (CK_FALSE == ckcapi_attrmatch(&pTemplate[i], o)) {
+ return CK_FALSE;
+ }
+ }
+
+ /* Every attribute passed */
+ return CK_TRUE;
+}
+
+#define CKAPI_ITEM_CHUNK 20
+
+#define PUT_Object(obj,err) \
+ { \
+ if (count >= size) { \
+ *listp = *listp ? \
+ nss_ZREALLOCARRAY(*listp, ckcapiInternalObject *, \
+ (size+CKAPI_ITEM_CHUNK) ) : \
+ nss_ZNEWARRAY(NULL, ckcapiInternalObject *, \
+ (size+CKAPI_ITEM_CHUNK) ) ; \
+ if ((ckcapiInternalObject **)NULL == *listp) { \
+ err = CKR_HOST_MEMORY; \
+ goto loser; \
+ } \
+ size += CKAPI_ITEM_CHUNK; \
+ } \
+ (*listp)[ count ] = (obj); \
+ count++; \
+ }
+
+
+/*
+ * pass parameters back through the callback.
+ */
+typedef struct BareCollectParamsStr {
+ CK_OBJECT_CLASS objClass;
+ CK_ATTRIBUTE_PTR pTemplate;
+ CK_ULONG ulAttributeCount;
+ ckcapiInternalObject ***listp;
+ PRUint32 size;
+ PRUint32 count;
+} BareCollectParams;
+
+/* collect_bare's callback. Called for each object that
+ * supposedly has a PROVINDER_INFO property */
+static BOOL WINAPI
+doBareCollect
+(
+ const CRYPT_HASH_BLOB *msKeyID,
+ DWORD flags,
+ void *reserved,
+ void *args,
+ DWORD cProp,
+ DWORD *propID,
+ void **propData,
+ DWORD *propSize
+)
+{
+ BareCollectParams *bcp = (BareCollectParams *) args;
+ PRUint32 size = bcp->size;
+ PRUint32 count = bcp->count;
+ ckcapiInternalObject ***listp = bcp->listp;
+ ckcapiInternalObject *io = NULL;
+ DWORD i;
+ CRYPT_KEY_PROV_INFO *keyProvInfo = NULL;
+ void *idData;
+ CK_RV error;
+
+ /* make sure there is a Key Provider Info property */
+ for (i=0; i < cProp; i++) {
+ if (CERT_KEY_PROV_INFO_PROP_ID == propID[i]) {
+ keyProvInfo = (CRYPT_KEY_PROV_INFO *)propData[i];
+ break;
+ }
+ }
+ if ((CRYPT_KEY_PROV_INFO *)NULL == keyProvInfo) {
+ return 1;
+ }
+
+ /* copy the key ID */
+ idData = nss_ZNEWARRAY(NULL, char, msKeyID->cbData);
+ if ((void *)NULL == idData) {
+ goto loser;
+ }
+ nsslibc_memcpy(idData, msKeyID->pbData, msKeyID->cbData);
+
+ /* build a bare internal object */
+ io = nss_ZNEW(NULL, ckcapiInternalObject);
+ if ((ckcapiInternalObject *)NULL == io) {
+ goto loser;
+ }
+ io->type = ckcapiBareKey;
+ io->objClass = bcp->objClass;
+ io->u.key.provInfo = *keyProvInfo;
+ io->u.key.provInfo.pwszContainerName =
+ nss_ckcapi_WideDup(keyProvInfo->pwszContainerName);
+ io->u.key.provInfo.pwszProvName =
+ nss_ckcapi_WideDup(keyProvInfo->pwszProvName);
+ io->u.key.provName = nss_ckcapi_WideToUTF8(keyProvInfo->pwszProvName);
+ io->u.key.containerName =
+ nss_ckcapi_WideToUTF8(keyProvInfo->pwszContainerName);
+ io->u.key.hProv = 0;
+ io->idData = idData;
+ io->id.data = idData;
+ io->id.size = msKeyID->cbData;
+ idData = NULL;
+
+ /* see if it matches */
+ if( CK_FALSE == ckcapi_match(bcp->pTemplate, bcp->ulAttributeCount, io) ) {
+ goto loser;
+ }
+ PUT_Object(io, error);
+ bcp->size = size;
+ bcp->count = count;
+ return 1;
+
+loser:
+ if (io) {
+ nss_ckcapi_DestroyInternalObject(io);
+ }
+ nss_ZFreeIf(idData);
+ return 1;
+}
+
+/*
+ * collect the bare keys running around
+ */
+static PRUint32
+collect_bare(
+ CK_OBJECT_CLASS objClass,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ ckcapiInternalObject ***listp,
+ PRUint32 *sizep,
+ PRUint32 count,
+ CK_RV *pError
+)
+{
+ BOOL rc;
+ BareCollectParams bareCollectParams;
+
+ bareCollectParams.objClass = objClass;
+ bareCollectParams.pTemplate = pTemplate;
+ bareCollectParams.ulAttributeCount = ulAttributeCount;
+ bareCollectParams.listp = listp;
+ bareCollectParams.size = *sizep;
+ bareCollectParams.count = count;
+
+ rc = CryptEnumKeyIdentifierProperties(NULL, CERT_KEY_PROV_INFO_PROP_ID, 0,
+ NULL, NULL, &bareCollectParams, doBareCollect);
+
+ *sizep = bareCollectParams.size;
+ return bareCollectParams.count;
+}
+
+/* find all the certs that represent the appropriate object (cert, priv key, or
+ * pub key) in the cert store.
+ */
+static PRUint32
+collect_class(
+ CK_OBJECT_CLASS objClass,
+ LPCSTR storeStr,
+ PRBool hasID,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ ckcapiInternalObject ***listp,
+ PRUint32 *sizep,
+ PRUint32 count,
+ CK_RV *pError
+)
+{
+ PRUint32 size = *sizep;
+ ckcapiInternalObject *next = NULL;
+ HCERTSTORE hStore;
+ PCCERT_CONTEXT certContext = NULL;
+ PRBool isKey =
+ (objClass == CKO_PUBLIC_KEY) | (objClass == CKO_PRIVATE_KEY);
+
+ hStore = CertOpenSystemStore((HCRYPTPROV)NULL, storeStr);
+ if (NULL == hStore) {
+ return count; /* none found does not imply an error */
+ }
+
+ /* FUTURE: use CertFindCertificateInStore to filter better -- so we don't
+ * have to enumerate all the certificates */
+ while ((PCERT_CONTEXT) NULL !=
+ (certContext= CertEnumCertificatesInStore(hStore, certContext))) {
+ /* first filter out non user certs if we are looking for keys */
+ if (isKey) {
+ /* make sure there is a Key Provider Info property */
+ CRYPT_KEY_PROV_INFO key_prov;
+ DWORD size = sizeof(CRYPT_KEY_PROV_INFO);
+ BOOL rv;
+ rv =CertGetCertificateContextProperty(certContext,
+ CERT_KEY_PROV_INFO_PROP_ID, &key_prov, &size);
+ if (!rv) {
+ int reason = GetLastError();
+ /* we only care if it exists, we don't really need to fetch it yet */
+ if (reason == CRYPT_E_NOT_FOUND) {
+ continue;
+ }
+ }
+ }
+
+ if ((ckcapiInternalObject *)NULL == next) {
+ next = nss_ZNEW(NULL, ckcapiInternalObject);
+ if ((ckcapiInternalObject *)NULL == next) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ }
+ next->type = ckcapiCert;
+ next->objClass = objClass;
+ next->u.cert.certContext = certContext;
+ next->u.cert.hasID = hasID;
+ next->u.cert.certStore = storeStr;
+ if( CK_TRUE == ckcapi_match(pTemplate, ulAttributeCount, next) ) {
+ /* clear cached values that may be dependent on our old certContext */
+ memset(&next->u.cert, 0, sizeof(next->u.cert));
+ /* get a 'permanent' context */
+ next->u.cert.certContext = CertDuplicateCertificateContext(certContext);
+ next->objClass = objClass;
+ next->u.cert.certContext = certContext;
+ next->u.cert.hasID = hasID;
+ next->u.cert.certStore = storeStr;
+ PUT_Object(next, *pError);
+ next = NULL; /* need to allocate a new one now */
+ } else {
+ /* don't cache the values we just loaded */
+ memset(&next->u.cert, 0, sizeof(next->u.cert));
+ }
+ }
+loser:
+ CertCloseStore(hStore, 0);
+ nss_ZFreeIf(next);
+ *sizep = size;
+ return count;
+}
+
+NSS_IMPLEMENT PRUint32
+nss_ckcapi_collect_all_certs(
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ ckcapiInternalObject ***listp,
+ PRUint32 *sizep,
+ PRUint32 count,
+ CK_RV *pError
+)
+{
+ count = collect_class(CKO_CERTIFICATE, "My", PR_TRUE, pTemplate,
+ ulAttributeCount, listp, sizep, count, pError);
+ count = collect_class(CKO_CERTIFICATE, "AddressBook", PR_FALSE, pTemplate,
+ ulAttributeCount, listp, sizep, count, pError);
+ count = collect_class(CKO_CERTIFICATE, "CA", PR_FALSE, pTemplate,
+ ulAttributeCount, listp, sizep, count, pError);
+ count = collect_class(CKO_CERTIFICATE, "Root", PR_FALSE, pTemplate,
+ ulAttributeCount, listp, sizep, count, pError);
+ count = collect_class(CKO_CERTIFICATE, "Trust", PR_FALSE, pTemplate,
+ ulAttributeCount, listp, sizep, count, pError);
+ count = collect_class(CKO_CERTIFICATE, "TrustedPeople", PR_FALSE, pTemplate,
+ ulAttributeCount, listp, sizep, count, pError);
+ count = collect_class(CKO_CERTIFICATE, "AuthRoot", PR_FALSE, pTemplate,
+ ulAttributeCount, listp, sizep, count, pError);
+ return count;
+}
+
+CK_OBJECT_CLASS
+ckcapi_GetObjectClass(CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount)
+{
+ CK_ULONG i;
+
+ for (i=0; i < ulAttributeCount; i++)
+ {
+ if (pTemplate[i].type == CKA_CLASS) {
+ return *(CK_OBJECT_CLASS *) pTemplate[i].pValue;
+ }
+ }
+ /* need to return a value that says 'fetch them all' */
+ return CK_INVALID_HANDLE;
+}
+
+static PRUint32
+collect_objects(
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ ckcapiInternalObject ***listp,
+ CK_RV *pError
+)
+{
+ PRUint32 i;
+ PRUint32 count = 0;
+ PRUint32 size = 0;
+ CK_OBJECT_CLASS objClass;
+
+ /*
+ * first handle the static build in objects (if any)
+ */
+ for( i = 0; i < nss_ckcapi_nObjects; i++ ) {
+ ckcapiInternalObject *o = (ckcapiInternalObject *)&nss_ckcapi_data[i];
+
+ if( CK_TRUE == ckcapi_match(pTemplate, ulAttributeCount, o) ) {
+ PUT_Object(o, *pError);
+ }
+ }
+
+ /*
+ * now handle the various object types
+ */
+ objClass = ckcapi_GetObjectClass(pTemplate, ulAttributeCount);
+ *pError = CKR_OK;
+ switch (objClass) {
+ case CKO_CERTIFICATE:
+ count = nss_ckcapi_collect_all_certs(pTemplate, ulAttributeCount, listp,
+ &size, count, pError);
+ break;
+ case CKO_PUBLIC_KEY:
+ count = collect_class(objClass, "My", PR_TRUE, pTemplate,
+ ulAttributeCount, listp, &size, count, pError);
+ count = collect_bare(objClass, pTemplate, ulAttributeCount, listp,
+ &size, count, pError);
+ break;
+ case CKO_PRIVATE_KEY:
+ count = collect_class(objClass, "My", PR_TRUE, pTemplate,
+ ulAttributeCount, listp, &size, count, pError);
+ count = collect_bare(objClass, pTemplate, ulAttributeCount, listp,
+ &size, count, pError);
+ break;
+ /* all of them */
+ case CK_INVALID_HANDLE:
+ count = nss_ckcapi_collect_all_certs(pTemplate, ulAttributeCount, listp,
+ &size, count, pError);
+ count = collect_class(CKO_PUBLIC_KEY, "My", PR_TRUE, pTemplate,
+ ulAttributeCount, listp, &size, count, pError);
+ count = collect_bare(CKO_PUBLIC_KEY, pTemplate, ulAttributeCount, listp,
+ &size, count, pError);
+ count = collect_class(CKO_PRIVATE_KEY, "My", PR_TRUE, pTemplate,
+ ulAttributeCount, listp, &size, count, pError);
+ count = collect_bare(CKO_PRIVATE_KEY, pTemplate, ulAttributeCount, listp,
+ &size, count, pError);
+ break;
+ default:
+ goto done; /* no other object types we understand in this module */
+ }
+ if (CKR_OK != *pError) {
+ goto loser;
+ }
+
+
+done:
+ return count;
+loser:
+ nss_ZFreeIf(*listp);
+ return 0;
+}
+
+
+
+NSS_IMPLEMENT NSSCKMDFindObjects *
+nss_ckcapi_FindObjectsInit
+(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+)
+{
+ /* This could be made more efficient. I'm rather rushed. */
+ NSSArena *arena;
+ NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
+ struct ckcapiFOStr *fo = (struct ckcapiFOStr *)NULL;
+ ckcapiInternalObject **temp = (ckcapiInternalObject **)NULL;
+
+ arena = NSSArena_Create();
+ if( (NSSArena *)NULL == arena ) {
+ goto loser;
+ }
+
+ rv = nss_ZNEW(arena, NSSCKMDFindObjects);
+ if( (NSSCKMDFindObjects *)NULL == rv ) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ fo = nss_ZNEW(arena, struct ckcapiFOStr);
+ if( (struct ckcapiFOStr *)NULL == fo ) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ fo->arena = arena;
+ /* fo->n and fo->i are already zero */
+
+ rv->etc = (void *)fo;
+ rv->Final = ckcapi_mdFindObjects_Final;
+ rv->Next = ckcapi_mdFindObjects_Next;
+ rv->null = (void *)NULL;
+
+ fo->n = collect_objects(pTemplate, ulAttributeCount, &temp, pError);
+ if (*pError != CKR_OK) {
+ goto loser;
+ }
+
+ fo->objs = nss_ZNEWARRAY(arena, ckcapiInternalObject *, fo->n);
+ if( (ckcapiInternalObject **)NULL == fo->objs ) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ (void)nsslibc_memcpy(fo->objs, temp, sizeof(ckcapiInternalObject *) * fo->n);
+ nss_ZFreeIf(temp);
+ temp = (ckcapiInternalObject **)NULL;
+
+ return rv;
+
+ loser:
+ nss_ZFreeIf(temp);
+ nss_ZFreeIf(fo);
+ nss_ZFreeIf(rv);
+ if ((NSSArena *)NULL != arena) {
+ NSSArena_Destroy(arena);
+ }
+ return (NSSCKMDFindObjects *)NULL;
+}
+
diff --git a/security/nss/lib/ckfw/capi/cinst.c b/security/nss/lib/ckfw/capi/cinst.c
new file mode 100644
index 000000000..fe5c3d25e
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/cinst.c
@@ -0,0 +1,148 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
+ *
+ * Contributor(s):
+ * Bob Relyea (rrelyea@redhat.com)
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
+#endif /* DEBUG */
+
+#include "ckcapi.h"
+
+/*
+ * ckcapi/cinstance.c
+ *
+ * This file implements the NSSCKMDInstance object for the
+ * "capi" cryptoki module.
+ */
+
+/*
+ * NSSCKMDInstance methods
+ */
+
+static CK_ULONG
+ckcapi_mdInstance_GetNSlots
+(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (CK_ULONG)1;
+}
+
+static CK_VERSION
+ckcapi_mdInstance_GetCryptokiVersion
+(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return nss_ckcapi_CryptokiVersion;
+}
+
+static NSSUTF8 *
+ckcapi_mdInstance_GetManufacturerID
+(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
+}
+
+static NSSUTF8 *
+ckcapi_mdInstance_GetLibraryDescription
+(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_ckcapi_LibraryDescription;
+}
+
+static CK_VERSION
+ckcapi_mdInstance_GetLibraryVersion
+(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return nss_ckcapi_LibraryVersion;
+}
+
+static CK_RV
+ckcapi_mdInstance_GetSlots
+(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDSlot *slots[]
+)
+{
+ slots[0] = (NSSCKMDSlot *)&nss_ckcapi_mdSlot;
+ return CKR_OK;
+}
+
+static CK_BBOOL
+ckcapi_mdInstance_ModuleHandlesSessionObjects
+(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ /* we don't want to allow any session object creation, at least
+ * until we can investigate whether or not we can use those objects
+ */
+ return CK_TRUE;
+}
+
+NSS_IMPLEMENT_DATA const NSSCKMDInstance
+nss_ckcapi_mdInstance = {
+ (void *)NULL, /* etc */
+ NULL, /* Initialize */
+ NULL, /* Finalize */
+ ckcapi_mdInstance_GetNSlots,
+ ckcapi_mdInstance_GetCryptokiVersion,
+ ckcapi_mdInstance_GetManufacturerID,
+ ckcapi_mdInstance_GetLibraryDescription,
+ ckcapi_mdInstance_GetLibraryVersion,
+ ckcapi_mdInstance_ModuleHandlesSessionObjects,
+ /*NULL, /* HandleSessionObjects */
+ ckcapi_mdInstance_GetSlots,
+ NULL, /* WaitForSlotEvent */
+ (void *)NULL /* null terminator */
+};
diff --git a/security/nss/lib/ckfw/capi/ckcapi.h b/security/nss/lib/ckfw/capi/ckcapi.h
new file mode 100644
index 000000000..fb434ce57
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/ckcapi.h
@@ -0,0 +1,309 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
+ *
+ * Contributor(s):
+ * Bob Relyea (rrelyea@redhat.com)
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef CKCAPI_H
+#define CKCAPI_H 1
+
+#ifdef DEBUG
+static const char CKCAPI_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
+#endif /* DEBUG */
+
+#include "nssckmdt.h"
+#include "nssckfw.h"
+
+/*
+ * I'm including this for access to the arena functions.
+ * Looks like we should publish that API.
+ */
+#ifndef BASE_H
+#include "base.h"
+#endif /* BASE_H */
+
+/*
+ * This is where the Netscape extensions live, at least for now.
+ */
+#ifndef CKT_H
+#include "ckt.h"
+#endif /* CKT_H */
+
+#include "WTypes.h"
+#include "WinCrypt.h"
+
+/*
+ * statically defined raw objects. Allows us to data description objects
+ * to this PKCS #11 module.
+ */
+struct ckcapiRawObjectStr {
+ CK_ULONG n;
+ const CK_ATTRIBUTE_TYPE *types;
+ const NSSItem *items;
+};
+typedef struct ckcapiRawObjectStr ckcapiRawObject;
+
+
+/*
+ * common values needed for both bare keys and cert referenced keys.
+ */
+struct ckcapiKeyParamsStr {
+ NSSItem modulus;
+ NSSItem exponent;
+ NSSItem privateExponent;
+ NSSItem prime1;
+ NSSItem prime2;
+ NSSItem exponent1;
+ NSSItem exponent2;
+ NSSItem coefficient;
+ unsigned char publicExponentData[sizeof(CK_ULONG)];
+ void *privateKey;
+ void *pubKey;
+};
+typedef struct ckcapiKeyParamsStr ckcapiKeyParams;
+
+/*
+ * Key objects. Handles bare keys which do not yet have certs associated
+ * with them. These are usually short lived, but may exist for several days
+ * while the CA is issuing the certificate.
+ */
+struct ckcapiKeyObjectStr {
+ CRYPT_KEY_PROV_INFO provInfo;
+ char *provName;
+ char *containerName;
+ HCRYPTPROV hProv;
+ ckcapiKeyParams key;
+};
+typedef struct ckcapiKeyObjectStr ckcapiKeyObject;
+
+/*
+ * Certificate and certificate referenced keys.
+ */
+struct ckcapiCertObjectStr {
+ PCCERT_CONTEXT certContext;
+ PRBool hasID;
+ const char *certStore;
+ NSSItem label;
+ NSSItem subject;
+ NSSItem issuer;
+ NSSItem serial;
+ NSSItem derCert;
+ ckcapiKeyParams key;
+ unsigned char *labelData;
+ /* static data: to do, make this dynamic like labelData */
+ unsigned char derSerial[128];
+};
+typedef struct ckcapiCertObjectStr ckcapiCertObject;
+
+typedef enum {
+ ckcapiRaw,
+ ckcapiCert,
+ ckcapiBareKey
+} ckcapiObjectType;
+
+/*
+ * all the various types of objects are abstracted away in cobject and
+ * cfind as ckcapiInternalObjects.
+ */
+struct ckcapiInternalObjectStr {
+ ckcapiObjectType type;
+ union {
+ ckcapiRawObject raw;
+ ckcapiCertObject cert;
+ ckcapiKeyObject key;
+ } u;
+ CK_OBJECT_CLASS objClass;
+ NSSItem hashKey;
+ NSSItem id;
+ void *idData;
+ unsigned char hashKeyData[128];
+ NSSCKMDObject mdObject;
+};
+typedef struct ckcapiInternalObjectStr ckcapiInternalObject;
+
+/* our raw object data array */
+NSS_EXTERN_DATA ckcapiInternalObject nss_ckcapi_data[];
+NSS_EXTERN_DATA const PRUint32 nss_ckcapi_nObjects;
+
+NSS_EXTERN_DATA const CK_VERSION nss_ckcapi_CryptokiVersion;
+NSS_EXTERN_DATA const NSSUTF8 * nss_ckcapi_ManufacturerID;
+NSS_EXTERN_DATA const NSSUTF8 * nss_ckcapi_LibraryDescription;
+NSS_EXTERN_DATA const CK_VERSION nss_ckcapi_LibraryVersion;
+NSS_EXTERN_DATA const NSSUTF8 * nss_ckcapi_SlotDescription;
+NSS_EXTERN_DATA const CK_VERSION nss_ckcapi_HardwareVersion;
+NSS_EXTERN_DATA const CK_VERSION nss_ckcapi_FirmwareVersion;
+NSS_EXTERN_DATA const NSSUTF8 * nss_ckcapi_TokenLabel;
+NSS_EXTERN_DATA const NSSUTF8 * nss_ckcapi_TokenModel;
+NSS_EXTERN_DATA const NSSUTF8 * nss_ckcapi_TokenSerialNumber;
+
+NSS_EXTERN_DATA const NSSCKMDInstance nss_ckcapi_mdInstance;
+NSS_EXTERN_DATA const NSSCKMDSlot nss_ckcapi_mdSlot;
+NSS_EXTERN_DATA const NSSCKMDToken nss_ckcapi_mdToken;
+NSS_EXTERN_DATA const NSSCKMDMechanism nss_ckcapi_mdMechanismRSA;
+
+NSS_EXTERN NSSCKMDSession *
+nss_ckcapi_CreateSession
+(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError
+);
+
+NSS_EXTERN NSSCKMDFindObjects *
+nss_ckcapi_FindObjectsInit
+(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+);
+
+/*
+ * Object Utilities
+ */
+NSS_EXTERN NSSCKMDObject *
+nss_ckcapi_CreateMDObject
+(
+ NSSArena *arena,
+ ckcapiInternalObject *io,
+ CK_RV *pError
+);
+
+NSS_EXTERN NSSCKMDObject *
+nss_ckcapi_CreateObject
+(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+);
+
+NSS_EXTERN const NSSItem *
+nss_ckcapi_FetchAttribute
+(
+ ckcapiInternalObject *io,
+ CK_ATTRIBUTE_TYPE type
+);
+
+NSS_EXTERN void
+nss_ckcapi_DestroyInternalObject
+(
+ ckcapiInternalObject *io
+);
+
+NSS_EXTERN CK_RV
+nss_ckcapi_FetchKeyContainer
+(
+ ckcapiInternalObject *iKey,
+ HCRYPTPROV *hProv,
+ DWORD *keySpec,
+ HCRYPTKEY *hKey
+);
+
+/*
+ * generic utilities
+ */
+
+/*
+ * So everyone else in the worlds stores their bignum data MSB first, but not
+ * Microsoft, we need to byte swap everything coming into and out of CAPI.
+ */
+void
+ckcapi_ReverseData
+(
+ NSSItem *item
+);
+
+/*
+ * unwrap a single DER value
+ */
+char *
+nss_ckcapi_DERUnwrap
+(
+ char *src,
+ int size,
+ int *outSize,
+ char **next
+);
+
+/*
+ * Return the size in bytes of a wide string
+ */
+int
+nss_ckcapi_WideSize
+(
+ LPCWSTR wide
+);
+
+/*
+ * Covert a Unicode wide character string to a UTF8 string
+ */
+char *
+nss_ckcapi_WideToUTF8
+(
+ LPCWSTR wide
+);
+
+/*
+ * Return a Wide String duplicated with nss allocated memory.
+ */
+LPWSTR
+nss_ckcapi_WideDup
+(
+ LPCWSTR wide
+);
+
+/*
+ * Covert a UTF8 string to Unicode wide character
+ */
+LPWSTR
+nss_ckcapi_UTF8ToWide
+(
+ char *buf
+);
+
+
+NSS_EXTERN PRUint32
+nss_ckcapi_collect_all_certs(
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ ckcapiInternalObject ***listp,
+ PRUint32 *sizep,
+ PRUint32 count,
+ CK_RV *pError
+);
+
+#define NSS_CKCAPI_ARRAY_SIZE(x) ((sizeof (x))/(sizeof ((x)[0])))
+
+#endif
diff --git a/security/nss/lib/ckfw/capi/ckcapiver.c b/security/nss/lib/ckfw/capi/ckcapiver.c
new file mode 100644
index 000000000..d69290575
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/ckcapiver.c
@@ -0,0 +1,59 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
+ *
+ * Contributor(s):
+ * Bob Relyea (rrelyea@redhat.com)
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/* Library identity and versioning */
+
+#include "nsscapi.h"
+
+#if defined(DEBUG)
+#define _DEBUG_STRING " (debug)"
+#else
+#define _DEBUG_STRING ""
+#endif
+
+/*
+ * Version information for the 'ident' and 'what commands
+ *
+ * NOTE: the first component of the concatenated rcsid string
+ * must not end in a '$' to prevent rcs keyword substitution.
+ */
+const char __nss_ckcapi_rcsid[] = "$Header: NSS Access to Microsoft Certificate Store "
+ NSS_CKCAPI_LIBRARY_VERSION _DEBUG_STRING
+ " " __DATE__ " " __TIME__ " $";
+const char __nss_ckcapi_sccsid[] = "@(#)NSS Access to Microsoft Certificate Store "
+ NSS_CKCAPI_LIBRARY_VERSION _DEBUG_STRING
+ " " __DATE__ " " __TIME__;
diff --git a/security/nss/lib/ckfw/capi/cobject.c b/security/nss/lib/ckfw/capi/cobject.c
new file mode 100644
index 000000000..c12971ff5
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/cobject.c
@@ -0,0 +1,2346 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
+ *
+ * Contributor(s):
+ * Bob Relyea (rrelyea@redhat.com)
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
+#endif /* DEBUG */
+
+#include "ckcapi.h"
+#include "nssbase.h"
+
+/*
+ * ckcapi/cobject.c
+ *
+ * This file implements the NSSCKMDObject object for the
+ * "nss to capi objects" cryptoki module.
+ */
+
+const CK_ATTRIBUTE_TYPE certAttrs[] = {
+ CKA_CLASS,
+ CKA_TOKEN,
+ CKA_PRIVATE,
+ CKA_MODIFIABLE,
+ CKA_LABEL,
+ CKA_CERTIFICATE_TYPE,
+ CKA_SUBJECT,
+ CKA_ISSUER,
+ CKA_SERIAL_NUMBER,
+ CKA_VALUE
+};
+const PRUint32 certAttrsCount = NSS_CKCAPI_ARRAY_SIZE(certAttrs);
+
+/* private keys, for now only support RSA */
+const CK_ATTRIBUTE_TYPE privKeyAttrs[] = {
+ CKA_CLASS,
+ CKA_TOKEN,
+ CKA_PRIVATE,
+ CKA_MODIFIABLE,
+ CKA_LABEL,
+ CKA_KEY_TYPE,
+ CKA_DERIVE,
+ CKA_LOCAL,
+ CKA_SUBJECT,
+ CKA_SENSITIVE,
+ CKA_DECRYPT,
+ CKA_SIGN,
+ CKA_SIGN_RECOVER,
+ CKA_UNWRAP,
+ CKA_EXTRACTABLE,
+ CKA_ALWAYS_SENSITIVE,
+ CKA_NEVER_EXTRACTABLE,
+ CKA_MODULUS,
+ CKA_PUBLIC_EXPONENT,
+};
+const PRUint32 privKeyAttrsCount = NSS_CKCAPI_ARRAY_SIZE(privKeyAttrs);
+
+/* public keys, for now only support RSA */
+const CK_ATTRIBUTE_TYPE pubKeyAttrs[] = {
+ CKA_CLASS,
+ CKA_TOKEN,
+ CKA_PRIVATE,
+ CKA_MODIFIABLE,
+ CKA_LABEL,
+ CKA_KEY_TYPE,
+ CKA_DERIVE,
+ CKA_LOCAL,
+ CKA_SUBJECT,
+ CKA_ENCRYPT,
+ CKA_VERIFY,
+ CKA_VERIFY_RECOVER,
+ CKA_WRAP,
+ CKA_MODULUS,
+ CKA_PUBLIC_EXPONENT,
+};
+const PRUint32 pubKeyAttrsCount = NSS_CKCAPI_ARRAY_SIZE(pubKeyAttrs);
+static const CK_BBOOL ck_true = CK_TRUE;
+static const CK_BBOOL ck_false = CK_FALSE;
+static const CK_CERTIFICATE_TYPE ckc_x509 = CKC_X_509;
+static const CK_KEY_TYPE ckk_rsa = CKK_RSA;
+static const CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
+static const CK_OBJECT_CLASS cko_private_key = CKO_PRIVATE_KEY;
+static const CK_OBJECT_CLASS cko_public_key = CKO_PUBLIC_KEY;
+static const NSSItem ckcapi_trueItem = {
+ (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) };
+static const NSSItem ckcapi_falseItem = {
+ (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) };
+static const NSSItem ckcapi_x509Item = {
+ (void *)&ckc_x509, (PRUint32)sizeof(CKC_X_509) };
+static const NSSItem ckcapi_rsaItem = {
+ (void *)&ckk_rsa, (PRUint32)sizeof(CK_KEY_TYPE) };
+static const NSSItem ckcapi_certClassItem = {
+ (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) };
+static const NSSItem ckcapi_privKeyClassItem = {
+ (void *)&cko_private_key, (PRUint32)sizeof(CK_OBJECT_CLASS) };
+static const NSSItem ckcapi_pubKeyClassItem = {
+ (void *)&cko_public_key, (PRUint32)sizeof(CK_OBJECT_CLASS) };
+static const NSSItem ckcapi_emptyItem = {
+ (void *)&ck_true, 0};
+
+/*
+ * these are utilities. The chould be moved to a new utilities file.
+ */
+
+/*
+ * unwrap a single DER value
+ */
+char *
+nss_ckcapi_DERUnwrap
+(
+ char *src,
+ int size,
+ int *outSize,
+ char **next
+)
+{
+ unsigned char *start = src;
+ unsigned char *end = src+size;
+ unsigned int len = 0;
+
+ /* initialize error condition return values */
+ *outSize = 0;
+ if (next) {
+ *next = src;
+ }
+
+ if (size < 2) {
+ return start;
+ }
+ src ++ ; /* skip the tag -- should check it against an expected value! */
+ len = (unsigned) *src++;
+ if (len & 0x80) {
+ int count = len & 0x7f;
+ len =0;
+
+ if (count+2 > size) {
+ return start;
+ }
+ while (count-- > 0) {
+ len = (len << 8) | (unsigned) *src++;
+ }
+ }
+ if (len + (src-start) > (unsigned int)size) {
+ return start;
+ }
+ if (next) {
+ *next = src+len;
+ }
+ *outSize = len;
+
+ return src;
+}
+
+/*
+ * convert a PKCS #11 bytestrin into a CK_ULONG, the byte stream must be
+ * less than sizeof (CK_ULONG).
+ */
+CK_ULONG
+nss_ckcapi_DataToInt
+(
+ NSSItem *data,
+ CK_RV *pError
+)
+{
+ CK_ULONG value = 0;
+ unsigned long count = data->size;
+ unsigned char *dataPtr = data->data;
+ unsigned long size = 0;
+
+ *pError = CKR_OK;
+
+ while (count--) {
+ value = value << 8;
+ value = value + *dataPtr++;
+ if (size || value) {
+ size++;
+ }
+ }
+ if (size > sizeof(CK_ULONG)) {
+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ return value;
+}
+
+/*
+ * convert a CK_ULONG to a bytestream. Data is stored in the buffer 'buf'
+ * and must be at least CK_ULONG. Caller must provide buf.
+ */
+CK_ULONG
+nss_ckcapi_IntToData
+(
+ CK_ULONG value,
+ NSSItem *data,
+ unsigned char *dataPtr,
+ CK_RV *pError
+)
+{
+ unsigned long count = 0;
+ unsigned long i;
+#define SHIFT ((sizeof(CK_ULONG)-1)*8)
+ PRBool first = 0;
+
+ *pError = CKR_OK;
+
+ data->data = dataPtr;
+ for (i=0; i < sizeof(CK_ULONG); i++) {
+ unsigned char digit = (unsigned char)((value >> SHIFT) & 0xff);
+
+ value = value << 8;
+
+ /* drop leading zero bytes */
+ if (first && (0 == digit)) {
+ continue;
+ }
+ *dataPtr++ = digit;
+ count++;
+ }
+ data->size = count;
+ return count;
+}
+
+/*
+ * get an attribute from a template. Value is returned in NSS item.
+ * data for the item is owned by the template.
+ */
+CK_RV
+nss_ckcapi_GetAttribute
+(
+ CK_ATTRIBUTE_TYPE type,
+ CK_ATTRIBUTE *template,
+ CK_ULONG templateSize,
+ NSSItem *item
+)
+{
+ CK_ULONG i;
+
+ for (i=0; i < templateSize; i++) {
+ if (template[i].type == type) {
+ item->data = template[i].pValue;
+ item->size = template[i].ulValueLen;
+ return CKR_OK;
+ }
+ }
+ return CKR_TEMPLATE_INCOMPLETE;
+}
+
+/*
+ * get an attribute which is type CK_ULONG.
+ */
+CK_ULONG
+nss_ckcapi_GetULongAttribute
+(
+ CK_ATTRIBUTE_TYPE type,
+ CK_ATTRIBUTE *template,
+ CK_ULONG templateSize,
+ CK_RV *pError
+)
+{
+ NSSItem item;
+
+ *pError = nss_ckcapi_GetAttribute(type, template, templateSize, &item);
+ if (CKR_OK != *pError) {
+ return (CK_ULONG) 0;
+ }
+ if (item.size != sizeof(CK_ULONG)) {
+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
+ return (CK_ULONG) 0;
+ }
+ return *(CK_ULONG *)item.data;
+}
+
+/*
+ * get an attribute which is type CK_BBOOL.
+ */
+CK_BBOOL
+nss_ckcapi_GetBoolAttribute
+(
+ CK_ATTRIBUTE_TYPE type,
+ CK_ATTRIBUTE *template,
+ CK_ULONG templateSize,
+ CK_RV *pError
+)
+{
+ NSSItem item;
+
+ *pError = nss_ckcapi_GetAttribute(type, template, templateSize, &item);
+ if (CKR_OK != *pError) {
+ return (CK_BBOOL) 0;
+ }
+ if (item.size != sizeof(CK_BBOOL)) {
+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
+ return (CK_BBOOL) 0;
+ }
+ return *(CK_BBOOL *)item.data;
+}
+
+/*
+ * get an attribute which is type CK_BBOOL.
+ */
+char *
+nss_ckcapi_GetStringAttribute
+(
+ CK_ATTRIBUTE_TYPE type,
+ CK_ATTRIBUTE *template,
+ CK_ULONG templateSize,
+ CK_RV *pError
+)
+{
+ NSSItem item;
+ char *str;
+
+ /* get the attribute */
+ *pError = nss_ckcapi_GetAttribute(type, template, templateSize, &item);
+ if (CKR_OK != *pError) {
+ return (char *)NULL;
+ }
+ /* make sure it is null terminated */
+ str = nss_ZNEWARRAY(NULL, char, item.size+1);
+ if ((char *)NULL == str) {
+ *pError = CKR_HOST_MEMORY;
+ return (char *)NULL;
+ }
+
+ nsslibc_memcpy(str, item.data, item.size);
+ str[item.size] = 0;
+
+ return str;
+}
+
+/*
+ * Return the size in bytes of a wide string
+ */
+int
+nss_ckcapi_WideSize
+(
+ LPCWSTR wide
+)
+{
+ DWORD size;
+
+ if ((LPWSTR)NULL == wide) {
+ return 0;
+ }
+ size = wcslen(wide)+1;
+ return size*2;
+}
+
+/*
+ * Covert a Unicode wide character string to a UTF8 string
+ */
+char *
+nss_ckcapi_WideToUTF8
+(
+ LPCWSTR wide
+)
+{
+ DWORD len;
+ DWORD size;
+ char *buf;
+
+ if ((LPWSTR)NULL == wide) {
+ return (char *)NULL;
+ }
+
+ len = nss_ckcapi_WideSize(wide);
+
+ size = WideCharToMultiByte(CP_UTF8, 0, wide, len, NULL, 0, NULL, 0);
+ if (size == 0) {
+ return (char *)NULL;
+ }
+ buf = nss_ZNEWARRAY(NULL, char, size);
+ size = WideCharToMultiByte(CP_UTF8, 0, wide, len, buf, size, NULL, 0);
+ if (size == 0) {
+ nss_ZFreeIf(buf);
+ return (char *)NULL;
+ }
+ return buf;
+}
+
+/*
+ * Return a Wide String duplicated with nss allocated memory.
+ */
+LPWSTR
+nss_ckcapi_WideDup
+(
+ LPCWSTR wide
+)
+{
+ DWORD len = nss_ckcapi_WideSize(wide);
+ LPWSTR buf;
+
+ if ((LPWSTR)NULL == wide) {
+ return (LPWSTR)NULL;
+ }
+
+ len = nss_ckcapi_WideSize(wide);
+
+ buf = (LPWSTR) nss_ZNEWARRAY(NULL, char, len);
+ if ((LPWSTR) NULL == buf) {
+ return buf;
+ }
+ nsslibc_memcpy(buf, wide, len);
+ return buf;
+}
+
+/*
+ * Covert a UTF8 string to Unicode wide character
+ */
+LPWSTR
+nss_ckcapi_UTF8ToWide
+(
+ char *buf
+)
+{
+ DWORD size;
+ DWORD len = strlen(buf)+1;
+ LPWSTR wide;
+
+ if ((char *)NULL == buf) {
+ return (LPWSTR) NULL;
+ }
+
+ len = strlen(buf)+1;
+
+ size = MultiByteToWideChar(CP_UTF8, 0, buf, len, NULL, 0);
+ if (size == 0) {
+ return (LPWSTR) NULL;
+ }
+ wide = nss_ZNEWARRAY(NULL, WCHAR, size);
+ size = MultiByteToWideChar(CP_UTF8, 0, buf, len, wide, size);
+ if (size == 0) {
+ nss_ZFreeIf(wide);
+ return (LPWSTR) NULL;
+ }
+ return wide;
+}
+
+
+/*
+ * keep all the knowlege of how the internalObject is laid out in this function
+ *
+ * nss_ckcapi_FetchKeyContainer
+ *
+ * fetches the Provider container and info as well as a key handle for a
+ * private key. If something other than a private key is passed in,
+ * this function fails with CKR_KEY_TYPE_INCONSISTENT
+ */
+NSS_EXTERN CK_RV
+nss_ckcapi_FetchKeyContainer
+(
+ ckcapiInternalObject *iKey,
+ HCRYPTPROV *hProv,
+ DWORD *keySpec,
+ HCRYPTKEY *hKey
+)
+{
+ ckcapiCertObject *co;
+ ckcapiKeyObject *ko;
+ BOOL rc, dummy;
+ DWORD msError;
+
+
+ switch (iKey->type) {
+ default:
+ case ckcapiRaw:
+ /* can't have raw private keys */
+ return CKR_KEY_TYPE_INCONSISTENT;
+ case ckcapiCert:
+ if (iKey->objClass != CKO_PRIVATE_KEY) {
+ /* Only private keys have private key provider handles */
+ return CKR_KEY_TYPE_INCONSISTENT;
+ }
+ co = &iKey->u.cert;
+
+ /* OK, get the Provider */
+ rc = CryptAcquireCertificatePrivateKey(co->certContext,
+ CRYPT_ACQUIRE_CACHE_FLAG|CRYPT_ACQUIRE_COMPARE_KEY_FLAG, NULL, hProv,
+ keySpec, &dummy);
+ if (!rc) {
+ goto loser;
+ }
+ break;
+ case ckcapiBareKey:
+ if (iKey->objClass != CKO_PRIVATE_KEY) {
+ /* Only private keys have private key provider handles */
+ return CKR_KEY_TYPE_INCONSISTENT;
+ }
+ ko = &iKey->u.key;
+
+ /* OK, get the Provider */
+ if (0 == ko->hProv) {
+ rc = CryptAcquireContext(hProv,
+ ko->containerName,
+ ko->provName,
+ ko->provInfo.dwProvType , 0);
+ if (!rc) {
+ goto loser;
+ }
+ } else {
+ *hProv = ko->hProv;
+ }
+ *keySpec = ko->provInfo.dwKeySpec;
+ break;
+ }
+
+ /* and get the crypto handle */
+ rc = CryptGetUserKey(*hProv, *keySpec, hKey);
+ if (!rc) {
+ goto loser;
+ }
+ return CKR_OK;
+loser:
+ /* map the microsoft error before leaving */
+ msError = GetLastError();
+ switch (msError) {
+ case ERROR_INVALID_HANDLE:
+ case ERROR_INVALID_PARAMETER:
+ case NTE_BAD_KEY:
+ case NTE_NO_KEY:
+ case NTE_BAD_PUBLIC_KEY:
+ case NTE_BAD_KEYSET:
+ case NTE_KEYSET_NOT_DEF:
+ return CKR_KEY_TYPE_INCONSISTENT;
+ case NTE_BAD_UID:
+ case NTE_KEYSET_ENTRY_BAD:
+ return CKR_DEVICE_ERROR;
+ }
+ return CKR_GENERAL_ERROR;
+}
+
+
+/*
+ * take a DER PUBLIC Key block and return the modulus and exponent
+ */
+static void
+ckcapi_CertPopulateModulusExponent
+(
+ ckcapiInternalObject *io
+)
+{
+ ckcapiKeyParams *kp = &io->u.cert.key;
+ PCCERT_CONTEXT certContext = io->u.cert.certContext;
+ char *pkData = certContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData;
+ CK_ULONG size= certContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData;
+ CK_ULONG newSize;
+ char *ptr, *newptr;
+
+ /* find the start of the modulus -- this will not give good results if
+ * the key isn't an rsa key! */
+ ptr = nss_ckcapi_DERUnwrap(pkData, size, &newSize, NULL);
+ kp->modulus.data = nss_ckcapi_DERUnwrap(ptr, newSize,
+ &kp->modulus.size, &newptr);
+ /* changed from signed to unsigned int */
+ if (0 == *(char *)kp->modulus.data) {
+ kp->modulus.data = ((char *)kp->modulus.data)+1;
+ kp->modulus.size = kp->modulus.size - 1;
+ }
+ /* changed from signed to unsigned int */
+ kp->exponent.data = nss_ckcapi_DERUnwrap(newptr, (newptr-ptr)+newSize,
+ &kp->exponent.size, NULL);
+ if (0 == *(char *)kp->exponent.data) {
+ kp->exponent.data = ((char *)kp->exponent.data)+1;
+ kp->exponent.size = kp->exponent.size - 1;
+ }
+ return;
+}
+
+typedef struct _CAPI_RSA_KEY_BLOB {
+ PUBLICKEYSTRUC header;
+ RSAPUBKEY rsa;
+ char data[1];
+} CAPI_RSA_KEY_BLOB;
+
+#define CAPI_MODULUS_OFFSET(modSize) 0
+#define CAPI_PRIME_1_OFFSET(modSize) (modSize)
+#define CAPI_PRIME_2_OFFSET(modSize) ((modSize)+(modSize)/2)
+#define CAPI_EXPONENT_1_OFFSET(modSize) ((modSize)*2)
+#define CAPI_EXPONENT_2_OFFSET(modSize) ((modSize)*2+(modSize)/2)
+#define CAPI_COEFFICIENT_OFFSET(modSize) ((modSize)*3)
+#define CAPI_PRIVATE_EXP_OFFSET(modSize) ((modSize)*3+(modSize)/2)
+
+void
+ckcapi_FetchPublicKey
+(
+ ckcapiInternalObject *io
+)
+{
+ ckcapiKeyParams *kp;
+ HCRYPTPROV hProv;
+ DWORD keySpec;
+ HCRYPTKEY hKey = 0;
+ CK_RV error;
+ DWORD bufLen;
+ BOOL rc;
+ unsigned long modulus;
+ char *buf = NULL;
+ CAPI_RSA_KEY_BLOB *blob;
+
+ error = nss_ckcapi_FetchKeyContainer(io, &hProv, &keySpec, &hKey);
+ if (CKR_OK != error) {
+ goto loser;
+ }
+ kp = (ckcapiCert == io->type) ? &io->u.cert.key : &io->u.key.key;
+
+ rc = CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, buf, &bufLen);
+ if (!rc) {
+ goto loser;
+ }
+ buf = nss_ZNEWARRAY(NULL, char, bufLen);
+ rc = CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, buf, &bufLen);
+ if (!rc) {
+ goto loser;
+ }
+ /* validate the blob */
+ blob = (CAPI_RSA_KEY_BLOB *)buf;
+ if ((PUBLICKEYBLOB != blob->header.bType) ||
+ (0x02 != blob->header.bVersion) ||
+ (0x31415352 != blob->rsa.magic)) {
+ goto loser;
+ }
+ modulus = blob->rsa.bitlen/8;
+ kp->pubKey = buf;
+ buf = NULL;
+
+ kp->modulus.data = &blob->data[CAPI_MODULUS_OFFSET(modulus)];
+ kp->modulus.size = modulus;
+ ckcapi_ReverseData(&kp->modulus);
+ nss_ckcapi_IntToData(blob->rsa.pubexp, &kp->exponent,
+ kp->publicExponentData, &error);
+
+loser:
+ nss_ZFreeIf(buf);
+ if (0 != hKey) {
+ CryptDestroyKey(hKey);
+ }
+ return;
+}
+
+void
+ckcapi_FetchPrivateKey
+(
+ ckcapiInternalObject *io
+)
+{
+ ckcapiKeyParams *kp;
+ HCRYPTPROV hProv;
+ DWORD keySpec;
+ HCRYPTKEY hKey = 0;
+ CK_RV error;
+ DWORD bufLen;
+ BOOL rc;
+ unsigned long modulus;
+ char *buf = NULL;
+ CAPI_RSA_KEY_BLOB *blob;
+
+ error = nss_ckcapi_FetchKeyContainer(io, &hProv, &keySpec, &hKey);
+ if (CKR_OK != error) {
+ goto loser;
+ }
+ kp = (ckcapiCert == io->type) ? &io->u.cert.key : &io->u.key.key;
+
+ rc = CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, buf, &bufLen);
+ if (!rc) {
+ goto loser;
+ }
+ buf = nss_ZNEWARRAY(NULL, char, bufLen);
+ rc = CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, buf, &bufLen);
+ if (!rc) {
+ goto loser;
+ }
+ /* validate the blob */
+ blob = (CAPI_RSA_KEY_BLOB *)buf;
+ if ((PRIVATEKEYBLOB != blob->header.bType) ||
+ (0x02 != blob->header.bVersion) ||
+ (0x32415352 != blob->rsa.magic)) {
+ goto loser;
+ }
+ modulus = blob->rsa.bitlen/8;
+ kp->privateKey = buf;
+ buf = NULL;
+
+ kp->privateExponent.data = &blob->data[CAPI_PRIVATE_EXP_OFFSET(modulus)];
+ kp->privateExponent.size = modulus;
+ ckcapi_ReverseData(&kp->privateExponent);
+ kp->prime1.data = &blob->data[CAPI_PRIME_1_OFFSET(modulus)];
+ kp->prime1.size = modulus/2;
+ ckcapi_ReverseData(&kp->prime1);
+ kp->prime2.data = &blob->data[CAPI_PRIME_2_OFFSET(modulus)];
+ kp->prime2.size = modulus/2;
+ ckcapi_ReverseData(&kp->prime2);
+ kp->exponent1.data = &blob->data[CAPI_EXPONENT_1_OFFSET(modulus)];
+ kp->exponent1.size = modulus/2;
+ ckcapi_ReverseData(&kp->exponent1);
+ kp->exponent2.data = &blob->data[CAPI_EXPONENT_2_OFFSET(modulus)];
+ kp->exponent2.size = modulus/2;
+ ckcapi_ReverseData(&kp->exponent2);
+ kp->coefficient.data = &blob->data[CAPI_COEFFICIENT_OFFSET(modulus)];
+ kp->coefficient.size = modulus/2;
+ ckcapi_ReverseData(&kp->coefficient);
+
+loser:
+ nss_ZFreeIf(buf);
+ if (0 != hKey) {
+ CryptDestroyKey(hKey);
+ }
+ return;
+}
+
+
+void
+ckcapi_PopulateModulusExponent
+(
+ ckcapiInternalObject *io
+)
+{
+ if (ckcapiCert == io->type) {
+ ckcapi_CertPopulateModulusExponent(io);
+ } else {
+ ckcapi_FetchPublicKey(io);
+ }
+ return;
+}
+
+/*
+ * fetch the friendly name attribute.
+ * can only be called with ckcapiCert type objects!
+ */
+void
+ckcapi_FetchLabel
+(
+ ckcapiInternalObject *io
+)
+{
+ ckcapiCertObject *co = &io->u.cert;
+ char *label;
+ PCCERT_CONTEXT certContext = io->u.cert.certContext;
+ char labelDataUTF16[128];
+ DWORD size = sizeof(labelDataUTF16);
+ DWORD size8 = sizeof(co->labelData);
+ BOOL rv;
+
+ rv = CertGetCertificateContextProperty(certContext,
+ CERT_FRIENDLY_NAME_PROP_ID, labelDataUTF16, &size);
+ if (rv) {
+ co->labelData = nss_ckcapi_WideToUTF8((LPCWSTR)labelDataUTF16);
+ if ((CHAR *)NULL == co->labelData) {
+ rv = 0;
+ } else {
+ size = strlen(co->labelData);
+ }
+ }
+ label = co->labelData;
+ /* we are presuming a user cert, make sure it has a nickname, even if
+ * Microsoft never gave it one */
+ if (!rv && co->hasID) {
+ DWORD mserror = GetLastError();
+#define DEFAULT_NICKNAME "no Microsoft nickname"
+ label = DEFAULT_NICKNAME;
+ size = sizeof(DEFAULT_NICKNAME);
+ rv = 1;
+ }
+
+ if (rv) {
+ co->label.data = label;
+ co->label.size = size;
+ }
+ return;
+}
+
+void
+ckcapi_FetchSerial
+(
+ ckcapiInternalObject *io
+)
+{
+ ckcapiCertObject *co = &io->u.cert;
+ PCCERT_CONTEXT certContext = io->u.cert.certContext;
+ DWORD size = sizeof(co->derSerial);
+
+ BOOL rc = CryptEncodeObject(X509_ASN_ENCODING,
+ X509_MULTI_BYTE_INTEGER,
+ &certContext->pCertInfo->SerialNumber,
+ co->derSerial,
+ &size);
+ if (rc) {
+ co->serial.data = co->derSerial;
+ co->serial.size = size;
+ }
+ return;
+}
+
+/*
+ * fetch the key ID.
+ */
+void
+ckcapi_FetchID
+(
+ ckcapiInternalObject *io
+)
+{
+ PCCERT_CONTEXT certContext = io->u.cert.certContext;
+ DWORD size = 0;
+ BOOL rc;
+
+ rc = CertGetCertificateContextProperty(certContext,
+ CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
+ if (!rc) {
+ return;
+ }
+ io->idData = nss_ZNEWARRAY(NULL, char, size);
+ if (io->idData == NULL) {
+ return;
+ }
+
+ rc = CertGetCertificateContextProperty(certContext,
+ CERT_KEY_IDENTIFIER_PROP_ID, io->idData, &size);
+ if (!rc) {
+ nss_ZFreeIf(io->idData);
+ io->idData = NULL;
+ return;
+ }
+ io->id.data = io->idData;
+ io->id.size = size;
+ return;
+}
+
+/*
+ * fetch the hash key.
+ */
+void
+ckcapi_CertFetchHashKey
+(
+ ckcapiInternalObject *io
+)
+{
+ ckcapiCertObject *co = &io->u.cert;
+ PCCERT_CONTEXT certContext = io->u.cert.certContext;
+ DWORD size = certContext->cbCertEncoded;
+ DWORD max = sizeof(io->hashKeyData)-1;
+ DWORD offset = 0;
+
+ /* make sure we don't over flow. NOTE: cutting the top of a cert is
+ * not a big issue because the signature for will be unique for the cert */
+ if (size > max) {
+ offset = size - max;
+ size = max;
+ }
+
+ nsslibc_memcpy(io->hashKeyData,certContext->pbCertEncoded+offset, size);
+ io->hashKeyData[size] = (char)(io->objClass & 0xff);
+
+ io->hashKey.data = io->hashKeyData;
+ io->hashKey.size = size+1;
+ return;
+}
+
+/*
+ * fetch the hash key.
+ */
+void
+ckcapi_KeyFetchHashKey
+(
+ ckcapiInternalObject *io
+)
+{
+ ckcapiKeyObject *ko = &io->u.key;
+ DWORD size;
+ DWORD max = sizeof(io->hashKeyData)-2;
+ DWORD offset = 0;
+ DWORD provLen = strlen(ko->provName);
+ DWORD containerLen = strlen(ko->containerName);
+
+
+ size = provLen + containerLen;
+
+ /* make sure we don't overflow, try to keep things unique */
+ if (size > max) {
+ DWORD diff = ((size - max)+1)/2;
+ provLen -= diff;
+ containerLen -= diff;
+ size = provLen+containerLen;
+ }
+
+ nsslibc_memcpy(io->hashKeyData, ko->provName, provLen);
+ nsslibc_memcpy(&io->hashKeyData[provLen],
+ ko->containerName,
+ containerLen);
+ io->hashKeyData[size] = (char)(io->objClass & 0xff);
+ io->hashKeyData[size+1] = (char)(ko->provInfo.dwKeySpec & 0xff);
+
+ io->hashKey.data = io->hashKeyData;
+ io->hashKey.size = size+2;
+ return;
+}
+
+/*
+ * fetch the hash key.
+ */
+void
+ckcapi_FetchHashKey
+(
+ ckcapiInternalObject *io
+)
+{
+ if (ckcapiCert == io->type) {
+ ckcapi_CertFetchHashKey(io);
+ } else {
+ ckcapi_KeyFetchHashKey(io);
+ }
+ return;
+}
+
+const NSSItem *
+ckcapi_FetchCertAttribute
+(
+ ckcapiInternalObject *io,
+ CK_ATTRIBUTE_TYPE type
+)
+{
+ PCCERT_CONTEXT certContext = io->u.cert.certContext;
+ switch(type) {
+ case CKA_CLASS:
+ return &ckcapi_certClassItem;
+ case CKA_TOKEN:
+ return &ckcapi_trueItem;
+ case CKA_MODIFIABLE:
+ case CKA_PRIVATE:
+ return &ckcapi_falseItem;
+ case CKA_CERTIFICATE_TYPE:
+ return &ckcapi_x509Item;
+ case CKA_LABEL:
+ if (0 == io->u.cert.label.size) {
+ ckcapi_FetchLabel(io);
+ }
+ return &io->u.cert.label;
+ case CKA_SUBJECT:
+ if (0 == io->u.cert.subject.size) {
+ io->u.cert.subject.data = certContext->pCertInfo->Subject.pbData;
+ io->u.cert.subject.size = certContext->pCertInfo->Subject.cbData;
+ }
+ return &io->u.cert.subject;
+ case CKA_ISSUER:
+ if (0 == io->u.cert.issuer.size) {
+ io->u.cert.issuer.data = certContext->pCertInfo->Issuer.pbData;
+ io->u.cert.issuer.size = certContext->pCertInfo->Issuer.cbData;
+ }
+ return &io->u.cert.issuer;
+ case CKA_SERIAL_NUMBER:
+ if (0 == io->u.cert.serial.size) {
+ /* not exactly right. This should be the encoded serial number, but
+ * it's the decoded serial number! */
+ ckcapi_FetchSerial(io);
+ }
+ return &io->u.cert.serial;
+ case CKA_VALUE:
+ if (0 == io->u.cert.derCert.size) {
+ io->u.cert.derCert.data = io->u.cert.certContext->pbCertEncoded;
+ io->u.cert.derCert.size = io->u.cert.certContext->cbCertEncoded;
+ }
+ return &io->u.cert.derCert;
+ case CKA_ID:
+ if (!io->u.cert.hasID) {
+ return NULL;
+ }
+ if (0 == io->id.size) {
+ ckcapi_FetchID(io);
+ }
+ return &io->id;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+const NSSItem *
+ckcapi_FetchPubKeyAttribute
+(
+ ckcapiInternalObject *io,
+ CK_ATTRIBUTE_TYPE type
+)
+{
+ PRBool isCertType = (ckcapiCert == io->type);
+ ckcapiKeyParams *kp = isCertType ? &io->u.cert.key : &io->u.key.key;
+
+ switch(type) {
+ case CKA_CLASS:
+ return &ckcapi_pubKeyClassItem;
+ case CKA_TOKEN:
+ case CKA_LOCAL:
+ case CKA_ENCRYPT:
+ case CKA_VERIFY:
+ case CKA_VERIFY_RECOVER:
+ return &ckcapi_trueItem;
+ case CKA_PRIVATE:
+ case CKA_MODIFIABLE:
+ case CKA_DERIVE:
+ case CKA_WRAP:
+ return &ckcapi_falseItem;
+ case CKA_KEY_TYPE:
+ return &ckcapi_rsaItem;
+ case CKA_LABEL:
+ if (!isCertType) {
+ return &ckcapi_emptyItem;
+ }
+ if (0 == io->u.cert.label.size) {
+ ckcapi_FetchLabel(io);
+ }
+ return &io->u.cert.label;
+ case CKA_SUBJECT:
+ if (!isCertType) {
+ return &ckcapi_emptyItem;
+ }
+ if (0 == io->u.cert.subject.size) {
+ PCCERT_CONTEXT certContext= io->u.cert.certContext;
+ io->u.cert.subject.data = certContext->pCertInfo->Subject.pbData;
+ io->u.cert.subject.size = certContext->pCertInfo->Subject.cbData;
+ }
+ return &io->u.cert.subject;
+ case CKA_MODULUS:
+ if (0 == kp->modulus.size) {
+ ckcapi_PopulateModulusExponent(io);
+ }
+ return &kp->modulus;
+ case CKA_PUBLIC_EXPONENT:
+ if (0 == kp->modulus.size) {
+ ckcapi_PopulateModulusExponent(io);
+ }
+ return &kp->exponent;
+ case CKA_ID:
+ if (0 == io->id.size) {
+ ckcapi_FetchID(io);
+ }
+ return &io->id;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+const NSSItem *
+ckcapi_FetchPrivKeyAttribute
+(
+ ckcapiInternalObject *io,
+ CK_ATTRIBUTE_TYPE type
+)
+{
+ PRBool isCertType = (ckcapiCert == io->type);
+ ckcapiKeyParams *kp = isCertType ? &io->u.cert.key : &io->u.key.key;
+
+ switch(type) {
+ case CKA_CLASS:
+ return &ckcapi_privKeyClassItem;
+ case CKA_TOKEN:
+ case CKA_LOCAL:
+ case CKA_SIGN:
+ case CKA_DECRYPT:
+ case CKA_SIGN_RECOVER:
+ return &ckcapi_trueItem;
+ case CKA_SENSITIVE:
+ case CKA_PRIVATE: /* should move in the future */
+ case CKA_MODIFIABLE:
+ case CKA_DERIVE:
+ case CKA_UNWRAP:
+ case CKA_EXTRACTABLE: /* will probably move in the future */
+ case CKA_ALWAYS_SENSITIVE:
+ case CKA_NEVER_EXTRACTABLE:
+ return &ckcapi_falseItem;
+ case CKA_KEY_TYPE:
+ return &ckcapi_rsaItem;
+ case CKA_LABEL:
+ if (!isCertType) {
+ return &ckcapi_emptyItem;
+ }
+ if (0 == io->u.cert.label.size) {
+ ckcapi_FetchLabel(io);
+ }
+ return &io->u.cert.label;
+ case CKA_SUBJECT:
+ if (!isCertType) {
+ return &ckcapi_emptyItem;
+ }
+ if (0 == io->u.cert.subject.size) {
+ PCCERT_CONTEXT certContext= io->u.cert.certContext;
+ io->u.cert.subject.data = certContext->pCertInfo->Subject.pbData;
+ io->u.cert.subject.size = certContext->pCertInfo->Subject.cbData;
+ }
+ return &io->u.cert.subject;
+ case CKA_MODULUS:
+ if (0 == kp->modulus.size) {
+ ckcapi_PopulateModulusExponent(io);
+ }
+ return &kp->modulus;
+ case CKA_PUBLIC_EXPONENT:
+ if (0 == kp->modulus.size) {
+ ckcapi_PopulateModulusExponent(io);
+ }
+ return &kp->exponent;
+ case CKA_PRIVATE_EXPONENT:
+ if (0 == kp->privateExponent.size) {
+ ckcapi_FetchPrivateKey(io);
+ }
+ return &kp->privateExponent;
+ case CKA_PRIME_1:
+ if (0 == kp->privateExponent.size) {
+ ckcapi_FetchPrivateKey(io);
+ }
+ return &kp->prime1;
+ case CKA_PRIME_2:
+ if (0 == kp->privateExponent.size) {
+ ckcapi_FetchPrivateKey(io);
+ }
+ return &kp->prime2;
+ case CKA_EXPONENT_1:
+ if (0 == kp->privateExponent.size) {
+ ckcapi_FetchPrivateKey(io);
+ }
+ return &kp->exponent1;
+ case CKA_EXPONENT_2:
+ if (0 == kp->privateExponent.size) {
+ ckcapi_FetchPrivateKey(io);
+ }
+ return &kp->exponent2;
+ case CKA_COEFFICIENT:
+ if (0 == kp->privateExponent.size) {
+ ckcapi_FetchPrivateKey(io);
+ }
+ return &kp->coefficient;
+ case CKA_ID:
+ if (0 == io->id.size) {
+ ckcapi_FetchID(io);
+ }
+ return &io->id;
+ default:
+ return NULL;
+ }
+}
+
+const NSSItem *
+nss_ckcapi_FetchAttribute
+(
+ ckcapiInternalObject *io,
+ CK_ATTRIBUTE_TYPE type
+)
+{
+ CK_ULONG i;
+
+ if (io->type == ckcapiRaw) {
+ for( i = 0; i < io->u.raw.n; i++ ) {
+ if( type == io->u.raw.types[i] ) {
+ return &io->u.raw.items[i];
+ }
+ }
+ return NULL;
+ }
+ /* deal with the common attributes */
+ switch (io->objClass) {
+ case CKO_CERTIFICATE:
+ return ckcapi_FetchCertAttribute(io, type);
+ case CKO_PRIVATE_KEY:
+ return ckcapi_FetchPrivKeyAttribute(io, type);
+ case CKO_PUBLIC_KEY:
+ return ckcapi_FetchPubKeyAttribute(io, type);
+ }
+ return NULL;
+}
+
+/*
+ * check to see if the certificate already exists
+ */
+static PRBool
+ckcapi_cert_exists(
+ NSSItem *value,
+ ckcapiInternalObject **io
+)
+{
+ int count,i;
+ PRUint32 size = 0;
+ ckcapiInternalObject **listp = NULL;
+ CK_ATTRIBUTE myTemplate[2];
+ CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
+ CK_ULONG templateCount = 2;
+ CK_RV error;
+ PRBool found = PR_FALSE;
+
+ myTemplate[0].type = CKA_CLASS;
+ myTemplate[0].pValue = &cert_class;
+ myTemplate[0].ulValueLen = sizeof(cert_class);
+ myTemplate[1].type = CKA_VALUE;
+ myTemplate[1].pValue = value->data;
+ myTemplate[1].ulValueLen = value->size;
+
+ count = nss_ckcapi_collect_all_certs(myTemplate, templateCount, &listp,
+ &size, 0, &error);
+
+ /* free them */
+ if (count > 1) {
+ *io = listp[0];
+ found = PR_TRUE;
+ }
+
+ for (i=1; i < count; i++) {
+ nss_ckcapi_DestroyInternalObject(listp[i]);
+ }
+ nss_ZFreeIf(listp);
+ return found;
+}
+
+static PRBool
+ckcapi_cert_hasEmail
+(
+ PCCERT_CONTEXT certContext
+)
+{
+ int count;
+
+ count = CertGetNameString(certContext, CERT_NAME_EMAIL_TYPE,
+ 0, NULL, NULL, 0);
+
+ return count > 1 ? PR_TRUE : PR_FALSE;
+}
+
+static PRBool
+ckcapi_cert_isRoot
+(
+ PCCERT_CONTEXT certContext
+)
+{
+ return CertCompareCertificateName(certContext->dwCertEncodingType,
+ &certContext->pCertInfo->Issuer, &certContext->pCertInfo->Subject);
+}
+
+static PRBool
+ckcapi_cert_isCA
+(
+ PCCERT_CONTEXT certContext
+)
+{
+ PCERT_EXTENSION extension;
+ CERT_BASIC_CONSTRAINTS2_INFO basicInfo;
+ DWORD size = sizeof(basicInfo);
+ BOOL rc;
+
+ extension = CertFindExtension (szOID_BASIC_CONSTRAINTS,
+ certContext->pCertInfo->cExtension,
+ certContext->pCertInfo->rgExtension);
+ if ((PCERT_EXTENSION) NULL == extension ) {
+ return PR_FALSE;
+ }
+ rc = CryptDecodeObject(X509_ASN_ENCODING, szOID_BASIC_CONSTRAINTS2,
+ extension->Value.pbData, extension->Value.cbData,
+ 0, &basicInfo, &size);
+ if (!rc) {
+ return PR_FALSE;
+ }
+ return (PRBool) basicInfo.fCA;
+}
+
+static CRYPT_KEY_PROV_INFO *
+ckcapi_cert_getPrivateKeyInfo
+(
+ PCCERT_CONTEXT certContext,
+ NSSItem *keyID
+)
+{
+ BOOL rc;
+ CRYPT_HASH_BLOB msKeyID;
+ DWORD size = 0;
+ CRYPT_KEY_PROV_INFO *prov = NULL;
+
+ msKeyID.cbData = keyID->size;
+ msKeyID.pbData = keyID->data;
+
+ rc = CryptGetKeyIdentifierProperty(
+ &msKeyID,
+ CERT_KEY_PROV_INFO_PROP_ID,
+ 0, NULL, NULL, NULL, &size);
+ if (!rc) {
+ return (CRYPT_KEY_PROV_INFO *)NULL;
+ }
+ prov = (CRYPT_KEY_PROV_INFO *)nss_ZAlloc(NULL, size);
+ if ((CRYPT_KEY_PROV_INFO *)prov == NULL) {
+ return (CRYPT_KEY_PROV_INFO *) NULL;
+ }
+ rc = CryptGetKeyIdentifierProperty(
+ &msKeyID,
+ CERT_KEY_PROV_INFO_PROP_ID,
+ 0, NULL, NULL, prov, &size);
+ if (!rc) {
+ nss_ZFreeIf(prov);
+ return (CRYPT_KEY_PROV_INFO *)NULL;
+ }
+
+ return prov;
+}
+
+static CRYPT_KEY_PROV_INFO *
+ckcapi_cert_getProvInfo
+(
+ ckcapiInternalObject *io
+)
+{
+ BOOL rc;
+ DWORD size = 0;
+ CRYPT_KEY_PROV_INFO *prov = NULL;
+
+ rc = CertGetCertificateContextProperty(
+ io->u.cert.certContext,
+ CERT_KEY_PROV_INFO_PROP_ID,
+ NULL, &size);
+ if (!rc) {
+ return (CRYPT_KEY_PROV_INFO *)NULL;
+ }
+ prov = (CRYPT_KEY_PROV_INFO *)nss_ZAlloc(NULL, size);
+ if ((CRYPT_KEY_PROV_INFO *)prov == NULL) {
+ return (CRYPT_KEY_PROV_INFO *) NULL;
+ }
+ rc = CertGetCertificateContextProperty(
+ io->u.cert.certContext,
+ CERT_KEY_PROV_INFO_PROP_ID,
+ prov, &size);
+ if (!rc) {
+ nss_ZFreeIf(prov);
+ return (CRYPT_KEY_PROV_INFO *)NULL;
+ }
+
+ return prov;
+}
+
+/* forward declaration */
+static void
+ckcapi_removeObjectFromHash
+(
+ ckcapiInternalObject *io
+);
+
+/*
+ * Finalize - unneeded
+ * Destroy
+ * IsTokenObject - CK_TRUE
+ * GetAttributeCount
+ * GetAttributeTypes
+ * GetAttributeSize
+ * GetAttribute
+ * SetAttribute
+ * GetObjectSize
+ */
+
+static CK_RV
+ckcapi_mdObject_Destroy
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
+ CK_OBJECT_CLASS objClass;
+ BOOL rc;
+ DWORD provType;
+ DWORD msError;
+ PRBool isCertType = (PRBool)(ckcapiCert == io->type);
+ HCERTSTORE hStore = 0;
+
+ if (ckcapiRaw == io->type) {
+ /* there is not 'object write protected' error, use the next best thing */
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+
+ objClass = io->objClass;
+ if (CKO_CERTIFICATE == objClass) {
+ PCCERT_CONTEXT certContext;
+
+ /* get the store */
+ hStore = CertOpenSystemStore(0, io->u.cert.certStore);
+ if (0 == hStore) {
+ rc = 0;
+ goto loser;
+ }
+ certContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING, 0,
+ CERT_FIND_EXISTING, io->u.cert.certContext, NULL);
+ if ((PCCERT_CONTEXT)NULL == certContext) {
+ rc = 0;
+ goto loser;
+ }
+ rc = CertDeleteCertificateFromStore(certContext);
+ CertFreeCertificateContext(certContext);
+ } else {
+ char *provName = NULL;
+ char *containerName = NULL;
+ HCRYPTPROV hProv;
+ CRYPT_HASH_BLOB msKeyID;
+
+ if (0 == io->id.size) {
+ ckcapi_FetchID(io);
+ }
+
+ if (isCertType) {
+ CRYPT_KEY_PROV_INFO * provInfo = ckcapi_cert_getProvInfo(io);
+ provName = nss_ckcapi_WideToUTF8(provInfo->pwszProvName);
+ containerName = nss_ckcapi_WideToUTF8(provInfo->pwszContainerName);
+ provType = provInfo->dwProvType;
+ nss_ZFreeIf(provInfo);
+ } else {
+ provName = io->u.key.provName;
+ containerName = io->u.key.containerName;
+ provType = io->u.key.provInfo.dwProvType;
+ io->u.key.provName = NULL;
+ io->u.key.containerName = NULL;
+ }
+ /* first remove the key id pointer */
+ msKeyID.cbData = io->id.size;
+ msKeyID.pbData = io->id.data;
+ rc = CryptSetKeyIdentifierProperty(&msKeyID,
+ CERT_KEY_PROV_INFO_PROP_ID, CRYPT_KEYID_DELETE_FLAG, NULL, NULL, NULL);
+ if (rc) {
+ rc = CryptAcquireContext(&hProv, containerName, provName, provType,
+ CRYPT_DELETEKEYSET);
+ }
+ nss_ZFreeIf(provName);
+ nss_ZFreeIf(containerName);
+ }
+loser:
+
+ if (hStore) {
+ CertCloseStore(hStore, 0);
+ }
+ if (!rc) {
+ msError = GetLastError();
+ return CKR_GENERAL_ERROR;
+ }
+
+ /* remove it from the hash */
+ ckcapi_removeObjectFromHash(io);
+
+ /* free the puppy.. */
+ nss_ckcapi_DestroyInternalObject(io);
+ return CKR_OK;
+}
+
+static CK_BBOOL
+ckcapi_mdObject_IsTokenObject
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return CK_TRUE;
+}
+
+static CK_ULONG
+ckcapi_mdObject_GetAttributeCount
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
+
+ if (ckcapiRaw == io->type) {
+ return io->u.raw.n;
+ }
+ switch (io->objClass) {
+ case CKO_CERTIFICATE:
+ return certAttrsCount;
+ case CKO_PUBLIC_KEY:
+ return pubKeyAttrsCount;
+ case CKO_PRIVATE_KEY:
+ return privKeyAttrsCount;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static CK_RV
+ckcapi_mdObject_GetAttributeTypes
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE_PTR typeArray,
+ CK_ULONG ulCount
+)
+{
+ ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
+ CK_ULONG i;
+ CK_RV error = CKR_OK;
+ const CK_ATTRIBUTE_TYPE *attrs = NULL;
+ CK_ULONG size = ckcapi_mdObject_GetAttributeCount(
+ mdObject, fwObject, mdSession, fwSession,
+ mdToken, fwToken, mdInstance, fwInstance, &error);
+
+ if( size != ulCount ) {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ if (io->type == ckcapiRaw) {
+ attrs = io->u.raw.types;
+ } else switch(io->objClass) {
+ case CKO_CERTIFICATE:
+ attrs = certAttrs;
+ break;
+ case CKO_PUBLIC_KEY:
+ attrs = pubKeyAttrs;
+ break;
+ case CKO_PRIVATE_KEY:
+ attrs = privKeyAttrs;
+ break;
+ default:
+ return CKR_OK;
+ }
+
+ for( i = 0; i < size; i++) {
+ typeArray[i] = attrs[i];
+ }
+
+ return CKR_OK;
+}
+
+static CK_ULONG
+ckcapi_mdObject_GetAttributeSize
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+)
+{
+ ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
+
+ const NSSItem *b;
+
+ b = nss_ckcapi_FetchAttribute(io, attribute);
+
+ if ((const NSSItem *)NULL == b) {
+ *pError = CKR_ATTRIBUTE_TYPE_INVALID;
+ return 0;
+ }
+ return b->size;
+}
+
+static CK_RV
+ckcapi_mdObject_SetAttribute
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ NSSItem *value
+)
+{
+ return CKR_OK;
+}
+
+static NSSCKFWItem
+ckcapi_mdObject_GetAttribute
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+)
+{
+ NSSCKFWItem mdItem;
+ ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
+
+ mdItem.needsFreeing = PR_FALSE;
+ mdItem.item = (NSSItem*)nss_ckcapi_FetchAttribute(io, attribute);
+
+ if ((NSSItem *)NULL == mdItem.item) {
+ *pError = CKR_ATTRIBUTE_TYPE_INVALID;
+ }
+
+ return mdItem;
+}
+
+static CK_ULONG
+ckcapi_mdObject_GetObjectSize
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
+ CK_ULONG rv = 1;
+
+ /* size is irrelevant to this token */
+ return rv;
+}
+
+static const NSSCKMDObject
+ckcapi_prototype_mdObject = {
+ (void *)NULL, /* etc */
+ NULL, /* Finalize */
+ ckcapi_mdObject_Destroy,
+ ckcapi_mdObject_IsTokenObject,
+ ckcapi_mdObject_GetAttributeCount,
+ ckcapi_mdObject_GetAttributeTypes,
+ ckcapi_mdObject_GetAttributeSize,
+ ckcapi_mdObject_GetAttribute,
+ NULL, /* FreeAttribute */
+ ckcapi_mdObject_SetAttribute,
+ ckcapi_mdObject_GetObjectSize,
+ (void *)NULL /* null terminator */
+};
+
+static nssHash *ckcapiInternalObjectHash = NULL;
+
+NSS_IMPLEMENT NSSCKMDObject *
+nss_ckcapi_CreateMDObject
+(
+ NSSArena *arena,
+ ckcapiInternalObject *io,
+ CK_RV *pError
+)
+{
+ if ((nssHash *)NULL == ckcapiInternalObjectHash) {
+ ckcapiInternalObjectHash = nssHash_CreateItem(NULL, 10);
+ }
+ if (ckcapiCert == io->type) {
+ /* the hash key, not a cryptographic key */
+ NSSItem *key = &io->hashKey;
+ ckcapiInternalObject *old_o = NULL;
+
+ if (key->size == 0) {
+ ckcapi_FetchHashKey(io);
+ }
+ old_o = (ckcapiInternalObject *)
+ nssHash_Lookup(ckcapiInternalObjectHash, key);
+ if (!old_o) {
+ nssHash_Add(ckcapiInternalObjectHash, key, io);
+ } else if (old_o != io) {
+ nss_ckcapi_DestroyInternalObject(io);
+ io = old_o;
+ }
+ }
+
+ if ( (void*)NULL == io->mdObject.etc) {
+ (void) nsslibc_memcpy(&io->mdObject,&ckcapi_prototype_mdObject,
+ sizeof(ckcapi_prototype_mdObject));
+ io->mdObject.etc = (void *)io;
+ }
+ return &io->mdObject;
+}
+
+static void
+ckcapi_removeObjectFromHash
+(
+ ckcapiInternalObject *io
+)
+{
+ NSSItem *key = &io->hashKey;
+
+ if ((nssHash *)NULL == ckcapiInternalObjectHash) {
+ return;
+ }
+ if (key->size == 0) {
+ ckcapi_FetchHashKey(io);
+ }
+ nssHash_Remove(ckcapiInternalObjectHash, key);
+ return;
+}
+
+void
+nss_ckcapi_DestroyInternalObject
+(
+ ckcapiInternalObject *io
+)
+{
+ switch (io->type) {
+ case ckcapiRaw:
+ return;
+ case ckcapiCert:
+ CertFreeCertificateContext(io->u.cert.certContext);
+ nss_ZFreeIf(io->u.cert.labelData);
+ nss_ZFreeIf(io->u.cert.key.privateKey);
+ nss_ZFreeIf(io->u.cert.key.pubKey);
+ nss_ZFreeIf(io->idData);
+ break;
+ case ckcapiBareKey:
+ nss_ZFreeIf(io->u.key.provInfo.pwszContainerName);
+ nss_ZFreeIf(io->u.key.provInfo.pwszProvName);
+ nss_ZFreeIf(io->u.key.provName);
+ nss_ZFreeIf(io->u.key.containerName);
+ nss_ZFreeIf(io->u.key.key.privateKey);
+ nss_ZFreeIf(io->u.key.key.pubKey);
+ if (0 != io->u.key.hProv) {
+ CryptReleaseContext(io->u.key.hProv, 0);
+ }
+ nss_ZFreeIf(io->idData);
+ break;
+ }
+ nss_ZFreeIf(io);
+ return;
+}
+
+static ckcapiInternalObject *
+nss_ckcapi_CreateCertificate
+(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+)
+{
+ NSSItem value;
+ NSSItem keyID;
+ char *storeStr;
+ ckcapiInternalObject *io = NULL;
+ PCCERT_CONTEXT certContext = NULL;
+ PCCERT_CONTEXT storedCertContext = NULL;
+ CRYPT_KEY_PROV_INFO *prov_info = NULL;
+ char *nickname = NULL;
+ HCERTSTORE hStore = 0;
+ DWORD msError = 0;
+ PRBool hasID;
+ CK_RV dummy;
+ BOOL rc;
+
+ *pError = nss_ckcapi_GetAttribute(CKA_VALUE, pTemplate,
+ ulAttributeCount, &value);
+
+ if (CKR_OK != *pError) {
+ return (ckcapiInternalObject *)NULL;
+ }
+
+ *pError = nss_ckcapi_GetAttribute(CKA_ID, pTemplate,
+ ulAttributeCount, &keyID);
+
+ if (CKR_OK != *pError) {
+ return (ckcapiInternalObject *)NULL;
+ }
+
+ if (ckcapi_cert_exists(&value, &io)) {
+ return io;
+ }
+
+ /* OK, we are creating a new one, figure out what store it belongs to..
+ * first get a certContext handle.. */
+ certContext = CertCreateCertificateContext(X509_ASN_ENCODING,
+ value.data, value.size);
+ if ((PCCERT_CONTEXT) NULL == certContext) {
+ msError = GetLastError();
+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto loser;
+ }
+
+ /* do we have a private key laying around... */
+ prov_info = ckcapi_cert_getPrivateKeyInfo(certContext, &keyID);
+ if (prov_info) {
+ CRYPT_DATA_BLOB msKeyID;
+ storeStr = "My";
+ hasID = PR_TRUE;
+ rc = CertSetCertificateContextProperty(certContext,
+ CERT_KEY_PROV_INFO_PROP_ID,
+ 0, prov_info);
+ nss_ZFreeIf(prov_info);
+ if (!rc) {
+ msError = GetLastError();
+ *pError = CKR_DEVICE_ERROR;
+ goto loser;
+ }
+ msKeyID.cbData = keyID.size;
+ msKeyID.pbData = keyID.data;
+ rc = CertSetCertificateContextProperty(certContext,
+ CERT_KEY_IDENTIFIER_PROP_ID,
+ 0, &msKeyID);
+ if (!rc) {
+ msError = GetLastError();
+ *pError = CKR_DEVICE_ERROR;
+ goto loser;
+ }
+
+ /* does it look like a CA */
+ } else if (ckcapi_cert_isCA(certContext)) {
+ storeStr = ckcapi_cert_isRoot(certContext) ? "CA" : "Root";
+ /* does it look like an S/MIME cert */
+ } else if (ckcapi_cert_hasEmail(certContext)) {
+ storeStr = "AddressBook";
+ } else {
+ /* just pick a store */
+ storeStr = "CA";
+ }
+
+ /* get the nickname, not an error if we can't find it */
+ nickname = nss_ckcapi_GetStringAttribute(CKA_LABEL, pTemplate,
+ ulAttributeCount, &dummy);
+ if (nickname) {
+ LPWSTR nicknameUTF16 = NULL;
+ CRYPT_DATA_BLOB nicknameBlob;
+
+ nicknameUTF16 = nss_ckcapi_UTF8ToWide(nickname);
+ nss_ZFreeIf(nickname);
+ nickname = NULL;
+ if ((LPWSTR)NULL == nicknameUTF16) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ nicknameBlob.cbData = nss_ckcapi_WideSize(nicknameUTF16);
+ nicknameBlob.pbData = (BYTE *)nicknameUTF16;
+ rc = CertSetCertificateContextProperty(certContext,
+ CERT_FRIENDLY_NAME_PROP_ID, 0, &nicknameBlob);
+ nss_ZFreeIf(nicknameUTF16);
+ if (!rc) {
+ msError = GetLastError();
+ *pError = CKR_DEVICE_ERROR;
+ goto loser;
+ }
+ }
+
+ hStore = CertOpenSystemStore((HCRYPTPROV) NULL, storeStr);
+ if (0 == hStore) {
+ msError = GetLastError();
+ *pError = CKR_DEVICE_ERROR;
+ goto loser;
+ }
+
+ rc = CertAddCertificateContextToStore(hStore, certContext,
+ CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, &storedCertContext);
+ CertFreeCertificateContext(certContext);
+ certContext = NULL;
+ CertCloseStore(hStore, 0);
+ hStore = 0;
+ if (!rc) {
+ msError = GetLastError();
+ *pError = CKR_DEVICE_ERROR;
+ goto loser;
+ }
+
+ io = nss_ZNEW(NULL, ckcapiInternalObject);
+ if ((ckcapiInternalObject *)NULL == io) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ io->type = ckcapiCert;
+ io->objClass = CKO_CERTIFICATE;
+ io->u.cert.certContext = storedCertContext;
+ io->u.cert.hasID = hasID;
+ return io;
+
+loser:
+ if (certContext) {
+ CertFreeCertificateContext(certContext);
+ certContext = NULL;
+ }
+ if (storedCertContext) {
+ CertFreeCertificateContext(storedCertContext);
+ storedCertContext = NULL;
+ }
+ if (0 != hStore) {
+ CertCloseStore(hStore, 0);
+ }
+ return (ckcapiInternalObject *)NULL;
+
+}
+
+static char *
+ckcapi_getDefaultProvider
+(
+ CK_RV *pError
+)
+{
+ char *name = NULL;
+ BOOL rc;
+ DWORD nameLength = 0;
+
+ rc = CryptGetDefaultProvider(PROV_RSA_FULL, NULL, CRYPT_USER_DEFAULT, NULL,
+ &nameLength);
+ if (!rc) {
+ return (char *)NULL;
+ }
+
+ name = nss_ZNEWARRAY(NULL, char, nameLength);
+ if ((char *)NULL == name ) {
+ return (char *)NULL;
+ }
+ rc = CryptGetDefaultProvider(PROV_RSA_FULL, NULL, CRYPT_USER_DEFAULT, name,
+ &nameLength);
+ if (!rc) {
+ nss_ZFreeIf(name);
+ return (char *)NULL;
+ }
+
+ return name;
+}
+
+static char *
+ckcapi_getContainer
+(
+ CK_RV *pError,
+ NSSItem *id
+)
+{
+ RPC_STATUS rstat;
+ UUID uuid;
+ char *uuidStr;
+ char *container;
+
+ rstat = UuidCreate(&uuid);
+ rstat = UuidToString(&uuid, &uuidStr);
+
+ /* convert it from rcp memory to our own */
+ container = nssUTF8_Duplicate(uuidStr, NULL);
+ RpcStringFree(&uuidStr);
+
+ return container;
+}
+
+static CK_RV
+ckcapi_buildPrivateKeyBlob
+(
+ NSSItem *keyBlob,
+ NSSItem *modulus,
+ NSSItem *publicExponent,
+ NSSItem *privateExponent,
+ NSSItem *prime1,
+ NSSItem *prime2,
+ NSSItem *exponent1,
+ NSSItem *exponent2,
+ NSSItem *coefficient,
+ PRBool isKeyExchange
+)
+{
+ CAPI_RSA_KEY_BLOB *keyBlobData = NULL;
+ unsigned char *target;
+ unsigned long modSize = modulus->size;
+ unsigned long dataSize;
+ CK_RV error = CKR_OK;
+
+ /* validate extras */
+ if (privateExponent->size != modSize) {
+ error = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto loser;
+ }
+ if (prime1->size != modSize/2) {
+ error = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto loser;
+ }
+ if (prime2->size != modSize/2) {
+ error = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto loser;
+ }
+ if (exponent1->size != modSize/2) {
+ error = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto loser;
+ }
+ if (exponent2->size != modSize/2) {
+ error = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto loser;
+ }
+ if (coefficient->size != modSize/2) {
+ error = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto loser;
+ }
+ dataSize = (modSize*4)+(modSize/2) + sizeof(CAPI_RSA_KEY_BLOB);
+ keyBlobData = (CAPI_RSA_KEY_BLOB *)nss_ZAlloc(NULL, dataSize);
+ if ((CAPI_RSA_KEY_BLOB *)NULL == keyBlobData) {
+ error = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ keyBlobData->header.bType = PRIVATEKEYBLOB;
+ keyBlobData->header.bVersion = 0x02;
+ keyBlobData->header.reserved = 0x00;
+ keyBlobData->header.aiKeyAlg = isKeyExchange ? CALG_RSA_KEYX:CALG_RSA_SIGN;
+ keyBlobData->rsa.magic = 0x32415352;
+ keyBlobData->rsa.bitlen = modSize * 8;
+ keyBlobData->rsa.pubexp = nss_ckcapi_DataToInt(publicExponent,&error);
+ if (CKR_OK != error) {
+ goto loser;
+ }
+
+ target = &keyBlobData->data[CAPI_MODULUS_OFFSET(modSize)];
+ nsslibc_memcpy(target, modulus->data, modulus->size);
+ modulus->data = target;
+ ckcapi_ReverseData(modulus);
+
+ target = &keyBlobData->data[CAPI_PRIVATE_EXP_OFFSET(modSize)];
+ nsslibc_memcpy(target, privateExponent->data, privateExponent->size);
+ privateExponent->data = target;
+ ckcapi_ReverseData(privateExponent);
+
+ target = &keyBlobData->data[CAPI_PRIME_1_OFFSET(modSize)];
+ nsslibc_memcpy(target, prime1->data, prime1->size);
+ prime1->data = target;
+ ckcapi_ReverseData(prime1);
+
+ target = &keyBlobData->data[CAPI_PRIME_2_OFFSET(modSize)];
+ nsslibc_memcpy(target, prime2->data, prime2->size);
+ prime2->data = target;
+ ckcapi_ReverseData(prime2);
+
+ target = &keyBlobData->data[CAPI_EXPONENT_1_OFFSET(modSize)];
+ nsslibc_memcpy(target, exponent1->data, exponent1->size);
+ exponent1->data = target;
+ ckcapi_ReverseData(exponent1);
+
+ target = &keyBlobData->data[CAPI_EXPONENT_2_OFFSET(modSize)];
+ nsslibc_memcpy(target, exponent2->data, exponent2->size);
+ exponent2->data = target;
+ ckcapi_ReverseData(exponent2);
+
+ target = &keyBlobData->data[CAPI_COEFFICIENT_OFFSET(modSize)];
+ nsslibc_memcpy(target, coefficient->data, coefficient->size);
+ coefficient->data = target;
+ ckcapi_ReverseData(coefficient);
+
+ keyBlob->data = keyBlobData;
+ keyBlob->size = dataSize;
+
+ return CKR_OK;
+
+loser:
+ nss_ZFreeIf(keyBlobData);
+ return error;
+}
+
+static ckcapiInternalObject *
+nss_ckcapi_CreatePrivateKey
+(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+)
+{
+ NSSItem modulus;
+ NSSItem publicExponent;
+ NSSItem privateExponent;
+ NSSItem exponent1;
+ NSSItem exponent2;
+ NSSItem prime1;
+ NSSItem prime2;
+ NSSItem coefficient;
+ NSSItem keyID;
+ NSSItem keyBlob;
+ ckcapiInternalObject *io = NULL;
+ char *providerName = NULL;
+ char *containerName = NULL;
+ char *idData = NULL;
+ CRYPT_KEY_PROV_INFO provInfo;
+ CRYPT_HASH_BLOB msKeyID;
+ CK_KEY_TYPE keyType;
+ HCRYPTPROV hProv = 0;
+ HCRYPTKEY hKey = 0;
+ PRBool decrypt;
+ DWORD keySpec;
+ DWORD msError;
+ BOOL rc;
+
+ keyType = nss_ckcapi_GetULongAttribute
+ (CKA_KEY_TYPE, pTemplate, ulAttributeCount, pError);
+ if (CKR_OK != *pError) {
+ return (ckcapiInternalObject *)NULL;
+ }
+ if (CKK_RSA != keyType) {
+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
+ return (ckcapiInternalObject *)NULL;
+ }
+
+ decrypt = nss_ckcapi_GetBoolAttribute(CKA_DECRYPT,
+ pTemplate, ulAttributeCount, pError);
+ if (CKR_TEMPLATE_INCOMPLETE == *pError) {
+ decrypt = PR_TRUE; /* default to true */
+ }
+ decrypt = decrypt || nss_ckcapi_GetBoolAttribute(CKA_UNWRAP,
+ pTemplate, ulAttributeCount, pError);
+ if (CKR_TEMPLATE_INCOMPLETE == *pError) {
+ decrypt = PR_TRUE; /* default to true */
+ }
+ keySpec = decrypt ? AT_KEYEXCHANGE : AT_SIGNATURE;
+
+ *pError = nss_ckcapi_GetAttribute(CKA_MODULUS, pTemplate,
+ ulAttributeCount, &modulus);
+ if (CKR_OK != *pError) {
+ return (ckcapiInternalObject *)NULL;
+ }
+ *pError = nss_ckcapi_GetAttribute(CKA_PUBLIC_EXPONENT, pTemplate,
+ ulAttributeCount, &publicExponent);
+ if (CKR_OK != *pError) {
+ return (ckcapiInternalObject *)NULL;
+ }
+ *pError = nss_ckcapi_GetAttribute(CKA_PRIVATE_EXPONENT, pTemplate,
+ ulAttributeCount, &privateExponent);
+ if (CKR_OK != *pError) {
+ return (ckcapiInternalObject *)NULL;
+ }
+ *pError = nss_ckcapi_GetAttribute(CKA_PRIME_1, pTemplate,
+ ulAttributeCount, &prime1);
+ if (CKR_OK != *pError) {
+ return (ckcapiInternalObject *)NULL;
+ }
+ *pError = nss_ckcapi_GetAttribute(CKA_PRIME_2, pTemplate,
+ ulAttributeCount, &prime2);
+ if (CKR_OK != *pError) {
+ return (ckcapiInternalObject *)NULL;
+ }
+ *pError = nss_ckcapi_GetAttribute(CKA_EXPONENT_1, pTemplate,
+ ulAttributeCount, &exponent1);
+ if (CKR_OK != *pError) {
+ return (ckcapiInternalObject *)NULL;
+ }
+ *pError = nss_ckcapi_GetAttribute(CKA_EXPONENT_2, pTemplate,
+ ulAttributeCount, &exponent2);
+ if (CKR_OK != *pError) {
+ return (ckcapiInternalObject *)NULL;
+ }
+ *pError = nss_ckcapi_GetAttribute(CKA_COEFFICIENT, pTemplate,
+ ulAttributeCount, &coefficient);
+ if (CKR_OK != *pError) {
+ return (ckcapiInternalObject *)NULL;
+ }
+ *pError = nss_ckcapi_GetAttribute(CKA_ID, pTemplate,
+ ulAttributeCount, &keyID);
+ if (CKR_OK != *pError) {
+ return (ckcapiInternalObject *)NULL;
+ }
+ providerName = ckcapi_getDefaultProvider(pError);
+ if ((char *)NULL == providerName ) {
+ return (ckcapiInternalObject *)NULL;
+ }
+ containerName = ckcapi_getContainer(pError, &keyID);
+ if ((char *)NULL == providerName ) {
+ goto loser;
+ }
+ rc = CryptAcquireContext(&hProv, containerName, providerName,
+ PROV_RSA_FULL, CRYPT_NEWKEYSET);
+ if (!rc) {
+ msError = GetLastError();
+ *pError = CKR_DEVICE_ERROR;
+ goto loser;
+ }
+
+ *pError = ckcapi_buildPrivateKeyBlob(
+ &keyBlob,
+ &modulus,
+ &publicExponent,
+ &privateExponent,
+ &prime1,
+ &prime2,
+ &exponent1,
+ &exponent2,
+ &coefficient,
+ decrypt);
+ if (CKR_OK != *pError) {
+ goto loser;
+ }
+
+ rc = CryptImportKey(hProv, keyBlob.data, keyBlob.size,
+ 0, CRYPT_EXPORTABLE, &hKey);
+ if (!rc) {
+ msError = GetLastError();
+ *pError = CKR_DEVICE_ERROR;
+ goto loser;
+ }
+
+ idData = nss_ZNEWARRAY(NULL, char, keyID.size);
+ if ((void *)NULL == idData) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ nsslibc_memcpy(idData, keyID.data, keyID.size);
+
+ provInfo.pwszContainerName = nss_ckcapi_UTF8ToWide(containerName);
+ provInfo.pwszProvName = nss_ckcapi_UTF8ToWide(providerName);
+ provInfo.dwProvType = PROV_RSA_FULL;
+ provInfo.dwFlags = 0;
+ provInfo.cProvParam = 0;
+ provInfo.rgProvParam = NULL;
+ provInfo.dwKeySpec = keySpec;
+
+ msKeyID.cbData = keyID.size;
+ msKeyID.pbData = keyID.data;
+
+ rc = CryptSetKeyIdentifierProperty(&msKeyID, CERT_KEY_PROV_INFO_PROP_ID,
+ 0, NULL, NULL, &provInfo);
+ if (!rc) {
+ goto loser;
+ }
+
+ /* handle error here */
+ io = nss_ZNEW(NULL, ckcapiInternalObject);
+ if ((ckcapiInternalObject *)NULL == io) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ io->type = ckcapiBareKey;
+ io->objClass = CKO_PRIVATE_KEY;
+ io->u.key.provInfo = provInfo;
+ io->u.key.provName = providerName;
+ io->u.key.containerName = containerName;
+ io->u.key.hProv = hProv; /* save the handle */
+ io->idData = idData;
+ io->id.data = idData;
+ io->id.size = keyID.size;
+ /* done with the key handle */
+ CryptDestroyKey(hKey);
+ return io;
+
+loser:
+ nss_ZFreeIf(containerName);
+ nss_ZFreeIf(providerName);
+ nss_ZFreeIf(idData);
+ if (0 != hProv) {
+ CryptReleaseContext(hProv, 0);
+ }
+ if (0 != hKey) {
+ CryptDestroyKey(hKey);
+ }
+ return (ckcapiInternalObject *)NULL;
+}
+
+
+NSS_EXTERN NSSCKMDObject *
+nss_ckcapi_CreateObject
+(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+)
+{
+ CK_OBJECT_CLASS objClass;
+ ckcapiInternalObject *io;
+ CK_BBOOL isToken;
+
+ /*
+ * only create token objects
+ */
+ isToken = nss_ckcapi_GetBoolAttribute(CKA_TOKEN, pTemplate,
+ ulAttributeCount, pError);
+ if (CKR_OK != *pError) {
+ return (NSSCKMDObject *) NULL;
+ }
+ if (!isToken) {
+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
+ return (NSSCKMDObject *) NULL;
+ }
+
+ /*
+ * only create keys and certs.
+ */
+ objClass = nss_ckcapi_GetULongAttribute(CKA_CLASS, pTemplate,
+ ulAttributeCount, pError);
+ if (CKR_OK != *pError) {
+ return (NSSCKMDObject *) NULL;
+ }
+#ifdef notdef
+ if (objClass == CKO_PUBLIC_KEY) {
+ return CKR_OK; /* fake public key creation, happens as a side effect of
+ * private key creation */
+ }
+#endif
+ if (objClass == CKO_CERTIFICATE) {
+ io = nss_ckcapi_CreateCertificate(fwSession, pTemplate,
+ ulAttributeCount, pError);
+ } else if (objClass == CKO_PRIVATE_KEY) {
+ io = nss_ckcapi_CreatePrivateKey(fwSession, pTemplate,
+ ulAttributeCount, pError);
+ } else {
+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ if ((ckcapiInternalObject *)NULL == io) {
+ return (NSSCKMDObject *) NULL;
+ }
+ return nss_ckcapi_CreateMDObject(NULL, io, pError);
+}
diff --git a/security/nss/cmd/SSLsample/nmakefile95.nss b/security/nss/lib/ckfw/capi/config.mk
index 43aa929e1..fdfc8cf09 100755..100644
--- a/security/nss/cmd/SSLsample/nmakefile95.nss
+++ b/security/nss/lib/ckfw/capi/config.mk
@@ -34,31 +34,38 @@
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
+CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-# NSS 2.6.2 Sample Win95 Makefile
#
+# Override TARGETS variable so that only shared libraries
+# are specifed as dependencies within rules.mk.
#
-# This nmake file will build server.c and client.c on Windows 95.
-#
-
-DEFINES=-D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG -DWIN32 -D_WINDOWS
-
-INCPATH=/I. /I..\include\dbm /I..\include\nspr /I..\include\security
-
-LIBS=nss.lib ssl.lib pkcs7.lib pkcs12.lib secmod.lib cert.lib key.lib crypto.lib secutil.lib hash.lib dbm.lib libplc3.lib libplds3.lib libnspr3.lib wsock32.lib
-CFLAGS=-O2 -MD -W3 -nologo
+TARGETS = $(SHARED_LIBRARY)
+LIBRARY =
+IMPORT_LIBRARY =
+PROGRAM =
-CC=cl
+ifeq (,$(filter-out WIN%,$(OS_TARGET)))
+ SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
+ RES = $(OBJDIR)/$(LIBRARY_NAME).res
+ RESNAME = $(LIBRARY_NAME).rc
+endif
-LDOPTIONS=/link /LIBPATH:..\lib /nodefaultlib:libcd.lib /subsystem:console
+ifdef BUILD_IDG
+ DEFINES += -DNSSDEBUG
+endif
-server:
- $(CC) $(CFLAGS) $(INCPATH) /Feserver server.c getopt.c $(LIBS) $(DEFINES) $(LDOPTIONS)
-
-client:
- $(CC) $(CFLAGS) $(INCPATH) /Feclient client.c getopt.c $(LIBS) $(DEFINES) $(LDOPTIONS)
+#
+# To create a loadable module on Darwin, we must use -bundle.
+#
+ifeq ($(OS_TARGET),Darwin)
+DSO_LDOPTS = -bundle
+endif
-clean:
- del /S server.exe client.exe server.lib server.exp client.lib client.exp server.obj client.obj getopt.obj
+ifeq ($(OS_TARGET),SunOS)
+# The -R '$ORIGIN' linker option instructs this library to search for its
+# dependencies in the same directory where it resides.
+MKSHLIB += -R '$$ORIGIN'
+endif
diff --git a/security/nss/lib/ckfw/capi/constants.c b/security/nss/lib/ckfw/capi/constants.c
new file mode 100644
index 000000000..4e509da65
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/constants.c
@@ -0,0 +1,98 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
+ *
+ * Contributor(s):
+ * Bob Relyea (rrelyea@redhat.com)
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
+#endif /* DEBUG */
+
+/*
+ * ckcapi/constants.c
+ *
+ * Identification and other constants, all collected here in one place.
+ */
+
+#ifndef NSSBASET_H
+#include "nssbaset.h"
+#endif /* NSSBASET_H */
+
+#ifndef NSSCKT_H
+#include "nssckt.h"
+#endif /* NSSCKT_H */
+
+#ifndef NSSCAPI_H
+#include "nsscapi.h"
+#endif /* NSSCAPI_H */
+
+NSS_IMPLEMENT_DATA const CK_VERSION
+nss_ckcapi_CryptokiVersion = {
+ NSS_CKCAPI_CRYPTOKI_VERSION_MAJOR,
+ NSS_CKCAPI_CRYPTOKI_VERSION_MINOR };
+
+NSS_IMPLEMENT_DATA const NSSUTF8 *
+nss_ckcapi_ManufacturerID = (NSSUTF8 *) "Mozilla Foundation";
+
+NSS_IMPLEMENT_DATA const NSSUTF8 *
+nss_ckcapi_LibraryDescription = (NSSUTF8 *) "NSS Access to Microsoft Certificate Store";
+
+NSS_IMPLEMENT_DATA const CK_VERSION
+nss_ckcapi_LibraryVersion = {
+ NSS_CKCAPI_LIBRARY_VERSION_MAJOR,
+ NSS_CKCAPI_LIBRARY_VERSION_MINOR};
+
+NSS_IMPLEMENT_DATA const NSSUTF8 *
+nss_ckcapi_SlotDescription = (NSSUTF8 *) "Microsoft Certificate Store";
+
+NSS_IMPLEMENT_DATA const CK_VERSION
+nss_ckcapi_HardwareVersion = {
+ NSS_CKCAPI_HARDWARE_VERSION_MAJOR,
+ NSS_CKCAPI_HARDWARE_VERSION_MINOR };
+
+NSS_IMPLEMENT_DATA const CK_VERSION
+nss_ckcapi_FirmwareVersion = {
+ NSS_CKCAPI_FIRMWARE_VERSION_MAJOR,
+ NSS_CKCAPI_FIRMWARE_VERSION_MINOR };
+
+NSS_IMPLEMENT_DATA const NSSUTF8 *
+nss_ckcapi_TokenLabel = (NSSUTF8 *) "Microsoft Certificate Store";
+
+NSS_IMPLEMENT_DATA const NSSUTF8 *
+nss_ckcapi_TokenModel = (NSSUTF8 *) "1";
+
+NSS_IMPLEMENT_DATA const NSSUTF8 *
+nss_ckcapi_TokenSerialNumber = (NSSUTF8 *) "1";
+
diff --git a/security/nss/lib/ckfw/capi/crsa.c b/security/nss/lib/ckfw/capi/crsa.c
new file mode 100644
index 000000000..ce0f42797
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/crsa.c
@@ -0,0 +1,748 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Red Hat, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Bob Relyea (rrelyea@redhat.com)
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
+#endif /* DEBUG */
+
+#include "ckcapi.h"
+#include "secdert.h"
+
+#define SSL3_SHAMD5_HASH_SIZE 36 /* LEN_MD5 (16) + LEN_SHA1 (20) */
+
+/*
+ * ckcapi/crsa.c
+ *
+ * This file implements the NSSCKMDMechnaism and NSSCKMDCryptoOperation objects
+ * for the RSA operation on the CAPI cryptoki module.
+ */
+
+/*
+ * write a Decimal value to a string
+ */
+
+static char *
+putDecimalString(char *cstr, unsigned long value)
+{
+ unsigned long tenpower;
+ int first = 1;
+
+ for (tenpower=10000000; tenpower; tenpower /= 10) {
+ unsigned char digit = (unsigned char )(value/tenpower);
+ value = value % tenpower;
+
+ /* drop leading zeros */
+ if (first && (0 == digit)) {
+ continue;
+ }
+ first = 0;
+ *cstr++ = digit + '0';
+ }
+
+ /* if value was zero, put one of them out */
+ if (first) {
+ *cstr++ = '0';
+ }
+ return cstr;
+}
+
+
+/*
+ * Create a Capi OID string value from a DER OID
+ */
+static char *
+nss_ckcapi_GetOidString
+(
+ unsigned char *oidTag,
+ int oidTagSize,
+ CK_RV *pError
+)
+{
+ unsigned char *oid;
+ char *oidStr;
+ char *cstr;
+ unsigned long value;
+ int oidSize;
+
+ if (DER_OBJECT_ID != *oidTag) {
+ /* wasn't an oid */
+ *pError = CKR_DATA_INVALID;
+ return NULL;
+ }
+ oid = nss_ckcapi_DERUnwrap(oidTag, oidTagSize, &oidSize, NULL);
+
+ if (oidSize < 2) {
+ *pError = CKR_DATA_INVALID;
+ return NULL;
+ }
+
+ oidStr = nss_ZNEWARRAY( NULL, char, oidSize*4 );
+ if ((char *)NULL == oidStr) {
+ *pError = CKR_HOST_MEMORY;
+ return NULL;
+ }
+ cstr = oidStr;
+ cstr = putDecimalString(cstr, (*oid) / 40);
+ *cstr++ = '.';
+ cstr = putDecimalString(cstr, (*oid) % 40);
+ oidSize--;
+
+ value = 0;
+ while (oidSize--) {
+ oid++;
+ value = (value << 7) + (*oid & 0x7f);
+ if (0 == (*oid & 0x80)) {
+ *cstr++ = '.';
+ cstr = putDecimalString(cstr, value);
+ value = 0;
+ }
+ }
+
+ *cstr = 0; /* NULL terminate */
+
+ if (value != 0) {
+ nss_ZFreeIf(oidStr);
+ *pError = CKR_DATA_INVALID;
+ return NULL;
+ }
+ return oidStr;
+}
+
+
+/*
+ * PKCS #11 sign for RSA expects to take a fully DER-encoded hash value,
+ * which includes the hash OID. CAPI expects to take a Hash Context. While
+ * CAPI does have the capability of setting a raw hash value, it does not
+ * have the ability to sign an arbitrary value. This function tries to
+ * reduce the passed in data into something that CAPI could actually sign.
+ */
+static CK_RV
+ckcapi_GetRawHash
+(
+ const NSSItem *input,
+ NSSItem *hash,
+ ALG_ID *hashAlg
+)
+{
+ unsigned char *current;
+ unsigned char *algid;
+ unsigned char *oid;
+ unsigned char *hashData;
+ char *oidStr;
+ CK_RV error;
+ int oidSize;
+ int size;
+ /*
+ * there are 2 types of hashes NSS typically tries to sign, regular
+ * RSA signature format (with encoded DER_OIDS), and SSL3 Signed hashes.
+ * CAPI knows not to add any oids to SSL3_Signed hashes, so if we have any
+ * random hash that is exactly the same size as an SSL3 hash, then we can
+ * just pass the data through. CAPI has know way of knowing if the value
+ * is really a combined hash or some other arbitrary data, so it's safe to
+ * handle this case first.
+ */
+ if (SSL3_SHAMD5_HASH_SIZE == input->size) {
+ hash->data = input->data;
+ hash->size = input->size;
+ *hashAlg = CALG_SSL3_SHAMD5;
+ return CKR_OK;
+ }
+
+ current = (unsigned char *)input->data;
+
+ /* make sure we have a sequence tag */
+ if ((DER_SEQUENCE|DER_CONSTRUCTED) != *current) {
+ return CKR_DATA_INVALID;
+ }
+
+ /* parse the input block to get 1) the hash oid, and 2) the raw hash value.
+ * unfortunatly CAPI doesn't have a builtin function to do this work, so
+ * we go ahead and do it by hand here.
+ *
+ * format is:
+ * SEQUENCE {
+ * SECQUENCE { // algid
+ * OID {} // oid
+ * ANY {} // optional params
+ * }
+ * OCTECT {} // hash
+ */
+
+ /* unwrap */
+ algid = nss_ckcapi_DERUnwrap(current,input->size, &size, NULL);
+
+ if (algid+size != current+input->size) {
+ /* make sure there is not extra data at the end */
+ return CKR_DATA_INVALID;
+ }
+
+ if ((DER_SEQUENCE|DER_CONSTRUCTED) != *algid) {
+ /* wasn't an algid */
+ return CKR_DATA_INVALID;
+ }
+ oid = nss_ckcapi_DERUnwrap(algid, size, &oidSize, &hashData);
+
+ if (DER_OCTET_STRING != *hashData) {
+ /* wasn't a hash */
+ return CKR_DATA_INVALID;
+ }
+
+ /* get the real hash */
+ current = hashData;
+ size = size - (hashData-algid);
+ hash->data = nss_ckcapi_DERUnwrap(current, size, &hash->size, NULL);
+
+ /* get the real oid as a string. Again, Microsoft does not
+ * export anything that does this for us */
+ oidStr = nss_ckcapi_GetOidString(oid, oidSize, &error);
+ if ((char *)NULL == oidStr ) {
+ return error;
+ }
+
+ /* look up the hash alg from the oid (fortunately CAPI does to this) */
+ *hashAlg = CertOIDToAlgId(oidStr);
+ nss_ZFreeIf(oidStr);
+ if (0 == *hashAlg) {
+ return CKR_HOST_MEMORY;
+ }
+
+ /* hash looks reasonably consistent, we should be able to sign it now */
+ return CKR_OK;
+}
+
+/*
+ * So everyone else in the worlds stores their bignum data MSB first, but not
+ * Microsoft, we need to byte swap everything coming into and out of CAPI.
+ */
+void
+ckcapi_ReverseData(NSSItem *item)
+{
+ int end = (item->size)-1;
+ int middle = (item->size)/2;
+ unsigned char *buf = item->data;
+ int i;
+
+ for (i=0; i < middle; i++) {
+ unsigned char tmp = buf[i];
+ buf[i] = buf[end-i];
+ buf[end-i] = tmp;
+ }
+ return;
+}
+
+typedef struct ckcapiInternalCryptoOperationRSAPrivStr
+ ckcapiInternalCryptoOperationRSAPriv;
+struct ckcapiInternalCryptoOperationRSAPrivStr
+{
+ NSSCKMDCryptoOperation mdOperation;
+ NSSCKMDMechanism *mdMechanism;
+ ckcapiInternalObject *iKey;
+ HCRYPTPROV hProv;
+ DWORD keySpec;
+ HCRYPTKEY hKey;
+ NSSItem *buffer;
+};
+
+/*
+ * ckcapi_mdCryptoOperationRSAPriv_Create
+ */
+static NSSCKMDCryptoOperation *
+ckcapi_mdCryptoOperationRSAPriv_Create
+(
+ const NSSCKMDCryptoOperation *proto,
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKMDObject *mdKey,
+ CK_RV *pError
+)
+{
+ ckcapiInternalObject *iKey = (ckcapiInternalObject *)mdKey->etc;
+ const NSSItem *classItem = nss_ckcapi_FetchAttribute(iKey, CKA_CLASS);
+ const NSSItem *keyType = nss_ckcapi_FetchAttribute(iKey, CKA_KEY_TYPE);
+ ckcapiInternalCryptoOperationRSAPriv *iOperation;
+ CK_RV error;
+ HCRYPTPROV hProv;
+ DWORD keySpec;
+ HCRYPTKEY hKey;
+
+ /* make sure we have the right objects */
+ if (((const NSSItem *)NULL == classItem) ||
+ (sizeof(CK_OBJECT_CLASS) != classItem->size) ||
+ (CKO_PRIVATE_KEY != *(CK_OBJECT_CLASS *)classItem->data) ||
+ ((const NSSItem *)NULL == keyType) ||
+ (sizeof(CK_KEY_TYPE) != keyType->size) ||
+ (CKK_RSA != *(CK_KEY_TYPE *)keyType->data)) {
+ *pError = CKR_KEY_TYPE_INCONSISTENT;
+ return (NSSCKMDCryptoOperation *)NULL;
+ }
+
+ error = nss_ckcapi_FetchKeyContainer(iKey, &hProv, &keySpec, &hKey);
+ if (error != CKR_OK) {
+ *pError = error;
+ return (NSSCKMDCryptoOperation *)NULL;
+ }
+
+ iOperation = nss_ZNEW(NULL, ckcapiInternalCryptoOperationRSAPriv);
+ if ((ckcapiInternalCryptoOperationRSAPriv *)NULL == iOperation) {
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKMDCryptoOperation *)NULL;
+ }
+ iOperation->mdMechanism = mdMechanism;
+ iOperation->iKey = iKey;
+ iOperation->hProv = hProv;
+ iOperation->keySpec = keySpec;
+ iOperation->hKey = hKey;
+
+ nsslibc_memcpy(&iOperation->mdOperation,
+ proto, sizeof(NSSCKMDCryptoOperation));
+ iOperation->mdOperation.etc = iOperation;
+
+ return &iOperation->mdOperation;
+}
+
+static CK_RV
+ckcapi_mdCryptoOperationRSAPriv_Destroy
+(
+ NSSCKMDCryptoOperation *mdOperation,
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ ckcapiInternalCryptoOperationRSAPriv *iOperation =
+ (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
+
+ if (iOperation->hKey) {
+ CryptDestroyKey(iOperation->hKey);
+ }
+ if (iOperation->buffer) {
+ nssItem_Destroy(iOperation->buffer);
+ }
+ nss_ZFreeIf(iOperation);
+ return CKR_OK;
+}
+
+static CK_ULONG
+ckcapi_mdCryptoOperationRSA_GetFinalLength
+(
+ NSSCKMDCryptoOperation *mdOperation,
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ ckcapiInternalCryptoOperationRSAPriv *iOperation =
+ (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
+ const NSSItem *modulus =
+ nss_ckcapi_FetchAttribute(iOperation->iKey, CKA_MODULUS);
+
+ return modulus->size;
+}
+
+
+/*
+ * ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength
+ * we won't know the length until we actually decrypt the
+ * input block. Since we go to all the work to decrypt the
+ * the block, we'll save if for when the block is asked for
+ */
+static CK_ULONG
+ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength
+(
+ NSSCKMDCryptoOperation *mdOperation,
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ const NSSItem *input,
+ CK_RV *pError
+)
+{
+ ckcapiInternalCryptoOperationRSAPriv *iOperation =
+ (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
+ BOOL rc;
+
+ /* Microsoft's Decrypt operation works in place. Since we don't want
+ * to trash our input buffer, we make a copy of it */
+ iOperation->buffer = nssItem_Duplicate((NSSItem *)input, NULL, NULL);
+ if ((NSSItem *) NULL == iOperation->buffer) {
+ *pError = CKR_HOST_MEMORY;
+ return 0;
+ }
+ /* Sigh, reverse it */
+ ckcapi_ReverseData(iOperation->buffer);
+
+ rc = CryptDecrypt(iOperation->hKey, 0, TRUE, 0,
+ iOperation->buffer->data, &iOperation->buffer->size);
+ if (!rc) {
+ DWORD msError = GetLastError();
+ switch (msError) {
+ case NTE_BAD_DATA:
+ *pError = CKR_ENCRYPTED_DATA_INVALID;
+ break;
+ case NTE_FAIL:
+ case NTE_BAD_UID:
+ *pError = CKR_DEVICE_ERROR;
+ break;
+ default:
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return 0;
+ }
+
+ return iOperation->buffer->size;
+}
+
+/*
+ * ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal
+ *
+ * NOTE: ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength is presumed to
+ * have been called previously.
+ */
+static CK_RV
+ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal
+(
+ NSSCKMDCryptoOperation *mdOperation,
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ const NSSItem *input,
+ NSSItem *output
+)
+{
+ ckcapiInternalCryptoOperationRSAPriv *iOperation =
+ (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
+ NSSItem *buffer = iOperation->buffer;
+
+ if ((NSSItem *)NULL == buffer) {
+ return CKR_GENERAL_ERROR;
+ }
+ nsslibc_memcpy(output->data, buffer->data, buffer->size);
+ output->size = buffer->size;
+ return CKR_OK;
+}
+
+/*
+ * ckcapi_mdCryptoOperationRSASign_UpdateFinal
+ *
+ */
+static CK_RV
+ckcapi_mdCryptoOperationRSASign_UpdateFinal
+(
+ NSSCKMDCryptoOperation *mdOperation,
+ NSSCKFWCryptoOperation *fwOperation,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ const NSSItem *input,
+ NSSItem *output
+)
+{
+ ckcapiInternalCryptoOperationRSAPriv *iOperation =
+ (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
+ CK_RV error = CKR_OK;
+ DWORD msError;
+ NSSItem hash;
+ HCRYPTHASH hHash = 0;
+ ALG_ID hashAlg;
+ DWORD hashSize;
+ DWORD len; /* temp length value we throw away */
+ BOOL rc;
+
+ /*
+ * PKCS #11 sign for RSA expects to take a fully DER-encoded hash value,
+ * which includes the hash OID. CAPI expects to take a Hash Context. While
+ * CAPI does have the capability of setting a raw hash value, it does not
+ * have the ability to sign an arbitrary value. This function tries to
+ * reduce the passed in data into something that CAPI could actually sign.
+ */
+ error = ckcapi_GetRawHash(input, &hash, &hashAlg);
+ if (CKR_OK != error) {
+ goto loser;
+ }
+
+ rc = CryptCreateHash(iOperation->hProv, hashAlg, 0, 0, &hHash);
+ if (!rc) {
+ goto loser;
+ }
+
+ /* make sure the hash lens match before we set it */
+ len = sizeof(DWORD);
+ rc = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashSize, &len, 0);
+ if (!rc) {
+ goto loser;
+ }
+
+ if (hash.size != hashSize) {
+ /* The input must have been bad for this to happen */
+ error = CKR_DATA_INVALID;
+ goto loser;
+ }
+
+ /* we have an explicit hash, set it, note that the length is
+ * implicit by the hashAlg used in create */
+ rc = CryptSetHashParam(hHash, HP_HASHVAL, hash.data, 0);
+ if (!rc) {
+ goto loser;
+ }
+
+ /* OK, we have the data in a hash structure, sign it! */
+ rc = CryptSignHash(hHash, iOperation->keySpec, NULL, 0,
+ output->data, &output->size);
+ if (!rc) {
+ goto loser;
+ }
+
+ /* Don't return a signature that might have been broken because of a cosmic
+ * ray, or a broken processor, verify that it is valid... */
+ rc = CryptVerifySignature(hHash, output->data, output->size,
+ iOperation->hKey, NULL, 0);
+ if (!rc) {
+ goto loser;
+ }
+
+ /* OK, Microsoft likes to do things completely differently than anyone
+ * else. We need to reverse the data we recieved here */
+ ckcapi_ReverseData(output);
+ CryptDestroyHash(hHash);
+ return CKR_OK;
+
+loser:
+ /* map the microsoft error */
+ if (CKR_OK == error) {
+ msError = GetLastError();
+ switch (msError) {
+ case ERROR_NOT_ENOUGH_MEMORY:
+ error = CKR_HOST_MEMORY;
+ break;
+ case NTE_NO_MEMORY:
+ error = CKR_DEVICE_MEMORY;
+ break;
+ case ERROR_MORE_DATA:
+ return CKR_BUFFER_TOO_SMALL;
+ case ERROR_INVALID_PARAMETER: /* these params were derived from the */
+ case ERROR_INVALID_HANDLE: /* inputs, so if they are bad, the input */
+ case NTE_BAD_ALGID: /* data is bad */
+ case NTE_BAD_HASH:
+ error = CKR_DATA_INVALID;
+ break;
+ case ERROR_BUSY:
+ case NTE_FAIL:
+ case NTE_BAD_UID:
+ error = CKR_DEVICE_ERROR;
+ break;
+ default:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+ }
+ if (hHash) {
+ CryptDestroyHash(hHash);
+ }
+ return error;
+}
+
+
+NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation
+ckcapi_mdCryptoOperationRSADecrypt_proto = {
+ NULL, /* etc */
+ ckcapi_mdCryptoOperationRSAPriv_Destroy,
+ NULL, /* GetFinalLengh - not needed for one shot Decrypt/Encrypt */
+ ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength,
+ NULL, /* Final - not needed for one shot operation */
+ NULL, /* Update - not needed for one shot operation */
+ NULL, /* DigetUpdate - not needed for one shot operation */
+ ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal,
+ NULL, /* UpdateCombo - not needed for one shot operation */
+ NULL, /* DigetKey - not needed for one shot operation */
+ (void *)NULL /* null terminator */
+};
+
+NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation
+ckcapi_mdCryptoOperationRSASign_proto = {
+ NULL, /* etc */
+ ckcapi_mdCryptoOperationRSAPriv_Destroy,
+ ckcapi_mdCryptoOperationRSA_GetFinalLength,
+ NULL, /* GetOperationLengh - not needed for one shot Sign/Verify */
+ NULL, /* Final - not needed for one shot operation */
+ NULL, /* Update - not needed for one shot operation */
+ NULL, /* DigetUpdate - not needed for one shot operation */
+ ckcapi_mdCryptoOperationRSASign_UpdateFinal,
+ NULL, /* UpdateCombo - not needed for one shot operation */
+ NULL, /* DigetKey - not needed for one shot operation */
+ (void *)NULL /* null terminator */
+};
+
+/********** NSSCKMDMechansim functions ***********************/
+/*
+ * ckcapi_mdMechanismRSA_Destroy
+ */
+static void
+ckcapi_mdMechanismRSA_Destroy
+(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ nss_ZFreeIf(fwMechanism);
+}
+
+/*
+ * ckcapi_mdMechanismRSA_GetMinKeySize
+ */
+static CK_ULONG
+ckcapi_mdMechanismRSA_GetMinKeySize
+(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return 384;
+}
+
+/*
+ * ckcapi_mdMechanismRSA_GetMaxKeySize
+ */
+static CK_ULONG
+ckcapi_mdMechanismRSA_GetMaxKeySize
+(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return 16384;
+}
+
+/*
+ * ckcapi_mdMechanismRSA_DecryptInit
+ */
+static NSSCKMDCryptoOperation *
+ckcapi_mdMechanismRSA_DecryptInit
+(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM *pMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdKey,
+ NSSCKFWObject *fwKey,
+ CK_RV *pError
+)
+{
+ return ckcapi_mdCryptoOperationRSAPriv_Create(
+ &ckcapi_mdCryptoOperationRSADecrypt_proto,
+ mdMechanism, mdKey, pError);
+}
+
+/*
+ * ckcapi_mdMechanismRSA_SignInit
+ */
+static NSSCKMDCryptoOperation *
+ckcapi_mdMechanismRSA_SignInit
+(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM *pMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdKey,
+ NSSCKFWObject *fwKey,
+ CK_RV *pError
+)
+{
+ return ckcapi_mdCryptoOperationRSAPriv_Create(
+ &ckcapi_mdCryptoOperationRSASign_proto,
+ mdMechanism, mdKey, pError);
+}
+
+
+NSS_IMPLEMENT_DATA const NSSCKMDMechanism
+nss_ckcapi_mdMechanismRSA = {
+ (void *)NULL, /* etc */
+ ckcapi_mdMechanismRSA_Destroy,
+ ckcapi_mdMechanismRSA_GetMinKeySize,
+ ckcapi_mdMechanismRSA_GetMaxKeySize,
+ NULL, /* GetInHardware - default false */
+ NULL, /* EncryptInit - default errs */
+ ckcapi_mdMechanismRSA_DecryptInit,
+ NULL, /* DigestInit - default errs*/
+ ckcapi_mdMechanismRSA_SignInit,
+ NULL, /* VerifyInit - default errs */
+ ckcapi_mdMechanismRSA_SignInit, /* SignRecoverInit */
+ NULL, /* VerifyRecoverInit - default errs */
+ NULL, /* GenerateKey - default errs */
+ NULL, /* GenerateKeyPair - default errs */
+ NULL, /* GetWrapKeyLength - default errs */
+ NULL, /* WrapKey - default errs */
+ NULL, /* UnwrapKey - default errs */
+ NULL, /* DeriveKey - default errs */
+ (void *)NULL /* null terminator */
+};
diff --git a/security/nss/lib/ckfw/capi/csession.c b/security/nss/lib/ckfw/capi/csession.c
new file mode 100644
index 000000000..f0abd6d0b
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/csession.c
@@ -0,0 +1,131 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
+ *
+ * Contributor(s):
+ * Bob Relyea (rrelyea@redhat.com)
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
+#endif /* DEBUG */
+
+#include "ckcapi.h"
+
+/*
+ * ckcapi/csession.c
+ *
+ * This file implements the NSSCKMDSession object for the
+ * "nss to capi" cryptoki module.
+ */
+
+static NSSCKMDFindObjects *
+ckcapi_mdSession_FindObjectsInit
+(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+)
+{
+ return nss_ckcapi_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError);
+}
+
+static NSSCKMDObject *
+ckcapi_mdSession_CreateObject
+(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+)
+{
+ return nss_ckcapi_CreateObject(fwSession, pTemplate, ulAttributeCount, pError);
+}
+
+NSS_IMPLEMENT NSSCKMDSession *
+nss_ckcapi_CreateSession
+(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError
+)
+{
+ NSSArena *arena;
+ NSSCKMDSession *rv;
+
+ arena = NSSCKFWSession_GetArena(fwSession, pError);
+ if( (NSSArena *)NULL == arena ) {
+ return (NSSCKMDSession *)NULL;
+ }
+
+ rv = nss_ZNEW(arena, NSSCKMDSession);
+ if( (NSSCKMDSession *)NULL == rv ) {
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKMDSession *)NULL;
+ }
+
+ /*
+ * rv was zeroed when allocated, so we only
+ * need to set the non-zero members.
+ */
+
+ rv->etc = (void *)fwSession;
+ /* rv->Close */
+ /* rv->GetDeviceError */
+ /* rv->Login */
+ /* rv->Logout */
+ /* rv->InitPIN */
+ /* rv->SetPIN */
+ /* rv->GetOperationStateLen */
+ /* rv->GetOperationState */
+ /* rv->SetOperationState */
+ rv->CreateObject = ckcapi_mdSession_CreateObject;
+ /* rv->CopyObject */
+ rv->FindObjectsInit = ckcapi_mdSession_FindObjectsInit;
+ /* rv->SeedRandom */
+ /* rv->GetRandom */
+ /* rv->null */
+
+ return rv;
+}
diff --git a/security/nss/lib/ckfw/capi/cslot.c b/security/nss/lib/ckfw/capi/cslot.c
new file mode 100644
index 000000000..1c42c107d
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/cslot.c
@@ -0,0 +1,129 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
+ *
+ * Contributor(s):
+ * Bob Relyea (rrelyea@redhat.com)
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
+#endif /* DEBUG */
+
+#include "ckcapi.h"
+
+/*
+ * ckcapi/cslot.c
+ *
+ * This file implements the NSSCKMDSlot object for the
+ * "nss to capi" cryptoki module.
+ */
+
+static NSSUTF8 *
+ckcapi_mdSlot_GetSlotDescription
+(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_ckcapi_SlotDescription;
+}
+
+static NSSUTF8 *
+ckcapi_mdSlot_GetManufacturerID
+(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
+}
+
+static CK_VERSION
+ckcapi_mdSlot_GetHardwareVersion
+(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return nss_ckcapi_HardwareVersion;
+}
+
+static CK_VERSION
+ckcapi_mdSlot_GetFirmwareVersion
+(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return nss_ckcapi_FirmwareVersion;
+}
+
+static NSSCKMDToken *
+ckcapi_mdSlot_GetToken
+(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSCKMDToken *)&nss_ckcapi_mdToken;
+}
+
+NSS_IMPLEMENT_DATA const NSSCKMDSlot
+nss_ckcapi_mdSlot = {
+ (void *)NULL, /* etc */
+ NULL, /* Initialize */
+ NULL, /* Destroy */
+ ckcapi_mdSlot_GetSlotDescription,
+ ckcapi_mdSlot_GetManufacturerID,
+ NULL, /* GetTokenPresent -- defaults to true */
+ NULL, /* GetRemovableDevice -- defaults to false */
+ NULL, /* GetHardwareSlot -- defaults to false */
+ ckcapi_mdSlot_GetHardwareVersion,
+ ckcapi_mdSlot_GetFirmwareVersion,
+ ckcapi_mdSlot_GetToken,
+ (void *)NULL /* null terminator */
+};
diff --git a/security/nss/lib/ckfw/capi/ctoken.c b/security/nss/lib/ckfw/capi/ctoken.c
new file mode 100644
index 000000000..bce2c17e2
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/ctoken.c
@@ -0,0 +1,246 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
+ *
+ * Contributor(s):
+ * Bob Relyea (rrelyea@redhat.com)
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
+#endif /* DEBUG */
+
+#include "ckcapi.h"
+
+/*
+ * ckcapi/ctoken.c
+ *
+ * This file implements the NSSCKMDToken object for the
+ * "nss to capi" cryptoki module.
+ */
+
+static NSSUTF8 *
+ckcapi_mdToken_GetLabel
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_ckcapi_TokenLabel;
+}
+
+static NSSUTF8 *
+ckcapi_mdToken_GetManufacturerID
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
+}
+
+static NSSUTF8 *
+ckcapi_mdToken_GetModel
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_ckcapi_TokenModel;
+}
+
+static NSSUTF8 *
+ckcapi_mdToken_GetSerialNumber
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_ckcapi_TokenSerialNumber;
+}
+
+static CK_BBOOL
+ckcapi_mdToken_GetIsWriteProtected
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return CK_FALSE;
+}
+
+/* fake out Mozilla so we don't try to initialize the token */
+static CK_BBOOL
+ckcapi_mdToken_GetUserPinInitialized
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return CK_TRUE;
+}
+
+static CK_VERSION
+ckcapi_mdToken_GetHardwareVersion
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return nss_ckcapi_HardwareVersion;
+}
+
+static CK_VERSION
+ckcapi_mdToken_GetFirmwareVersion
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return nss_ckcapi_FirmwareVersion;
+}
+
+static NSSCKMDSession *
+ckcapi_mdToken_OpenSession
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWSession *fwSession,
+ CK_BBOOL rw,
+ CK_RV *pError
+)
+{
+ return nss_ckcapi_CreateSession(fwSession, pError);
+}
+
+static CK_ULONG
+ckcapi_mdToken_GetMechanismCount
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return (CK_ULONG)1;
+}
+
+static CK_RV
+ckcapi_mdToken_GetMechanismTypes
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_MECHANISM_TYPE types[]
+)
+{
+ types[0] = CKM_RSA_PKCS;
+ return CKR_OK;
+}
+
+static NSSCKMDMechanism *
+ckcapi_mdToken_GetMechanism
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_MECHANISM_TYPE which,
+ CK_RV *pError
+)
+{
+ if (which != CKM_RSA_PKCS) {
+ *pError = CKR_MECHANISM_INVALID;
+ return (NSSCKMDMechanism *)NULL;
+ }
+ return (NSSCKMDMechanism *)&nss_ckcapi_mdMechanismRSA;
+}
+
+NSS_IMPLEMENT_DATA const NSSCKMDToken
+nss_ckcapi_mdToken = {
+ (void *)NULL, /* etc */
+ NULL, /* Setup */
+ NULL, /* Invalidate */
+ NULL, /* InitToken -- default errs */
+ ckcapi_mdToken_GetLabel,
+ ckcapi_mdToken_GetManufacturerID,
+ ckcapi_mdToken_GetModel,
+ ckcapi_mdToken_GetSerialNumber,
+ NULL, /* GetHasRNG -- default is false */
+ ckcapi_mdToken_GetIsWriteProtected,
+ NULL, /* GetLoginRequired -- default is false */
+ ckcapi_mdToken_GetUserPinInitialized,
+ NULL, /* GetRestoreKeyNotNeeded -- irrelevant */
+ NULL, /* GetHasClockOnToken -- default is false */
+ NULL, /* GetHasProtectedAuthenticationPath -- default is false */
+ NULL, /* GetSupportsDualCryptoOperations -- default is false */
+ NULL, /* GetMaxSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
+ NULL, /* GetMaxRwSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
+ NULL, /* GetMaxPinLen -- irrelevant */
+ NULL, /* GetMinPinLen -- irrelevant */
+ NULL, /* GetTotalPublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
+ NULL, /* GetFreePublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
+ NULL, /* GetTotalPrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
+ NULL, /* GetFreePrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
+ ckcapi_mdToken_GetHardwareVersion,
+ ckcapi_mdToken_GetFirmwareVersion,
+ NULL, /* GetUTCTime -- no clock */
+ ckcapi_mdToken_OpenSession,
+ ckcapi_mdToken_GetMechanismCount,
+ ckcapi_mdToken_GetMechanismTypes,
+ ckcapi_mdToken_GetMechanism,
+ (void *)NULL /* null terminator */
+};
diff --git a/security/nss/cmd/makefile.win b/security/nss/lib/ckfw/capi/manifest.mn
index 0f7b8cc5f..8959e5d2d 100644
--- a/security/nss/cmd/makefile.win
+++ b/security/nss/lib/ckfw/capi/manifest.mn
@@ -1,4 +1,4 @@
-#
+#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
@@ -34,19 +34,33 @@
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
+MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-VERBOSE = 1
-include <manifest.mn>
+CORE_DEPTH = ../../../..
-include <$(DEPTH)\config\config.mak>
+MODULE = nss
+MAPFILE = $(OBJDIR)/nsscapi.def
-include <$(DEPTH)\config\rules.mak>
+EXPORTS = \
+ nsscapi.h \
+ $(NULL)
-objs: $(OBJS)
+CSRCS = \
+ anchor.c \
+ constants.c \
+ cfind.c \
+ cinst.c \
+ cobject.c \
+ crsa.c \
+ csession.c \
+ cslot.c \
+ ctoken.c \
+ ckcapiver.c \
+ staticobj.c \
+ $(NULL)
-programs: $(PROGRAM)
+REQUIRES = nspr
-syms:
- @echo "OBJS is $(OBJS)"
- @echo "INCS is $(INCS)"
+LIBRARY_NAME = nsscapi
+#EXTRA_SHARED_LIBS = -L$(DIST)/lib -lnssckfw -lnssb -lplc4 -lplds4
diff --git a/security/nss/lib/ckfw/capi/nsscapi.def b/security/nss/lib/ckfw/capi/nsscapi.def
new file mode 100644
index 000000000..0e6106c62
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/nsscapi.def
@@ -0,0 +1,58 @@
+;+#
+;+# ***** BEGIN LICENSE BLOCK *****
+;+# 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 Netscape security libraries.
+;+#
+;+# The Initial Developer of the Original Code is
+;+# Netscape Communications Corporation.
+;+# Portions created by the Initial Developer are Copyright (C) 2003
+;+# the Initial Developer. All Rights Reserved.
+;+#
+;+# Contributor(s):
+;+#
+;+# 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.
+;+#
+;+# ***** END LICENSE BLOCK *****
+;+#
+;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
+;+# 1. For all unix platforms, the string ";-" means "remove this line"
+;+# 2. For all unix platforms, the string " DATA " will be removed from any
+;+# line on which it occurs.
+;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
+;+# On AIX, lines containing ";+" will be removed.
+;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
+;+# 5. For all unix platforms, after the above processing has taken place,
+;+# all characters after the first ";" on the line will be removed.
+;+# And for AIX, the first ";" will also be removed.
+;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
+;+# directives are hidden behind ";", ";+", and ";-"
+;+
+;+NSS_3.1 { # NSS 3.1 release
+;+ global:
+LIBRARY nsscapi ;-
+EXPORTS ;-
+C_GetFunctionList;
+;+ local:
+;+*;
+;+};
diff --git a/security/nss/lib/ckfw/capi/nsscapi.h b/security/nss/lib/ckfw/capi/nsscapi.h
new file mode 100644
index 000000000..1d80487e9
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/nsscapi.h
@@ -0,0 +1,75 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
+ *
+ * Contributor(s):
+ * Bob Relyea (rrelyea@redhat.com)
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef NSSCAPI_H
+#define NSSCAPI_H
+
+/*
+ * NSS CKCAPI Version numbers.
+ *
+ * These are the version numbers for the capi module packaged with
+ * this release on NSS. To determine the version numbers of the builtin
+ * module you are using, use the appropriate PKCS #11 calls.
+ *
+ * These version numbers detail changes to the PKCS #11 interface. They map
+ * to the PKCS #11 spec versions.
+ */
+#define NSS_CKCAPI_CRYPTOKI_VERSION_MAJOR 2
+#define NSS_CKCAPI_CRYPTOKI_VERSION_MINOR 20
+
+/* These version numbers detail the changes
+ * to the list of trusted certificates.
+ *
+ * NSS_CKCAPI_LIBRARY_VERSION_MINOR is a CK_BYTE. It's not clear
+ * whether we may use its full range (0-255) or only 0-99 because
+ * of the comment in the CK_VERSION type definition.
+ */
+#define NSS_CKCAPI_LIBRARY_VERSION_MAJOR 1
+#define NSS_CKCAPI_LIBRARY_VERSION_MINOR 1
+#define NSS_CKCAPI_LIBRARY_VERSION "1.1"
+
+/* These version numbers detail the semantic changes to the ckfw engine. */
+#define NSS_CKCAPI_HARDWARE_VERSION_MAJOR 1
+#define NSS_CKCAPI_HARDWARE_VERSION_MINOR 0
+
+/* These version numbers detail the semantic changes to ckbi itself
+ * (new PKCS #11 objects), etc. */
+#define NSS_CKCAPI_FIRMWARE_VERSION_MAJOR 1
+#define NSS_CKCAPI_FIRMWARE_VERSION_MINOR 0
+
+#endif /* NSSCKBI_H */
diff --git a/security/nss/lib/ckfw/capi/nsscapi.rc b/security/nss/lib/ckfw/capi/nsscapi.rc
new file mode 100644
index 000000000..d5024f7a6
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/nsscapi.rc
@@ -0,0 +1,97 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsscapi.h"
+#include <winver.h>
+
+#define MY_LIBNAME "nsscapi"
+#define MY_FILEDESCRIPTION "NSS Access to Microsoft CAPI"
+
+#ifdef _DEBUG
+#define MY_DEBUG_STR " (debug)"
+#define MY_FILEFLAGS_1 VS_FF_DEBUG
+#else
+#define MY_DEBUG_STR ""
+#define MY_FILEFLAGS_1 0x0L
+#endif
+#if NSS_BETA
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
+#else
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
+#endif
+
+#ifdef WINNT
+#define MY_FILEOS VOS_NT_WINDOWS32
+#else
+#define MY_FILEOS VOS__WINDOWS32
+#endif
+
+#define MY_INTERNAL_NAME MY_LIBNAME
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version-information resource
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION NSS_CKCAPI_LIBRARY_VERSION_MAJOR,NSS_CKCAPI_LIBRARY_VERSION_MINOR,0,0
+ PRODUCTVERSION NSS_CKCAPI_LIBRARY_VERSION_MAJOR,NSS_CKCAPI_LIBRARY_VERSION_MINOR,0,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS MY_FILEFLAGS_2
+ FILEOS MY_FILEOS
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L // not used
+
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", "Mozilla Foundation\0"
+ VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
+ VALUE "FileVersion", NSS_CKCAPI_LIBRARY_VERSION "\0"
+ VALUE "InternalName", MY_INTERNAL_NAME "\0"
+ VALUE "LegalCopyright", "Copyright \251 1994-2005 Netscape Communications Corporation\0"
+ VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
+ VALUE "ProductName", "Network Security Services\0"
+ VALUE "ProductVersion", NSS_CKCAPI_LIBRARY_VERSION "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/security/nss/lib/ckfw/capi/staticobj.c b/security/nss/lib/ckfw/capi/staticobj.c
new file mode 100644
index 000000000..8cfd8fbdd
--- /dev/null
+++ b/security/nss/lib/ckfw/capi/staticobj.c
@@ -0,0 +1,74 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
+ *
+ * Contributor(s):
+ * Bob Relyea (rrelyea@redhat.com)
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$""; @(#) $RCSfile$ $Revision$ $Date$";
+#endif /* DEBUG */
+
+#ifndef CKCAPI_H
+#include "ckcapi.h"
+#endif /* CKCAPI_H */
+
+static const CK_TRUST ckt_netscape_valid = CKT_NETSCAPE_VALID;
+static const CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
+static const CK_TRUST ckt_netscape_trusted_delegator = CKT_NETSCAPE_TRUSTED_DELEGATOR;
+static const CK_OBJECT_CLASS cko_netscape_trust = CKO_NETSCAPE_TRUST;
+static const CK_BBOOL ck_true = CK_TRUE;
+static const CK_OBJECT_CLASS cko_data = CKO_DATA;
+static const CK_CERTIFICATE_TYPE ckc_x_509 = CKC_X_509;
+static const CK_BBOOL ck_false = CK_FALSE;
+static const CK_OBJECT_CLASS cko_netscape_builtin_root_list = CKO_NETSCAPE_BUILTIN_ROOT_LIST;
+
+/* example of a static object */
+static const CK_ATTRIBUTE_TYPE nss_ckcapi_types_1 [] = {
+ CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL
+};
+
+static const NSSItem nss_ckcapi_items_1 [] = {
+ { (void *)&cko_data, (PRUint32)sizeof(CK_OBJECT_CLASS) },
+ { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) },
+ { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
+ { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
+ { (void *)"Mozilla CAPI Access", (PRUint32)20 }
+};
+
+PR_IMPLEMENT_DATA(ckcapiInternalObject) nss_ckcapi_data[] = {
+ { ckcapiRaw, { 5, nss_ckcapi_types_1, nss_ckcapi_items_1} , {NULL} },
+};
+
+PR_IMPLEMENT_DATA(const PRUint32) nss_ckcapi_nObjects = 1;
diff --git a/security/nss/lib/ckfw/ckfwm.h b/security/nss/lib/ckfw/ckfwm.h
index d54cff194..542bc390c 100644
--- a/security/nss/lib/ckfw/ckfwm.h
+++ b/security/nss/lib/ckfw/ckfwm.h
@@ -161,11 +161,4 @@ nssCKFWHash_Iterate
void *closure
);
-NSS_EXTERN CK_RV
-nssSetLockArgs(
- CK_C_INITIALIZE_ARGS_PTR pInitArgs,
- CryptokiLockingState* returned
-);
-
-
#endif /* CKFWM_H */
diff --git a/security/nss/lib/ckfw/manifest.mn b/security/nss/lib/ckfw/manifest.mn
index 345ea81e1..f5e9fb953 100644
--- a/security/nss/lib/ckfw/manifest.mn
+++ b/security/nss/lib/ckfw/manifest.mn
@@ -68,7 +68,6 @@ CSRCS = \
hash.c \
instance.c \
mutex.c \
- nsprstub.c \
object.c \
session.c \
sessobj.c \
diff --git a/security/nss/lib/ckfw/mutex.c b/security/nss/lib/ckfw/mutex.c
index b9fa7c6be..0b6b80019 100644
--- a/security/nss/lib/ckfw/mutex.c
+++ b/security/nss/lib/ckfw/mutex.c
@@ -67,11 +67,7 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
*/
struct NSSCKFWMutexStr {
- CK_VOID_PTR etc;
-
- CK_DESTROYMUTEX Destroy;
- CK_LOCKMUTEX Lock;
- CK_UNLOCKMUTEX Unlock;
+ PRLock *lock;
};
#ifdef DEBUG
@@ -144,23 +140,13 @@ nssCKFWMutex_Create
*pError = CKR_HOST_MEMORY;
return (NSSCKFWMutex *)NULL;
}
-
- switch (LockingState)
- {
- default:
- case SingleThreaded:
- *pError = CKR_OK;
- mutex->Destroy = (CK_DESTROYMUTEX)mutex_noop;
- mutex->Lock = (CK_LOCKMUTEX )mutex_noop;
- mutex->Unlock = (CK_UNLOCKMUTEX )mutex_noop;
- break;
-
- case MultiThreaded:
- *pError = pInitArgs->CreateMutex(&mutex->etc);
- mutex->Destroy = pInitArgs->DestroyMutex;
- mutex->Lock = pInitArgs->LockMutex;
- mutex->Unlock = pInitArgs->UnlockMutex;
- break;
+ *pError = CKR_OK;
+ mutex->lock = NULL;
+ if (LockingState == MultiThreaded) {
+ mutex->lock = PR_NewLock();
+ if (!mutex->lock) {
+ *pError = CKR_HOST_MEMORY; /* we couldn't get the resource */
+ }
}
if( CKR_OK != *pError ) {
@@ -171,6 +157,9 @@ nssCKFWMutex_Create
#ifdef DEBUG
*pError = mutex_add_pointer(mutex);
if( CKR_OK != *pError ) {
+ if (mutex->lock) {
+ PR_DestroyLock(mutex->lock);
+ }
(void)nss_ZFreeIf(mutex);
return (NSSCKFWMutex *)NULL;
}
@@ -197,8 +186,10 @@ nssCKFWMutex_Destroy
return rv;
}
#endif /* NSSDEBUG */
-
- rv = mutex->Destroy(mutex->etc);
+
+ if (mutex->lock) {
+ PR_DestroyLock(mutex->lock);
+ }
#ifdef DEBUG
(void)mutex_remove_pointer(mutex);
@@ -224,8 +215,11 @@ nssCKFWMutex_Lock
return rv;
}
#endif /* NSSDEBUG */
+ if (mutex->lock) {
+ PR_Lock(mutex->lock);
+ }
- return mutex->Lock(mutex->etc);
+ return CKR_OK;
}
/*
@@ -238,14 +232,24 @@ nssCKFWMutex_Unlock
NSSCKFWMutex *mutex
)
{
+ PRStatus nrv;
#ifdef NSSDEBUG
CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
+
if( CKR_OK != rv ) {
return rv;
}
#endif /* NSSDEBUG */
- return mutex->Unlock(mutex->etc);
+ if (!mutex->lock)
+ return CKR_OK;
+
+ nrv = PR_Unlock(mutex->lock);
+
+ /* if unlock fails, either we have a programming error, or we have
+ * some sort of hardware failure... in either case return CKR_DEVICE_ERROR.
+ */
+ return nrv == PR_SUCCESS ? CKR_OK : CKR_DEVICE_ERROR;
}
/*
diff --git a/security/nss/lib/ckfw/wrap.c b/security/nss/lib/ckfw/wrap.c
index eaa504bb3..b9af321a3 100644
--- a/security/nss/lib/ckfw/wrap.c
+++ b/security/nss/lib/ckfw/wrap.c
@@ -125,6 +125,46 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
* NSSCKFWC_CancelFunction
*/
+/* figure out out locking semantics */
+static CK_RV
+nssCKFW_GetThreadSafeState(CK_C_INITIALIZE_ARGS_PTR pInitArgs,
+ CryptokiLockingState *pLocking_state) {
+ int functionCount = 0;
+
+ /* parsed according to (PKCS #11 Section 11.4) */
+ /* no args, the degenerate version of case 1 */
+ if (!pInitArgs) {
+ *pLocking_state = SingleThreaded;
+ return CKR_OK;
+ }
+
+ /* CKF_OS_LOCKING_OK set, Cases 2 and 4 */
+ if (pInitArgs->flags & CKF_OS_LOCKING_OK) {
+ *pLocking_state = MultiThreaded;
+ return CKR_OK;
+ }
+ if ((CK_CREATEMUTEX) NULL != pInitArgs->CreateMutex) functionCount++;
+ if ((CK_DESTROYMUTEX) NULL != pInitArgs->DestroyMutex) functionCount++;
+ if ((CK_LOCKMUTEX) NULL != pInitArgs->LockMutex) functionCount++;
+ if ((CK_UNLOCKMUTEX) NULL != pInitArgs->UnlockMutex) functionCount++;
+
+ /* CKF_OS_LOCKING_OK is not set, and not functions supplied,
+ * explicit case 1 */
+ if (0 == functionCount) {
+ *pLocking_state = SingleThreaded;
+ return CKR_OK;
+ }
+
+ /* OS_LOCKING_OK is not set and functions have been supplied. Since
+ * ckfw uses nssbase library which explicitly calls NSPR, and since
+ * there is no way to reliably override these explicit calls to NSPR,
+ * therefore we can't support applications which have their own threading
+ * module. Return CKR_CANT_LOCK if they supplied the correct number of
+ * arguments, or CKR_ARGUMENTS_BAD if they did not in either case we will
+ * fail the initialize */
+ return (4 == functionCount) ? CKR_CANT_LOCK : CKR_ARGUMENTS_BAD;
+}
+
/*
* NSSCKFWC_Initialize
*
@@ -155,12 +195,9 @@ NSSCKFWC_Initialize
goto loser;
}
- /* remember the locking args for those times we need to get a lock in code
- * outside the framework.
- */
- error = nssSetLockArgs(pInitArgs, &locking_state);
- if (CKR_OK != error) {
- goto loser;
+ error = nssCKFW_GetThreadSafeState(pInitArgs,&locking_state);
+ if( CKR_OK != error ) {
+ goto loser;
}
*pFwInstance = nssCKFWInstance_Create(pInitArgs, locking_state, mdInstance, &error);
diff --git a/security/nss/lib/crmf/cmmfrec.c b/security/nss/lib/crmf/cmmfrec.c
index 3aa3d266d..3dd7cdd07 100644
--- a/security/nss/lib/crmf/cmmfrec.c
+++ b/security/nss/lib/crmf/cmmfrec.c
@@ -70,22 +70,22 @@ CMMF_DestroyKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep)
{
PORT_Assert(inKeyRecRep != NULL);
if (inKeyRecRep != NULL && inKeyRecRep->poolp != NULL) {
- if (!inKeyRecRep->isDecoded) {
- int i;
+ int i;
+ if (!inKeyRecRep->isDecoded && inKeyRecRep->newSigCert != NULL) {
CERT_DestroyCertificate(inKeyRecRep->newSigCert);
- if (inKeyRecRep->caCerts != NULL) {
- for (i=0; inKeyRecRep->caCerts[i] != NULL; i++) {
- CERT_DestroyCertificate(inKeyRecRep->caCerts[i]);
- }
+ }
+ if (inKeyRecRep->caCerts != NULL) {
+ for (i=0; inKeyRecRep->caCerts[i] != NULL; i++) {
+ CERT_DestroyCertificate(inKeyRecRep->caCerts[i]);
}
- if (inKeyRecRep->keyPairHist != NULL) {
- for (i=0; inKeyRecRep->keyPairHist[i] != NULL; i++) {
- if (inKeyRecRep->keyPairHist[i]->certOrEncCert.choice ==
+ }
+ if (inKeyRecRep->keyPairHist != NULL) {
+ for (i=0; inKeyRecRep->keyPairHist[i] != NULL; i++) {
+ if (inKeyRecRep->keyPairHist[i]->certOrEncCert.choice ==
cmmfCertificate) {
- CERT_DestroyCertificate(inKeyRecRep->keyPairHist[i]->
+ CERT_DestroyCertificate(inKeyRecRep->keyPairHist[i]->
certOrEncCert.cert.certificate);
- }
}
}
}
@@ -117,6 +117,10 @@ CMMF_KeyRecRepContentSetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep,
if (inKeyRecRep == NULL || inNewSignCert == NULL) {
return SECFailure;
}
+ if (!inKeyRecRep->isDecoded && inKeyRecRep->newSigCert) {
+ CERT_DestroyCertificate(inKeyRecRep->newSigCert);
+ }
+ inKeyRecRep->isDecoded = PR_FALSE;
inKeyRecRep->newSigCert = CERT_DupCertificate(inNewSignCert);
return (inKeyRecRep->newSigCert == NULL) ? SECFailure : SECSuccess;
}
@@ -231,6 +235,12 @@ CMMF_KeyRecRepContentGetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep)
inKeyRecRep->newSigCert == NULL) {
return NULL;
}
+ /* newSigCert may not be a real certificate, it may be a hand decoded
+ * cert structure. This code makes sure we hand off a real, fully formed
+ * CERTCertificate to the caller. TODO: This should move into the decode
+ * portion so that we never wind up with a half formed CERTCertificate
+ * here. In this case the call would be to CERT_DupCertificate.
+ */
return CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
&inKeyRecRep->newSigCert->signatureWrap.data,
NULL, PR_FALSE, PR_TRUE);
diff --git a/security/nss/lib/cryptohi/hasht.h b/security/nss/lib/cryptohi/hasht.h
index 2d2c6b0ca..6df38b49a 100644
--- a/security/nss/lib/cryptohi/hasht.h
+++ b/security/nss/lib/cryptohi/hasht.h
@@ -72,13 +72,15 @@ typedef enum {
* Structure to hold hash computation info and routines
*/
struct SECHashObjectStr {
- unsigned int length;
+ unsigned int length; /* hash output length (in bytes) */
void * (*create)(void);
void * (*clone)(void *);
void (*destroy)(void *, PRBool);
void (*begin)(void *);
void (*update)(void *, const unsigned char *, unsigned int);
void (*end)(void *, unsigned char *, unsigned int *, unsigned int);
+ unsigned int blocklength; /* hash input block size (in bytes) */
+ HASH_HashType type;
};
struct HASHContextStr {
diff --git a/security/nss/lib/cryptohi/keyhi.h b/security/nss/lib/cryptohi/keyhi.h
index c66edbcd7..8707c3d1d 100644
--- a/security/nss/lib/cryptohi/keyhi.h
+++ b/security/nss/lib/cryptohi/keyhi.h
@@ -283,9 +283,7 @@ SECKEY_AddPublicKeyToListTail( SECKEYPublicKeyList *list,
#define PUBKEY_LIST_NEXT(n) ((SECKEYPublicKeyListNode *)n->links.next)
#define PUBKEY_LIST_END(n,l) (((void *)n) == ((void *)&l->list))
-#ifdef NSS_ENABLE_ECC
extern int SECKEY_ECParamsToKeySize(const SECItem *params);
-#endif /* NSS_ENABLE_ECC */
SEC_END_PROTOS
diff --git a/security/nss/lib/cryptohi/manifest.mn b/security/nss/lib/cryptohi/manifest.mn
index 657302e69..897559896 100644
--- a/security/nss/lib/cryptohi/manifest.mn
+++ b/security/nss/lib/cryptohi/manifest.mn
@@ -65,8 +65,3 @@ LIBSRCS = \
$(NULL)
CSRCS = $(LIBSRCS)
-
-ifdef NSS_ENABLE_ECC
-DEFINES += -DNSS_ENABLE_ECC
-endif
-
diff --git a/security/nss/lib/cryptohi/sechash.c b/security/nss/lib/cryptohi/sechash.c
index e977dd5f2..eebe23d95 100644
--- a/security/nss/lib/cryptohi/sechash.c
+++ b/security/nss/lib/cryptohi/sechash.c
@@ -114,7 +114,9 @@ const SECHashObject SECHashObjects[] = {
(void (*)(void *)) null_hash_begin,
(void (*)(void *, const unsigned char *, unsigned int)) null_hash_update,
(void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) null_hash_end
+ unsigned int)) null_hash_end,
+ 0,
+ HASH_AlgNULL
},
{ MD2_LENGTH,
(void * (*)(void)) md2_NewContext,
@@ -123,7 +125,9 @@ const SECHashObject SECHashObjects[] = {
(void (*)(void *)) PK11_DigestBegin,
(void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
(void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- PK11_DigestFinal
+ PK11_DigestFinal,
+ MD2_BLOCK_LENGTH,
+ HASH_AlgMD2
},
{ MD5_LENGTH,
(void * (*)(void)) md5_NewContext,
@@ -132,7 +136,9 @@ const SECHashObject SECHashObjects[] = {
(void (*)(void *)) PK11_DigestBegin,
(void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
(void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- PK11_DigestFinal
+ PK11_DigestFinal,
+ MD5_BLOCK_LENGTH,
+ HASH_AlgMD5
},
{ SHA1_LENGTH,
(void * (*)(void)) sha1_NewContext,
@@ -141,7 +147,9 @@ const SECHashObject SECHashObjects[] = {
(void (*)(void *)) PK11_DigestBegin,
(void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
(void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- PK11_DigestFinal
+ PK11_DigestFinal,
+ SHA1_BLOCK_LENGTH,
+ HASH_AlgSHA1
},
{ SHA256_LENGTH,
(void * (*)(void)) sha256_NewContext,
@@ -150,7 +158,9 @@ const SECHashObject SECHashObjects[] = {
(void (*)(void *)) PK11_DigestBegin,
(void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
(void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- PK11_DigestFinal
+ PK11_DigestFinal,
+ SHA256_BLOCK_LENGTH,
+ HASH_AlgSHA256
},
{ SHA384_LENGTH,
(void * (*)(void)) sha384_NewContext,
@@ -159,7 +169,9 @@ const SECHashObject SECHashObjects[] = {
(void (*)(void *)) PK11_DigestBegin,
(void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
(void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- PK11_DigestFinal
+ PK11_DigestFinal,
+ SHA384_BLOCK_LENGTH,
+ HASH_AlgSHA384
},
{ SHA512_LENGTH,
(void * (*)(void)) sha512_NewContext,
@@ -168,7 +180,9 @@ const SECHashObject SECHashObjects[] = {
(void (*)(void *)) PK11_DigestBegin,
(void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
(void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- PK11_DigestFinal
+ PK11_DigestFinal,
+ SHA512_BLOCK_LENGTH,
+ HASH_AlgSHA512
},
};
diff --git a/security/nss/lib/cryptohi/seckey.c b/security/nss/lib/cryptohi/seckey.c
index 843ce9a26..97f79d99e 100644
--- a/security/nss/lib/cryptohi/seckey.c
+++ b/security/nss/lib/cryptohi/seckey.c
@@ -243,7 +243,6 @@ SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, SECKEYPublicKey **pubk, void *c
SECKEYPrivateKey *
SECKEY_CreateECPrivateKey(SECKEYECParams *param, SECKEYPublicKey **pubk, void *cx)
{
-#ifdef NSS_ENABLE_ECC
SECKEYPrivateKey *privk;
PK11SlotInfo *slot = PK11_GetBestSlot(CKM_EC_KEY_PAIR_GEN,cx);
@@ -255,9 +254,6 @@ SECKEY_CreateECPrivateKey(SECKEYECParams *param, SECKEYPublicKey **pubk, void *c
PK11_FreeSlot(slot);
return(privk);
-#else
- return NULL;
-#endif /* NSS_ENABLE_ECC */
}
void
@@ -299,10 +295,22 @@ SECKEY_CopySubjectPublicKeyInfo(PRArenaPool *arena,
CERTSubjectPublicKeyInfo *from)
{
SECStatus rv;
+ SECItem spk;
rv = SECOID_CopyAlgorithmID(arena, &to->algorithm, &from->algorithm);
- if (rv == SECSuccess)
- rv = SECITEM_CopyItem(arena, &to->subjectPublicKey, &from->subjectPublicKey);
+ if (rv == SECSuccess) {
+ /*
+ * subjectPublicKey is a bit string, whose length is in bits.
+ * Convert the length from bits to bytes for SECITEM_CopyItem.
+ */
+ spk = from->subjectPublicKey;
+ DER_ConvertBitString(&spk);
+ rv = SECITEM_CopyItem(arena, &to->subjectPublicKey, &spk);
+ /* Set the length back to bits. */
+ if (rv == SECSuccess) {
+ to->subjectPublicKey.len = from->subjectPublicKey.len;
+ }
+ }
return rv;
}
@@ -1093,7 +1101,6 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
break;
-#ifdef NSS_ENABLE_ECC
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
pubk->keyType = ecKey;
pubk->u.ec.size = 0;
@@ -1108,7 +1115,6 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, &newOs);
if (rv == SECSuccess) return pubk;
break;
-#endif /* NSS_ENABLE_ECC */
default:
rv = SECFailure;
@@ -1305,7 +1311,6 @@ SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk)
pubk->u.dh.publicValue.len - 1;
case fortezzaKey:
return PR_MAX(pubk->u.fortezza.KEAKey.len, pubk->u.fortezza.DSSKey.len);
-#ifdef NSS_ENABLE_ECC
case ecKey:
/* Get the key size in bits and adjust */
if (pubk->u.ec.size == 0) {
@@ -1313,7 +1318,6 @@ SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk)
SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
}
return (pubk->u.ec.size + 7)/8;
-#endif /* NSS_ENABLE_ECC */
default:
break;
}
@@ -1330,14 +1334,12 @@ SECKEY_PublicKeyStrengthInBits(SECKEYPublicKey *pubk)
case dhKey:
case fortezzaKey:
return SECKEY_PublicKeyStrength(pubk) * 8; /* 1 byte = 8 bits */
-#ifdef NSS_ENABLE_ECC
case ecKey:
if (pubk->u.ec.size == 0) {
pubk->u.ec.size =
SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
}
return pubk->u.ec.size;
-#endif /* NSS_ENABLE_ECC */
default:
break;
}
@@ -1493,7 +1495,6 @@ SECKEY_CopyPublicKey(SECKEYPublicKey *pubk)
rv = SECITEM_CopyItem(arena, &copyk->u.dh.publicValue,
&pubk->u.dh.publicValue);
break;
-#ifdef NSS_ENABLE_ECC
case ecKey:
copyk->u.ec.size = pubk->u.ec.size;
rv = SECITEM_CopyItem(arena,&copyk->u.ec.DEREncodedParams,
@@ -1502,7 +1503,6 @@ SECKEY_CopyPublicKey(SECKEYPublicKey *pubk)
rv = SECITEM_CopyItem(arena,&copyk->u.ec.publicValue,
&pubk->u.ec.publicValue);
break;
-#endif /* NSS_ENABLE_ECC */
case nullKey:
return copyk;
default:
@@ -1661,7 +1661,6 @@ SECKEY_CreateSubjectPublicKeyInfo(SECKEYPublicKey *pubk)
}
SECITEM_FreeItem(&params, PR_FALSE);
break;
-#ifdef NSS_ENABLE_ECC
case ecKey:
rv = SECITEM_CopyItem(arena, &params,
&pubk->u.ec.DEREncodedParams);
@@ -1687,7 +1686,6 @@ SECKEY_CreateSubjectPublicKeyInfo(SECKEYPublicKey *pubk)
return spki;
}
break;
-#endif /* NSS_ENABLE_ECC */
case keaKey:
case dhKey: /* later... */
diff --git a/security/nss/lib/cryptohi/secsign.c b/security/nss/lib/cryptohi/secsign.c
index 68447be26..12e6ed3ad 100644
--- a/security/nss/lib/cryptohi/secsign.c
+++ b/security/nss/lib/cryptohi/secsign.c
@@ -121,18 +121,16 @@ SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key)
signalg = SEC_OID_MISSI_DSS; /* XXX Is there a better algid? */
keyType = fortezzaKey;
break;
-#ifdef NSS_ENABLE_ECC
case SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST:
hashalg = SEC_OID_SHA1;
- signalg = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
+ signalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
keyType = ecKey;
break;
-#endif /* NSS_ENABLE_ECC */
/* we don't implement MD4 hashes.
* we *CERTAINLY* don't want to sign one! */
case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
return 0;
}
@@ -266,7 +264,7 @@ SGN_End(SGNContext *cx, SECItem *result)
}
if ((cx->signalg == SEC_OID_ANSIX9_DSA_SIGNATURE) ||
- (cx->signalg == SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST)) {
+ (cx->signalg == SEC_OID_ANSIX962_EC_PUBLIC_KEY)) {
/* DSAU_EncodeDerSigWithLen works for DSA and ECDSA */
rv = DSAU_EncodeDerSigWithLen(result, &sigitem, signatureLen);
PORT_Free(sigitem.data);
@@ -319,57 +317,6 @@ SEC_SignData(SECItem *res, unsigned char *buf, int len,
return rv;
}
-/*
-** Sign the input file's contents returning in result a bunch of bytes
-** that are the signature. Returns zero on success, an error code on
-** failure.
-*/
-SECStatus
-SEC_SignFile(SECItem *result, FILE *input,
- SECKEYPrivateKey *pk, SECOidTag algid)
-{
- unsigned char buf[1024];
- SECStatus rv;
- int nb;
- SGNContext *sgn;
-
- sgn = SGN_NewContext(algid, pk);
- if (sgn == NULL)
- return SECFailure;
- rv = SGN_Begin(sgn);
- if (rv != SECSuccess)
- goto loser;
-
- /*
- ** Now feed the contents of the input file into the digest
- ** algorithm, one chunk at a time, until we have exhausted the
- ** input
- */
- for (;;) {
- if (feof(input)) break;
- nb = fread(buf, 1, sizeof(buf), input);
- if (nb == 0) {
- if (ferror(input)) {
- PORT_SetError(SEC_ERROR_IO);
- rv = SECFailure;
- goto loser;
- }
- break;
- }
- rv = SGN_Update(sgn, buf, nb);
- if (rv != SECSuccess)
- goto loser;
- }
-
- /* Sign the digest */
- rv = SGN_End(sgn, result);
- /* FALL THROUGH */
-
- loser:
- SGN_DestroyContext(sgn, PR_TRUE);
- return rv;
-}
-
/************************************************************************/
DERTemplate CERTSignedDataTemplate[] =
@@ -425,14 +372,12 @@ SEC_DerSignData(PRArenaPool *arena, SECItem *result,
case dsaKey:
algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
break;
-#ifdef NSS_ENABLE_ECC
case ecKey:
algID = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
break;
-#endif /* NSS_ENABLE_ECC */
default:
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
return SECFailure;
- break;
}
}
@@ -557,12 +502,10 @@ SEC_GetSignatureAlgorithmOidTag(KeyType keyType, SECOidTag hashAlgTag)
break;
}
break;
-#ifdef NSS_ENABLE_ECC
case ecKey:
/* XXX For now only ECDSA with SHA1 is supported */
sigTag = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
break;
-#endif /* NSS_ENABLE_ECC */
default:
break;
}
diff --git a/security/nss/lib/cryptohi/secvfy.c b/security/nss/lib/cryptohi/secvfy.c
index 4a5de4e0f..311bec35e 100644
--- a/security/nss/lib/cryptohi/secvfy.c
+++ b/security/nss/lib/cryptohi/secvfy.c
@@ -50,12 +50,14 @@
#include "secerr.h"
/*
-** Decrypt signature block using public key (in place)
+** Decrypt signature block using public key
+** Store the hash algorithm oid tag in *tagp
+** Store the digest in the digest buffer
** XXX this is assuming that the signature algorithm has WITH_RSA_ENCRYPTION
*/
static SECStatus
-DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, SECKEYPublicKey *key,
- SECItem *sig, char *wincx)
+DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, unsigned int len,
+ SECKEYPublicKey *key, SECItem *sig, char *wincx)
{
SGNDigestInfo *di = NULL;
unsigned char *buf = NULL;
@@ -83,7 +85,7 @@ DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, SECKEYPublicKey *key,
*/
tag = SECOID_GetAlgorithmTag(&di->digestAlgorithm);
/* XXX Check that tag is an appropriate algorithm? */
- if (di->digest.len > HASH_LENGTH_MAX) {
+ if (di->digest.len > len) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
goto loser;
}
@@ -107,29 +109,45 @@ DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, SECKEYPublicKey *key,
typedef enum { VFY_RSA, VFY_DSA, VFY_ECDSA } VerifyType;
struct VFYContextStr {
- SECOidTag alg;
+ SECOidTag alg; /* the hash algorithm */
VerifyType type;
SECKEYPublicKey *key;
/*
- * digest holds either the hash (<= HASH_LENGTH_MAX=64 bytes)
- * in the RSA signature, or the full DSA signature (40 bytes).
+ * This buffer holds either the digest or the full signature
+ * depending on the type of the signature. It is defined as a
+ * union to make sure it always has enough space.
+ *
+ * Use the "buffer" union member to reference the buffer.
+ * Note: do not take the size of the "buffer" union member. Take
+ * the size of the union or some other union member instead.
*/
- unsigned char digest[HASH_LENGTH_MAX];
+ union {
+ unsigned char buffer[1];
+
+ /* the digest in the decrypted RSA signature */
+ unsigned char rsadigest[HASH_LENGTH_MAX];
+ /* the full DSA signature... 40 bytes */
+ unsigned char dsasig[DSA_SIGNATURE_LEN];
+ /* the full ECDSA signature */
+ unsigned char ecdsasig[2 * MAX_ECKEY_LEN];
+ } u;
void * wincx;
void *hashcx;
const SECHashObject *hashobj;
- SECOidTag sigAlg;
- PRBool hasSignature;
- unsigned char ecdsadigest[2 * MAX_ECKEY_LEN];
+ SECOidTag sigAlg; /* the (composite) signature algorithm */
+ PRBool hasSignature; /* true if the signature was provided in the
+ * VFY_CreateContext call. If false, the
+ * signature must be provided with a
+ * VFY_EndWithSignature call. */
};
/*
* decode the ECDSA or DSA signature from it's DER wrapping.
* The unwrapped/raw signature is placed in the buffer pointed
- * to by digest and has enough room for len bytes.
+ * to by dsig and has enough room for len bytes.
*/
static SECStatus
-decodeECorDSASignature(SECOidTag algid, SECItem *sig, unsigned char *digest,
+decodeECorDSASignature(SECOidTag algid, SECItem *sig, unsigned char *dsig,
unsigned int len) {
SECItem *dsasig = NULL; /* also used for ECDSA */
SECStatus rv=SECSuccess;
@@ -152,14 +170,14 @@ decodeECorDSASignature(SECOidTag algid, SECItem *sig, unsigned char *digest,
if ((dsasig == NULL) || (dsasig->len != len)) {
rv = SECFailure;
} else {
- PORT_Memcpy(digest, dsasig->data, dsasig->len);
+ PORT_Memcpy(dsig, dsasig->data, dsasig->len);
}
break;
default:
if (sig->len != len) {
rv = SECFailure;
} else {
- PORT_Memcpy(digest, sig->data, sig->len);
+ PORT_Memcpy(dsig, sig->data, sig->len);
}
break;
}
@@ -176,7 +194,9 @@ decodeECorDSASignature(SECOidTag algid, SECItem *sig, unsigned char *digest,
* alg: the composite algorithm to dissect.
* hashalg: address of a SECOidTag which will be set with the hash algorithm.
* signalg: address of a SECOidTag which will be set with the signing alg.
+ * (not implemented)
* keyType: address of a KeyType which will be set with the key type.
+ * (not implemented)
* Returns: SECSuccess if the algorithm was acceptable, SECFailure if the
* algorithm was not found or was not a signing algorithm.
*/
@@ -234,7 +254,6 @@ VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid,
{
VFYContext *cx;
SECStatus rv;
- unsigned char *tmp;
unsigned int sigLen;
cx = (VFYContext*) PORT_ZAlloc(sizeof(VFYContext));
@@ -249,8 +268,8 @@ VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid,
cx->key = SECKEY_CopyPublicKey(key); /* extra safety precautions */
if (sig) {
SECOidTag hashid = SEC_OID_UNKNOWN;
- rv = DecryptSigBlock(&hashid, &cx->digest[0],
- cx->key, sig, (char*)wincx);
+ rv = DecryptSigBlock(&hashid, cx->u.buffer,
+ HASH_LENGTH_MAX, cx->key, sig, (char*)wincx);
cx->alg = hashid;
} else {
rv = decodeSigAlg(algid,&cx->alg);
@@ -265,16 +284,14 @@ VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid,
* (it depends on the key size)
*/
sigLen = SECKEY_PublicKeyStrength(key) * 2;
- tmp = cx->ecdsadigest;
} else {
cx->type = VFY_DSA;
sigLen = DSA_SIGNATURE_LEN;
- tmp = cx->digest;
}
cx->alg = SEC_OID_SHA1;
cx->key = SECKEY_CopyPublicKey(key);
if (sig) {
- rv = decodeECorDSASignature(algid,sig,tmp,sigLen);
+ rv = decodeECorDSASignature(algid,sig,cx->u.buffer,sigLen);
}
break;
default:
@@ -371,11 +388,10 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
switch (cx->type) {
case VFY_DSA:
case VFY_ECDSA:
+ dsasig.data = cx->u.buffer;
if (cx->type == VFY_DSA) {
- dsasig.data = cx->digest;
dsasig.len = DSA_SIGNATURE_LEN;
} else {
- dsasig.data = cx->ecdsadigest;
dsasig.len = SECKEY_PublicKeyStrength(cx->key) * 2;
}
if (sig) {
@@ -396,14 +412,14 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
case VFY_RSA:
if (sig) {
SECOidTag hashid = SEC_OID_UNKNOWN;
- rv = DecryptSigBlock(&hashid, &cx->digest[0],
- cx->key, sig, (char*)cx->wincx);
+ rv = DecryptSigBlock(&hashid, cx->u.buffer,
+ HASH_LENGTH_MAX, cx->key, sig, (char*)cx->wincx);
if ((rv != SECSuccess) || (hashid != cx->alg)) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
return SECFailure;
}
}
- if (PORT_Memcmp(final, cx->digest, part)) {
+ if (PORT_Memcmp(final, cx->u.buffer, part)) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
return SECFailure;
}
@@ -434,10 +450,7 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig,
{
SECStatus rv;
VFYContext *cx;
- SECItem dsasig;
-#ifdef NSS_ENABLE_ECC
- SECItem ecdsasig;
-#endif /* NSS_ENABLE_ECC */
+ SECItem dsasig; /* also used for ECDSA */
rv = SECFailure;
@@ -445,7 +458,7 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig,
if (cx != NULL) {
switch (key->keyType) {
case rsaKey:
- if (PORT_Memcmp(digest->data, cx->digest, digest->len)) {
+ if (PORT_Memcmp(digest->data, cx->u.buffer, digest->len)) {
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
} else {
rv = SECSuccess;
@@ -453,26 +466,21 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig,
break;
case fortezzaKey:
case dsaKey:
- dsasig.data = &cx->digest[0];
- dsasig.len = DSA_SIGNATURE_LEN; /* magic size of dsa signature */
- if (PK11_Verify(cx->key, &dsasig, digest, cx->wincx) != SECSuccess) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ case ecKey:
+ dsasig.data = cx->u.buffer;
+ if (key->keyType == ecKey) {
+ dsasig.len = SECKEY_PublicKeyStrength(cx->key) * 2;
} else {
- rv = SECSuccess;
+ /* magic size of dsa signature */
+ dsasig.len = DSA_SIGNATURE_LEN;
}
- break;
-#ifdef NSS_ENABLE_ECC
- case ecKey:
- ecdsasig.data = &cx->ecdsadigest[0];
- ecdsasig.len = SECKEY_PublicKeyStrength(cx->key) * 2;
- if (PK11_Verify(cx->key, &ecdsasig, digest, cx->wincx)
+ if (PK11_Verify(cx->key, &dsasig, digest, cx->wincx)
!= SECSuccess) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
} else {
rv = SECSuccess;
}
break;
-#endif /* NSS_ENABLE_ECC */
default:
break;
}
@@ -502,49 +510,3 @@ VFY_VerifyData(unsigned char *buf, int len, SECKEYPublicKey *key,
VFY_DestroyContext(cx, PR_TRUE);
return rv;
}
-
-SECStatus
-SEC_VerifyFile(FILE *input, SECKEYPublicKey *key, SECItem *sig,
- SECOidTag algid, void *wincx)
-{
- unsigned char buf[1024];
- SECStatus rv;
- int nb;
- VFYContext *cx;
-
- cx = VFY_CreateContext(key, sig, algid, wincx);
- if (cx == NULL)
- rv = SECFailure;
-
- rv = VFY_Begin(cx);
- if (rv == SECSuccess) {
- /*
- * Now feed the contents of the input file into the digest algorithm,
- * one chunk at a time, until we have exhausted the input.
- */
- for (;;) {
- if (feof(input))
- break;
- nb = fread(buf, 1, sizeof(buf), input);
- if (nb == 0) {
- if (ferror(input)) {
- PORT_SetError(SEC_ERROR_IO);
- VFY_DestroyContext(cx, PR_TRUE);
- return SECFailure;
- }
- break;
- }
- rv = VFY_Update(cx, buf, nb);
- if (rv != SECSuccess)
- goto loser;
- }
- }
-
- /* Verify the digest */
- rv = VFY_End(cx);
- /* FALL THROUGH */
-
- loser:
- VFY_DestroyContext(cx, PR_TRUE);
- return rv;
-}
diff --git a/security/nss/lib/freebl/Makefile b/security/nss/lib/freebl/Makefile
index dd844160a..1805d1c5e 100644
--- a/security/nss/lib/freebl/Makefile
+++ b/security/nss/lib/freebl/Makefile
@@ -62,12 +62,16 @@ include $(CORE_DEPTH)/coreconf/config.mk
-include config.mk
+# default for all platforms
+# unset this on those that have multiple freebl libraries
+FREEBL_BUILD_SINGLE_SHLIB = 1
+
ifdef USE_64
DEFINES += -DNSS_USE_64
endif
-ifdef USE_HYBRID
- DEFINES += -DNSS_USE_HYBRID
+ifdef USE_ABI32_FPU
+ DEFINES += -DNSS_USE_ABI32_FPU
endif
# des.c wants _X86_ defined for intel CPUs.
@@ -132,22 +136,16 @@ ifeq ($(CPU_ARCH),x86_64)
ASFILES = arcfour-amd64-gas.s mpi_amd64_gas.s
ASFLAGS += -march=opteron -m64 -fPIC
DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
- MPI_SRCS += mpi_amd64.c
+ DEFINES += -DNSS_USE_COMBA
+ MPI_SRCS += mpi_amd64.c mp_comba.c
endif
ifeq ($(CPU_ARCH),x86)
ASFILES = mpi_x86.s
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
DEFINES += -DMP_ASSEMBLY_DIV_2DX1D
- USE_FP_CODE = 1
+ # The floating point ECC code doesn't work on Linux x86 (bug 311432).
+ #ECL_USE_FP = 1
endif
-ifdef NSS_ENABLE_ECC
- ifdef USE_FP_CODE
- #enable floating point ECC code
- DEFINES += -DECL_USE_FP
- ECL_SRCS += ecp_fp160.c ecp_fp192.c ecp_fp224.c ecp_fp.c
- ECL_HDRS += ecp_fp.h
- endif
-endif # NSS_ENABLE_ECC
endif # Linux
ifeq ($(OS_TARGET),AIX)
@@ -159,10 +157,16 @@ endif # AIX
ifeq ($(OS_TARGET), HP-UX)
ifneq ($(OS_TEST), ia64)
-MKSHLIB += +k +vshlibunsats -u FREEBL_GetVector +e FREEBL_GetVector
-ifndef FREEBL_EXTENDED_BUILD
-ifdef USE_PURE_32
-# build for DA1.1 (HP PA 1.1) pure 32 bit model
+# PA-RISC
+ASFILES += ret_cr16.s
+ifndef USE_64
+ FREEBL_BUILD_SINGLE_SHLIB =
+ HAVE_ABI32_INT32 = 1
+ HAVE_ABI32_FPU = 1
+endif
+ifdef FREEBL_CHILD_BUILD
+ifdef USE_ABI32_INT32
+# build for DA1.1 (HP PA 1.1) 32-bit ABI build with 32-bit arithmetic
DEFINES += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
else
@@ -172,71 +176,159 @@ ifdef USE_64
ASFILES += hpma512.s hppa20.s
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
else
-# this builds for DA2.0 (HP PA 2.0 Narrow) hybrid model
+# this builds for DA2.0 (HP PA 2.0 Narrow) ABI32_FPU model
# (the 32-bit ABI with 64-bit registers) using 32-bit digits
MPI_SRCS += mpi_hp.c
ASFILES += hpma512.s hppa20.s
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
+ ARCHFLAG = -Aa +e +DA2.0 +DS2.0
endif
endif
endif
endif
endif
-# Note: -xarch=v8 or v9 is now done in coreconf
+# The blapi functions are defined not only in the freebl shared
+# libraries but also in the shared libraries linked with loader.c
+# (libsoftokn3.so and libssl3.so). We need to use GNU ld's
+# -Bsymbolic option or the equivalent option for other linkers
+# to bind the blapi function references in FREEBLVector vector
+# (ldvector.c) to the blapi functions defined in the freebl
+# shared libraries.
+ifeq (,$(filter-out BSD_OS FreeBSD Linux NetBSD, $(OS_TARGET)))
+ MKSHLIB += -Wl,-Bsymbolic
+endif
+
ifeq ($(OS_TARGET),SunOS)
# The -R '$ORIGIN' linker option instructs this library to search for its
# dependencies in the same directory where it resides.
MKSHLIB += -R '$$ORIGIN'
-
+ifdef NS_USE_GCC
+ ifdef GCC_USE_GNU_LD
+ MKSHLIB += -Wl,-Bsymbolic,-z,now,-z,text
+ else
+ MKSHLIB += -Wl,-B,symbolic,-z,now,-z,text
+ endif # GCC_USE_GNU_LD
+else
+ MKSHLIB += -B symbolic -z now -z text
+endif # NS_USE_GCC
+
+# Sun's WorkShop defines v8, v8plus and v9 architectures.
+# gcc on Solaris defines v8 and v9 "cpus".
+# gcc's v9 is equivalent to Workshop's v8plus.
+# gcc's -m64 is equivalent to Workshop's v9
+# We always use Sun's assembler, which uses Sun's naming convention.
ifeq ($(CPU_ARCH),sparc)
- ifndef NS_USE_GCC
- ifdef USE_HYBRID
- OS_CFLAGS += -xchip=ultra2
- endif # USE_HYBRID
- endif # NS_USE_GCC
- SYSV_SPARC=1
+ FREEBL_BUILD_SINGLE_SHLIB=
+ ifdef USE_64
+ HAVE_ABI64_INT = 1
+ HAVE_ABI64_FPU = 1
+ else
+ HAVE_ABI32_INT32 = 1
+ HAVE_ABI32_FPU = 1
+ HAVE_ABI32_INT64 = 1
+ endif
+ SYSV_SPARC = 1
SOLARIS_AS = /usr/ccs/bin/as
+ #### set arch, asm, c flags
ifdef NS_USE_GCC
- ifdef GCC_USE_GNU_LD
- MKSHLIB += -Wl,-Bsymbolic,-z,defs,-z,now,-z,text,--version-script,mapfile.Solaris
- else
- MKSHLIB += -Wl,-B,symbolic,-z,defs,-z,now,-z,text,-M,mapfile.Solaris
- endif # GCC_USE_GNU_LD
- else
- MKSHLIB += -B symbolic -z defs -z now -z text -M mapfile.Solaris
+ ifdef USE_ABI32_INT32
+ # default ARCHFLAG=-mcpu=v8 set by coreconf/sunOS5.mk
+ endif
+ ifdef USE_ABI32_INT64
+ ARCHFLAG=-mcpu=v9 -Wa,-xarch=v8plus
+ endif
+ ifdef USE_ABI32_FPU
+ ARCHFLAG=-mcpu=v9 -Wa,-xarch=v8plus
+ endif # USE_ABI32_FPU
+ ifdef USE_ABI64_INT
+ # this builds for Sparc v9a pure 64-bit architecture
+ endif
+ ifdef USE_ABI64_FPU
+ # this builds for Sparc v9a pure 64-bit architecture
+ # It uses floating point, and 32-bit word size
+ endif
+ else # NS_USE_GCC
+ ifdef USE_ABI32_INT32
+ #ARCHFLAG=-xarch=v8 set in coreconf/sunOS5.mk
+ endif
+ ifdef USE_ABI32_INT64
+ # this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
+ # 32-bit ABI, it uses 64-bit words, integer arithmetic,
+ # no FPU (non-VIS cpus).
+ # These flags were suggested by the compiler group for building
+ # with SunStudio 10.
+ SOL_CFLAGS += -xO4 -xtarget=generic
+ ARCHFLAG = -xarch=v8plus
+ SOLARIS_AS_FLAGS = -xarch=v8plus -K PIC
+ endif
+ ifdef USE_ABI32_FPU
+ # this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
+ # 32-bit ABI, it uses FPU code, and 32-bit word size.
+ # these flags were determined by running cc -### -fast and copying
+ # the generated flag settings
+ SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fns -fsimple=2 -fsingle
+ SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all
+ SOL_CFLAGS += -xcache=64/32/4:1024/64/4 -xchip=ultra3 -xdepend
+ SOL_CFLAGS += -xlibmil -xmemalign=8s -xO5
+ ARCHFLAG = -xarch=v8plusa
+ SOLARIS_AS_FLAGS = -xarch=v8plusa -K PIC
+ endif
+ ifdef USE_ABI64_INT
+ # this builds for Sparc v9a pure 64-bit architecture,
+ # no FPU (non-VIS cpus). For building with SunStudio 10.
+ SOL_CFLAGS += -xO4 -xtarget=generic
+ ARCHFLAG = -xarch=v9
+ SOLARIS_AS_FLAGS = -xarch=v9 -K PIC
+ endif
+ ifdef USE_ABI64_FPU
+ # this builds for Sparc v9a pure 64-bit architecture
+ # It uses floating point, and 32-bit word size.
+ # See comment for USE_ABI32_FPU.
+ SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fns -fsimple=2 -fsingle
+ SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all
+ SOL_CFLAGS += -xcache=64/32/4:1024/64/4 -xchip=ultra3 -xdepend
+ SOL_CFLAGS += -xlibmil -xmemalign=8s -xO5
+ ARCHFLAG = -xarch=v9a
+ SOLARIS_AS_FLAGS = -xarch=v9a -K PIC
+ endif
endif # NS_USE_GCC
- ifdef USE_PURE_32
+
+ ### set MP_ flags for both GCC and Sun cc
+ ifdef USE_ABI32_INT32
# this builds for Sparc v8 pure 32-bit architecture
- DEFINES += -DMP_USE_LONG_LONG_MULTIPLY -DMP_USE_UINT_DIGIT
- DEFINES += -DMP_NO_MP_WORD
+ DEFINES += -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY
+ ASFILES = mpv_sparcv8x.s
DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
- else
- ifdef USE_64
- # this builds for Sparc v9a pure 64-bit architecture
- MPI_SRCS += mpi_sparc.c
- ASFILES = mpv_sparcv9.s montmulfv9.s
- DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_USING_MONT_MULF
- DEFINES += -DMP_USE_UINT_DIGIT
- SOLARIS_FLAGS = -fast -xO5 -xrestrict=%all -xchip=ultra -xarch=v9a
- SOLARIS_FLAGS += -KPIC -mt
- SOLARIS_AS_FLAGS = -xarch=v9a -K PIC
- else
- # this builds for Sparc v8+a hybrid architecture, 64-bit registers,
- # 32-bit ABI
- MPI_SRCS += mpi_sparc.c
- ASFILES = mpv_sparcv8.s montmulfv8.s
- DEFINES += -DMP_NO_MP_WORD -DMP_ASSEMBLY_MULTIPLY
- DEFINES += -DMP_USING_MONT_MULF -DMP_USE_UINT_DIGIT
- SOLARIS_AS_FLAGS = -xarch=v8plusa -K PIC
- endif # USE_64
- endif # USE_PURE_32
- ifdef NSS_ENABLE_ECC
- DEFINES += -DECL_USE_FP
- ECL_SRCS += ecp_fp160.c ecp_fp192.c ecp_fp224.c ecp_fp.c
- ECL_HDRS += ecp_fp.h
- endif # NSS_ENABLE_ECC
+ endif
+ ifdef USE_ABI32_INT64
+ # this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
+ # 32-bit ABI, it uses 64-bit words, integer arithmetic, no FPU
+ # best times are with no MP_ flags specified
+ endif
+ ifdef USE_ABI32_FPU
+ # this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
+ # 32-bit ABI, it uses FPU code, and 32-bit word size
+ MPI_SRCS += mpi_sparc.c
+ ASFILES = mpv_sparcv8.s montmulfv8.s
+ DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY
+ DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL
+ endif
+ ifdef USE_ABI64_INT
+ # this builds for Sparc v9a pure 64-bit architecture
+ # best times are with no MP_ flags specified
+ endif
+ ifdef USE_ABI64_FPU
+ # this builds for Sparc v9a pure 64-bit architecture
+ # It uses floating point, and 32-bit word size
+ MPI_SRCS += mpi_sparc.c
+ ASFILES = mpv_sparcv9.s montmulfv9.s
+ DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY
+ DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL
+ endif
+
+ ECL_USE_FP = 1
else
# Solaris for non-sparc family CPUs
ifdef NS_USE_GCC
@@ -249,11 +341,16 @@ else
ifdef NS_USE_GCC
ASFILES = arcfour-amd64-gas.s mpi_amd64_gas.s
ASFLAGS += -march=opteron -m64 -fPIC
+ MPI_SRCS += mp_comba.c
else
- ASFILES = arcfour-amd64-sun.s mpi_amd64_sun.s
+ ASFILES = arcfour-amd64-sun.s mpi_amd64_sun.s sha-fast-amd64-sun.s
+ ASFILES += mp_comba_amd64_sun.s mpcpucache_amd64.s
ASFLAGS += -xarch=generic64 -K PIC
+ SHA_SRCS =
+ MPCPU_SRCS =
endif
DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
+ DEFINES += -DNSS_USE_COMBA
MPI_SRCS += mpi_amd64.c
else
# Solaris x86
@@ -262,11 +359,22 @@ else
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
DEFINES += -DMP_ASSEMBLY_DIV_2DX1D
ASFILES = mpi_i86pc.s
+ ifndef NS_USE_GCC
+ MPCPU_SRCS =
+ ASFILES += mpcpucache_x86.s
+ endif
endif
endif # Solaris for non-sparc family CPUs
endif # target == SunOS
-$(OBJDIR)/sysrand$(OBJ_SUFFIX): sysrand.c unix_rand.c win_rand.c mac_rand.c os2_rand.c
+ifdef NSS_ENABLE_ECC
+ ifdef ECL_USE_FP
+ #enable floating point ECC code
+ DEFINES += -DECL_USE_FP
+ ECL_SRCS += ecp_fp160.c ecp_fp192.c ecp_fp224.c ecp_fp.c
+ ECL_HDRS += ecp_fp.h
+ endif
+endif # NSS_ENABLE_ECC
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
@@ -291,21 +399,12 @@ rijndael_tables:
$(DEFINES) $(INCLUDES) $(OBJDIR)/libfreebl.a
$(OBJDIR)/make_rijndael_tab
-ifdef USE_PURE_32
-vpath %.h $(FREEBL_PARENT)/ecl $(FREEBL_PARENT)/mpi $(FREEBL_PARENT)
-vpath %.c $(FREEBL_PARENT)/ecl $(FREEBL_PARENT)/mpi $(FREEBL_PARENT)
-vpath %.S $(FREEBL_PARENT)/ecl $(FREEBL_PARENT)/mpi $(FREEBL_PARENT)
-vpath %.s $(FREEBL_PARENT)/ecl $(FREEBL_PARENT)/mpi $(FREEBL_PARENT)
-vpath %.asm $(FREEBL_PARENT)/ecl $(FREEBL_PARENT)/mpi $(FREEBL_PARENT)
-INCLUDES += -I$(FREEBL_PARENT) -I$(FREEBL_PARENT)/mpi -I$(FREEBL_PARENT)/ecl
-else
vpath %.h mpi ecl
vpath %.c mpi ecl
vpath %.S mpi ecl
vpath %.s mpi ecl
vpath %.asm mpi ecl
INCLUDES += -Impi -Iecl
-endif
DEFINES += -DMP_API_COMPATIBLE
@@ -315,22 +414,26 @@ MPI_USERS = dh.c pqg.c dsa.c rsa.c ec.c
MPI_OBJS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(MPI_SRCS:.c=$(OBJ_SUFFIX)))
MPI_OBJS += $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(MPI_USERS:.c=$(OBJ_SUFFIX)))
+$(MPI_OBJS): $(MPI_HDRS)
+
ECL_USERS = ec.c
ECL_OBJS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(ECL_SRCS:.c=$(OBJ_SUFFIX)) $(ECL_ASM_SRCS:$(ASM_SUFFIX)=$(OBJ_SUFFIX)))
ECL_OBJS += $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(ECL_USERS:.c=$(OBJ_SUFFIX)))
-$(MPI_OBJS): $(MPI_HDRS)
-
$(ECL_OBJS): $(ECL_HDRS)
+
+
+$(OBJDIR)/sysrand$(OBJ_SUFFIX): sysrand.c unix_rand.c win_rand.c mac_rand.c os2_rand.c
+
$(OBJDIR)/$(PROG_PREFIX)mpprime$(OBJ_SUFFIX): primes.c
$(OBJDIR)/ldvector$(OBJ_SUFFIX) $(OBJDIR)/loader$(OBJ_SUFFIX) : loader.h
ifeq ($(SYSV_SPARC),1)
-$(OBJDIR)/mpv_sparcv8.o $(OBJDIR)/montmulfv8.o : $(OBJDIR)/%.o : %.s
+$(OBJDIR)/mpv_sparcv8.o $(OBJDIR)/mpv_sparcv8x.o $(OBJDIR)/montmulfv8.o : $(OBJDIR)/%.o : %.s
@$(MAKE_OBJDIR)
$(SOLARIS_AS) -o $@ $(SOLARIS_AS_FLAGS) $<
@@ -342,39 +445,100 @@ $(OBJDIR)/mpmontg.o: mpmontg.c montmulf.h
endif
-ifdef FREEBL_EXTENDED_BUILD
+ifndef FREEBL_CHILD_BUILD
+
+# Parent build. This is where we decide which shared libraries to build
+
+ifdef FREEBL_BUILD_SINGLE_SHLIB
+
+################### Single shared lib stuff #########################
+SINGLE_SHLIB_DIR = $(OBJDIR)/$(OS_TARGET)_SINGLE_SHLIB
+ALL_TRASH += $(SINGLE_SHLIB_DIR)
+
+$(SINGLE_SHLIB_DIR):
+ -mkdir $(SINGLE_SHLIB_DIR)
+
+release_md libs:: $(SINGLE_SHLIB_DIR)
+ $(MAKE) FREEBL_CHILD_BUILD=1 \
+ OBJDIR=$(SINGLE_SHLIB_DIR) $@
+######################## common stuff #########################
+
+endif
+
+# multiple shared libraries
+
+######################## ABI32_FPU stuff #########################
+ifdef HAVE_ABI32_FPU
+ABI32_FPU_DIR = $(OBJDIR)/$(OS_TARGET)_ABI32_FPU
+ALL_TRASH += $(ABI32_FPU_DIR)
+
+$(ABI32_FPU_DIR):
+ -mkdir $(ABI32_FPU_DIR)
+
+release_md libs:: $(ABI32_FPU_DIR)
+ $(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI32_FPU=1 \
+ OBJDIR=$(ABI32_FPU_DIR) $@
+endif
+
+######################## ABI32_INT32 stuff #########################
+ifdef HAVE_ABI32_INT32
+ABI32_INT32_DIR = $(OBJDIR)/$(OS_TARGET)_ABI32_INT32
+ALL_TRASH += $(ABI32_INT32_DIR)
-PURE32DIR = $(OBJDIR)/$(OS_TARGET)pure32
-ALL_TRASH += $(PURE32DIR)
+$(ABI32_INT32_DIR):
+ -mkdir $(ABI32_INT32_DIR)
-FILES2LN = \
- $(wildcard *.tab) \
- $(wildcard mapfile.*) \
- Makefile manifest.mn config.mk
+release_md libs:: $(ABI32_INT32_DIR)
+ $(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI32_INT32=1 \
+ OBJDIR=$(ABI32_INT32_DIR) $@
+endif
-LINKEDFILES = $(addprefix $(PURE32DIR)/, $(FILES2LN))
+######################## ABI32_INT64 stuff #########################
+ifdef HAVE_ABI32_INT64
+ABI32_INT64_DIR = $(OBJDIR)/$(OS_TARGET)_ABI32_INT64
+ALL_TRASH += $(ABI32_INT64_DIR)
-CDDIR := $(shell pwd)
+$(ABI32_INT64_DIR):
+ -mkdir $(ABI32_INT64_DIR)
-$(PURE32DIR):
- -mkdir $(PURE32DIR)
- -ln -s $(CDDIR)/mpi $(PURE32DIR)
+release_md libs:: $(ABI32_INT64_DIR)
+ $(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI32_INT64=1\
+ OBJDIR=$(ABI32_INT64_DIR) $@
+endif
-$(LINKEDFILES) : $(PURE32DIR)/% : %
- ln -s $(CDDIR)/$* $(PURE32DIR)
+######################## END of 32-bit stuff #########################
-libs::
- $(MAKE) FREEBL_RECURSIVE_BUILD=1 USE_HYBRID=1 libs
+# above is 32-bit builds, below is 64-bit builds
-libs:: $(PURE32DIR) $(LINKEDFILES)
- cd $(PURE32DIR) && $(MAKE) FREEBL_RECURSIVE_BUILD=1 USE_PURE_32=1 FREEBL_PARENT=$(CDDIR) CORE_DEPTH=$(CDDIR)/$(CORE_DEPTH) libs
+######################## ABI64_FPU stuff #########################
+ifdef HAVE_ABI64_FPU
+ABI64_FPU_DIR = $(OBJDIR)/$(OS_TARGET)_ABI64_FPU
+ALL_TRASH += $(ABI64_FPU_DIR)
-release_md::
- $(MAKE) FREEBL_RECURSIVE_BUILD=1 USE_HYBRID=1 $@
- cd $(PURE32DIR) && $(MAKE) FREEBL_RECURSIVE_BUILD=1 USE_PURE_32=1 FREEBL_PARENT=$(CDDIR) CORE_DEPTH=$(CDDIR)/$(CORE_DEPTH) $@
+$(ABI64_FPU_DIR):
+ -mkdir $(ABI64_FPU_DIR)
+release_md libs:: $(ABI64_FPU_DIR)
+ $(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI64_FPU=1 \
+ OBJDIR=$(ABI64_FPU_DIR) $@
endif
+######################## ABI64_INT stuff #########################
+ifdef HAVE_ABI64_INT
+ABI64_INT_DIR = $(OBJDIR)/$(OS_TARGET)_ABI64_INT
+ALL_TRASH += $(ABI64_INT_DIR)
+
+$(ABI64_INT_DIR):
+ -mkdir $(ABI64_INT_DIR)
+
+release_md libs:: $(ABI64_INT_DIR)
+ $(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI64_INT=1 \
+ OBJDIR=$(ABI64_INT_DIR) $@
+endif
+
+endif # FREEBL_CHILD_BUILD
+
+
# Bugzilla Bug 209827: disable optimization to work around what appears
# to be a VACPP optimizer bug.
ifdef XP_OS2_VACPP
diff --git a/security/nss/lib/freebl/aeskeywrap.c b/security/nss/lib/freebl/aeskeywrap.c
index ad7d01b27..c61a94a4d 100644
--- a/security/nss/lib/freebl/aeskeywrap.c
+++ b/security/nss/lib/freebl/aeskeywrap.c
@@ -50,11 +50,11 @@
#include "secport.h" /* for PORT_XXX */
#include "secerr.h"
#include "blapi.h" /* for AES_ functions */
-
+#include "rijndael.h"
struct AESKeyWrapContextStr {
- AESContext * aescx;
unsigned char iv[AES_KEY_WRAP_IV_BYTES];
+ AESContext aescx;
};
/******************************************/
@@ -62,6 +62,37 @@ struct AESKeyWrapContextStr {
** AES key wrap algorithm, RFC 3394
*/
+AESKeyWrapContext *
+AESKeyWrap_AllocateContext(void)
+{
+ AESKeyWrapContext * cx = PORT_New(AESKeyWrapContext);
+ return cx;
+}
+
+SECStatus
+AESKeyWrap_InitContext(AESKeyWrapContext *cx,
+ const unsigned char *key,
+ unsigned int keylen,
+ const unsigned char *iv,
+ int x1,
+ unsigned int encrypt,
+ unsigned int x2)
+{
+ SECStatus rv = SECFailure;
+ if (!cx) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ if (iv) {
+ memcpy(cx->iv, iv, sizeof cx->iv);
+ } else {
+ memset(cx->iv, 0xA6, sizeof cx->iv);
+ }
+ rv = AES_InitContext(&cx->aescx, key, keylen, NULL, NSS_AES, encrypt,
+ AES_BLOCK_SIZE);
+ return rv;
+}
+
/*
** Create a new AES context suitable for AES encryption/decryption.
** "key" raw key data
@@ -71,19 +102,14 @@ extern AESKeyWrapContext *
AESKeyWrap_CreateContext(const unsigned char *key, const unsigned char *iv,
int encrypt, unsigned int keylen)
{
- AESKeyWrapContext * cx = PORT_ZNew(AESKeyWrapContext);
+ SECStatus rv;
+ AESKeyWrapContext * cx = AESKeyWrap_AllocateContext();
if (!cx)
return NULL; /* error is already set */
- cx->aescx = AES_CreateContext(key, NULL, NSS_AES, encrypt, keylen,
- AES_BLOCK_SIZE);
- if (!cx->aescx) {
+ rv = AESKeyWrap_InitContext(cx, key, keylen, iv, 0, encrypt, 0);
+ if (rv != SECSuccess) {
PORT_Free(cx);
- return NULL; /* error should already be set */
- }
- if (iv) {
- memcpy(cx->iv, iv, AES_KEY_WRAP_IV_BYTES);
- } else {
- memset(cx->iv, 0xA6, AES_KEY_WRAP_IV_BYTES);
+ cx = NULL; /* error should already be set */
}
return cx;
}
@@ -97,9 +123,8 @@ extern void
AESKeyWrap_DestroyContext(AESKeyWrapContext *cx, PRBool freeit)
{
if (cx) {
- if (cx->aescx)
- AES_DestroyContext(cx->aescx, PR_TRUE);
- memset(cx, 0, sizeof *cx);
+ AES_DestroyContext(&cx->aescx, PR_FALSE);
+/* memset(cx, 0, sizeof *cx); */
if (freeit)
PORT_Free(cx);
}
@@ -253,7 +278,7 @@ AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
for (j = 0; j < 6; ++j) {
for (i = 1; i <= nBlocks; ++i) {
B[1] = R[i];
- s = AES_Encrypt(cx->aescx, (unsigned char *)B, &aesLen,
+ s = AES_Encrypt(&cx->aescx, (unsigned char *)B, &aesLen,
sizeof B, (unsigned char *)B, sizeof B);
if (s != SECSuccess)
break;
@@ -358,7 +383,7 @@ AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
xor_and_decrement((unsigned char *)&A, (unsigned char *)&t);
#endif
B[1] = R[i];
- s = AES_Decrypt(cx->aescx, (unsigned char *)B, &aesLen,
+ s = AES_Decrypt(&cx->aescx, (unsigned char *)B, &aesLen,
sizeof B, (unsigned char *)B, sizeof B);
if (s != SECSuccess)
break;
diff --git a/security/nss/lib/freebl/alg2268.c b/security/nss/lib/freebl/alg2268.c
index bf8b6f357..dcc5418dc 100644
--- a/security/nss/lib/freebl/alg2268.c
+++ b/security/nss/lib/freebl/alg2268.c
@@ -36,7 +36,6 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
-/* $Id$ */
/* $Id$ */
@@ -132,22 +131,15 @@ static const PRUint8 S[256] = {
0305,0363,0333,0107,0345,0245,0234,0167,0012,0246,0040,0150,0376,0177,0301,0255
};
-/*
-** Create a new RC2 context suitable for RC2 encryption/decryption.
-** "key" raw key data
-** "len" the number of bytes of key data
-** "iv" is the CBC initialization vector (if mode is NSS_RC2_CBC)
-** "mode" one of NSS_RC2 or NSS_RC2_CBC
-** "effectiveKeyLen" in bytes, not bits.
-**
-** When mode is set to NSS_RC2_CBC the RC2 cipher is run in "cipher block
-** chaining" mode.
-*/
-RC2Context *
-RC2_CreateContext(const unsigned char *key, unsigned int len,
- const unsigned char *input, int mode, unsigned efLen8)
+RC2Context * RC2_AllocateContext(void)
+{
+ return PORT_ZNew(RC2Context);
+}
+SECStatus
+RC2_InitContext(RC2Context *cx, const unsigned char *key, unsigned int len,
+ const unsigned char *input, int mode, unsigned int efLen8,
+ unsigned int unused)
{
- RC2Context *cx;
PRUint8 *L,*L2;
int i;
#if !defined(IS_LITTLE_ENDIAN)
@@ -155,23 +147,23 @@ RC2_CreateContext(const unsigned char *key, unsigned int len,
#endif
PRUint8 tmpB;
- if (!key || len == 0 || len > (sizeof cx->B) || efLen8 > (sizeof cx->B)) {
- return NULL;
+ if (!key || !cx || !len || len > (sizeof cx->B) ||
+ efLen8 > (sizeof cx->B)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (mode == NSS_RC2) {
/* groovy */
} else if (mode == NSS_RC2_CBC) {
if (!input) {
- return NULL; /* not groovy */
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
} else {
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
- cx = PORT_ZNew(RC2Context);
- if (!cx)
- return cx;
-
if (mode == NSS_RC2_CBC) {
cx->enc = & rc2_EncryptCBC;
cx->dec = & rc2_DecryptCBC;
@@ -208,6 +200,32 @@ RC2_CreateContext(const unsigned char *key, unsigned int len,
SWAPK(i); /* candidate for unrolling */
}
#endif
+ return SECSuccess;
+}
+
+/*
+** Create a new RC2 context suitable for RC2 encryption/decryption.
+** "key" raw key data
+** "len" the number of bytes of key data
+** "iv" is the CBC initialization vector (if mode is NSS_RC2_CBC)
+** "mode" one of NSS_RC2 or NSS_RC2_CBC
+** "effectiveKeyLen" in bytes, not bits.
+**
+** When mode is set to NSS_RC2_CBC the RC2 cipher is run in "cipher block
+** chaining" mode.
+*/
+RC2Context *
+RC2_CreateContext(const unsigned char *key, unsigned int len,
+ const unsigned char *iv, int mode, unsigned efLen8)
+{
+ RC2Context *cx = PORT_ZNew(RC2Context);
+ if (cx) {
+ SECStatus rv = RC2_InitContext(cx, key, len, iv, mode, efLen8, 0);
+ if (rv != SECSuccess) {
+ RC2_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ }
+ }
return cx;
}
diff --git a/security/nss/lib/softoken/alghmac.c b/security/nss/lib/freebl/alghmac.c
index a6af07beb..b1174f460 100644
--- a/security/nss/lib/softoken/alghmac.c
+++ b/security/nss/lib/freebl/alghmac.c
@@ -34,66 +34,74 @@
*
* ***** END LICENSE BLOCK ***** */
-#include "sechash.h"
#include "secport.h"
+#include "hasht.h"
+#include "blapit.h"
#include "alghmac.h"
#include "secerr.h"
-#define HMAC_PAD_SIZE 64
+#define HMAC_PAD_SIZE HASH_BLOCK_LENGTH_MAX
struct HMACContextStr {
void *hash;
const SECHashObject *hashobj;
+ PRBool wasAllocated;
unsigned char ipad[HMAC_PAD_SIZE];
unsigned char opad[HMAC_PAD_SIZE];
};
void
-HMAC_Destroy(HMACContext *cx)
+HMAC_Destroy(HMACContext *cx, PRBool freeit)
{
if (cx == NULL)
return;
- if (cx->hash != NULL)
+ PORT_Assert(!freeit == !cx->wasAllocated);
+ if (cx->hash != NULL) {
cx->hashobj->destroy(cx->hash, PR_TRUE);
- PORT_ZFree(cx, sizeof(HMACContext));
+ PORT_Memset(cx, 0, sizeof *cx);
+ }
+ if (freeit)
+ PORT_Free(cx);
}
-HMACContext *
-HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
- unsigned int secret_len, PRBool isFIPS)
+SECStatus
+HMAC_Init( HMACContext * cx, const SECHashObject *hash_obj,
+ const unsigned char *secret, unsigned int secret_len, PRBool isFIPS)
{
- HMACContext *cx;
unsigned int i;
unsigned char hashed_secret[HASH_LENGTH_MAX];
/* required by FIPS 198 Section 3 */
if (isFIPS && secret_len < hash_obj->length/2) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ return SECFailure;
}
- cx = (HMACContext*)PORT_ZAlloc(sizeof(HMACContext));
- if (cx == NULL)
- return NULL;
+ if (cx == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ cx->wasAllocated = PR_FALSE;
cx->hashobj = hash_obj;
-
cx->hash = cx->hashobj->create();
if (cx->hash == NULL)
goto loser;
- if (secret_len > HMAC_PAD_SIZE) {
+ if (secret_len > cx->hashobj->blocklength) {
cx->hashobj->begin( cx->hash);
cx->hashobj->update(cx->hash, secret, secret_len);
PORT_Assert(cx->hashobj->length <= sizeof hashed_secret);
cx->hashobj->end( cx->hash, hashed_secret, &secret_len,
sizeof hashed_secret);
- if (secret_len != cx->hashobj->length)
+ if (secret_len != cx->hashobj->length) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
goto loser;
+ }
secret = (const unsigned char *)&hashed_secret[0];
}
- PORT_Memset(cx->ipad, 0x36, sizeof cx->ipad);
- PORT_Memset(cx->opad, 0x5c, sizeof cx->opad);
+ PORT_Memset(cx->ipad, 0x36, cx->hashobj->blocklength);
+ PORT_Memset(cx->opad, 0x5c, cx->hashobj->blocklength);
/* fold secret into padding */
for (i = 0; i < secret_len; i++) {
@@ -101,12 +109,30 @@ HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
cx->opad[i] ^= secret[i];
}
PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
- return cx;
+ return SECSuccess;
loser:
PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
- HMAC_Destroy(cx);
- return NULL;
+ if (cx->hash != NULL)
+ cx->hashobj->destroy(cx->hash, PR_TRUE);
+ return SECFailure;
+}
+
+HMACContext *
+HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
+ unsigned int secret_len, PRBool isFIPS)
+{
+ SECStatus rv;
+ HMACContext * cx = PORT_ZNew(HMACContext);
+ if (cx == NULL)
+ return NULL;
+ rv = HMAC_Init(cx, hash_obj, secret, secret_len, isFIPS);
+ cx->wasAllocated = PR_TRUE;
+ if (rv != SECSuccess) {
+ PORT_Free(cx); /* contains no secret info */
+ cx = NULL;
+ }
+ return cx;
}
void
@@ -114,7 +140,7 @@ HMAC_Begin(HMACContext *cx)
{
/* start inner hash */
cx->hashobj->begin(cx->hash);
- cx->hashobj->update(cx->hash, cx->ipad, sizeof(cx->ipad));
+ cx->hashobj->update(cx->hash, cx->ipad, cx->hashobj->blocklength);
}
void
@@ -137,7 +163,7 @@ HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len,
return SECFailure;
cx->hashobj->begin(cx->hash);
- cx->hashobj->update(cx->hash, cx->opad, sizeof(cx->opad));
+ cx->hashobj->update(cx->hash, cx->opad, cx->hashobj->blocklength);
cx->hashobj->update(cx->hash, result, *result_len);
cx->hashobj->end(cx->hash, result, result_len, max_result_len);
return SECSuccess;
@@ -152,15 +178,16 @@ HMAC_Clone(HMACContext *cx)
if (newcx == NULL)
goto loser;
+ newcx->wasAllocated = PR_TRUE;
newcx->hashobj = cx->hashobj;
newcx->hash = cx->hashobj->clone(cx->hash);
if (newcx->hash == NULL)
goto loser;
- PORT_Memcpy(newcx->ipad, cx->ipad, sizeof(cx->ipad));
- PORT_Memcpy(newcx->opad, cx->opad, sizeof(cx->opad));
+ PORT_Memcpy(newcx->ipad, cx->ipad, cx->hashobj->blocklength);
+ PORT_Memcpy(newcx->opad, cx->opad, cx->hashobj->blocklength);
return newcx;
loser:
- HMAC_Destroy(newcx);
+ HMAC_Destroy(newcx, PR_TRUE);
return NULL;
}
diff --git a/security/nss/lib/softoken/alghmac.h b/security/nss/lib/freebl/alghmac.h
index 77c674746..81c5bfa50 100644
--- a/security/nss/lib/softoken/alghmac.h
+++ b/security/nss/lib/freebl/alghmac.h
@@ -43,10 +43,10 @@ SEC_BEGIN_PROTOS
/* destroy HMAC context */
extern void
-HMAC_Destroy(HMACContext *cx);
+HMAC_Destroy(HMACContext *cx, PRBool freeit);
/* create HMAC context
- * hashObj hash object from SECRawHashObjects[]
+ * hash_obj hash object from SECRawHashObjects[]
* secret the secret with which the HMAC is performed.
* secret_len the length of the secret.
* isFIPS true if conforming to FIPS 198.
@@ -54,9 +54,14 @@ HMAC_Destroy(HMACContext *cx);
* NULL is returned if an error occurs.
*/
extern HMACContext *
-HMAC_Create(const SECHashObject *hashObj, const unsigned char *secret,
+HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
unsigned int secret_len, PRBool isFIPS);
+/* like HMAC_Create, except caller allocates HMACContext. */
+SECStatus
+HMAC_Init(HMACContext *cx, const SECHashObject *hash_obj,
+ const unsigned char *secret, unsigned int secret_len, PRBool isFIPS);
+
/* reset HMAC for a fresh round */
extern void
HMAC_Begin(HMACContext *cx);
diff --git a/security/nss/lib/freebl/arcfour-amd64-gas.s b/security/nss/lib/freebl/arcfour-amd64-gas.s
index 66daf07ba..e131fd16a 100644
--- a/security/nss/lib/freebl/arcfour-amd64-gas.s
+++ b/security/nss/lib/freebl/arcfour-amd64-gas.s
@@ -114,3 +114,7 @@ ARCFOUR:
ret
.L_ARCFOUR_end:
.size ARCFOUR,.L_ARCFOUR_end-ARCFOUR
+
+# Magic indicating no need for an executable stack
+.section .note.GNU-stack,"",@progbits
+.previous
diff --git a/security/nss/lib/freebl/arcfour.c b/security/nss/lib/freebl/arcfour.c
index 4601ace65..52329beda 100644
--- a/security/nss/lib/freebl/arcfour.c
+++ b/security/nss/lib/freebl/arcfour.c
@@ -64,7 +64,7 @@
#define WORD ARC4WORD
#endif
-#if defined(NSS_USE_HYBRID) && !defined(SOLARIS) && !defined(NSS_USE_64)
+#if defined(IS_64) && !defined(__sparc) && !defined(NSS_USE_64)
typedef unsigned long long WORD;
#else
typedef unsigned long WORD;
@@ -140,28 +140,30 @@ static const Stype Kinit[256] = {
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
-/*
- * Initialize a new generator.
- */
RC4Context *
-RC4_CreateContext(const unsigned char *key, int len)
+RC4_AllocateContext(void)
+{
+ return PORT_ZNew(RC4Context);
+}
+
+SECStatus
+RC4_InitContext(RC4Context *cx, const unsigned char *key, unsigned int len,
+ const unsigned char * unused1, int unused2,
+ unsigned int unused3, unsigned int unused4)
{
int i;
PRUint8 j, tmp;
- RC4Context *cx;
PRUint8 K[256];
PRUint8 *L;
/* verify the key length. */
PORT_Assert(len > 0 && len < ARCFOUR_STATE_SIZE);
if (len < 0 || len >= ARCFOUR_STATE_SIZE) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ return SECFailure;
}
- /* Create space for the context. */
- cx = (RC4Context *)PORT_ZAlloc(sizeof(RC4Context));
if (cx == NULL) {
- PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
/* Initialize the state using array indices. */
memcpy(cx->S, Kinit, sizeof cx->S);
@@ -185,7 +187,25 @@ RC4_CreateContext(const unsigned char *key, int len)
}
cx->i = 0;
cx->j = 0;
- return cx;
+ return SECSuccess;
+}
+
+
+/*
+ * Initialize a new generator.
+ */
+RC4Context *
+RC4_CreateContext(const unsigned char *key, int len)
+{
+ RC4Context *cx = RC4_AllocateContext();
+ if (cx) {
+ SECStatus rv = RC4_InitContext(cx, key, len, NULL, 0, 0, 0);
+ if (rv != SECSuccess) {
+ PORT_ZFree(cx, sizeof(*cx));
+ cx = NULL;
+ }
+ }
+ return cx;
}
void
@@ -331,7 +351,7 @@ rc4_unrolled(RC4Context *cx, unsigned char *output,
ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n );
#endif
-#if (defined(NSS_USE_HYBRID) && !defined(SOLARIS)) || defined(NSS_USE_64)
+#if (defined(IS_64) && !defined(__sparc)) || defined(NSS_USE_64)
/* 64-bit wordsize */
#ifdef IS_LITTLE_ENDIAN
#define ARCFOUR_NEXT_WORD() \
diff --git a/security/nss/lib/freebl/blapi.h b/security/nss/lib/freebl/blapi.h
index cdc8b9cb5..899eadd45 100644
--- a/security/nss/lib/freebl/blapi.h
+++ b/security/nss/lib/freebl/blapi.h
@@ -43,7 +43,8 @@
#define _BLAPI_H_
#include "blapit.h"
-
+#include "hasht.h"
+#include "alghmac.h"
SEC_BEGIN_PROTOS
@@ -207,7 +208,7 @@ extern SECStatus EC_NewKeyFromSeed(ECParams * params,
int seedlen);
/* Validates an EC public key as described in Section 5.2.2 of
- * X9.63. Such validation prevents against small subgroup attacks
+ * X9.62. Such validation prevents against small subgroup attacks
* when the ECDH primitive is used with the cofactor.
*/
extern SECStatus EC_ValidatePublicKey(ECParams * params,
@@ -267,6 +268,15 @@ extern SECStatus ECDSA_SignDigestWithSeed(ECPrivateKey *key,
*/
extern RC4Context *RC4_CreateContext(const unsigned char *key, int len);
+extern RC4Context *RC4_AllocateContext(void);
+extern SECStatus RC4_InitContext(RC4Context *cx,
+ const unsigned char *key,
+ unsigned int keylen,
+ const unsigned char *,
+ int,
+ unsigned int ,
+ unsigned int );
+
/*
** Destroy an RC4 encryption/decryption context.
** "cx" the context
@@ -324,6 +334,14 @@ extern SECStatus RC4_Decrypt(RC4Context *cx, unsigned char *output,
extern RC2Context *RC2_CreateContext(const unsigned char *key, unsigned int len,
const unsigned char *iv, int mode,
unsigned effectiveKeyLen);
+extern RC2Context *RC2_AllocateContext(void);
+extern SECStatus RC2_InitContext(RC2Context *cx,
+ const unsigned char *key,
+ unsigned int keylen,
+ const unsigned char *iv,
+ int mode,
+ unsigned int effectiveKeyLen,
+ unsigned int );
/*
** Destroy an RC2 encryption/decryption context.
@@ -379,6 +397,14 @@ extern SECStatus RC2_Decrypt(RC2Context *cx, unsigned char *output,
*/
extern RC5Context *RC5_CreateContext(const SECItem *key, unsigned int rounds,
unsigned int wordSize, const unsigned char *iv, int mode);
+extern RC5Context *RC5_AllocateContext(void);
+extern SECStatus RC5_InitContext(RC5Context *cx,
+ const unsigned char *key,
+ unsigned int keylen,
+ const unsigned char *iv,
+ int mode,
+ unsigned int rounds,
+ unsigned int wordSize);
/*
** Destroy an RC5 encryption/decryption context.
@@ -440,6 +466,14 @@ extern SECStatus RC5_Decrypt(RC5Context *cx, unsigned char *output,
extern DESContext *DES_CreateContext(const unsigned char *key,
const unsigned char *iv,
int mode, PRBool encrypt);
+extern DESContext *DES_AllocateContext(void);
+extern SECStatus DES_InitContext(DESContext *cx,
+ const unsigned char *key,
+ unsigned int keylen,
+ const unsigned char *iv,
+ int mode,
+ unsigned int encrypt,
+ unsigned int );
/*
** Destroy an DES encryption/decryption context.
@@ -498,6 +532,14 @@ extern AESContext *
AES_CreateContext(const unsigned char *key, const unsigned char *iv,
int mode, int encrypt,
unsigned int keylen, unsigned int blocklen);
+extern AESContext *AES_AllocateContext(void);
+extern SECStatus AES_InitContext(AESContext *cx,
+ const unsigned char *key,
+ unsigned int keylen,
+ const unsigned char *iv,
+ int mode,
+ unsigned int encrypt,
+ unsigned int blocklen);
/*
** Destroy a AES encryption/decryption context.
@@ -554,6 +596,15 @@ AES_Decrypt(AESContext *cx, unsigned char *output,
extern AESKeyWrapContext *
AESKeyWrap_CreateContext(const unsigned char *key, const unsigned char *iv,
int encrypt, unsigned int keylen);
+extern AESKeyWrapContext * AESKeyWrap_AllocateContext(void);
+extern SECStatus
+ AESKeyWrap_InitContext(AESKeyWrapContext *cx,
+ const unsigned char *key,
+ unsigned int keylen,
+ const unsigned char *iv,
+ int ,
+ unsigned int encrypt,
+ unsigned int );
/*
** Destroy a AES KeyWrap context.
@@ -649,6 +700,7 @@ extern void MD5_Update(MD5Context *cx,
*/
extern void MD5_End(MD5Context *cx, unsigned char *digest,
unsigned int *digestLen, unsigned int maxDigestLen);
+
/*
* Return the the size of a buffer needed to flatten the MD5 Context into
* "cx" the context
@@ -671,6 +723,7 @@ extern SECStatus MD5_Flatten(MD5Context *cx,unsigned char *space);
* returns resurected context;
*/
extern MD5Context * MD5_Resurrect(unsigned char *space, void *arg);
+extern void MD5_Clone(MD5Context *dest, MD5Context *src);
/*
** trace the intermediate state info of the MD5 hash.
@@ -748,6 +801,7 @@ extern SECStatus MD2_Flatten(MD2Context *cx,unsigned char *space);
* returns resurected context;
*/
extern MD2Context * MD2_Resurrect(unsigned char *space, void *arg);
+extern void MD2_Clone(MD2Context *dest, MD2Context *src);
/******************************************/
/*
@@ -830,6 +884,7 @@ extern SECStatus SHA1_Flatten(SHA1Context *cx,unsigned char *space);
* returns resurected context;
*/
extern SHA1Context * SHA1_Resurrect(unsigned char *space, void *arg);
+extern void SHA1_Clone(SHA1Context *dest, SHA1Context *src);
/******************************************/
@@ -847,6 +902,7 @@ extern void SHA256_TraceState(SHA256Context *cx);
extern unsigned int SHA256_FlattenSize(SHA256Context *cx);
extern SECStatus SHA256_Flatten(SHA256Context *cx,unsigned char *space);
extern SHA256Context * SHA256_Resurrect(unsigned char *space, void *arg);
+extern void SHA256_Clone(SHA256Context *dest, SHA256Context *src);
/******************************************/
@@ -864,6 +920,7 @@ extern void SHA512_TraceState(SHA512Context *cx);
extern unsigned int SHA512_FlattenSize(SHA512Context *cx);
extern SECStatus SHA512_Flatten(SHA512Context *cx,unsigned char *space);
extern SHA512Context * SHA512_Resurrect(unsigned char *space, void *arg);
+extern void SHA512_Clone(SHA512Context *dest, SHA512Context *src);
/******************************************/
@@ -881,6 +938,15 @@ extern void SHA384_TraceState(SHA384Context *cx);
extern unsigned int SHA384_FlattenSize(SHA384Context *cx);
extern SECStatus SHA384_Flatten(SHA384Context *cx,unsigned char *space);
extern SHA384Context * SHA384_Resurrect(unsigned char *space, void *arg);
+extern void SHA384_Clone(SHA384Context *dest, SHA384Context *src);
+
+/****************************************
+ * implement TLS Pseudo Random Function (PRF)
+ */
+
+extern SECStatus
+TLS_PRF(const SECItem *secret, const char *label, SECItem *seed,
+ SECItem *result, PRBool isFIPS);
/******************************************/
/*
@@ -916,6 +982,7 @@ extern SECStatus RNG_GenerateGlobalRandomBytes(void *dest, size_t len);
*/
extern void RNG_RNGShutdown(void);
+extern void RNG_SystemInfoForRNG(void);
/* Generate PQGParams and PQGVerify structs.
* Length of seed and length of h both equal length of P.
@@ -987,6 +1054,9 @@ PRBool BLAPI_SHVerify(const char *name, PRFuncPtr addr);
**************************************************************************/
PRBool BLAPI_VerifySelf(const char *name);
+/*********************************************************************/
+extern const SECHashObject * HASH_GetRawHashObject(HASH_HashType hashType);
+
SEC_END_PROTOS
#endif /* _BLAPI_H_ */
diff --git a/security/nss/lib/freebl/blapit.h b/security/nss/lib/freebl/blapit.h
index 36aa8db82..2400ce325 100644
--- a/security/nss/lib/freebl/blapit.h
+++ b/security/nss/lib/freebl/blapit.h
@@ -95,9 +95,13 @@
* Input block size for each hash algorithm.
*/
+#define MD2_BLOCK_LENGTH 64 /* bytes */
+#define MD5_BLOCK_LENGTH 64 /* bytes */
+#define SHA1_BLOCK_LENGTH 64 /* bytes */
#define SHA256_BLOCK_LENGTH 64 /* bytes */
#define SHA384_BLOCK_LENGTH 128 /* bytes */
#define SHA512_BLOCK_LENGTH 128 /* bytes */
+#define HASH_BLOCK_LENGTH_MAX SHA512_BLOCK_LENGTH
#define AES_KEY_WRAP_IV_BYTES 8
#define AES_KEY_WRAP_BLOCK_SIZE 8 /* bytes */
@@ -146,7 +150,9 @@
* function takes desired number of bits in P,
* returns index (0..8) or -1 if number of bits is invalid.
*/
-#define PQG_PBITS_TO_INDEX(bits) ((((bits)-512) % 64) ? -1 : (int)((bits)-512)/64)
+#define PQG_PBITS_TO_INDEX(bits) \
+ (((bits) < 512 || (bits) > 1024 || (bits) % 64) ? \
+ -1 : (int)((bits)-512)/64)
/*
* function takes index (0-8)
@@ -348,4 +354,19 @@ struct ECPrivateKeyStr {
};
typedef struct ECPrivateKeyStr ECPrivateKey;
+typedef void * (*BLapiAllocateFunc)(void);
+typedef void (*BLapiDestroyContextFunc)(void *cx, PRBool freeit);
+typedef SECStatus (*BLapiInitContextFunc)(void *cx,
+ const unsigned char *key,
+ unsigned int keylen,
+ const unsigned char *,
+ int,
+ unsigned int ,
+ unsigned int );
+typedef SECStatus (*BLapiEncrypt)(void *cx, unsigned char *output,
+ unsigned int *outputLen,
+ unsigned int maxOutputLen,
+ const unsigned char *input,
+ unsigned int inputLen);
+
#endif /* _BLAPIT_H_ */
diff --git a/security/nss/lib/freebl/config.mk b/security/nss/lib/freebl/config.mk
index c5e5b0d3b..ecbc9373f 100644
--- a/security/nss/lib/freebl/config.mk
+++ b/security/nss/lib/freebl/config.mk
@@ -36,38 +36,21 @@
# ***** END LICENSE BLOCK *****
# only do this in the outermost freebl build.
-ifndef FREEBL_RECURSIVE_BUILD
-# we only do this stuff for some of the 32-bit builds, no 64-bit builds
-ifndef USE_64
-
-ifeq ($(OS_TARGET), HP-UX)
- ifneq ($(OS_TEST), ia64)
- FREEBL_EXTENDED_BUILD = 1
- endif
-endif
-
-ifeq ($(OS_TARGET),SunOS)
- ifeq ($(CPU_ARCH),sparc)
- FREEBL_EXTENDED_BUILD = 1
- endif
-endif
+ifndef FREEBL_CHILD_BUILD
-ifdef FREEBL_EXTENDED_BUILD
# We're going to change this build so that it builds libfreebl.a with
# just loader.c. Then we have to build this directory twice again to
# build the two DSOs.
# To build libfreebl.a with just loader.c, we must now override many
# of the make variables setup by the prior inclusion of CORECONF's config.mk
-CSRCS = loader.c sysrand.c
+CSRCS = loader.c
SIMPLE_OBJS = $(CSRCS:.c=$(OBJ_SUFFIX))
OBJS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(SIMPLE_OBJS))
ALL_TRASH := $(TARGETS) $(OBJS) $(OBJDIR) LOGS TAGS $(GARBAGE) \
$(NOSUCHFILE) so_locations
-endif
-#end of 32-bit only stuff.
-endif
+# this is not a recursive child make. We make a static lib. (archive)
# Override the values defined in coreconf's ruleset.mk.
#
@@ -83,25 +66,47 @@ endif
PROGRAM =
else
-# This is a recursive build.
+# This is a recursive child make. We build the shared lib.
-TARGETS = $(SHARED_LIBRARY)
+TARGETS = $(SHARED_LIBRARY)
LIBRARY =
+IMPORT_LIBRARY =
PROGRAM =
-#ifeq ($(OS_TARGET), HP-UX)
- EXTRA_LIBS += \
- $(DIST)/lib/libsecutil.$(LIB_SUFFIX) \
+EXTRA_LIBS += $(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX)
+
+ifeq (,$(filter-out WIN%,$(OS_TARGET)))
+
+# don't want the 32 in the shared library name
+SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
+
+RES = $(OBJDIR)/$(LIBRARY_NAME).res
+RESNAME = freebl.rc
+
+ifdef NS_USE_GCC
+EXTRA_SHARED_LIBS += \
+ -L$(NSPR_LIB_DIR) \
+ -lplc4 \
+ -lplds4 \
+ -lnspr4 \
$(NULL)
+else # ! NS_USE_GCC
+EXTRA_SHARED_LIBS += \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
+ $(NULL)
+endif # NS_USE_GCC
-# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
-# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
- EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib/ \
+else
+
+EXTRA_SHARED_LIBS += \
+ -L$(NSPR_LIB_DIR) \
-lplc4 \
-lplds4 \
-lnspr4 \
- -lc
-#endif
+ $(NULL)
+
+endif
endif
diff --git a/security/nss/lib/freebl/desblapi.c b/security/nss/lib/freebl/desblapi.c
index ff038c573..b9b3288ac 100644
--- a/security/nss/lib/freebl/desblapi.c
+++ b/security/nss/lib/freebl/desblapi.c
@@ -179,12 +179,21 @@ DES_EDE3CBCDe(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
}
DESContext *
-DES_CreateContext(const BYTE * key, const BYTE *iv, int mode, PRBool encrypt)
+DES_AllocateContext(void)
+{
+ return PORT_ZNew(DESContext);
+}
+
+SECStatus
+DES_InitContext(DESContext *cx, const unsigned char *key, unsigned int keylen,
+ const unsigned char *iv, int mode, unsigned int encrypt,
+ unsigned int unused)
{
- DESContext *cx = PORT_ZNew(DESContext);
DESDirection opposite;
- if (!cx)
- return 0;
+ if (!cx) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
cx->direction = encrypt ? DES_ENCRYPT : DES_DECRYPT;
opposite = encrypt ? DES_DECRYPT : DES_ENCRYPT;
switch (mode) {
@@ -228,10 +237,21 @@ DES_CreateContext(const BYTE * key, const BYTE *iv, int mode, PRBool encrypt)
break;
default:
- PORT_Free(cx);
- cx = 0;
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- break;
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+DESContext *
+DES_CreateContext(const BYTE * key, const BYTE *iv, int mode, PRBool encrypt)
+{
+ DESContext *cx = PORT_ZNew(DESContext);
+ SECStatus rv = DES_InitContext(cx, key, 0, iv, mode, encrypt, 0);
+
+ if (rv != SECSuccess) {
+ PORT_ZFree(cx, sizeof *cx);
+ cx = NULL;
}
return cx;
}
diff --git a/security/nss/lib/freebl/dsa.c b/security/nss/lib/freebl/dsa.c
index 85ceb2e51..7f4c42863 100644
--- a/security/nss/lib/freebl/dsa.c
+++ b/security/nss/lib/freebl/dsa.c
@@ -46,37 +46,24 @@
#include "secitem.h"
#include "blapi.h"
#include "mpi.h"
+#include "secmpi.h"
/* XXX to be replaced by define in blapit.h */
#define NSS_FREEBL_DSA_DEFAULT_CHUNKSIZE 2048
-#define CHECKOK(func) if (MP_OKAY > (err = func)) goto cleanup
-
-#define SECITEM_TO_MPINT(it, mp) \
- CHECKOK(mp_read_unsigned_octets((mp), (it).data, (it).len))
-
-/* DSA-specific random number functions defined in prng_fips1861.c. */
-extern SECStatus
-DSA_RandomUpdate(void *data, size_t bytes, unsigned char *q);
-
+/* DSA-specific random number function defined in prng_fips1861.c. */
extern SECStatus
-DSA_GenerateGlobalRandomBytes(void *dest, size_t len, unsigned char *q);
+DSA_GenerateGlobalRandomBytes(void *dest, size_t len, const unsigned char *q);
static void translate_mpi_error(mp_err err)
{
- switch (err) {
- case MP_MEM: PORT_SetError(SEC_ERROR_NO_MEMORY); break;
- case MP_RANGE: PORT_SetError(SEC_ERROR_BAD_DATA); break;
- case MP_BADARG: PORT_SetError(SEC_ERROR_INVALID_ARGS); break;
- default: PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); break;
- }
+ MP_TO_SEC_ERROR(err);
}
SECStatus
dsa_NewKey(const PQGParams *params, DSAPrivateKey **privKey,
const unsigned char *xb)
{
- unsigned int y_len;
mp_int p, g;
mp_int x, y;
mp_err err;
@@ -105,29 +92,27 @@ dsa_NewKey(const PQGParams *params, DSAPrivateKey **privKey,
MP_DIGITS(&g) = 0;
MP_DIGITS(&x) = 0;
MP_DIGITS(&y) = 0;
- CHECKOK( mp_init(&p) );
- CHECKOK( mp_init(&g) );
- CHECKOK( mp_init(&x) );
- CHECKOK( mp_init(&y) );
+ CHECK_MPI_OK( mp_init(&p) );
+ CHECK_MPI_OK( mp_init(&g) );
+ CHECK_MPI_OK( mp_init(&x) );
+ CHECK_MPI_OK( mp_init(&y) );
/* Copy over the PQG params */
- CHECKOK( SECITEM_CopyItem(arena, &key->params.prime, &params->prime) );
- CHECKOK( SECITEM_CopyItem(arena, &key->params.subPrime, &params->subPrime));
- CHECKOK( SECITEM_CopyItem(arena, &key->params.base, &params->base) );
+ CHECK_MPI_OK( SECITEM_CopyItem(arena, &key->params.prime,
+ &params->prime) );
+ CHECK_MPI_OK( SECITEM_CopyItem(arena, &key->params.subPrime,
+ &params->subPrime) );
+ CHECK_MPI_OK( SECITEM_CopyItem(arena, &key->params.base, &params->base) );
/* Convert stored p, g, and received x into MPI integers. */
SECITEM_TO_MPINT(params->prime, &p);
SECITEM_TO_MPINT(params->base, &g);
- CHECKOK( mp_read_unsigned_octets(&x, xb, DSA_SUBPRIME_LEN) );
+ OCTETS_TO_MPINT(xb, &x, DSA_SUBPRIME_LEN);
/* Store x in private key */
SECITEM_AllocItem(arena, &key->privateValue, DSA_SUBPRIME_LEN);
memcpy(key->privateValue.data, xb, DSA_SUBPRIME_LEN);
/* Compute public key y = g**x mod p */
- CHECKOK( mp_exptmod(&g, &x, &p, &y) );
+ CHECK_MPI_OK( mp_exptmod(&g, &x, &p, &y) );
/* Store y in public key */
- y_len = mp_unsigned_octet_size(&y);
- SECITEM_AllocItem(arena, &key->publicValue, y_len);
- err = mp_to_unsigned_octets(&y, key->publicValue.data, y_len);
- /* mp_to_unsigned_octets returns bytes written (y_len) if okay */
- if (err < 0) goto cleanup; else err = MP_OKAY;
+ MPINT_TO_SECITEM(&y, &key->publicValue, arena);
*privKey = key;
key = NULL;
cleanup:
@@ -155,10 +140,33 @@ DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
{
SECStatus rv;
unsigned char seed[DSA_SUBPRIME_LEN];
- /* Generate seed bytes for x according to FIPS 186-1 appendix 3 */
- if (DSA_GenerateGlobalRandomBytes(seed, DSA_SUBPRIME_LEN,
- params->subPrime.data))
+ int retries = 10;
+ int i;
+ PRBool good;
+
+ do {
+ /* Generate seed bytes for x according to FIPS 186-1 appendix 3 */
+ if (DSA_GenerateGlobalRandomBytes(seed, DSA_SUBPRIME_LEN,
+ params->subPrime.data))
+ return SECFailure;
+ /* Disallow values of 0 and 1 for x. */
+ good = PR_FALSE;
+ for (i = 0; i < DSA_SUBPRIME_LEN-1; i++) {
+ if (seed[i] != 0) {
+ good = PR_TRUE;
+ break;
+ }
+ }
+ if (!good && seed[i] > 1) {
+ good = PR_TRUE;
+ }
+ } while (!good && --retries > 0);
+
+ if (!good) {
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
return SECFailure;
+ }
+
/* Generate a new DSA key using random seed. */
rv = dsa_NewKey(params, privKey, seed);
return rv;
@@ -202,13 +210,13 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
MP_DIGITS(&k) = 0;
MP_DIGITS(&r) = 0;
MP_DIGITS(&s) = 0;
- CHECKOK( mp_init(&p) );
- CHECKOK( mp_init(&q) );
- CHECKOK( mp_init(&g) );
- CHECKOK( mp_init(&x) );
- CHECKOK( mp_init(&k) );
- CHECKOK( mp_init(&r) );
- CHECKOK( mp_init(&s) );
+ CHECK_MPI_OK( mp_init(&p) );
+ CHECK_MPI_OK( mp_init(&q) );
+ CHECK_MPI_OK( mp_init(&g) );
+ CHECK_MPI_OK( mp_init(&x) );
+ CHECK_MPI_OK( mp_init(&k) );
+ CHECK_MPI_OK( mp_init(&r) );
+ CHECK_MPI_OK( mp_init(&s) );
/*
** Convert stored PQG and private key into MPI integers.
*/
@@ -216,24 +224,24 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
SECITEM_TO_MPINT(key->params.subPrime, &q);
SECITEM_TO_MPINT(key->params.base, &g);
SECITEM_TO_MPINT(key->privateValue, &x);
- CHECKOK( mp_read_unsigned_octets(&k, kb, DSA_SUBPRIME_LEN) );
+ OCTETS_TO_MPINT(kb, &k, DSA_SUBPRIME_LEN);
/*
** FIPS 186-1, Section 5, Step 1
**
** r = (g**k mod p) mod q
*/
- CHECKOK( mp_exptmod(&g, &k, &p, &r) ); /* r = g**k mod p */
- CHECKOK( mp_mod(&r, &q, &r) ); /* r = r mod q */
+ CHECK_MPI_OK( mp_exptmod(&g, &k, &p, &r) ); /* r = g**k mod p */
+ CHECK_MPI_OK( mp_mod(&r, &q, &r) ); /* r = r mod q */
/*
** FIPS 186-1, Section 5, Step 2
**
** s = (k**-1 * (SHA1(M) + x*r)) mod q
*/
SECITEM_TO_MPINT(*digest, &s); /* s = SHA1(M) */
- CHECKOK( mp_invmod(&k, &q, &k) ); /* k = k**-1 mod q */
- CHECKOK( mp_mulmod(&x, &r, &q, &x) ); /* x = x * r mod q */
- CHECKOK( mp_addmod(&s, &x, &q, &s) ); /* s = s + x mod q */
- CHECKOK( mp_mulmod(&s, &k, &q, &s) ); /* s = s * k mod q */
+ CHECK_MPI_OK( mp_invmod(&k, &q, &k) ); /* k = k**-1 mod q */
+ CHECK_MPI_OK( mp_mulmod(&x, &r, &q, &x) ); /* x = x * r mod q */
+ CHECK_MPI_OK( mp_addmod(&s, &x, &q, &s) ); /* s = s + x mod q */
+ CHECK_MPI_OK( mp_mulmod(&s, &k, &q, &s) ); /* s = s * k mod q */
/*
** verify r != 0 and s != 0
** mentioned as optional in FIPS 186-1.
@@ -270,7 +278,7 @@ cleanup:
return rv;
}
-/* signature is caller-supplied buffer of at least 20 bytes.
+/* signature is caller-supplied buffer of at least 40 bytes.
** On input, signature->len == size of buffer to hold signature.
** digest->len == size of digest.
** On output, signature->len == size of signature in buffer.
@@ -282,6 +290,8 @@ DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
SECStatus rv;
int retries = 10;
unsigned char kSeed[DSA_SUBPRIME_LEN];
+ int i;
+ PRBool good;
PORT_SetError(0);
do {
@@ -289,6 +299,19 @@ DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
key->params.subPrime.data);
if (rv != SECSuccess)
break;
+ /* Disallow a value of 0 for k. */
+ good = PR_FALSE;
+ for (i = 0; i < DSA_SUBPRIME_LEN; i++) {
+ if (kSeed[i] != 0) {
+ good = PR_TRUE;
+ break;
+ }
+ }
+ if (!good) {
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ rv = SECFailure;
+ continue;
+ }
rv = dsa_SignDigest(key, signature, digest, kSeed);
} while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
--retries > 0);
@@ -341,16 +364,16 @@ DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
MP_DIGITS(&u2) = 0;
MP_DIGITS(&v) = 0;
MP_DIGITS(&w) = 0;
- CHECKOK( mp_init(&p) );
- CHECKOK( mp_init(&q) );
- CHECKOK( mp_init(&g) );
- CHECKOK( mp_init(&y) );
- CHECKOK( mp_init(&r_) );
- CHECKOK( mp_init(&s_) );
- CHECKOK( mp_init(&u1) );
- CHECKOK( mp_init(&u2) );
- CHECKOK( mp_init(&v) );
- CHECKOK( mp_init(&w) );
+ CHECK_MPI_OK( mp_init(&p) );
+ CHECK_MPI_OK( mp_init(&q) );
+ CHECK_MPI_OK( mp_init(&g) );
+ CHECK_MPI_OK( mp_init(&y) );
+ CHECK_MPI_OK( mp_init(&r_) );
+ CHECK_MPI_OK( mp_init(&s_) );
+ CHECK_MPI_OK( mp_init(&u1) );
+ CHECK_MPI_OK( mp_init(&u2) );
+ CHECK_MPI_OK( mp_init(&v) );
+ CHECK_MPI_OK( mp_init(&w) );
/*
** Convert stored PQG and public key into MPI integers.
*/
@@ -361,43 +384,45 @@ DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
/*
** Convert received signature (r', s') into MPI integers.
*/
- CHECKOK( mp_read_unsigned_octets(&r_, signature->data, DSA_SUBPRIME_LEN) );
- CHECKOK( mp_read_unsigned_octets(&s_, signature->data + DSA_SUBPRIME_LEN,
- DSA_SUBPRIME_LEN) );
+ OCTETS_TO_MPINT(signature->data, &r_, DSA_SUBPRIME_LEN);
+ OCTETS_TO_MPINT(signature->data + DSA_SUBPRIME_LEN, &s_, DSA_SUBPRIME_LEN);
/*
** Verify that 0 < r' < q and 0 < s' < q
*/
if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 ||
- mp_cmp(&r_, &q) >= 0 || mp_cmp(&s_, &q) >= 0)
+ mp_cmp(&r_, &q) >= 0 || mp_cmp(&s_, &q) >= 0) {
+ /* err is zero here. */
+ PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
goto cleanup; /* will return verified == SECFailure */
+ }
/*
** FIPS 186-1, Section 6, Step 1
**
** w = (s')**-1 mod q
*/
- CHECKOK( mp_invmod(&s_, &q, &w) ); /* w = (s')**-1 mod q */
+ CHECK_MPI_OK( mp_invmod(&s_, &q, &w) ); /* w = (s')**-1 mod q */
/*
** FIPS 186-1, Section 6, Step 2
**
** u1 = ((SHA1(M')) * w) mod q
*/
- SECITEM_TO_MPINT(*digest, &u1); /* u1 = SHA1(M') */
- CHECKOK( mp_mulmod(&u1, &w, &q, &u1) ); /* u1 = u1 * w mod q */
+ SECITEM_TO_MPINT(*digest, &u1); /* u1 = SHA1(M') */
+ CHECK_MPI_OK( mp_mulmod(&u1, &w, &q, &u1) ); /* u1 = u1 * w mod q */
/*
** FIPS 186-1, Section 6, Step 3
**
** u2 = ((r') * w) mod q
*/
- CHECKOK( mp_mulmod(&r_, &w, &q, &u2) );
+ CHECK_MPI_OK( mp_mulmod(&r_, &w, &q, &u2) );
/*
** FIPS 186-1, Section 6, Step 4
**
** v = ((g**u1 * y**u2) mod p) mod q
*/
- CHECKOK( mp_exptmod(&g, &u1, &p, &g) ); /* g = g**u1 mod p */
- CHECKOK( mp_exptmod(&y, &u2, &p, &y) ); /* y = y**u2 mod p */
- CHECKOK( mp_mulmod(&g, &y, &p, &v) ); /* v = g * y mod p */
- CHECKOK( mp_mod(&v, &q, &v) ); /* v = v mod q */
+ CHECK_MPI_OK( mp_exptmod(&g, &u1, &p, &g) ); /* g = g**u1 mod p */
+ CHECK_MPI_OK( mp_exptmod(&y, &u2, &p, &y) ); /* y = y**u2 mod p */
+ CHECK_MPI_OK( mp_mulmod(&g, &y, &p, &v) ); /* v = g * y mod p */
+ CHECK_MPI_OK( mp_mod(&v, &q, &v) ); /* v = v mod q */
/*
** Verification: v == r'
*/
diff --git a/security/nss/lib/freebl/ec.c b/security/nss/lib/freebl/ec.c
index 1eefdf1f0..53949ab94 100644
--- a/security/nss/lib/freebl/ec.c
+++ b/security/nss/lib/freebl/ec.c
@@ -115,7 +115,7 @@ ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
len = (params->fieldID.size + 7) >> 3;
if (pointP != NULL) {
if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
- (pointP->len != (2 * len + 1))) {
+ (pointP->len != (2 * len + 1))) {
return SECFailure;
};
}
@@ -220,21 +220,15 @@ cleanup:
return rv;
}
-
-static unsigned char bitmask[] = {
- 0xff, 0x7f, 0x3f, 0x1f,
- 0x0f, 0x07, 0x03, 0x01
-};
#endif /* NSS_ENABLE_ECC */
/* Generates a new EC key pair. The private key is a supplied
- * random value (in seed) and the public key is the result of
- * performing a scalar point multiplication of that value with
- * the curve's base point.
+ * value and the public key is the result of performing a scalar
+ * point multiplication of that value with the curve's base point.
*/
SECStatus
-EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
- const unsigned char *seed, int seedlen)
+ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
+ const unsigned char *privKeyBytes, int privKeyLen)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
@@ -245,10 +239,10 @@ EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
int len;
#if EC_DEBUG
- printf("EC_NewKeyFromSeed called\n");
+ printf("ec_NewKey called\n");
#endif
- if (!ecParams || !privKey || !seed || (seedlen < 0)) {
+ if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@@ -301,16 +295,17 @@ EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curveOID,
&ecParams->curveOID));
- len = (ecParams->fieldID.size + 7) >> 3;
- SECITEM_AllocItem(arena, &key->privateValue, len);
+ len = (ecParams->fieldID.size + 7) >> 3;
SECITEM_AllocItem(arena, &key->publicValue, 2*len + 1);
+ len = ecParams->order.len;
+ SECITEM_AllocItem(arena, &key->privateValue, len);
/* Copy private key */
- if (seedlen >= len) {
- memcpy(key->privateValue.data, seed, len);
+ if (privKeyLen >= len) {
+ memcpy(key->privateValue.data, privKeyBytes, len);
} else {
- memset(key->privateValue.data, 0, (len - seedlen));
- memcpy(key->privateValue.data + (len - seedlen), seed, seedlen);
+ memset(key->privateValue.data, 0, (len - privKeyLen));
+ memcpy(key->privateValue.data + (len - privKeyLen), privKeyBytes, privKeyLen);
}
/* Compute corresponding public key */
@@ -329,7 +324,7 @@ cleanup:
PORT_FreeArena(arena, PR_TRUE);
#if EC_DEBUG
- printf("EC_NewKeyFromSeed returning %s\n",
+ printf("ec_NewKey returning %s\n",
(rv == SECSuccess) ? "success" : "failure");
#endif
#else
@@ -340,35 +335,82 @@ cleanup:
}
+/* Generates a new EC key pair. The private key is a supplied
+ * random value (in seed) and the public key is the result of
+ * performing a scalar point multiplication of that value with
+ * the curve's base point.
+ */
+SECStatus
+EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
+ const unsigned char *seed, int seedlen)
+{
+ SECStatus rv = SECFailure;
+#ifdef NSS_ENABLE_ECC
+ rv = ec_NewKey(ecParams, privKey, seed, seedlen);
+#else
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
+#endif /* NSS_ENABLE_ECC */
+ return rv;
+}
+
/* Generates a new EC key pair. The private key is a random value and
* the public key is the result of performing a scalar point multiplication
- * of that value with the curve's base point.
+ * of that value with the curve's base point. The random value for the
+ * private key is generated using the algorithm A.4.1 of ANSI X9.62,
+ * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the
+ * random number generator.
*/
SECStatus
EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey)
{
SECStatus rv = SECFailure;
#ifdef NSS_ENABLE_ECC
+ mp_err err;
int len;
- unsigned char *seed;
+ unsigned char *privKeyBytes = NULL;
+ mp_int privKeyVal, order_1, one;
if (!ecParams || !privKey) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- /* Generate random private key */
- len = (ecParams->fieldID.size + 7) >> 3;
- if ((seed = PORT_Alloc(len)) == NULL) goto cleanup;
- if (RNG_GenerateGlobalRandomBytes(seed, len) != SECSuccess) goto cleanup;
-
- /* Fit private key to the field size */
- seed[0] &= bitmask[len * 8 - ecParams->fieldID.size];
- rv = EC_NewKeyFromSeed(ecParams, privKey, seed, len);
+ MP_DIGITS(&privKeyVal) = 0;
+ MP_DIGITS(&order_1) = 0;
+ MP_DIGITS(&one) = 0;
+ CHECK_MPI_OK( mp_init(&privKeyVal) );
+ CHECK_MPI_OK( mp_init(&order_1) );
+ CHECK_MPI_OK( mp_init(&one) );
+
+ /* Generate random private key.
+ * Generates 2*len random bytes using the global random bit generator
+ * (which implements Algorithm 1 of FIPS 186-2 Change Notice 1) then
+ * reduces modulo the group order.
+ */
+ len = ecParams->order.len;
+ if ((privKeyBytes = PORT_Alloc(2*len)) == NULL) goto cleanup;
+ CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) );
+ CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) );
+ CHECK_MPI_OK( mp_read_unsigned_octets(&order_1,
+ ecParams->order.data, len) );
+ CHECK_MPI_OK( mp_set_int(&one, 1) );
+ CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) );
+ CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) );
+ CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) );
+ CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) );
+ /* generate public key */
+ CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len) );
cleanup:
- if (!seed) {
- PORT_ZFree(seed, len);
+ mp_clear(&privKeyVal);
+ mp_clear(&order_1);
+ mp_clear(&one);
+ if (privKeyBytes) {
+ PORT_ZFree(privKeyBytes, 2*len);
+ }
+ if (err < MP_OKAY) {
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
#if EC_DEBUG
printf("EC_NewKey returning %s\n",
@@ -382,7 +424,7 @@ cleanup:
}
/* Validates an EC public key as described in Section 5.2.2 of
- * X9.63. The ECDH primitive when used without the cofactor does
+ * X9.62. The ECDH primitive when used without the cofactor does
* not address small subgroup attacks, which may occur when the
* public key is not valid. These attacks can be prevented by
* validating the public key before using ECDH.
@@ -391,13 +433,78 @@ SECStatus
EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue)
{
#ifdef NSS_ENABLE_ECC
+ mp_int Px, Py;
+ ECGroup *group = NULL;
+ SECStatus rv = SECFailure;
+ mp_err err = MP_OKAY;
+ int len;
+
if (!ecParams || !publicValue) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
+
+ /* NOTE: We only support uncompressed points for now */
+ len = (ecParams->fieldID.size + 7) >> 3;
+ if (publicValue->data[0] != EC_POINT_FORM_UNCOMPRESSED) {
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
+ return SECFailure;
+ } else if (publicValue->len != (2 * len + 1)) {
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ return SECFailure;
+ }
+
+ MP_DIGITS(&Px) = 0;
+ MP_DIGITS(&Py) = 0;
+ CHECK_MPI_OK( mp_init(&Px) );
+ CHECK_MPI_OK( mp_init(&Py) );
+
+ /* Initialize Px and Py */
+ CHECK_MPI_OK( mp_read_unsigned_octets(&Px, publicValue->data + 1, (mp_size) len) );
+ CHECK_MPI_OK( mp_read_unsigned_octets(&Py, publicValue->data + 1 + len, (mp_size) len) );
+
+ /* construct from named params */
+ group = ECGroup_fromName(ecParams->name);
+ if (group == NULL) {
+ /*
+ * ECGroup_fromName fails if ecParams->name is not a valid
+ * ECCurveName value, or if we run out of memory, or perhaps
+ * for other reasons. Unfortunately if ecParams->name is a
+ * valid ECCurveName value, we don't know what the right error
+ * code should be because ECGroup_fromName doesn't return an
+ * error code to the caller. Set err to MP_UNDEF because
+ * that's what ECGroup_fromName uses internally.
+ */
+ if ((ecParams->name <= ECCurve_noName) ||
+ (ecParams->name >= ECCurve_pastLastCurve)) {
+ err = MP_BADARG;
+ } else {
+ err = MP_UNDEF;
+ }
+ goto cleanup;
+ }
- /* XXX Add actual checks here. */
- return SECSuccess;
+ /* validate public point */
+ if ((err = ECPoint_validate(group, &Px, &Py)) < MP_YES) {
+ if (err == MP_NO) {
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ rv = SECFailure;
+ err = MP_OKAY; /* don't change the error code */
+ }
+ goto cleanup;
+ }
+
+ rv = SECSuccess;
+
+cleanup:
+ ECGroup_free(group);
+ mp_clear(&Px);
+ mp_clear(&Py);
+ if (err) {
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
+ }
+ return rv;
#else
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
return SECFailure;
diff --git a/security/nss/lib/freebl/ecl/ec2.h b/security/nss/lib/freebl/ecl/ec2.h
index a4bf649b9..2ca8418b3 100644
--- a/security/nss/lib/freebl/ecl/ec2.h
+++ b/security/nss/lib/freebl/ecl/ec2.h
@@ -62,6 +62,9 @@ mp_err ec_GF2m_pt_sub_aff(const mp_int *px, const mp_int *py,
mp_err ec_GF2m_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
mp_int *ry, const ECGroup *group);
+/* Validates a point on a GF2m curve. */
+mp_err ec_GF2m_validate_point(const mp_int *px, const mp_int *py, 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
diff --git a/security/nss/lib/freebl/ecl/ec2_aff.c b/security/nss/lib/freebl/ecl/ec2_aff.c
index eef3f4821..45b277001 100644
--- a/security/nss/lib/freebl/ecl/ec2_aff.c
+++ b/security/nss/lib/freebl/ecl/ec2_aff.c
@@ -269,3 +269,79 @@ ec_GF2m_pt_mul_aff(const mp_int *n, const mp_int *px, const mp_int *py,
return res;
}
#endif
+
+/* Validates a point on a GF2m curve. */
+mp_err
+ec_GF2m_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group)
+{
+ mp_err res = MP_NO;
+ mp_int accl, accr, tmp, pxt, pyt;
+
+ MP_DIGITS(&accl) = 0;
+ MP_DIGITS(&accr) = 0;
+ MP_DIGITS(&tmp) = 0;
+ MP_DIGITS(&pxt) = 0;
+ MP_DIGITS(&pyt) = 0;
+ MP_CHECKOK(mp_init(&accl));
+ MP_CHECKOK(mp_init(&accr));
+ MP_CHECKOK(mp_init(&tmp));
+ MP_CHECKOK(mp_init(&pxt));
+ MP_CHECKOK(mp_init(&pyt));
+
+ /* 1: Verify that publicValue is not the point at infinity */
+ if (ec_GF2m_pt_is_inf_aff(px, py) == MP_YES) {
+ res = MP_NO;
+ goto CLEANUP;
+ }
+ /* 2: Verify that the coordinates of publicValue are elements
+ * of the field.
+ */
+ if ((MP_SIGN(px) == MP_NEG) || (mp_cmp(px, &group->meth->irr) >= 0) ||
+ (MP_SIGN(py) == MP_NEG) || (mp_cmp(py, &group->meth->irr) >= 0)) {
+ res = MP_NO;
+ goto CLEANUP;
+ }
+ /* 3: Verify that publicValue is on the curve. */
+ if (group->meth->field_enc) {
+ group->meth->field_enc(px, &pxt, group->meth);
+ group->meth->field_enc(py, &pyt, group->meth);
+ } else {
+ mp_copy(px, &pxt);
+ mp_copy(py, &pyt);
+ }
+ /* left-hand side: y^2 + x*y */
+ MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) );
+ MP_CHECKOK( group->meth->field_mul(&pxt, &pyt, &tmp, group->meth) );
+ MP_CHECKOK( group->meth->field_mul(&pxt, &pyt, &tmp, group->meth) );
+ MP_CHECKOK( group->meth->field_add(&accl, &tmp, &accl, group->meth) );
+ /* right-hand side: x^3 + a*x^2 + b */
+ MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) );
+ MP_CHECKOK( group->meth->field_mul(&pxt, &tmp, &accr, group->meth) );
+ MP_CHECKOK( group->meth->field_mul(&group->curvea, &tmp, &tmp, group->meth) );
+ MP_CHECKOK( group->meth->field_add(&tmp, &accr, &accr, group->meth) );
+ MP_CHECKOK( group->meth->field_add(&accr, &group->curveb, &accr, group->meth) );
+ /* check LHS - RHS == 0 */
+ MP_CHECKOK( group->meth->field_add(&accl, &accr, &accr, group->meth) );
+ if (mp_cmp_z(&accr) != 0) {
+ res = MP_NO;
+ goto CLEANUP;
+ }
+ /* 4: Verify that the order of the curve times the publicValue
+ * is the point at infinity.
+ */
+ MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt) );
+ if (ec_GF2m_pt_is_inf_aff(&pxt, &pyt) != MP_YES) {
+ res = MP_NO;
+ goto CLEANUP;
+ }
+
+ res = MP_YES;
+
+CLEANUP:
+ mp_clear(&accl);
+ mp_clear(&accr);
+ mp_clear(&tmp);
+ mp_clear(&pxt);
+ mp_clear(&pyt);
+ return res;
+}
diff --git a/security/nss/lib/freebl/ecl/ecl-curve.h b/security/nss/lib/freebl/ecl/ecl-curve.h
index cba22b2a7..fed21fa52 100644
--- a/security/nss/lib/freebl/ecl/ecl-curve.h
+++ b/security/nss/lib/freebl/ecl/ecl-curve.h
@@ -117,7 +117,7 @@ static const ECCurveParams ecCurve_NIST_K233 = {
"000000000000000000000000000000000000000000000000000000000001",
"017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
"01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
- "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4
+ "8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4
};
static const ECCurveParams ecCurve_NIST_B233 = {
"NIST-B233", ECField_GF2m, 233,
@@ -155,7 +155,7 @@ static const ECCurveParams ecCurve_NIST_K409 = {
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
"0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
"01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
- "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
+ "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
4
};
static const ECCurveParams ecCurve_NIST_B409 = {
diff --git a/security/nss/lib/freebl/ecl/ecl-priv.h b/security/nss/lib/freebl/ecl/ecl-priv.h
index 39072e374..bce7ccf09 100644
--- a/security/nss/lib/freebl/ecl/ecl-priv.h
+++ b/security/nss/lib/freebl/ecl/ecl-priv.h
@@ -144,6 +144,7 @@ struct ECGroupStr {
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);
+ mp_err (*validate_point) (const mp_int *px, const mp_int *py, const ECGroup *group);
/* Extra storage for implementation-specific data. Any memory
* allocated to these extra fields will be cleared by extra_free. */
void *extra1;
diff --git a/security/nss/lib/freebl/ecl/ecl.c b/security/nss/lib/freebl/ecl/ecl.c
index 5dc853647..520755f6a 100644
--- a/security/nss/lib/freebl/ecl/ecl.c
+++ b/security/nss/lib/freebl/ecl/ecl.c
@@ -68,6 +68,7 @@ ECGroup_new()
MP_CHECKOK(mp_init(&group->order));
group->base_point_mul = NULL;
group->points_mul = NULL;
+ group->validate_point = NULL;
group->extra1 = NULL;
group->extra2 = NULL;
group->extra_free = NULL;
@@ -110,6 +111,7 @@ ECGroup_consGFp(const mp_int *irr, const mp_int *curvea,
group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
group->base_point_mul = NULL;
group->points_mul = &ec_GFp_pts_mul_jac;
+ group->validate_point = &ec_GFp_validate_point;
CLEANUP:
if (res != MP_OKAY) {
@@ -152,6 +154,7 @@ ECGroup_consGFp_mont(const mp_int *irr, const mp_int *curvea,
group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
group->base_point_mul = NULL;
group->points_mul = &ec_GFp_pts_mul_jac;
+ group->validate_point = &ec_GFp_validate_point;
CLEANUP:
if (res != MP_OKAY) {
@@ -193,6 +196,7 @@ ECGroup_consGF2m(const mp_int *irr, const unsigned int irr_arr[5],
group->point_mul = &ec_GF2m_pt_mul_mont;
group->base_point_mul = NULL;
group->points_mul = &ec_pts_mul_basic;
+ group->validate_point = &ec_GF2m_validate_point;
CLEANUP:
if (res != MP_OKAY) {
@@ -329,11 +333,10 @@ ecgroup_fromNameAndHex(const ECCurveName name,
/* set name, if any */
if (params->text != NULL) {
- group->text = (char *) malloc(sizeof(char) * strlen(params->text));
+ group->text = strdup(params->text);
if (group->text == NULL) {
res = MP_MEM;
}
- strcpy(group->text, params->text);
}
CLEANUP:
@@ -391,6 +394,21 @@ ECGroup_fromName(const ECCurveName name)
return group;
}
+/* Validates an EC public key as described in Section 5.2.2 of X9.62. */
+mp_err ECPoint_validate(const ECGroup *group, const mp_int *px, const
+ mp_int *py)
+{
+ /* 1: Verify that publicValue is not the point at infinity */
+ /* 2: Verify that the coordinates of publicValue are elements
+ * of the field.
+ */
+ /* 3: Verify that publicValue is on the curve. */
+ /* 4: Verify that the order of the curve times the publicValue
+ * is the point at infinity.
+ */
+ return group->validate_point(px, py, group);
+}
+
/* Free the memory allocated (if any) to an ECGroup object. */
void
ECGroup_free(ECGroup *group)
diff --git a/security/nss/lib/freebl/ecl/ecl.h b/security/nss/lib/freebl/ecl/ecl.h
index 6d8fb5a59..dbd86c253 100644
--- a/security/nss/lib/freebl/ecl/ecl.h
+++ b/security/nss/lib/freebl/ecl/ecl.h
@@ -81,4 +81,11 @@ 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);
+/* Validates an EC public key as described in Section 5.2.2 of X9.62.
+ * Returns MP_YES if the public key is valid, MP_NO if the public key
+ * is invalid, or an error code if the validation could not be
+ * performed. */
+mp_err ECPoint_validate(const ECGroup *group, const mp_int *px, const
+ mp_int *py);
+
#endif /* __ecl_h_ */
diff --git a/security/nss/lib/freebl/ecl/ecl_mult.c b/security/nss/lib/freebl/ecl/ecl_mult.c
index ede2b0e02..106c7ee42 100644
--- a/security/nss/lib/freebl/ecl/ecl_mult.c
+++ b/security/nss/lib/freebl/ecl/ecl_mult.c
@@ -41,7 +41,6 @@
#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)
@@ -163,7 +162,6 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px,
{
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;
@@ -181,23 +179,18 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px,
}
/* 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;
+ MP_DIGITS(&precomp[i][j][0]) = 0;
+ MP_DIGITS(&precomp[i][j][1]) = 0;
+ }
+ }
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ MP_CHECKOK( mp_init_size(&precomp[i][j][0],
+ ECL_MAX_FIELD_SIZE_DIGITS) );
+ MP_CHECKOK( mp_init_size(&precomp[i][j][1],
+ ECL_MAX_FIELD_SIZE_DIGITS) );
}
}
@@ -299,6 +292,12 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px,
}
CLEANUP:
+ 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;
}
@@ -345,17 +344,13 @@ ECPoints_mul(const ECGroup *group, const mp_int *k1, const mp_int *k2,
/* if points_mul is defined, then use it */
if (group->points_mul) {
- return group->points_mul(k1p, k2p, px, py, rx, ry, group);
+ res = group->points_mul(k1p, k2p, px, py, rx, ry, group);
} else {
- return ec_pts_mul_simul_w2(k1p, k2p, px, py, rx, ry, group);
+ res = 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);
- }
+ mp_clear(&k1t);
+ mp_clear(&k2t);
return res;
}
diff --git a/security/nss/lib/freebl/ecl/ecp.h b/security/nss/lib/freebl/ecl/ecp.h
index 43c6dcb5b..1d247b154 100644
--- a/security/nss/lib/freebl/ecl/ecp.h
+++ b/security/nss/lib/freebl/ecl/ecp.h
@@ -62,6 +62,9 @@ mp_err ec_GFp_pt_sub_aff(const mp_int *px, const mp_int *py,
mp_err ec_GFp_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
mp_int *ry, const ECGroup *group);
+/* Validates a point on a GFp curve. */
+mp_err ec_GFp_validate_point(const mp_int *px, const mp_int *py, 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
diff --git a/security/nss/lib/freebl/ecl/ecp_aff.c b/security/nss/lib/freebl/ecl/ecp_aff.c
index 1831e4bea..cda04ed22 100644
--- a/security/nss/lib/freebl/ecl/ecp_aff.c
+++ b/security/nss/lib/freebl/ecl/ecp_aff.c
@@ -282,3 +282,76 @@ ec_GFp_pt_mul_aff(const mp_int *n, const mp_int *px, const mp_int *py,
return res;
}
#endif
+
+/* Validates a point on a GFp curve. */
+mp_err
+ec_GFp_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group)
+{
+ mp_err res = MP_NO;
+ mp_int accl, accr, tmp, pxt, pyt;
+
+ MP_DIGITS(&accl) = 0;
+ MP_DIGITS(&accr) = 0;
+ MP_DIGITS(&tmp) = 0;
+ MP_DIGITS(&pxt) = 0;
+ MP_DIGITS(&pyt) = 0;
+ MP_CHECKOK(mp_init(&accl));
+ MP_CHECKOK(mp_init(&accr));
+ MP_CHECKOK(mp_init(&tmp));
+ MP_CHECKOK(mp_init(&pxt));
+ MP_CHECKOK(mp_init(&pyt));
+
+ /* 1: Verify that publicValue is not the point at infinity */
+ if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
+ res = MP_NO;
+ goto CLEANUP;
+ }
+ /* 2: Verify that the coordinates of publicValue are elements
+ * of the field.
+ */
+ if ((MP_SIGN(px) == MP_NEG) || (mp_cmp(px, &group->meth->irr) >= 0) ||
+ (MP_SIGN(py) == MP_NEG) || (mp_cmp(py, &group->meth->irr) >= 0)) {
+ res = MP_NO;
+ goto CLEANUP;
+ }
+ /* 3: Verify that publicValue is on the curve. */
+ if (group->meth->field_enc) {
+ group->meth->field_enc(px, &pxt, group->meth);
+ group->meth->field_enc(py, &pyt, group->meth);
+ } else {
+ mp_copy(px, &pxt);
+ mp_copy(py, &pyt);
+ }
+ /* left-hand side: y^2 */
+ MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) );
+ /* right-hand side: x^3 + a*x + b */
+ MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) );
+ MP_CHECKOK( group->meth->field_mul(&pxt, &tmp, &accr, group->meth) );
+ MP_CHECKOK( group->meth->field_mul(&group->curvea, &pxt, &tmp, group->meth) );
+ MP_CHECKOK( group->meth->field_add(&tmp, &accr, &accr, group->meth) );
+ MP_CHECKOK( group->meth->field_add(&accr, &group->curveb, &accr, group->meth) );
+ /* check LHS - RHS == 0 */
+ MP_CHECKOK( group->meth->field_sub(&accl, &accr, &accr, group->meth) );
+ if (mp_cmp_z(&accr) != 0) {
+ res = MP_NO;
+ goto CLEANUP;
+ }
+ /* 4: Verify that the order of the curve times the publicValue
+ * is the point at infinity.
+ */
+ MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt) );
+ if (ec_GFp_pt_is_inf_aff(&pxt, &pyt) != MP_YES) {
+ res = MP_NO;
+ goto CLEANUP;
+ }
+
+ res = MP_YES;
+
+CLEANUP:
+ mp_clear(&accl);
+ mp_clear(&accr);
+ mp_clear(&tmp);
+ mp_clear(&pxt);
+ mp_clear(&pyt);
+ return res;
+}
diff --git a/security/nss/lib/freebl/ecl/ecp_jm.c b/security/nss/lib/freebl/ecl/ecp_jm.c
index 397e01f47..3b19cc825 100644
--- a/security/nss/lib/freebl/ecl/ecp_jm.c
+++ b/security/nss/lib/freebl/ecl/ecp_jm.c
@@ -283,7 +283,7 @@ ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
orderBitSize = mpl_significant_bits(&group->order);
/* Allocate memory for NAF */
- naf = (signed char *) malloc(sizeof(signed char) * orderBitSize);
+ naf = (signed char *) malloc(sizeof(signed char) * (orderBitSize + 1));
if (naf == NULL) {
res = MP_MEM;
goto CLEANUP;
diff --git a/security/nss/lib/freebl/ecl/tests/ec2_test.c b/security/nss/lib/freebl/ecl/tests/ec2_test.c
index 1c7639d1a..e82b47da0 100644
--- a/security/nss/lib/freebl/ecl/tests/ec2_test.c
+++ b/security/nss/lib/freebl/ecl/tests/ec2_test.c
@@ -348,6 +348,19 @@ ectest_curve_GF2m(ECGroup *group, int ectestPrint, int ectestTime,
goto CLEANUP;
}
+ /* test validate_point function */
+ if (ECPoint_validate(group, &gx, &gy) != MP_YES) {
+ printf(" Error: validate point on base point failed.\n");
+ res = MP_NO;
+ goto CLEANUP;
+ }
+ MP_CHECKOK(mp_add_d(&gy, 1, &ry));
+ if (ECPoint_validate(group, &gx, &ry) != MP_NO) {
+ printf(" Error: validate point on invalid point passed.\n");
+ res = MP_NO;
+ goto CLEANUP;
+ }
+
if (ectestTime) {
/* compute random scalar */
size = mpl_significant_bits(&group->meth->irr);
diff --git a/security/nss/lib/freebl/ecl/tests/ecp_test.c b/security/nss/lib/freebl/ecl/tests/ecp_test.c
index 9e3ae4d99..d7ce299ec 100644
--- a/security/nss/lib/freebl/ecl/tests/ecp_test.c
+++ b/security/nss/lib/freebl/ecl/tests/ecp_test.c
@@ -310,6 +310,19 @@ ectest_curve_GFp(ECGroup *group, int ectestPrint, int ectestTime,
goto CLEANUP;
}
+ /* test validate_point function */
+ if (ECPoint_validate(group, &gx, &gy) != MP_YES) {
+ printf(" Error: validate point on base point failed.\n");
+ res = MP_NO;
+ goto CLEANUP;
+ }
+ MP_CHECKOK(mp_add_d(&gy, 1, &ry));
+ if (ECPoint_validate(group, &gx, &ry) != MP_NO) {
+ printf(" Error: validate point on invalid point passed.\n");
+ res = MP_NO;
+ goto CLEANUP;
+ }
+
if (ectestTime) {
/* compute random scalar */
size = mpl_significant_bits(&group->meth->irr);
diff --git a/security/nss/lib/freebl/freebl.def b/security/nss/lib/freebl/freebl.def
new file mode 100644
index 000000000..61b3337c2
--- /dev/null
+++ b/security/nss/lib/freebl/freebl.def
@@ -0,0 +1,58 @@
+;+#
+;+# ***** BEGIN LICENSE BLOCK *****
+;+# 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 Netscape security libraries.
+;+#
+;+# The Initial Developer of the Original Code is
+;+# Netscape Communications Corporation.
+;+# Portions created by the Initial Developer are Copyright (C) 2000
+;+# the Initial Developer. All Rights Reserved.
+;+#
+;+# Contributor(s):
+;+#
+;+# 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.
+;+#
+;+# ***** END LICENSE BLOCK *****
+;+#
+;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
+;+# 1. For all unix platforms, the string ";-" means "remove this line"
+;+# 2. For all unix platforms, the string " DATA " will be removed from any
+;+# line on which it occurs.
+;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
+;+# On AIX, lines containing ";+" will be removed.
+;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
+;+# 5. For all unix platforms, after the above processing has taken place,
+;+# all characters after the first ";" on the line will be removed.
+;+# And for AIX, the first ";" will also be removed.
+;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
+;+# directives are hidden behind ";", ";+", and ";-"
+;+
+;+NSSprivate_3.11 { # NSS 3.11 release
+;+ global:
+LIBRARY freebl3 ;-
+EXPORTS ;-
+FREEBL_GetVector;
+;+ local:
+;+ *;
+;+};
diff --git a/security/nss/lib/freebl/freeblver.c b/security/nss/lib/freebl/freeblver.c
new file mode 100644
index 000000000..e2c6a538c
--- /dev/null
+++ b/security/nss/lib/freebl/freeblver.c
@@ -0,0 +1,56 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Library identity and versioning */
+
+#include "nss.h"
+
+#if defined(DEBUG)
+#define _DEBUG_STRING " (debug)"
+#else
+#define _DEBUG_STRING ""
+#endif
+
+/*
+ * Version information for the 'ident' and 'what commands
+ *
+ * NOTE: the first component of the concatenated rcsid string
+ * must not end in a '$' to prevent rcs keyword substitution.
+ */
+const char __nss_freebl_rcsid[] = "$Header: NSS " NSS_VERSION _DEBUG_STRING
+ " " __DATE__ " " __TIME__ " $";
+const char __nss_freebl_sccsid[] = "@(#)NSS " NSS_VERSION _DEBUG_STRING
+ " " __DATE__ " " __TIME__;
diff --git a/security/nss/lib/freebl/ldvector.c b/security/nss/lib/freebl/ldvector.c
index 63bd76fcb..595d7dd8b 100644
--- a/security/nss/lib/freebl/ldvector.c
+++ b/security/nss/lib/freebl/ldvector.c
@@ -40,8 +40,10 @@
/* $Id$ */
#include "loader.h"
+#include "alghmac.h"
-static const struct FREEBLVectorStr vector = {
+static const struct FREEBLVectorStr vector =
+{
sizeof vector,
FREEBL_VERSION,
@@ -185,12 +187,52 @@ static const struct FREEBLVectorStr vector = {
ECDSA_SignDigestWithSeed,
/* End of Version 3.006. */
+ /* End of Version 3.007. */
+
+ AES_InitContext,
+ AESKeyWrap_InitContext,
+ DES_InitContext,
+ RC2_InitContext,
+ RC4_InitContext,
+
+ AES_AllocateContext,
+ AESKeyWrap_AllocateContext,
+ DES_AllocateContext,
+ RC2_AllocateContext,
+ RC4_AllocateContext,
+
+ MD2_Clone,
+ MD5_Clone,
+ SHA1_Clone,
+ SHA256_Clone,
+ SHA384_Clone,
+ SHA512_Clone,
+
+ TLS_PRF,
+ HASH_GetRawHashObject,
+
+ HMAC_Create,
+ HMAC_Init,
+ HMAC_Begin,
+ HMAC_Update,
+ HMAC_Clone,
+ HMAC_Finish,
+ HMAC_Destroy,
+
+ RNG_SystemInfoForRNG,
+
+ /* End of Version 3.008. */
};
-
const FREEBLVector *
FREEBL_GetVector(void)
{
- return &vector;
+ extern const char __nss_freebl_rcsid[];
+ extern const char __nss_freebl_sccsid[];
+
+ /* force a reference that won't get optimized away */
+ volatile char c = __nss_freebl_rcsid[0] + __nss_freebl_sccsid[0];
+
+ return &vector;
}
diff --git a/security/nss/lib/freebl/loader.c b/security/nss/lib/freebl/loader.c
index 3b3c4a68a..141cc1b7f 100644
--- a/security/nss/lib/freebl/loader.c
+++ b/security/nss/lib/freebl/loader.c
@@ -44,190 +44,242 @@
#include "prerror.h"
#include "prinit.h"
-#if defined(SOLARIS)
+static const char* default_name =
+ SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX;
+
+/* getLibName() returns the name of the library to load. */
+
+#if defined(SOLARIS) && defined(__sparc)
#include <stddef.h>
#include <strings.h>
#include <sys/systeminfo.h>
-#if defined(SOLARIS2_5)
-static int
-isHybrid(void)
-{
- long buflen;
- int rv = 0; /* false */
- char buf[256];
- buflen = sysinfo(SI_MACHINE, buf, sizeof buf);
- if (buflen > 0) {
- rv = (!strcmp(buf, "sun4u") || !strcmp(buf, "sun4u1"));
- }
- return rv;
-}
-#else /* SunOS2.6or higher has SI_ISALIST */
-static int
-isHybrid(void)
+
+#if defined(NSS_USE_64)
+
+const static char fpu_hybrid_shared_lib[] = "libfreebl_64fpu_3.so";
+const static char int_hybrid_shared_lib[] = "libfreebl_64int_3.so";
+const static char non_hybrid_shared_lib[] = "libfreebl_64fpu_3.so";
+
+const static char int_hybrid_isa[] = "sparcv9";
+const static char fpu_hybrid_isa[] = "sparcv9+vis";
+
+#else
+
+const static char fpu_hybrid_shared_lib[] = "libfreebl_32fpu_3.so";
+const static char int_hybrid_shared_lib[] = "libfreebl_32int64_3.so";
+const static char non_hybrid_shared_lib[] = "libfreebl_32int_3.so";
+
+const static char int_hybrid_isa[] = "sparcv8plus";
+const static char fpu_hybrid_isa[] = "sparcv8plus+vis";
+
+#endif
+
+static const char *
+getLibName(void)
{
+ char * found_int_hybrid;
+ char * found_fpu_hybrid;
long buflen;
- int rv = 0; /* false */
char buf[256];
+
buflen = sysinfo(SI_ISALIST, buf, sizeof buf);
- if (buflen > 0) {
-#if defined(NSS_USE_64)
- char * found = strstr(buf, "sparcv9+vis");
-#else
- char * found = strstr(buf, "sparcv8plus+vis");
-#endif
- rv = (found != 0);
+ if (buflen <= 0)
+ return NULL;
+ /* The ISA list is a space separated string of names of ISAs and
+ * ISA extensions, in order of decreasing performance.
+ * There are two different ISAs with which NSS's crypto code can be
+ * accelerated. If both are in the list, we take the first one.
+ * If one is in the list, we use it, and if neither then we use
+ * the base unaccelerated code.
+ */
+ found_int_hybrid = strstr(buf, int_hybrid_isa);
+ found_fpu_hybrid = strstr(buf, fpu_hybrid_isa);
+ if (found_fpu_hybrid &&
+ (!found_int_hybrid ||
+ (found_int_hybrid - found_fpu_hybrid) >= 0)) {
+ return fpu_hybrid_shared_lib;
+ }
+ if (found_int_hybrid) {
+ return int_hybrid_shared_lib;
}
- return rv;
+ return non_hybrid_shared_lib;
}
-#endif
-#elif defined(HPUX)
+
+#elif defined(HPUX) && !defined(NSS_USE_64) && !defined(__ia64)
/* This code tests to see if we're running on a PA2.x CPU.
** It returns true (1) if so, and false (0) otherwise.
*/
-static int
-isHybrid(void)
+static const char *
+getLibName(void)
{
long cpu = sysconf(_SC_CPU_VERSION);
- return (cpu == CPU_PA_RISC2_0);
+ return (cpu == CPU_PA_RISC2_0)
+ ? "libfreebl_32fpu_3.sl"
+ : "libfreebl_32int32_3.sl" ;
}
-
#else
-#error "code for this platform is missing."
+/* default case, for platforms/ABIs that have only one freebl shared lib. */
+static const char * getLibName(void) { return default_name; }
#endif
-/*
- * On Solaris, if an application using libnss3.so is linked
- * with the -R linker option, the -R search patch is only used
- * to search for the direct dependencies of the application
- * (such as libnss3.so) and is not used to search for the
- * dependencies of libnss3.so. So we build libnss3.so with
- * the -R '$ORIGIN' linker option to instruct it to search for
- * its dependencies (libfreebl_*.so) in the same directory
- * where it resides. This requires that libnss3.so, not
- * libnspr4.so, be the shared library that calls dlopen().
- * Therefore we have to duplicate the relevant code in the PR
- * load library functions here.
- */
-
-#if defined(SOLARIS)
-
-#include <dlfcn.h>
+#ifdef XP_UNIX
+#include <unistd.h>
-typedef struct {
- void *dlh;
-} BLLibrary;
-
-static BLLibrary *
-bl_LoadLibrary(const char *name)
-{
- BLLibrary *lib;
- const char *error;
- Dl_info dli;
+#define BL_MAXSYMLINKS 20
- lib = PR_NEWZAP(BLLibrary);
- if (NULL == lib) {
- PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+/*
+ * If 'link' is a symbolic link, this function follows the symbolic links
+ * and returns the pathname of the ultimate source of the symbolic links.
+ * If 'link' is not a symbolic link, this function returns NULL.
+ * The caller should call PR_Free to free the string returned by this
+ * function.
+ */
+static char* bl_GetOriginalPathname(const char* link)
+{
+ char* resolved = NULL;
+ char* input = NULL;
+ PRUint32 iterations = 0;
+ PRInt32 len = 0, retlen = 0;
+ if (!link) {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
return NULL;
}
-
- /*
- * In setuid applications, Solaris is unwilling to load freebl unless
- * we specify an absolute path. We construct one from the path of the
- * library that contains this function.
- */
- if (dladdr((void *)bl_LoadLibrary, &dli) != 0) {
- const char *slash = strrchr(dli.dli_fname, '/');
- if (slash) {
- size_t dirsize = slash - dli.dli_fname + 1;
- char *pathname = PR_Malloc(dirsize + strlen(name) + 1);
- if (NULL == pathname) {
- PR_Free(lib);
- PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
- return NULL;
- }
- memcpy(pathname, dli.dli_fname, dirsize);
- strcpy(pathname + dirsize, name);
- lib->dlh = dlopen(pathname, RTLD_NOW | RTLD_LOCAL);
- PR_Free(pathname);
- if (NULL != lib->dlh)
- return lib;
+ len = PR_MAX(1024, strlen(link) + 1);
+ resolved = PR_Malloc(len);
+ input = PR_Malloc(len);
+ if (!resolved || !input) {
+ if (resolved) {
+ PR_Free(resolved);
+ }
+ if (input) {
+ PR_Free(input);
}
- }
-
- lib->dlh = dlopen(name, RTLD_NOW | RTLD_LOCAL);
- if (NULL == lib->dlh) {
- PR_SetError(PR_LOAD_LIBRARY_ERROR, 0);
- error = dlerror();
- if (NULL != error)
- PR_SetErrorText(strlen(error), error);
- PR_Free(lib);
return NULL;
}
- return lib;
-}
-
-static void *
-bl_FindSymbol(BLLibrary *lib, const char *name)
-{
- void *f;
- const char *error;
-
- f = dlsym(lib->dlh, name);
- if (NULL == f) {
- PR_SetError(PR_FIND_SYMBOL_ERROR, 0);
- error = dlerror();
- if (NULL != error)
- PR_SetErrorText(strlen(error), error);
+ strcpy(input, link);
+ while ( (iterations++ < BL_MAXSYMLINKS) &&
+ ( (retlen = readlink(input, resolved, len - 1)) > 0) ) {
+ char* tmp = input;
+ resolved[retlen] = '\0'; /* NULL termination */
+ input = resolved;
+ resolved = tmp;
}
- return f;
-}
-
-static PRStatus
-bl_UnloadLibrary(BLLibrary *lib)
-{
- const char *error;
-
- if (dlclose(lib->dlh) == -1) {
- PR_SetError(PR_UNLOAD_LIBRARY_ERROR, 0);
- error = dlerror();
- if (NULL != error)
- PR_SetErrorText(strlen(error), error);
- return PR_FAILURE;
+ PR_Free(resolved);
+ if (iterations == 1 && retlen < 0) {
+ PR_Free(input);
+ input = NULL;
}
- PR_Free(lib);
- return PR_SUCCESS;
+ return input;
}
+#endif /* XP_UNIX */
+
+/*
+ * We use PR_GetLibraryFilePathname to get the pathname of the loaded
+ * shared lib that contains this function, and then do a PR_LoadLibrary
+ * with an absolute pathname for the freebl shared library.
+ */
-#elif defined(HPUX)
+#include "prio.h"
+#include "prprf.h"
+#include <stdio.h>
+#include "prsystem.h"
-#include <dl.h>
-#include <string.h>
-#include <errno.h>
+const char* softoken=SHLIB_PREFIX"softokn"SOFTOKEN_SHLIB_VERSION"."SHLIB_SUFFIX;
typedef struct {
- shl_t dlh;
+ PRLibrary *dlh;
} BLLibrary;
+/*
+ * Load the freebl library with the file name 'name' residing in the same
+ * directory as libsoftoken, whose pathname is 'softokenPath'.
+ */
+static PRLibrary *
+bl_LoadFreeblLibInSoftokenDir(const char *softokenPath, const char *name)
+{
+ PRLibrary *dlh = NULL;
+ char *fullName = NULL;
+ char* c;
+ PRLibSpec libSpec;
+
+ /* Remove "libsoftokn" from the pathname and add the freebl libname */
+ c = strrchr(softokenPath, PR_GetDirectorySeparator());
+ if (c) {
+ size_t softoknPathSize = 1 + c - softokenPath;
+ fullName = (char*) PORT_Alloc(strlen(name) + softoknPathSize + 1);
+ if (fullName) {
+ memcpy(fullName, softokenPath, softoknPathSize);
+ strcpy(fullName + softoknPathSize, name);
+#ifdef DEBUG_LOADER
+ PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n",
+ fullName);
+#endif
+ libSpec.type = PR_LibSpec_Pathname;
+ libSpec.value.pathname = fullName;
+ dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL);
+ PORT_Free(fullName);
+ }
+ }
+ return dlh;
+}
+
static BLLibrary *
bl_LoadLibrary(const char *name)
{
- BLLibrary *lib;
- const char *error;
+ BLLibrary *lib = NULL;
+ PRFuncPtr fn_addr;
+ char* softokenPath = NULL;
+ PRLibSpec libSpec;
lib = PR_NEWZAP(BLLibrary);
if (NULL == lib) {
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
return NULL;
}
- lib->dlh = shl_load(name, DYNAMIC_PATH | BIND_IMMEDIATE, 0L);
+
+ /* Get the pathname for the loaded libsoftokn, i.e. /usr/lib/libsoftokn3.so
+ * PR_GetLibraryFilePathname works with either the base library name or a
+ * function pointer, depending on the platform. We can't query an exported
+ * symbol such as NSC_GetFunctionList, because on some platforms we can't
+ * find symbols in loaded implicit dependencies such as libsoftokn.
+ * But we can just get the address of this function !
+ */
+ fn_addr = (PRFuncPtr) &bl_LoadLibrary;
+ softokenPath = PR_GetLibraryFilePathname(softoken, fn_addr);
+
+ if (softokenPath) {
+ lib->dlh = bl_LoadFreeblLibInSoftokenDir(softokenPath, name);
+#ifdef XP_UNIX
+ if (!lib->dlh) {
+ /*
+ * If softokenPath is a symbolic link, resolve the symbolic
+ * link and try again.
+ */
+ char* originalSoftokenPath = bl_GetOriginalPathname(softokenPath);
+ if (originalSoftokenPath) {
+ PR_Free(softokenPath);
+ softokenPath = originalSoftokenPath;
+ lib->dlh = bl_LoadFreeblLibInSoftokenDir(softokenPath, name);
+ }
+ }
+#endif
+ PR_Free(softokenPath);
+ }
+ if (!lib->dlh) {
+#ifdef DEBUG_LOADER
+ PR_fprintf(PR_STDOUT, "\nAttempting to load %s\n", name);
+#endif
+ libSpec.type = PR_LibSpec_Pathname;
+ libSpec.value.pathname = name;
+ lib->dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL);
+ }
if (NULL == lib->dlh) {
- PR_SetError(PR_LOAD_LIBRARY_ERROR, errno);
- error = strerror(errno);
- if (NULL != error)
- PR_SetErrorText(strlen(error), error);
+#ifdef DEBUG_LOADER
+ PR_fprintf(PR_STDOUT, "\nLoading failed : %s.\n", name);
+#endif
PR_Free(lib);
- return NULL;
+ lib = NULL;
}
return lib;
}
@@ -236,38 +288,21 @@ static void *
bl_FindSymbol(BLLibrary *lib, const char *name)
{
void *f;
- const char *error;
-
- if (shl_findsym(&lib->dlh, name, TYPE_PROCEDURE, &f) == -1) {
- f = NULL;
- PR_SetError(PR_FIND_SYMBOL_ERROR, errno);
- error = strerror(errno);
- if (NULL != error)
- PR_SetErrorText(strlen(error), error);
- }
+
+ f = PR_FindSymbol(lib->dlh, name);
return f;
}
static PRStatus
bl_UnloadLibrary(BLLibrary *lib)
{
- const char *error;
-
- if (shl_unload(lib->dlh) == -1) {
- PR_SetError(PR_UNLOAD_LIBRARY_ERROR, errno);
- error = strerror(errno);
- if (NULL != error)
- PR_SetErrorText(strlen(error), error);
+ if (PR_SUCCESS != PR_UnloadLibrary(lib->dlh)) {
return PR_FAILURE;
}
PR_Free(lib);
return PR_SUCCESS;
}
-#else
-#error "code for this platform is missing."
-#endif
-
#define LSB(x) ((x)&0xff)
#define MSB(x) ((x)>>8)
@@ -279,18 +314,13 @@ static const char *libraryName = NULL;
static PRStatus
freebl_LoadDSO( void )
{
- int hybrid = isHybrid();
BLLibrary * handle;
- const char * name;
+ const char * name = getLibName();
- name = hybrid ?
-#if defined( AIX )
- "libfreebl_hybrid_3_shr.a" : "libfreebl_pure32_3_shr.a";
-#elif defined( HPUX )
- "libfreebl_hybrid_3.sl" : "libfreebl_pure32_3.sl";
-#else
- "libfreebl_hybrid_3.so" : "libfreebl_pure32_3.so";
-#endif
+ if (!name) {
+ PR_SetError(PR_LOAD_LIBRARY_ERROR, 0);
+ return PR_FAILURE;
+ }
handle = bl_LoadLibrary(name);
if (handle) {
@@ -1373,3 +1403,231 @@ ECDSA_SignDigestWithSeed(ECPrivateKey * key, SECItem * signature,
seed, seedlen );
}
+/* ============== New for 3.008 =============================== */
+
+AESContext *
+AES_AllocateContext(void)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_AES_AllocateContext)();
+}
+
+AESKeyWrapContext *
+AESKeyWrap_AllocateContext(void)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_AESKeyWrap_AllocateContext)();
+}
+
+DESContext *
+DES_AllocateContext(void)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_DES_AllocateContext)();
+}
+
+RC2Context *
+RC2_AllocateContext(void)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_RC2_AllocateContext)();
+}
+
+RC4Context *
+RC4_AllocateContext(void)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_RC4_AllocateContext)();
+}
+
+SECStatus
+AES_InitContext(AESContext *cx, const unsigned char *key,
+ unsigned int keylen, const unsigned char *iv, int mode,
+ unsigned int encrypt, unsigned int blocklen)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_AES_InitContext)(cx, key, keylen, iv, mode, encrypt,
+ blocklen);
+}
+
+SECStatus
+AESKeyWrap_InitContext(AESKeyWrapContext *cx, const unsigned char *key,
+ unsigned int keylen, const unsigned char *iv, int mode,
+ unsigned int encrypt, unsigned int blocklen)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_AESKeyWrap_InitContext)(cx, key, keylen, iv, mode,
+ encrypt, blocklen);
+}
+
+SECStatus
+DES_InitContext(DESContext *cx, const unsigned char *key,
+ unsigned int keylen, const unsigned char *iv, int mode,
+ unsigned int encrypt, unsigned int xtra)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_DES_InitContext)(cx, key, keylen, iv, mode, encrypt, xtra);
+}
+
+SECStatus
+RC2_InitContext(RC2Context *cx, const unsigned char *key,
+ unsigned int keylen, const unsigned char *iv, int mode,
+ unsigned int effectiveKeyLen, unsigned int xtra)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RC2_InitContext)(cx, key, keylen, iv, mode,
+ effectiveKeyLen, xtra);
+}
+
+SECStatus
+RC4_InitContext(RC4Context *cx, const unsigned char *key,
+ unsigned int keylen, const unsigned char *x1, int x2,
+ unsigned int x3, unsigned int x4)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_RC4_InitContext)(cx, key, keylen, x1, x2, x3, x4);
+}
+
+void
+MD2_Clone(MD2Context *dest, MD2Context *src)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_MD2_Clone)(dest, src);
+}
+
+void
+MD5_Clone(MD5Context *dest, MD5Context *src)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_MD5_Clone)(dest, src);
+}
+
+void
+SHA1_Clone(SHA1Context *dest, SHA1Context *src)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA1_Clone)(dest, src);
+}
+
+void
+SHA256_Clone(SHA256Context *dest, SHA256Context *src)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA256_Clone)(dest, src);
+}
+
+void
+SHA384_Clone(SHA384Context *dest, SHA384Context *src)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA384_Clone)(dest, src);
+}
+
+void
+SHA512_Clone(SHA512Context *dest, SHA512Context *src)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_SHA512_Clone)(dest, src);
+}
+
+SECStatus
+TLS_PRF(const SECItem *secret, const char *label,
+ SECItem *seed, SECItem *result, PRBool isFIPS)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_TLS_PRF)(secret, label, seed, result, isFIPS);
+}
+
+const SECHashObject *
+HASH_GetRawHashObject(HASH_HashType hashType)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_HASH_GetRawHashObject)(hashType);
+}
+
+
+void
+HMAC_Destroy(HMACContext *cx, PRBool freeit)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_HMAC_Destroy)(cx, freeit);
+}
+
+HMACContext *
+HMAC_Create(const SECHashObject *hashObj, const unsigned char *secret,
+ unsigned int secret_len, PRBool isFIPS)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_HMAC_Create)(hashObj, secret, secret_len, isFIPS);
+}
+
+SECStatus
+HMAC_Init(HMACContext *cx, const SECHashObject *hashObj,
+ const unsigned char *secret, unsigned int secret_len, PRBool isFIPS)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_HMAC_Init)(cx, hashObj, secret, secret_len, isFIPS);
+}
+
+void
+HMAC_Begin(HMACContext *cx)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_HMAC_Begin)(cx);
+}
+
+void
+HMAC_Update(HMACContext *cx, const unsigned char *data, unsigned int data_len)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return;
+ (vector->p_HMAC_Update)(cx, data, data_len);
+}
+
+SECStatus
+HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len,
+ unsigned int max_result_len)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return SECFailure;
+ return (vector->p_HMAC_Finish)(cx, result, result_len, max_result_len);
+}
+
+HMACContext *
+HMAC_Clone(HMACContext *cx)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return NULL;
+ return (vector->p_HMAC_Clone)(cx);
+}
+
+void
+RNG_SystemInfoForRNG(void)
+{
+ if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+ return ;
+ (vector->p_RNG_SystemInfoForRNG)();
+
+}
diff --git a/security/nss/lib/freebl/loader.h b/security/nss/lib/freebl/loader.h
index 2bd4a93e4..89bab5401 100644
--- a/security/nss/lib/freebl/loader.h
+++ b/security/nss/lib/freebl/loader.h
@@ -44,7 +44,7 @@
#include "blapi.h"
-#define FREEBL_VERSION 0x0307
+#define FREEBL_VERSION 0x0308
struct FREEBLVectorStr {
@@ -377,6 +377,78 @@ struct FREEBLVectorStr {
/* Version 3.007 came to here */
+ SECStatus (* p_AES_InitContext)(AESContext *cx,
+ const unsigned char *key,
+ unsigned int keylen,
+ const unsigned char *iv,
+ int mode,
+ unsigned int encrypt,
+ unsigned int blocklen);
+ SECStatus (* p_AESKeyWrap_InitContext)(AESKeyWrapContext *cx,
+ const unsigned char *key,
+ unsigned int keylen,
+ const unsigned char *iv,
+ int mode,
+ unsigned int encrypt,
+ unsigned int blocklen);
+ SECStatus (* p_DES_InitContext)(DESContext *cx,
+ const unsigned char *key,
+ unsigned int keylen,
+ const unsigned char *iv,
+ int mode,
+ unsigned int encrypt,
+ unsigned int );
+ SECStatus (* p_RC2_InitContext)(RC2Context *cx,
+ const unsigned char *key,
+ unsigned int keylen,
+ const unsigned char *iv,
+ int mode,
+ unsigned int effectiveKeyLen,
+ unsigned int );
+ SECStatus (* p_RC4_InitContext)(RC4Context *cx,
+ const unsigned char *key,
+ unsigned int keylen,
+ const unsigned char *,
+ int,
+ unsigned int ,
+ unsigned int );
+
+ AESContext *(*p_AES_AllocateContext)(void);
+ AESKeyWrapContext *(*p_AESKeyWrap_AllocateContext)(void);
+ DESContext *(*p_DES_AllocateContext)(void);
+ RC2Context *(*p_RC2_AllocateContext)(void);
+ RC4Context *(*p_RC4_AllocateContext)(void);
+
+ void (* p_MD2_Clone)(MD2Context *dest, MD2Context *src);
+ void (* p_MD5_Clone)(MD5Context *dest, MD5Context *src);
+ void (* p_SHA1_Clone)(SHA1Context *dest, SHA1Context *src);
+ void (* p_SHA256_Clone)(SHA256Context *dest, SHA256Context *src);
+ void (* p_SHA384_Clone)(SHA384Context *dest, SHA384Context *src);
+ void (* p_SHA512_Clone)(SHA512Context *dest, SHA512Context *src);
+
+ SECStatus (* p_TLS_PRF)(const SECItem *secret, const char *label,
+ SECItem *seed, SECItem *result, PRBool isFIPS);
+
+ const SECHashObject *(* p_HASH_GetRawHashObject)(HASH_HashType hashType);
+
+ HMACContext * (* p_HMAC_Create)(const SECHashObject *hashObj,
+ const unsigned char *secret,
+ unsigned int secret_len, PRBool isFIPS);
+ SECStatus (* p_HMAC_Init)(HMACContext *cx, const SECHashObject *hash_obj,
+ const unsigned char *secret,
+ unsigned int secret_len, PRBool isFIPS);
+ void (* p_HMAC_Begin)(HMACContext *cx);
+ void (* p_HMAC_Update)(HMACContext *cx, const unsigned char *data,
+ unsigned int data_len);
+ HMACContext * (* p_HMAC_Clone)(HMACContext *cx);
+ SECStatus (* p_HMAC_Finish)(HMACContext *cx, unsigned char *result,
+ unsigned int *result_len,
+ unsigned int max_result_len);
+ void (* p_HMAC_Destroy)(HMACContext *cx, PRBool freeit);
+
+ void (* p_RNG_SystemInfoForRNG)(void);
+
+ /* Version 3.008 came to here */
};
typedef struct FREEBLVectorStr FREEBLVector;
diff --git a/security/nss/lib/freebl/manifest.mn b/security/nss/lib/freebl/manifest.mn
index d5538b045..787c7fbec 100644
--- a/security/nss/lib/freebl/manifest.mn
+++ b/security/nss/lib/freebl/manifest.mn
@@ -21,8 +21,7 @@
#
# Contributor(s):
# Dr Vipul Gupta <vipul.gupta@sun.com> and
-# Douglas Stebila <douglas@stebila.ca>, Sun Microsystems
-# Laboratories
+# 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
@@ -37,25 +36,48 @@
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
+
+# NOTE: any ifdefs in this file must be defined on the gmake command line
+# (if anywhere). They cannot come from Makefile or config.mk
+
CORE_DEPTH = ../../..
MODULE = nss
-ifndef FREEBL_RECURSIVE_BUILD
- LIBRARY_NAME = freebl
-else
- ifdef USE_PURE_32
- CORE_DEPTH = ../../../..
- LIBRARY_NAME = freebl_pure32
- else
- LIBRARY_NAME = freebl_hybrid
+LIBRARY_NAME = freebl
+LIBRARY_VERSION = 3
+
+ifdef FREEBL_CHILD_BUILD
+ ifdef USE_ABI32_INT32
+ LIBRARY_NAME = freebl_32int
+ endif
+ ifdef USE_ABI32_INT64
+ LIBRARY_NAME = freebl_32int64
+ endif
+ ifdef USE_ABI32_FPU
+ LIBRARY_NAME = freebl_32fpu
+ endif
+ ifdef USE_ABI64_INT
+ LIBRARY_NAME = freebl_64int
endif
+ ifdef USE_ABI64_FPU
+ LIBRARY_NAME = freebl_64fpu
+ endif
+endif
+
+# if the library name contains _, we prefix the version with _
+ifneq (,$(findstring _,$(LIBRARY_NAME)))
+ LIBRARY_VERSION := _$(LIBRARY_VERSION)
endif
-# same version as rest of freebl
-LIBRARY_VERSION = _3
+MAPFILE_SOURCE = freebl.def
+MAPFILE = $(OBJDIR)/$(LIBRARY_NAME).def
+
+SOFTOKEN_LIBRARY_VERSION = 3
-DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\"
+DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" \
+ -DSHLIB_VERSION=\"$(LIBRARY_VERSION)\" \
+ -DSOFTOKEN_SHLIB_VERSION=\"$(SOFTOKEN_LIBRARY_VERSION)\"
REQUIRES =
@@ -66,6 +88,7 @@ EXPORTS = \
$(NULL)
PRIVATE_EXPORTS = \
+ alghmac.h \
blapi.h \
secmpi.h \
secrng.h \
@@ -76,6 +99,8 @@ PRIVATE_EXPORTS = \
MPI_HDRS = mpi-config.h mpi.h mpi-priv.h mplogic.h mpprime.h logtab.h mp_gf2m.h
MPI_SRCS = mpprime.c mpmontg.c mplogic.c mpi.c mp_gf2m.c
+
+
ECL_HDRS = ecl-exp.h ecl.h ec2.h ecp.h ecl-priv.h
ifdef NSS_ENABLE_ECC
ECL_SRCS = ecl.c ecl_curve.c ecl_mult.c ecl_gf.c \
@@ -87,15 +112,20 @@ ECL_SRCS = ecl.c ecl_curve.c ecl_mult.c ecl_gf.c \
else
ECL_SRCS = $(NULL)
endif
+SHA_SRCS = sha_fast.c
+MPCPU_SRCS = mpcpucache.c
CSRCS = \
+ freeblver.c \
ldvector.c \
prng_fips1861.c \
sysrand.c \
- sha_fast.c \
+ $(SHA_SRCS) \
md2.c \
md5.c \
sha512.c \
+ alghmac.c \
+ rawhash.c \
alg2268.c \
arcfour.c \
arcfive.c \
@@ -109,13 +139,16 @@ CSRCS = \
dsa.c \
rsa.c \
shvfy.c \
+ tlsprfalg.c \
$(MPI_SRCS) \
+ $(MPCPU_SRCS) \
$(ECL_SRCS) \
$(NULL)
ALL_CSRCS := $(CSRCS)
ALL_HDRS = \
+ alghmac.h \
blapi.h \
blapit.h \
des.h \
@@ -129,6 +162,7 @@ ALL_HDRS = \
vis_proto.h \
$(NULL)
+
ifdef NSS_ENABLE_ECC
DEFINES += -DNSS_ENABLE_ECC
endif
diff --git a/security/nss/lib/freebl/md2.c b/security/nss/lib/freebl/md2.c
index 6dc990a42..ddc7a9d7e 100644
--- a/security/nss/lib/freebl/md2.c
+++ b/security/nss/lib/freebl/md2.c
@@ -289,3 +289,8 @@ MD2_Resurrect(unsigned char *space, void *arg)
memcpy(cx, space, sizeof(*cx));
return cx;
}
+
+void MD2_Clone(MD2Context *dest, MD2Context *src)
+{
+ memcpy(dest, src, sizeof *dest);
+}
diff --git a/security/nss/lib/freebl/md5.c b/security/nss/lib/freebl/md5.c
index f5b99b2f0..fbcee7f46 100644
--- a/security/nss/lib/freebl/md5.c
+++ b/security/nss/lib/freebl/md5.c
@@ -229,15 +229,12 @@ SECStatus
MD5_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
{
unsigned int len;
- MD5Context *cx = MD5_NewContext();
- if (cx == NULL) {
- PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
- return SECFailure;
- }
- MD5_Begin(cx);
- MD5_Update(cx, src, src_length);
- MD5_End(cx, dest, &len, MD5_HASH_LEN);
- MD5_DestroyContext(cx, PR_TRUE);
+ MD5Context cx;
+
+ MD5_Begin(&cx);
+ MD5_Update(&cx, src, src_length);
+ MD5_End(&cx, dest, &len, MD5_HASH_LEN);
+/* memset(&cx, 0, sizeof cx); */
return SECSuccess;
}
@@ -256,8 +253,9 @@ MD5_NewContext(void)
void
MD5_DestroyContext(MD5Context *cx, PRBool freeit)
{
+/* memset(cx, 0, sizeof *cx); */
if (freeit) {
- PORT_ZFree(cx, sizeof(MD5Context));
+ PORT_Free(cx);
}
}
@@ -266,7 +264,7 @@ MD5_Begin(MD5Context *cx)
{
cx->lsbInput = 0;
cx->msbInput = 0;
- memset(cx->inBuf, 0, sizeof(cx->inBuf));
+/* memset(cx->inBuf, 0, sizeof(cx->inBuf)); */
cx->cv[0] = CV0_1;
cx->cv[1] = CV0_2;
cx->cv[2] = CV0_3;
@@ -585,6 +583,11 @@ MD5_Resurrect(unsigned char *space, void *arg)
return cx;
}
+void MD5_Clone(MD5Context *dest, MD5Context *src)
+{
+ memcpy(dest, src, sizeof *dest);
+}
+
void
MD5_TraceState(MD5Context *cx)
{
diff --git a/security/nss/lib/freebl/mpi/Makefile b/security/nss/lib/freebl/mpi/Makefile
index c28002701..3c780f5ac 100644
--- a/security/nss/lib/freebl/mpi/Makefile
+++ b/security/nss/lib/freebl/mpi/Makefile
@@ -89,7 +89,8 @@ VERS=1.7p6
##
## This is the list of source files that need to be packed into
## the distribution file
-SRCS= mpi.c mpprime.c mplogic.c mp_gf2m.c mpmontg.c mpi-test.c primes.c tests/ \
+SRCS= mpi.c mpprime.c mplogic.c mp_gf2m.c mpmontg.c mpi-test.c primes.c \
+ mpcpucache.c tests/ \
utils/gcd.c utils/invmod.c utils/lap.c \
utils/ptab.pl utils/sieve.c utils/isprime.c\
utils/dec2hex.c utils/hex2dec.c utils/bbs_rand.c \
diff --git a/security/nss/lib/freebl/mpi/mp_comba.c b/security/nss/lib/freebl/mpi/mp_comba.c
new file mode 100644
index 000000000..afac82a74
--- /dev/null
+++ b/security/nss/lib/freebl/mpi/mp_comba.c
@@ -0,0 +1,1306 @@
+/*
+ * The below file is derived from TFM v0.03.
+ * It contains code from fp_mul_comba.c and
+ * fp_sqr_comba.c, which contained the following license.
+ *
+ * Right now, the assembly in this file limits
+ * this code to AMD 64.
+ *
+ * This file is public domain.
+ */
+
+/* TomsFastMath, a fast ISO C bignum library.
+ *
+ * This project is meant to fill in where LibTomMath
+ * falls short. That is speed ;-)
+ *
+ * This project is public domain and free for all purposes.
+ *
+ * Tom St Denis, tomstdenis@iahu.ca
+ */
+
+
+#include "mpi-priv.h"
+
+
+
+/* clamp digits */
+#define mp_clamp(a) { while ((a)->used && (a)->dp[(a)->used-1] == 0) --((a)->used); (a)->sign = (a)->used ? (a)->sign : ZPOS; }
+
+/* anything you need at the start */
+#define COMBA_START
+
+/* clear the chaining variables */
+#define COMBA_CLEAR \
+ c0 = c1 = c2 = 0;
+
+/* forward the carry to the next digit */
+#define COMBA_FORWARD \
+ do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+
+/* anything you need at the end */
+#define COMBA_FINI
+
+/* this should multiply i and j */
+#define MULADD(i, j) \
+__asm__ ( \
+ "movq %6,%%rax \n\t" \
+ "mulq %7 \n\t" \
+ "addq %%rax,%0 \n\t" \
+ "adcq %%rdx,%1 \n\t" \
+ "adcq $0,%2 \n\t" \
+ :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","%cc");
+
+
+
+
+/* sqr macros only */
+#define CLEAR_CARRY \
+ c0 = c1 = c2 = 0;
+
+#define COMBA_STORE(x) \
+ x = c0;
+
+#define COMBA_STORE2(x) \
+ x = c1;
+
+#define CARRY_FORWARD \
+ do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+
+#define COMBA_FINI
+
+#define SQRADD(i, j) \
+__asm__ ( \
+ "movq %6,%%rax \n\t" \
+ "mulq %%rax \n\t" \
+ "addq %%rax,%0 \n\t" \
+ "adcq %%rdx,%1 \n\t" \
+ "adcq $0,%2 \n\t" \
+ :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i) :"%rax","%rdx","%cc");
+
+#define SQRADD2(i, j) \
+__asm__ ( \
+ "movq %6,%%rax \n\t" \
+ "mulq %7 \n\t" \
+ "addq %%rax,%0 \n\t" \
+ "adcq %%rdx,%1 \n\t" \
+ "adcq $0,%2 \n\t" \
+ "addq %%rax,%0 \n\t" \
+ "adcq %%rdx,%1 \n\t" \
+ "adcq $0,%2 \n\t" \
+ :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","%cc");
+
+#define SQRADDSC(i, j) \
+__asm__ ( \
+ "movq %6,%%rax \n\t" \
+ "mulq %7 \n\t" \
+ "movq %%rax,%0 \n\t" \
+ "movq %%rdx,%1 \n\t" \
+ "xorq %2,%2 \n\t" \
+ :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%rax","%rdx","%cc");
+
+#define SQRADDAC(i, j) \
+__asm__ ( \
+ "movq %6,%%rax \n\t" \
+ "mulq %7 \n\t" \
+ "addq %%rax,%0 \n\t" \
+ "adcq %%rdx,%1 \n\t" \
+ "adcq $0,%2 \n\t" \
+ :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%rax","%rdx","%cc");
+
+#define SQRADDDB \
+__asm__ ( \
+ "addq %3,%0 \n\t" \
+ "adcq %4,%1 \n\t" \
+ "adcq %5,%2 \n\t" \
+ "addq %3,%0 \n\t" \
+ "adcq %4,%1 \n\t" \
+ "adcq %5,%2 \n\t" \
+ :"=r"(c0), "=r"(c1), "=r"(c2), "=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(c0), "1"(c1), "2"(c2), "3"(sc0), "4"(sc1), "5"(sc2) : "%cc");
+
+
+
+
+
+void s_mp_mul_comba_4(const mp_int *A, const mp_int *B, mp_int *C)
+{
+ mp_digit c0, c1, c2, at[8];
+
+ memcpy(at, A->dp, 4 * sizeof(mp_digit));
+ memcpy(at+4, B->dp, 4 * sizeof(mp_digit));
+ COMBA_START;
+
+ COMBA_CLEAR;
+ /* 0 */
+ MULADD(at[0], at[4]);
+ COMBA_STORE(C->dp[0]);
+ /* 1 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[5]); MULADD(at[1], at[4]);
+ COMBA_STORE(C->dp[1]);
+ /* 2 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[6]); MULADD(at[1], at[5]); MULADD(at[2], at[4]);
+ COMBA_STORE(C->dp[2]);
+ /* 3 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[7]); MULADD(at[1], at[6]); MULADD(at[2], at[5]); MULADD(at[3], at[4]);
+ COMBA_STORE(C->dp[3]);
+ /* 4 */
+ COMBA_FORWARD;
+ MULADD(at[1], at[7]); MULADD(at[2], at[6]); MULADD(at[3], at[5]);
+ COMBA_STORE(C->dp[4]);
+ /* 5 */
+ COMBA_FORWARD;
+ MULADD(at[2], at[7]); MULADD(at[3], at[6]);
+ COMBA_STORE(C->dp[5]);
+ /* 6 */
+ COMBA_FORWARD;
+ MULADD(at[3], at[7]);
+ COMBA_STORE(C->dp[6]);
+ COMBA_STORE2(C->dp[7]);
+ C->used = 8;
+ C->sign = A->sign ^ B->sign;
+ mp_clamp(C);
+ COMBA_FINI;
+}
+
+void s_mp_mul_comba_8(const mp_int *A, const mp_int *B, mp_int *C)
+{
+ mp_digit c0, c1, c2, at[16];
+
+ memcpy(at, A->dp, 8 * sizeof(mp_digit));
+ memcpy(at+8, B->dp, 8 * sizeof(mp_digit));
+ COMBA_START;
+
+ COMBA_CLEAR;
+ /* 0 */
+ MULADD(at[0], at[8]);
+ COMBA_STORE(C->dp[0]);
+ /* 1 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[9]); MULADD(at[1], at[8]);
+ COMBA_STORE(C->dp[1]);
+ /* 2 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[10]); MULADD(at[1], at[9]); MULADD(at[2], at[8]);
+ COMBA_STORE(C->dp[2]);
+ /* 3 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[11]); MULADD(at[1], at[10]); MULADD(at[2], at[9]); MULADD(at[3], at[8]);
+ COMBA_STORE(C->dp[3]);
+ /* 4 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[12]); MULADD(at[1], at[11]); MULADD(at[2], at[10]); MULADD(at[3], at[9]); MULADD(at[4], at[8]);
+ COMBA_STORE(C->dp[4]);
+ /* 5 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[13]); MULADD(at[1], at[12]); MULADD(at[2], at[11]); MULADD(at[3], at[10]); MULADD(at[4], at[9]); MULADD(at[5], at[8]);
+ COMBA_STORE(C->dp[5]);
+ /* 6 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[14]); MULADD(at[1], at[13]); MULADD(at[2], at[12]); MULADD(at[3], at[11]); MULADD(at[4], at[10]); MULADD(at[5], at[9]); MULADD(at[6], at[8]);
+ COMBA_STORE(C->dp[6]);
+ /* 7 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[15]); MULADD(at[1], at[14]); MULADD(at[2], at[13]); MULADD(at[3], at[12]); MULADD(at[4], at[11]); MULADD(at[5], at[10]); MULADD(at[6], at[9]); MULADD(at[7], at[8]);
+ COMBA_STORE(C->dp[7]);
+ /* 8 */
+ COMBA_FORWARD;
+ MULADD(at[1], at[15]); MULADD(at[2], at[14]); MULADD(at[3], at[13]); MULADD(at[4], at[12]); MULADD(at[5], at[11]); MULADD(at[6], at[10]); MULADD(at[7], at[9]);
+ COMBA_STORE(C->dp[8]);
+ /* 9 */
+ COMBA_FORWARD;
+ MULADD(at[2], at[15]); MULADD(at[3], at[14]); MULADD(at[4], at[13]); MULADD(at[5], at[12]); MULADD(at[6], at[11]); MULADD(at[7], at[10]);
+ COMBA_STORE(C->dp[9]);
+ /* 10 */
+ COMBA_FORWARD;
+ MULADD(at[3], at[15]); MULADD(at[4], at[14]); MULADD(at[5], at[13]); MULADD(at[6], at[12]); MULADD(at[7], at[11]);
+ COMBA_STORE(C->dp[10]);
+ /* 11 */
+ COMBA_FORWARD;
+ MULADD(at[4], at[15]); MULADD(at[5], at[14]); MULADD(at[6], at[13]); MULADD(at[7], at[12]);
+ COMBA_STORE(C->dp[11]);
+ /* 12 */
+ COMBA_FORWARD;
+ MULADD(at[5], at[15]); MULADD(at[6], at[14]); MULADD(at[7], at[13]);
+ COMBA_STORE(C->dp[12]);
+ /* 13 */
+ COMBA_FORWARD;
+ MULADD(at[6], at[15]); MULADD(at[7], at[14]);
+ COMBA_STORE(C->dp[13]);
+ /* 14 */
+ COMBA_FORWARD;
+ MULADD(at[7], at[15]);
+ COMBA_STORE(C->dp[14]);
+ COMBA_STORE2(C->dp[15]);
+ C->used = 16;
+ C->sign = A->sign ^ B->sign;
+ mp_clamp(C);
+ COMBA_FINI;
+}
+
+void s_mp_mul_comba_16(const mp_int *A, const mp_int *B, mp_int *C)
+{
+ mp_digit c0, c1, c2, at[32];
+
+ memcpy(at, A->dp, 16 * sizeof(mp_digit));
+ memcpy(at+16, B->dp, 16 * sizeof(mp_digit));
+ COMBA_START;
+
+ COMBA_CLEAR;
+ /* 0 */
+ MULADD(at[0], at[16]);
+ COMBA_STORE(C->dp[0]);
+ /* 1 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[17]); MULADD(at[1], at[16]);
+ COMBA_STORE(C->dp[1]);
+ /* 2 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]);
+ COMBA_STORE(C->dp[2]);
+ /* 3 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]);
+ COMBA_STORE(C->dp[3]);
+ /* 4 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]);
+ COMBA_STORE(C->dp[4]);
+ /* 5 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]);
+ COMBA_STORE(C->dp[5]);
+ /* 6 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]);
+ COMBA_STORE(C->dp[6]);
+ /* 7 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]);
+ COMBA_STORE(C->dp[7]);
+ /* 8 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[24]); MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]);
+ COMBA_STORE(C->dp[8]);
+ /* 9 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[25]); MULADD(at[1], at[24]); MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]);
+ COMBA_STORE(C->dp[9]);
+ /* 10 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[26]); MULADD(at[1], at[25]); MULADD(at[2], at[24]); MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); MULADD(at[10], at[16]);
+ COMBA_STORE(C->dp[10]);
+ /* 11 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[27]); MULADD(at[1], at[26]); MULADD(at[2], at[25]); MULADD(at[3], at[24]); MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); MULADD(at[11], at[16]);
+ COMBA_STORE(C->dp[11]);
+ /* 12 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[28]); MULADD(at[1], at[27]); MULADD(at[2], at[26]); MULADD(at[3], at[25]); MULADD(at[4], at[24]); MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); MULADD(at[11], at[17]); MULADD(at[12], at[16]);
+ COMBA_STORE(C->dp[12]);
+ /* 13 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[29]); MULADD(at[1], at[28]); MULADD(at[2], at[27]); MULADD(at[3], at[26]); MULADD(at[4], at[25]); MULADD(at[5], at[24]); MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); MULADD(at[11], at[18]); MULADD(at[12], at[17]); MULADD(at[13], at[16]);
+ COMBA_STORE(C->dp[13]);
+ /* 14 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[30]); MULADD(at[1], at[29]); MULADD(at[2], at[28]); MULADD(at[3], at[27]); MULADD(at[4], at[26]); MULADD(at[5], at[25]); MULADD(at[6], at[24]); MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); MULADD(at[11], at[19]); MULADD(at[12], at[18]); MULADD(at[13], at[17]); MULADD(at[14], at[16]);
+ COMBA_STORE(C->dp[14]);
+ /* 15 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[31]); MULADD(at[1], at[30]); MULADD(at[2], at[29]); MULADD(at[3], at[28]); MULADD(at[4], at[27]); MULADD(at[5], at[26]); MULADD(at[6], at[25]); MULADD(at[7], at[24]); MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); MULADD(at[12], at[19]); MULADD(at[13], at[18]); MULADD(at[14], at[17]); MULADD(at[15], at[16]);
+ COMBA_STORE(C->dp[15]);
+ /* 16 */
+ COMBA_FORWARD;
+ MULADD(at[1], at[31]); MULADD(at[2], at[30]); MULADD(at[3], at[29]); MULADD(at[4], at[28]); MULADD(at[5], at[27]); MULADD(at[6], at[26]); MULADD(at[7], at[25]); MULADD(at[8], at[24]); MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); MULADD(at[12], at[20]); MULADD(at[13], at[19]); MULADD(at[14], at[18]); MULADD(at[15], at[17]);
+ COMBA_STORE(C->dp[16]);
+ /* 17 */
+ COMBA_FORWARD;
+ MULADD(at[2], at[31]); MULADD(at[3], at[30]); MULADD(at[4], at[29]); MULADD(at[5], at[28]); MULADD(at[6], at[27]); MULADD(at[7], at[26]); MULADD(at[8], at[25]); MULADD(at[9], at[24]); MULADD(at[10], at[23]); MULADD(at[11], at[22]); MULADD(at[12], at[21]); MULADD(at[13], at[20]); MULADD(at[14], at[19]); MULADD(at[15], at[18]);
+ COMBA_STORE(C->dp[17]);
+ /* 18 */
+ COMBA_FORWARD;
+ MULADD(at[3], at[31]); MULADD(at[4], at[30]); MULADD(at[5], at[29]); MULADD(at[6], at[28]); MULADD(at[7], at[27]); MULADD(at[8], at[26]); MULADD(at[9], at[25]); MULADD(at[10], at[24]); MULADD(at[11], at[23]); MULADD(at[12], at[22]); MULADD(at[13], at[21]); MULADD(at[14], at[20]); MULADD(at[15], at[19]);
+ COMBA_STORE(C->dp[18]);
+ /* 19 */
+ COMBA_FORWARD;
+ MULADD(at[4], at[31]); MULADD(at[5], at[30]); MULADD(at[6], at[29]); MULADD(at[7], at[28]); MULADD(at[8], at[27]); MULADD(at[9], at[26]); MULADD(at[10], at[25]); MULADD(at[11], at[24]); MULADD(at[12], at[23]); MULADD(at[13], at[22]); MULADD(at[14], at[21]); MULADD(at[15], at[20]);
+ COMBA_STORE(C->dp[19]);
+ /* 20 */
+ COMBA_FORWARD;
+ MULADD(at[5], at[31]); MULADD(at[6], at[30]); MULADD(at[7], at[29]); MULADD(at[8], at[28]); MULADD(at[9], at[27]); MULADD(at[10], at[26]); MULADD(at[11], at[25]); MULADD(at[12], at[24]); MULADD(at[13], at[23]); MULADD(at[14], at[22]); MULADD(at[15], at[21]);
+ COMBA_STORE(C->dp[20]);
+ /* 21 */
+ COMBA_FORWARD;
+ MULADD(at[6], at[31]); MULADD(at[7], at[30]); MULADD(at[8], at[29]); MULADD(at[9], at[28]); MULADD(at[10], at[27]); MULADD(at[11], at[26]); MULADD(at[12], at[25]); MULADD(at[13], at[24]); MULADD(at[14], at[23]); MULADD(at[15], at[22]);
+ COMBA_STORE(C->dp[21]);
+ /* 22 */
+ COMBA_FORWARD;
+ MULADD(at[7], at[31]); MULADD(at[8], at[30]); MULADD(at[9], at[29]); MULADD(at[10], at[28]); MULADD(at[11], at[27]); MULADD(at[12], at[26]); MULADD(at[13], at[25]); MULADD(at[14], at[24]); MULADD(at[15], at[23]);
+ COMBA_STORE(C->dp[22]);
+ /* 23 */
+ COMBA_FORWARD;
+ MULADD(at[8], at[31]); MULADD(at[9], at[30]); MULADD(at[10], at[29]); MULADD(at[11], at[28]); MULADD(at[12], at[27]); MULADD(at[13], at[26]); MULADD(at[14], at[25]); MULADD(at[15], at[24]);
+ COMBA_STORE(C->dp[23]);
+ /* 24 */
+ COMBA_FORWARD;
+ MULADD(at[9], at[31]); MULADD(at[10], at[30]); MULADD(at[11], at[29]); MULADD(at[12], at[28]); MULADD(at[13], at[27]); MULADD(at[14], at[26]); MULADD(at[15], at[25]);
+ COMBA_STORE(C->dp[24]);
+ /* 25 */
+ COMBA_FORWARD;
+ MULADD(at[10], at[31]); MULADD(at[11], at[30]); MULADD(at[12], at[29]); MULADD(at[13], at[28]); MULADD(at[14], at[27]); MULADD(at[15], at[26]);
+ COMBA_STORE(C->dp[25]);
+ /* 26 */
+ COMBA_FORWARD;
+ MULADD(at[11], at[31]); MULADD(at[12], at[30]); MULADD(at[13], at[29]); MULADD(at[14], at[28]); MULADD(at[15], at[27]);
+ COMBA_STORE(C->dp[26]);
+ /* 27 */
+ COMBA_FORWARD;
+ MULADD(at[12], at[31]); MULADD(at[13], at[30]); MULADD(at[14], at[29]); MULADD(at[15], at[28]);
+ COMBA_STORE(C->dp[27]);
+ /* 28 */
+ COMBA_FORWARD;
+ MULADD(at[13], at[31]); MULADD(at[14], at[30]); MULADD(at[15], at[29]);
+ COMBA_STORE(C->dp[28]);
+ /* 29 */
+ COMBA_FORWARD;
+ MULADD(at[14], at[31]); MULADD(at[15], at[30]);
+ COMBA_STORE(C->dp[29]);
+ /* 30 */
+ COMBA_FORWARD;
+ MULADD(at[15], at[31]);
+ COMBA_STORE(C->dp[30]);
+ COMBA_STORE2(C->dp[31]);
+ C->used = 32;
+ C->sign = A->sign ^ B->sign;
+ mp_clamp(C);
+ COMBA_FINI;
+}
+
+void s_mp_mul_comba_32(const mp_int *A, const mp_int *B, mp_int *C)
+{
+ mp_digit c0, c1, c2, at[64];
+
+ memcpy(at, A->dp, 32 * sizeof(mp_digit));
+ memcpy(at+32, B->dp, 32 * sizeof(mp_digit));
+ COMBA_START;
+
+ COMBA_CLEAR;
+ /* 0 */
+ MULADD(at[0], at[32]);
+ COMBA_STORE(C->dp[0]);
+ /* 1 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[33]); MULADD(at[1], at[32]);
+ COMBA_STORE(C->dp[1]);
+ /* 2 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[34]); MULADD(at[1], at[33]); MULADD(at[2], at[32]);
+ COMBA_STORE(C->dp[2]);
+ /* 3 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[35]); MULADD(at[1], at[34]); MULADD(at[2], at[33]); MULADD(at[3], at[32]);
+ COMBA_STORE(C->dp[3]);
+ /* 4 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[36]); MULADD(at[1], at[35]); MULADD(at[2], at[34]); MULADD(at[3], at[33]); MULADD(at[4], at[32]);
+ COMBA_STORE(C->dp[4]);
+ /* 5 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[37]); MULADD(at[1], at[36]); MULADD(at[2], at[35]); MULADD(at[3], at[34]); MULADD(at[4], at[33]); MULADD(at[5], at[32]);
+ COMBA_STORE(C->dp[5]);
+ /* 6 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[38]); MULADD(at[1], at[37]); MULADD(at[2], at[36]); MULADD(at[3], at[35]); MULADD(at[4], at[34]); MULADD(at[5], at[33]); MULADD(at[6], at[32]);
+ COMBA_STORE(C->dp[6]);
+ /* 7 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[39]); MULADD(at[1], at[38]); MULADD(at[2], at[37]); MULADD(at[3], at[36]); MULADD(at[4], at[35]); MULADD(at[5], at[34]); MULADD(at[6], at[33]); MULADD(at[7], at[32]);
+ COMBA_STORE(C->dp[7]);
+ /* 8 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[40]); MULADD(at[1], at[39]); MULADD(at[2], at[38]); MULADD(at[3], at[37]); MULADD(at[4], at[36]); MULADD(at[5], at[35]); MULADD(at[6], at[34]); MULADD(at[7], at[33]); MULADD(at[8], at[32]);
+ COMBA_STORE(C->dp[8]);
+ /* 9 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[41]); MULADD(at[1], at[40]); MULADD(at[2], at[39]); MULADD(at[3], at[38]); MULADD(at[4], at[37]); MULADD(at[5], at[36]); MULADD(at[6], at[35]); MULADD(at[7], at[34]); MULADD(at[8], at[33]); MULADD(at[9], at[32]);
+ COMBA_STORE(C->dp[9]);
+ /* 10 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[42]); MULADD(at[1], at[41]); MULADD(at[2], at[40]); MULADD(at[3], at[39]); MULADD(at[4], at[38]); MULADD(at[5], at[37]); MULADD(at[6], at[36]); MULADD(at[7], at[35]); MULADD(at[8], at[34]); MULADD(at[9], at[33]); MULADD(at[10], at[32]);
+ COMBA_STORE(C->dp[10]);
+ /* 11 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[43]); MULADD(at[1], at[42]); MULADD(at[2], at[41]); MULADD(at[3], at[40]); MULADD(at[4], at[39]); MULADD(at[5], at[38]); MULADD(at[6], at[37]); MULADD(at[7], at[36]); MULADD(at[8], at[35]); MULADD(at[9], at[34]); MULADD(at[10], at[33]); MULADD(at[11], at[32]);
+ COMBA_STORE(C->dp[11]);
+ /* 12 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[44]); MULADD(at[1], at[43]); MULADD(at[2], at[42]); MULADD(at[3], at[41]); MULADD(at[4], at[40]); MULADD(at[5], at[39]); MULADD(at[6], at[38]); MULADD(at[7], at[37]); MULADD(at[8], at[36]); MULADD(at[9], at[35]); MULADD(at[10], at[34]); MULADD(at[11], at[33]); MULADD(at[12], at[32]);
+ COMBA_STORE(C->dp[12]);
+ /* 13 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[45]); MULADD(at[1], at[44]); MULADD(at[2], at[43]); MULADD(at[3], at[42]); MULADD(at[4], at[41]); MULADD(at[5], at[40]); MULADD(at[6], at[39]); MULADD(at[7], at[38]); MULADD(at[8], at[37]); MULADD(at[9], at[36]); MULADD(at[10], at[35]); MULADD(at[11], at[34]); MULADD(at[12], at[33]); MULADD(at[13], at[32]);
+ COMBA_STORE(C->dp[13]);
+ /* 14 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[46]); MULADD(at[1], at[45]); MULADD(at[2], at[44]); MULADD(at[3], at[43]); MULADD(at[4], at[42]); MULADD(at[5], at[41]); MULADD(at[6], at[40]); MULADD(at[7], at[39]); MULADD(at[8], at[38]); MULADD(at[9], at[37]); MULADD(at[10], at[36]); MULADD(at[11], at[35]); MULADD(at[12], at[34]); MULADD(at[13], at[33]); MULADD(at[14], at[32]);
+ COMBA_STORE(C->dp[14]);
+ /* 15 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[47]); MULADD(at[1], at[46]); MULADD(at[2], at[45]); MULADD(at[3], at[44]); MULADD(at[4], at[43]); MULADD(at[5], at[42]); MULADD(at[6], at[41]); MULADD(at[7], at[40]); MULADD(at[8], at[39]); MULADD(at[9], at[38]); MULADD(at[10], at[37]); MULADD(at[11], at[36]); MULADD(at[12], at[35]); MULADD(at[13], at[34]); MULADD(at[14], at[33]); MULADD(at[15], at[32]);
+ COMBA_STORE(C->dp[15]);
+ /* 16 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[48]); MULADD(at[1], at[47]); MULADD(at[2], at[46]); MULADD(at[3], at[45]); MULADD(at[4], at[44]); MULADD(at[5], at[43]); MULADD(at[6], at[42]); MULADD(at[7], at[41]); MULADD(at[8], at[40]); MULADD(at[9], at[39]); MULADD(at[10], at[38]); MULADD(at[11], at[37]); MULADD(at[12], at[36]); MULADD(at[13], at[35]); MULADD(at[14], at[34]); MULADD(at[15], at[33]); MULADD(at[16], at[32]);
+ COMBA_STORE(C->dp[16]);
+ /* 17 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[49]); MULADD(at[1], at[48]); MULADD(at[2], at[47]); MULADD(at[3], at[46]); MULADD(at[4], at[45]); MULADD(at[5], at[44]); MULADD(at[6], at[43]); MULADD(at[7], at[42]); MULADD(at[8], at[41]); MULADD(at[9], at[40]); MULADD(at[10], at[39]); MULADD(at[11], at[38]); MULADD(at[12], at[37]); MULADD(at[13], at[36]); MULADD(at[14], at[35]); MULADD(at[15], at[34]); MULADD(at[16], at[33]); MULADD(at[17], at[32]);
+ COMBA_STORE(C->dp[17]);
+ /* 18 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[50]); MULADD(at[1], at[49]); MULADD(at[2], at[48]); MULADD(at[3], at[47]); MULADD(at[4], at[46]); MULADD(at[5], at[45]); MULADD(at[6], at[44]); MULADD(at[7], at[43]); MULADD(at[8], at[42]); MULADD(at[9], at[41]); MULADD(at[10], at[40]); MULADD(at[11], at[39]); MULADD(at[12], at[38]); MULADD(at[13], at[37]); MULADD(at[14], at[36]); MULADD(at[15], at[35]); MULADD(at[16], at[34]); MULADD(at[17], at[33]); MULADD(at[18], at[32]);
+ COMBA_STORE(C->dp[18]);
+ /* 19 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[51]); MULADD(at[1], at[50]); MULADD(at[2], at[49]); MULADD(at[3], at[48]); MULADD(at[4], at[47]); MULADD(at[5], at[46]); MULADD(at[6], at[45]); MULADD(at[7], at[44]); MULADD(at[8], at[43]); MULADD(at[9], at[42]); MULADD(at[10], at[41]); MULADD(at[11], at[40]); MULADD(at[12], at[39]); MULADD(at[13], at[38]); MULADD(at[14], at[37]); MULADD(at[15], at[36]); MULADD(at[16], at[35]); MULADD(at[17], at[34]); MULADD(at[18], at[33]); MULADD(at[19], at[32]);
+ COMBA_STORE(C->dp[19]);
+ /* 20 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[52]); MULADD(at[1], at[51]); MULADD(at[2], at[50]); MULADD(at[3], at[49]); MULADD(at[4], at[48]); MULADD(at[5], at[47]); MULADD(at[6], at[46]); MULADD(at[7], at[45]); MULADD(at[8], at[44]); MULADD(at[9], at[43]); MULADD(at[10], at[42]); MULADD(at[11], at[41]); MULADD(at[12], at[40]); MULADD(at[13], at[39]); MULADD(at[14], at[38]); MULADD(at[15], at[37]); MULADD(at[16], at[36]); MULADD(at[17], at[35]); MULADD(at[18], at[34]); MULADD(at[19], at[33]); MULADD(at[20], at[32]);
+ COMBA_STORE(C->dp[20]);
+ /* 21 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[53]); MULADD(at[1], at[52]); MULADD(at[2], at[51]); MULADD(at[3], at[50]); MULADD(at[4], at[49]); MULADD(at[5], at[48]); MULADD(at[6], at[47]); MULADD(at[7], at[46]); MULADD(at[8], at[45]); MULADD(at[9], at[44]); MULADD(at[10], at[43]); MULADD(at[11], at[42]); MULADD(at[12], at[41]); MULADD(at[13], at[40]); MULADD(at[14], at[39]); MULADD(at[15], at[38]); MULADD(at[16], at[37]); MULADD(at[17], at[36]); MULADD(at[18], at[35]); MULADD(at[19], at[34]); MULADD(at[20], at[33]); MULADD(at[21], at[32]);
+ COMBA_STORE(C->dp[21]);
+ /* 22 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[54]); MULADD(at[1], at[53]); MULADD(at[2], at[52]); MULADD(at[3], at[51]); MULADD(at[4], at[50]); MULADD(at[5], at[49]); MULADD(at[6], at[48]); MULADD(at[7], at[47]); MULADD(at[8], at[46]); MULADD(at[9], at[45]); MULADD(at[10], at[44]); MULADD(at[11], at[43]); MULADD(at[12], at[42]); MULADD(at[13], at[41]); MULADD(at[14], at[40]); MULADD(at[15], at[39]); MULADD(at[16], at[38]); MULADD(at[17], at[37]); MULADD(at[18], at[36]); MULADD(at[19], at[35]); MULADD(at[20], at[34]); MULADD(at[21], at[33]); MULADD(at[22], at[32]);
+ COMBA_STORE(C->dp[22]);
+ /* 23 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[55]); MULADD(at[1], at[54]); MULADD(at[2], at[53]); MULADD(at[3], at[52]); MULADD(at[4], at[51]); MULADD(at[5], at[50]); MULADD(at[6], at[49]); MULADD(at[7], at[48]); MULADD(at[8], at[47]); MULADD(at[9], at[46]); MULADD(at[10], at[45]); MULADD(at[11], at[44]); MULADD(at[12], at[43]); MULADD(at[13], at[42]); MULADD(at[14], at[41]); MULADD(at[15], at[40]); MULADD(at[16], at[39]); MULADD(at[17], at[38]); MULADD(at[18], at[37]); MULADD(at[19], at[36]); MULADD(at[20], at[35]); MULADD(at[21], at[34]); MULADD(at[22], at[33]); MULADD(at[23], at[32]);
+ COMBA_STORE(C->dp[23]);
+ /* 24 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[56]); MULADD(at[1], at[55]); MULADD(at[2], at[54]); MULADD(at[3], at[53]); MULADD(at[4], at[52]); MULADD(at[5], at[51]); MULADD(at[6], at[50]); MULADD(at[7], at[49]); MULADD(at[8], at[48]); MULADD(at[9], at[47]); MULADD(at[10], at[46]); MULADD(at[11], at[45]); MULADD(at[12], at[44]); MULADD(at[13], at[43]); MULADD(at[14], at[42]); MULADD(at[15], at[41]); MULADD(at[16], at[40]); MULADD(at[17], at[39]); MULADD(at[18], at[38]); MULADD(at[19], at[37]); MULADD(at[20], at[36]); MULADD(at[21], at[35]); MULADD(at[22], at[34]); MULADD(at[23], at[33]); MULADD(at[24], at[32]);
+ COMBA_STORE(C->dp[24]);
+ /* 25 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[57]); MULADD(at[1], at[56]); MULADD(at[2], at[55]); MULADD(at[3], at[54]); MULADD(at[4], at[53]); MULADD(at[5], at[52]); MULADD(at[6], at[51]); MULADD(at[7], at[50]); MULADD(at[8], at[49]); MULADD(at[9], at[48]); MULADD(at[10], at[47]); MULADD(at[11], at[46]); MULADD(at[12], at[45]); MULADD(at[13], at[44]); MULADD(at[14], at[43]); MULADD(at[15], at[42]); MULADD(at[16], at[41]); MULADD(at[17], at[40]); MULADD(at[18], at[39]); MULADD(at[19], at[38]); MULADD(at[20], at[37]); MULADD(at[21], at[36]); MULADD(at[22], at[35]); MULADD(at[23], at[34]); MULADD(at[24], at[33]); MULADD(at[25], at[32]);
+ COMBA_STORE(C->dp[25]);
+ /* 26 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[58]); MULADD(at[1], at[57]); MULADD(at[2], at[56]); MULADD(at[3], at[55]); MULADD(at[4], at[54]); MULADD(at[5], at[53]); MULADD(at[6], at[52]); MULADD(at[7], at[51]); MULADD(at[8], at[50]); MULADD(at[9], at[49]); MULADD(at[10], at[48]); MULADD(at[11], at[47]); MULADD(at[12], at[46]); MULADD(at[13], at[45]); MULADD(at[14], at[44]); MULADD(at[15], at[43]); MULADD(at[16], at[42]); MULADD(at[17], at[41]); MULADD(at[18], at[40]); MULADD(at[19], at[39]); MULADD(at[20], at[38]); MULADD(at[21], at[37]); MULADD(at[22], at[36]); MULADD(at[23], at[35]); MULADD(at[24], at[34]); MULADD(at[25], at[33]); MULADD(at[26], at[32]);
+ COMBA_STORE(C->dp[26]);
+ /* 27 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[59]); MULADD(at[1], at[58]); MULADD(at[2], at[57]); MULADD(at[3], at[56]); MULADD(at[4], at[55]); MULADD(at[5], at[54]); MULADD(at[6], at[53]); MULADD(at[7], at[52]); MULADD(at[8], at[51]); MULADD(at[9], at[50]); MULADD(at[10], at[49]); MULADD(at[11], at[48]); MULADD(at[12], at[47]); MULADD(at[13], at[46]); MULADD(at[14], at[45]); MULADD(at[15], at[44]); MULADD(at[16], at[43]); MULADD(at[17], at[42]); MULADD(at[18], at[41]); MULADD(at[19], at[40]); MULADD(at[20], at[39]); MULADD(at[21], at[38]); MULADD(at[22], at[37]); MULADD(at[23], at[36]); MULADD(at[24], at[35]); MULADD(at[25], at[34]); MULADD(at[26], at[33]); MULADD(at[27], at[32]);
+ COMBA_STORE(C->dp[27]);
+ /* 28 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[60]); MULADD(at[1], at[59]); MULADD(at[2], at[58]); MULADD(at[3], at[57]); MULADD(at[4], at[56]); MULADD(at[5], at[55]); MULADD(at[6], at[54]); MULADD(at[7], at[53]); MULADD(at[8], at[52]); MULADD(at[9], at[51]); MULADD(at[10], at[50]); MULADD(at[11], at[49]); MULADD(at[12], at[48]); MULADD(at[13], at[47]); MULADD(at[14], at[46]); MULADD(at[15], at[45]); MULADD(at[16], at[44]); MULADD(at[17], at[43]); MULADD(at[18], at[42]); MULADD(at[19], at[41]); MULADD(at[20], at[40]); MULADD(at[21], at[39]); MULADD(at[22], at[38]); MULADD(at[23], at[37]); MULADD(at[24], at[36]); MULADD(at[25], at[35]); MULADD(at[26], at[34]); MULADD(at[27], at[33]); MULADD(at[28], at[32]);
+ COMBA_STORE(C->dp[28]);
+ /* 29 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[61]); MULADD(at[1], at[60]); MULADD(at[2], at[59]); MULADD(at[3], at[58]); MULADD(at[4], at[57]); MULADD(at[5], at[56]); MULADD(at[6], at[55]); MULADD(at[7], at[54]); MULADD(at[8], at[53]); MULADD(at[9], at[52]); MULADD(at[10], at[51]); MULADD(at[11], at[50]); MULADD(at[12], at[49]); MULADD(at[13], at[48]); MULADD(at[14], at[47]); MULADD(at[15], at[46]); MULADD(at[16], at[45]); MULADD(at[17], at[44]); MULADD(at[18], at[43]); MULADD(at[19], at[42]); MULADD(at[20], at[41]); MULADD(at[21], at[40]); MULADD(at[22], at[39]); MULADD(at[23], at[38]); MULADD(at[24], at[37]); MULADD(at[25], at[36]); MULADD(at[26], at[35]); MULADD(at[27], at[34]); MULADD(at[28], at[33]); MULADD(at[29], at[32]);
+ COMBA_STORE(C->dp[29]);
+ /* 30 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[62]); MULADD(at[1], at[61]); MULADD(at[2], at[60]); MULADD(at[3], at[59]); MULADD(at[4], at[58]); MULADD(at[5], at[57]); MULADD(at[6], at[56]); MULADD(at[7], at[55]); MULADD(at[8], at[54]); MULADD(at[9], at[53]); MULADD(at[10], at[52]); MULADD(at[11], at[51]); MULADD(at[12], at[50]); MULADD(at[13], at[49]); MULADD(at[14], at[48]); MULADD(at[15], at[47]); MULADD(at[16], at[46]); MULADD(at[17], at[45]); MULADD(at[18], at[44]); MULADD(at[19], at[43]); MULADD(at[20], at[42]); MULADD(at[21], at[41]); MULADD(at[22], at[40]); MULADD(at[23], at[39]); MULADD(at[24], at[38]); MULADD(at[25], at[37]); MULADD(at[26], at[36]); MULADD(at[27], at[35]); MULADD(at[28], at[34]); MULADD(at[29], at[33]); MULADD(at[30], at[32]);
+ COMBA_STORE(C->dp[30]);
+ /* 31 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[63]); MULADD(at[1], at[62]); MULADD(at[2], at[61]); MULADD(at[3], at[60]); MULADD(at[4], at[59]); MULADD(at[5], at[58]); MULADD(at[6], at[57]); MULADD(at[7], at[56]); MULADD(at[8], at[55]); MULADD(at[9], at[54]); MULADD(at[10], at[53]); MULADD(at[11], at[52]); MULADD(at[12], at[51]); MULADD(at[13], at[50]); MULADD(at[14], at[49]); MULADD(at[15], at[48]); MULADD(at[16], at[47]); MULADD(at[17], at[46]); MULADD(at[18], at[45]); MULADD(at[19], at[44]); MULADD(at[20], at[43]); MULADD(at[21], at[42]); MULADD(at[22], at[41]); MULADD(at[23], at[40]); MULADD(at[24], at[39]); MULADD(at[25], at[38]); MULADD(at[26], at[37]); MULADD(at[27], at[36]); MULADD(at[28], at[35]); MULADD(at[29], at[34]); MULADD(at[30], at[33]); MULADD(at[31], at[32]);
+ COMBA_STORE(C->dp[31]);
+ /* 32 */
+ COMBA_FORWARD;
+ MULADD(at[1], at[63]); MULADD(at[2], at[62]); MULADD(at[3], at[61]); MULADD(at[4], at[60]); MULADD(at[5], at[59]); MULADD(at[6], at[58]); MULADD(at[7], at[57]); MULADD(at[8], at[56]); MULADD(at[9], at[55]); MULADD(at[10], at[54]); MULADD(at[11], at[53]); MULADD(at[12], at[52]); MULADD(at[13], at[51]); MULADD(at[14], at[50]); MULADD(at[15], at[49]); MULADD(at[16], at[48]); MULADD(at[17], at[47]); MULADD(at[18], at[46]); MULADD(at[19], at[45]); MULADD(at[20], at[44]); MULADD(at[21], at[43]); MULADD(at[22], at[42]); MULADD(at[23], at[41]); MULADD(at[24], at[40]); MULADD(at[25], at[39]); MULADD(at[26], at[38]); MULADD(at[27], at[37]); MULADD(at[28], at[36]); MULADD(at[29], at[35]); MULADD(at[30], at[34]); MULADD(at[31], at[33]);
+ COMBA_STORE(C->dp[32]);
+ /* 33 */
+ COMBA_FORWARD;
+ MULADD(at[2], at[63]); MULADD(at[3], at[62]); MULADD(at[4], at[61]); MULADD(at[5], at[60]); MULADD(at[6], at[59]); MULADD(at[7], at[58]); MULADD(at[8], at[57]); MULADD(at[9], at[56]); MULADD(at[10], at[55]); MULADD(at[11], at[54]); MULADD(at[12], at[53]); MULADD(at[13], at[52]); MULADD(at[14], at[51]); MULADD(at[15], at[50]); MULADD(at[16], at[49]); MULADD(at[17], at[48]); MULADD(at[18], at[47]); MULADD(at[19], at[46]); MULADD(at[20], at[45]); MULADD(at[21], at[44]); MULADD(at[22], at[43]); MULADD(at[23], at[42]); MULADD(at[24], at[41]); MULADD(at[25], at[40]); MULADD(at[26], at[39]); MULADD(at[27], at[38]); MULADD(at[28], at[37]); MULADD(at[29], at[36]); MULADD(at[30], at[35]); MULADD(at[31], at[34]);
+ COMBA_STORE(C->dp[33]);
+ /* 34 */
+ COMBA_FORWARD;
+ MULADD(at[3], at[63]); MULADD(at[4], at[62]); MULADD(at[5], at[61]); MULADD(at[6], at[60]); MULADD(at[7], at[59]); MULADD(at[8], at[58]); MULADD(at[9], at[57]); MULADD(at[10], at[56]); MULADD(at[11], at[55]); MULADD(at[12], at[54]); MULADD(at[13], at[53]); MULADD(at[14], at[52]); MULADD(at[15], at[51]); MULADD(at[16], at[50]); MULADD(at[17], at[49]); MULADD(at[18], at[48]); MULADD(at[19], at[47]); MULADD(at[20], at[46]); MULADD(at[21], at[45]); MULADD(at[22], at[44]); MULADD(at[23], at[43]); MULADD(at[24], at[42]); MULADD(at[25], at[41]); MULADD(at[26], at[40]); MULADD(at[27], at[39]); MULADD(at[28], at[38]); MULADD(at[29], at[37]); MULADD(at[30], at[36]); MULADD(at[31], at[35]);
+ COMBA_STORE(C->dp[34]);
+ /* 35 */
+ COMBA_FORWARD;
+ MULADD(at[4], at[63]); MULADD(at[5], at[62]); MULADD(at[6], at[61]); MULADD(at[7], at[60]); MULADD(at[8], at[59]); MULADD(at[9], at[58]); MULADD(at[10], at[57]); MULADD(at[11], at[56]); MULADD(at[12], at[55]); MULADD(at[13], at[54]); MULADD(at[14], at[53]); MULADD(at[15], at[52]); MULADD(at[16], at[51]); MULADD(at[17], at[50]); MULADD(at[18], at[49]); MULADD(at[19], at[48]); MULADD(at[20], at[47]); MULADD(at[21], at[46]); MULADD(at[22], at[45]); MULADD(at[23], at[44]); MULADD(at[24], at[43]); MULADD(at[25], at[42]); MULADD(at[26], at[41]); MULADD(at[27], at[40]); MULADD(at[28], at[39]); MULADD(at[29], at[38]); MULADD(at[30], at[37]); MULADD(at[31], at[36]);
+ COMBA_STORE(C->dp[35]);
+ /* 36 */
+ COMBA_FORWARD;
+ MULADD(at[5], at[63]); MULADD(at[6], at[62]); MULADD(at[7], at[61]); MULADD(at[8], at[60]); MULADD(at[9], at[59]); MULADD(at[10], at[58]); MULADD(at[11], at[57]); MULADD(at[12], at[56]); MULADD(at[13], at[55]); MULADD(at[14], at[54]); MULADD(at[15], at[53]); MULADD(at[16], at[52]); MULADD(at[17], at[51]); MULADD(at[18], at[50]); MULADD(at[19], at[49]); MULADD(at[20], at[48]); MULADD(at[21], at[47]); MULADD(at[22], at[46]); MULADD(at[23], at[45]); MULADD(at[24], at[44]); MULADD(at[25], at[43]); MULADD(at[26], at[42]); MULADD(at[27], at[41]); MULADD(at[28], at[40]); MULADD(at[29], at[39]); MULADD(at[30], at[38]); MULADD(at[31], at[37]);
+ COMBA_STORE(C->dp[36]);
+ /* 37 */
+ COMBA_FORWARD;
+ MULADD(at[6], at[63]); MULADD(at[7], at[62]); MULADD(at[8], at[61]); MULADD(at[9], at[60]); MULADD(at[10], at[59]); MULADD(at[11], at[58]); MULADD(at[12], at[57]); MULADD(at[13], at[56]); MULADD(at[14], at[55]); MULADD(at[15], at[54]); MULADD(at[16], at[53]); MULADD(at[17], at[52]); MULADD(at[18], at[51]); MULADD(at[19], at[50]); MULADD(at[20], at[49]); MULADD(at[21], at[48]); MULADD(at[22], at[47]); MULADD(at[23], at[46]); MULADD(at[24], at[45]); MULADD(at[25], at[44]); MULADD(at[26], at[43]); MULADD(at[27], at[42]); MULADD(at[28], at[41]); MULADD(at[29], at[40]); MULADD(at[30], at[39]); MULADD(at[31], at[38]);
+ COMBA_STORE(C->dp[37]);
+ /* 38 */
+ COMBA_FORWARD;
+ MULADD(at[7], at[63]); MULADD(at[8], at[62]); MULADD(at[9], at[61]); MULADD(at[10], at[60]); MULADD(at[11], at[59]); MULADD(at[12], at[58]); MULADD(at[13], at[57]); MULADD(at[14], at[56]); MULADD(at[15], at[55]); MULADD(at[16], at[54]); MULADD(at[17], at[53]); MULADD(at[18], at[52]); MULADD(at[19], at[51]); MULADD(at[20], at[50]); MULADD(at[21], at[49]); MULADD(at[22], at[48]); MULADD(at[23], at[47]); MULADD(at[24], at[46]); MULADD(at[25], at[45]); MULADD(at[26], at[44]); MULADD(at[27], at[43]); MULADD(at[28], at[42]); MULADD(at[29], at[41]); MULADD(at[30], at[40]); MULADD(at[31], at[39]);
+ COMBA_STORE(C->dp[38]);
+ /* 39 */
+ COMBA_FORWARD;
+ MULADD(at[8], at[63]); MULADD(at[9], at[62]); MULADD(at[10], at[61]); MULADD(at[11], at[60]); MULADD(at[12], at[59]); MULADD(at[13], at[58]); MULADD(at[14], at[57]); MULADD(at[15], at[56]); MULADD(at[16], at[55]); MULADD(at[17], at[54]); MULADD(at[18], at[53]); MULADD(at[19], at[52]); MULADD(at[20], at[51]); MULADD(at[21], at[50]); MULADD(at[22], at[49]); MULADD(at[23], at[48]); MULADD(at[24], at[47]); MULADD(at[25], at[46]); MULADD(at[26], at[45]); MULADD(at[27], at[44]); MULADD(at[28], at[43]); MULADD(at[29], at[42]); MULADD(at[30], at[41]); MULADD(at[31], at[40]);
+ COMBA_STORE(C->dp[39]);
+ /* 40 */
+ COMBA_FORWARD;
+ MULADD(at[9], at[63]); MULADD(at[10], at[62]); MULADD(at[11], at[61]); MULADD(at[12], at[60]); MULADD(at[13], at[59]); MULADD(at[14], at[58]); MULADD(at[15], at[57]); MULADD(at[16], at[56]); MULADD(at[17], at[55]); MULADD(at[18], at[54]); MULADD(at[19], at[53]); MULADD(at[20], at[52]); MULADD(at[21], at[51]); MULADD(at[22], at[50]); MULADD(at[23], at[49]); MULADD(at[24], at[48]); MULADD(at[25], at[47]); MULADD(at[26], at[46]); MULADD(at[27], at[45]); MULADD(at[28], at[44]); MULADD(at[29], at[43]); MULADD(at[30], at[42]); MULADD(at[31], at[41]);
+ COMBA_STORE(C->dp[40]);
+ /* 41 */
+ COMBA_FORWARD;
+ MULADD(at[10], at[63]); MULADD(at[11], at[62]); MULADD(at[12], at[61]); MULADD(at[13], at[60]); MULADD(at[14], at[59]); MULADD(at[15], at[58]); MULADD(at[16], at[57]); MULADD(at[17], at[56]); MULADD(at[18], at[55]); MULADD(at[19], at[54]); MULADD(at[20], at[53]); MULADD(at[21], at[52]); MULADD(at[22], at[51]); MULADD(at[23], at[50]); MULADD(at[24], at[49]); MULADD(at[25], at[48]); MULADD(at[26], at[47]); MULADD(at[27], at[46]); MULADD(at[28], at[45]); MULADD(at[29], at[44]); MULADD(at[30], at[43]); MULADD(at[31], at[42]);
+ COMBA_STORE(C->dp[41]);
+ /* 42 */
+ COMBA_FORWARD;
+ MULADD(at[11], at[63]); MULADD(at[12], at[62]); MULADD(at[13], at[61]); MULADD(at[14], at[60]); MULADD(at[15], at[59]); MULADD(at[16], at[58]); MULADD(at[17], at[57]); MULADD(at[18], at[56]); MULADD(at[19], at[55]); MULADD(at[20], at[54]); MULADD(at[21], at[53]); MULADD(at[22], at[52]); MULADD(at[23], at[51]); MULADD(at[24], at[50]); MULADD(at[25], at[49]); MULADD(at[26], at[48]); MULADD(at[27], at[47]); MULADD(at[28], at[46]); MULADD(at[29], at[45]); MULADD(at[30], at[44]); MULADD(at[31], at[43]);
+ COMBA_STORE(C->dp[42]);
+ /* 43 */
+ COMBA_FORWARD;
+ MULADD(at[12], at[63]); MULADD(at[13], at[62]); MULADD(at[14], at[61]); MULADD(at[15], at[60]); MULADD(at[16], at[59]); MULADD(at[17], at[58]); MULADD(at[18], at[57]); MULADD(at[19], at[56]); MULADD(at[20], at[55]); MULADD(at[21], at[54]); MULADD(at[22], at[53]); MULADD(at[23], at[52]); MULADD(at[24], at[51]); MULADD(at[25], at[50]); MULADD(at[26], at[49]); MULADD(at[27], at[48]); MULADD(at[28], at[47]); MULADD(at[29], at[46]); MULADD(at[30], at[45]); MULADD(at[31], at[44]);
+ COMBA_STORE(C->dp[43]);
+ /* 44 */
+ COMBA_FORWARD;
+ MULADD(at[13], at[63]); MULADD(at[14], at[62]); MULADD(at[15], at[61]); MULADD(at[16], at[60]); MULADD(at[17], at[59]); MULADD(at[18], at[58]); MULADD(at[19], at[57]); MULADD(at[20], at[56]); MULADD(at[21], at[55]); MULADD(at[22], at[54]); MULADD(at[23], at[53]); MULADD(at[24], at[52]); MULADD(at[25], at[51]); MULADD(at[26], at[50]); MULADD(at[27], at[49]); MULADD(at[28], at[48]); MULADD(at[29], at[47]); MULADD(at[30], at[46]); MULADD(at[31], at[45]);
+ COMBA_STORE(C->dp[44]);
+ /* 45 */
+ COMBA_FORWARD;
+ MULADD(at[14], at[63]); MULADD(at[15], at[62]); MULADD(at[16], at[61]); MULADD(at[17], at[60]); MULADD(at[18], at[59]); MULADD(at[19], at[58]); MULADD(at[20], at[57]); MULADD(at[21], at[56]); MULADD(at[22], at[55]); MULADD(at[23], at[54]); MULADD(at[24], at[53]); MULADD(at[25], at[52]); MULADD(at[26], at[51]); MULADD(at[27], at[50]); MULADD(at[28], at[49]); MULADD(at[29], at[48]); MULADD(at[30], at[47]); MULADD(at[31], at[46]);
+ COMBA_STORE(C->dp[45]);
+ /* 46 */
+ COMBA_FORWARD;
+ MULADD(at[15], at[63]); MULADD(at[16], at[62]); MULADD(at[17], at[61]); MULADD(at[18], at[60]); MULADD(at[19], at[59]); MULADD(at[20], at[58]); MULADD(at[21], at[57]); MULADD(at[22], at[56]); MULADD(at[23], at[55]); MULADD(at[24], at[54]); MULADD(at[25], at[53]); MULADD(at[26], at[52]); MULADD(at[27], at[51]); MULADD(at[28], at[50]); MULADD(at[29], at[49]); MULADD(at[30], at[48]); MULADD(at[31], at[47]);
+ COMBA_STORE(C->dp[46]);
+ /* 47 */
+ COMBA_FORWARD;
+ MULADD(at[16], at[63]); MULADD(at[17], at[62]); MULADD(at[18], at[61]); MULADD(at[19], at[60]); MULADD(at[20], at[59]); MULADD(at[21], at[58]); MULADD(at[22], at[57]); MULADD(at[23], at[56]); MULADD(at[24], at[55]); MULADD(at[25], at[54]); MULADD(at[26], at[53]); MULADD(at[27], at[52]); MULADD(at[28], at[51]); MULADD(at[29], at[50]); MULADD(at[30], at[49]); MULADD(at[31], at[48]);
+ COMBA_STORE(C->dp[47]);
+ /* 48 */
+ COMBA_FORWARD;
+ MULADD(at[17], at[63]); MULADD(at[18], at[62]); MULADD(at[19], at[61]); MULADD(at[20], at[60]); MULADD(at[21], at[59]); MULADD(at[22], at[58]); MULADD(at[23], at[57]); MULADD(at[24], at[56]); MULADD(at[25], at[55]); MULADD(at[26], at[54]); MULADD(at[27], at[53]); MULADD(at[28], at[52]); MULADD(at[29], at[51]); MULADD(at[30], at[50]); MULADD(at[31], at[49]);
+ COMBA_STORE(C->dp[48]);
+ /* 49 */
+ COMBA_FORWARD;
+ MULADD(at[18], at[63]); MULADD(at[19], at[62]); MULADD(at[20], at[61]); MULADD(at[21], at[60]); MULADD(at[22], at[59]); MULADD(at[23], at[58]); MULADD(at[24], at[57]); MULADD(at[25], at[56]); MULADD(at[26], at[55]); MULADD(at[27], at[54]); MULADD(at[28], at[53]); MULADD(at[29], at[52]); MULADD(at[30], at[51]); MULADD(at[31], at[50]);
+ COMBA_STORE(C->dp[49]);
+ /* 50 */
+ COMBA_FORWARD;
+ MULADD(at[19], at[63]); MULADD(at[20], at[62]); MULADD(at[21], at[61]); MULADD(at[22], at[60]); MULADD(at[23], at[59]); MULADD(at[24], at[58]); MULADD(at[25], at[57]); MULADD(at[26], at[56]); MULADD(at[27], at[55]); MULADD(at[28], at[54]); MULADD(at[29], at[53]); MULADD(at[30], at[52]); MULADD(at[31], at[51]);
+ COMBA_STORE(C->dp[50]);
+ /* 51 */
+ COMBA_FORWARD;
+ MULADD(at[20], at[63]); MULADD(at[21], at[62]); MULADD(at[22], at[61]); MULADD(at[23], at[60]); MULADD(at[24], at[59]); MULADD(at[25], at[58]); MULADD(at[26], at[57]); MULADD(at[27], at[56]); MULADD(at[28], at[55]); MULADD(at[29], at[54]); MULADD(at[30], at[53]); MULADD(at[31], at[52]);
+ COMBA_STORE(C->dp[51]);
+ /* 52 */
+ COMBA_FORWARD;
+ MULADD(at[21], at[63]); MULADD(at[22], at[62]); MULADD(at[23], at[61]); MULADD(at[24], at[60]); MULADD(at[25], at[59]); MULADD(at[26], at[58]); MULADD(at[27], at[57]); MULADD(at[28], at[56]); MULADD(at[29], at[55]); MULADD(at[30], at[54]); MULADD(at[31], at[53]);
+ COMBA_STORE(C->dp[52]);
+ /* 53 */
+ COMBA_FORWARD;
+ MULADD(at[22], at[63]); MULADD(at[23], at[62]); MULADD(at[24], at[61]); MULADD(at[25], at[60]); MULADD(at[26], at[59]); MULADD(at[27], at[58]); MULADD(at[28], at[57]); MULADD(at[29], at[56]); MULADD(at[30], at[55]); MULADD(at[31], at[54]);
+ COMBA_STORE(C->dp[53]);
+ /* 54 */
+ COMBA_FORWARD;
+ MULADD(at[23], at[63]); MULADD(at[24], at[62]); MULADD(at[25], at[61]); MULADD(at[26], at[60]); MULADD(at[27], at[59]); MULADD(at[28], at[58]); MULADD(at[29], at[57]); MULADD(at[30], at[56]); MULADD(at[31], at[55]);
+ COMBA_STORE(C->dp[54]);
+ /* 55 */
+ COMBA_FORWARD;
+ MULADD(at[24], at[63]); MULADD(at[25], at[62]); MULADD(at[26], at[61]); MULADD(at[27], at[60]); MULADD(at[28], at[59]); MULADD(at[29], at[58]); MULADD(at[30], at[57]); MULADD(at[31], at[56]);
+ COMBA_STORE(C->dp[55]);
+ /* 56 */
+ COMBA_FORWARD;
+ MULADD(at[25], at[63]); MULADD(at[26], at[62]); MULADD(at[27], at[61]); MULADD(at[28], at[60]); MULADD(at[29], at[59]); MULADD(at[30], at[58]); MULADD(at[31], at[57]);
+ COMBA_STORE(C->dp[56]);
+ /* 57 */
+ COMBA_FORWARD;
+ MULADD(at[26], at[63]); MULADD(at[27], at[62]); MULADD(at[28], at[61]); MULADD(at[29], at[60]); MULADD(at[30], at[59]); MULADD(at[31], at[58]);
+ COMBA_STORE(C->dp[57]);
+ /* 58 */
+ COMBA_FORWARD;
+ MULADD(at[27], at[63]); MULADD(at[28], at[62]); MULADD(at[29], at[61]); MULADD(at[30], at[60]); MULADD(at[31], at[59]);
+ COMBA_STORE(C->dp[58]);
+ /* 59 */
+ COMBA_FORWARD;
+ MULADD(at[28], at[63]); MULADD(at[29], at[62]); MULADD(at[30], at[61]); MULADD(at[31], at[60]);
+ COMBA_STORE(C->dp[59]);
+ /* 60 */
+ COMBA_FORWARD;
+ MULADD(at[29], at[63]); MULADD(at[30], at[62]); MULADD(at[31], at[61]);
+ COMBA_STORE(C->dp[60]);
+ /* 61 */
+ COMBA_FORWARD;
+ MULADD(at[30], at[63]); MULADD(at[31], at[62]);
+ COMBA_STORE(C->dp[61]);
+ /* 62 */
+ COMBA_FORWARD;
+ MULADD(at[31], at[63]);
+ COMBA_STORE(C->dp[62]);
+ COMBA_STORE2(C->dp[63]);
+ C->used = 64;
+ C->sign = A->sign ^ B->sign;
+ mp_clamp(C);
+ COMBA_FINI;
+}
+
+
+
+void s_mp_sqr_comba_4(const mp_int *A, mp_int *B)
+{
+ mp_digit *a, b[8], c0, c1, c2, sc0, sc1, sc2;
+ /* get rid of some compiler warnings */
+ sc0 = 0; sc1 = 0; sc2 = 0;
+
+ a = A->dp;
+ COMBA_START;
+
+ /* clear carries */
+ CLEAR_CARRY;
+
+ /* output 0 */
+ SQRADD(a[0],a[0]);
+ COMBA_STORE(b[0]);
+
+ /* output 1 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[1]);
+ COMBA_STORE(b[1]);
+
+ /* output 2 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
+ COMBA_STORE(b[2]);
+
+ /* output 3 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
+ COMBA_STORE(b[3]);
+
+ /* output 4 */
+ CARRY_FORWARD;
+ SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
+ COMBA_STORE(b[4]);
+
+ /* output 5 */
+ CARRY_FORWARD;
+ SQRADD2(a[2], a[3]);
+ COMBA_STORE(b[5]);
+
+ /* output 6 */
+ CARRY_FORWARD;
+ SQRADD(a[3], a[3]);
+ COMBA_STORE(b[6]);
+ COMBA_STORE2(b[7]);
+ COMBA_FINI;
+
+ B->used = 8;
+ B->sign = ZPOS;
+ memcpy(B->dp, b, 8 * sizeof(mp_digit));
+ mp_clamp(B);
+}
+
+void s_mp_sqr_comba_8(const mp_int *A, mp_int *B)
+{
+ mp_digit *a, b[16], c0, c1, c2, sc0, sc1, sc2;
+ /* get rid of some compiler warnings */
+ sc0 = 0; sc1 = 0; sc2 = 0;
+
+ a = A->dp;
+ COMBA_START;
+
+ /* clear carries */
+ CLEAR_CARRY;
+
+ /* output 0 */
+ SQRADD(a[0],a[0]);
+ COMBA_STORE(b[0]);
+
+ /* output 1 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[1]);
+ COMBA_STORE(b[1]);
+
+ /* output 2 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
+ COMBA_STORE(b[2]);
+
+ /* output 3 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
+ COMBA_STORE(b[3]);
+
+ /* output 4 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
+ COMBA_STORE(b[4]);
+
+ /* output 5 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
+ COMBA_STORE(b[5]);
+
+ /* output 6 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
+ COMBA_STORE(b[6]);
+
+ /* output 7 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
+ COMBA_STORE(b[7]);
+
+ /* output 8 */
+ CARRY_FORWARD;
+ SQRADDSC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]);
+ COMBA_STORE(b[8]);
+
+ /* output 9 */
+ CARRY_FORWARD;
+ SQRADDSC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB;
+ COMBA_STORE(b[9]);
+
+ /* output 10 */
+ CARRY_FORWARD;
+ SQRADD2(a[3], a[7]); SQRADD2(a[4], a[6]); SQRADD(a[5], a[5]);
+ COMBA_STORE(b[10]);
+
+ /* output 11 */
+ CARRY_FORWARD;
+ SQRADD2(a[4], a[7]); SQRADD2(a[5], a[6]);
+ COMBA_STORE(b[11]);
+
+ /* output 12 */
+ CARRY_FORWARD;
+ SQRADD2(a[5], a[7]); SQRADD(a[6], a[6]);
+ COMBA_STORE(b[12]);
+
+ /* output 13 */
+ CARRY_FORWARD;
+ SQRADD2(a[6], a[7]);
+ COMBA_STORE(b[13]);
+
+ /* output 14 */
+ CARRY_FORWARD;
+ SQRADD(a[7], a[7]);
+ COMBA_STORE(b[14]);
+ COMBA_STORE2(b[15]);
+ COMBA_FINI;
+
+ B->used = 16;
+ B->sign = ZPOS;
+ memcpy(B->dp, b, 16 * sizeof(mp_digit));
+ mp_clamp(B);
+}
+
+void s_mp_sqr_comba_16(const mp_int *A, mp_int *B)
+{
+ mp_digit *a, b[32], c0, c1, c2, sc0, sc1, sc2;
+ /* get rid of some compiler warnings */
+ sc0 = 0; sc1 = 0; sc2 = 0;
+
+ a = A->dp;
+ COMBA_START;
+
+ /* clear carries */
+ CLEAR_CARRY;
+
+ /* output 0 */
+ SQRADD(a[0],a[0]);
+ COMBA_STORE(b[0]);
+
+ /* output 1 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[1]);
+ COMBA_STORE(b[1]);
+
+ /* output 2 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
+ COMBA_STORE(b[2]);
+
+ /* output 3 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
+ COMBA_STORE(b[3]);
+
+ /* output 4 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
+ COMBA_STORE(b[4]);
+
+ /* output 5 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
+ COMBA_STORE(b[5]);
+
+ /* output 6 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
+ COMBA_STORE(b[6]);
+
+ /* output 7 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
+ COMBA_STORE(b[7]);
+
+ /* output 8 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]);
+ COMBA_STORE(b[8]);
+
+ /* output 9 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB;
+ COMBA_STORE(b[9]);
+
+ /* output 10 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]);
+ COMBA_STORE(b[10]);
+
+ /* output 11 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB;
+ COMBA_STORE(b[11]);
+
+ /* output 12 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]);
+ COMBA_STORE(b[12]);
+
+ /* output 13 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB;
+ COMBA_STORE(b[13]);
+
+ /* output 14 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]);
+ COMBA_STORE(b[14]);
+
+ /* output 15 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB;
+ COMBA_STORE(b[15]);
+
+ /* output 16 */
+ CARRY_FORWARD;
+ SQRADDSC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]);
+ COMBA_STORE(b[16]);
+
+ /* output 17 */
+ CARRY_FORWARD;
+ SQRADDSC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB;
+ COMBA_STORE(b[17]);
+
+ /* output 18 */
+ CARRY_FORWARD;
+ SQRADDSC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]);
+ COMBA_STORE(b[18]);
+
+ /* output 19 */
+ CARRY_FORWARD;
+ SQRADDSC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB;
+ COMBA_STORE(b[19]);
+
+ /* output 20 */
+ CARRY_FORWARD;
+ SQRADDSC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]);
+ COMBA_STORE(b[20]);
+
+ /* output 21 */
+ CARRY_FORWARD;
+ SQRADDSC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB;
+ COMBA_STORE(b[21]);
+
+ /* output 22 */
+ CARRY_FORWARD;
+ SQRADDSC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]);
+ COMBA_STORE(b[22]);
+
+ /* output 23 */
+ CARRY_FORWARD;
+ SQRADDSC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB;
+ COMBA_STORE(b[23]);
+
+ /* output 24 */
+ CARRY_FORWARD;
+ SQRADDSC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]);
+ COMBA_STORE(b[24]);
+
+ /* output 25 */
+ CARRY_FORWARD;
+ SQRADDSC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB;
+ COMBA_STORE(b[25]);
+
+ /* output 26 */
+ CARRY_FORWARD;
+ SQRADD2(a[11], a[15]); SQRADD2(a[12], a[14]); SQRADD(a[13], a[13]);
+ COMBA_STORE(b[26]);
+
+ /* output 27 */
+ CARRY_FORWARD;
+ SQRADD2(a[12], a[15]); SQRADD2(a[13], a[14]);
+ COMBA_STORE(b[27]);
+
+ /* output 28 */
+ CARRY_FORWARD;
+ SQRADD2(a[13], a[15]); SQRADD(a[14], a[14]);
+ COMBA_STORE(b[28]);
+
+ /* output 29 */
+ CARRY_FORWARD;
+ SQRADD2(a[14], a[15]);
+ COMBA_STORE(b[29]);
+
+ /* output 30 */
+ CARRY_FORWARD;
+ SQRADD(a[15], a[15]);
+ COMBA_STORE(b[30]);
+ COMBA_STORE2(b[31]);
+ COMBA_FINI;
+
+ B->used = 32;
+ B->sign = ZPOS;
+ memcpy(B->dp, b, 32 * sizeof(mp_digit));
+ mp_clamp(B);
+}
+
+
+void s_mp_sqr_comba_32(const mp_int *A, mp_int *B)
+{
+ mp_digit *a, b[64], c0, c1, c2, sc0, sc1, sc2;
+ /* get rid of some compiler warnings */
+ sc0 = 0; sc1 = 0; sc2 = 0;
+
+ a = A->dp;
+ COMBA_START;
+
+ /* clear carries */
+ CLEAR_CARRY;
+
+ /* output 0 */
+ SQRADD(a[0],a[0]);
+ COMBA_STORE(b[0]);
+
+ /* output 1 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[1]);
+ COMBA_STORE(b[1]);
+
+ /* output 2 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
+ COMBA_STORE(b[2]);
+
+ /* output 3 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
+ COMBA_STORE(b[3]);
+
+ /* output 4 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
+ COMBA_STORE(b[4]);
+
+ /* output 5 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
+ COMBA_STORE(b[5]);
+
+ /* output 6 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
+ COMBA_STORE(b[6]);
+
+ /* output 7 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
+ COMBA_STORE(b[7]);
+
+ /* output 8 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]);
+ COMBA_STORE(b[8]);
+
+ /* output 9 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB;
+ COMBA_STORE(b[9]);
+
+ /* output 10 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]);
+ COMBA_STORE(b[10]);
+
+ /* output 11 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB;
+ COMBA_STORE(b[11]);
+
+ /* output 12 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]);
+ COMBA_STORE(b[12]);
+
+ /* output 13 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB;
+ COMBA_STORE(b[13]);
+
+ /* output 14 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]);
+ COMBA_STORE(b[14]);
+
+ /* output 15 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB;
+ COMBA_STORE(b[15]);
+
+ /* output 16 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]);
+ COMBA_STORE(b[16]);
+
+ /* output 17 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[17]); SQRADDAC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB;
+ COMBA_STORE(b[17]);
+
+ /* output 18 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[18]); SQRADDAC(a[1], a[17]); SQRADDAC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]);
+ COMBA_STORE(b[18]);
+
+ /* output 19 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[19]); SQRADDAC(a[1], a[18]); SQRADDAC(a[2], a[17]); SQRADDAC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB;
+ COMBA_STORE(b[19]);
+
+ /* output 20 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[20]); SQRADDAC(a[1], a[19]); SQRADDAC(a[2], a[18]); SQRADDAC(a[3], a[17]); SQRADDAC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]);
+ COMBA_STORE(b[20]);
+
+ /* output 21 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[21]); SQRADDAC(a[1], a[20]); SQRADDAC(a[2], a[19]); SQRADDAC(a[3], a[18]); SQRADDAC(a[4], a[17]); SQRADDAC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB;
+ COMBA_STORE(b[21]);
+
+ /* output 22 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[22]); SQRADDAC(a[1], a[21]); SQRADDAC(a[2], a[20]); SQRADDAC(a[3], a[19]); SQRADDAC(a[4], a[18]); SQRADDAC(a[5], a[17]); SQRADDAC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]);
+ COMBA_STORE(b[22]);
+
+ /* output 23 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[23]); SQRADDAC(a[1], a[22]); SQRADDAC(a[2], a[21]); SQRADDAC(a[3], a[20]); SQRADDAC(a[4], a[19]); SQRADDAC(a[5], a[18]); SQRADDAC(a[6], a[17]); SQRADDAC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB;
+ COMBA_STORE(b[23]);
+
+ /* output 24 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[24]); SQRADDAC(a[1], a[23]); SQRADDAC(a[2], a[22]); SQRADDAC(a[3], a[21]); SQRADDAC(a[4], a[20]); SQRADDAC(a[5], a[19]); SQRADDAC(a[6], a[18]); SQRADDAC(a[7], a[17]); SQRADDAC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]);
+ COMBA_STORE(b[24]);
+
+ /* output 25 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[25]); SQRADDAC(a[1], a[24]); SQRADDAC(a[2], a[23]); SQRADDAC(a[3], a[22]); SQRADDAC(a[4], a[21]); SQRADDAC(a[5], a[20]); SQRADDAC(a[6], a[19]); SQRADDAC(a[7], a[18]); SQRADDAC(a[8], a[17]); SQRADDAC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB;
+ COMBA_STORE(b[25]);
+
+ /* output 26 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[26]); SQRADDAC(a[1], a[25]); SQRADDAC(a[2], a[24]); SQRADDAC(a[3], a[23]); SQRADDAC(a[4], a[22]); SQRADDAC(a[5], a[21]); SQRADDAC(a[6], a[20]); SQRADDAC(a[7], a[19]); SQRADDAC(a[8], a[18]); SQRADDAC(a[9], a[17]); SQRADDAC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]);
+ COMBA_STORE(b[26]);
+
+ /* output 27 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[27]); SQRADDAC(a[1], a[26]); SQRADDAC(a[2], a[25]); SQRADDAC(a[3], a[24]); SQRADDAC(a[4], a[23]); SQRADDAC(a[5], a[22]); SQRADDAC(a[6], a[21]); SQRADDAC(a[7], a[20]); SQRADDAC(a[8], a[19]); SQRADDAC(a[9], a[18]); SQRADDAC(a[10], a[17]); SQRADDAC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB;
+ COMBA_STORE(b[27]);
+
+ /* output 28 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[28]); SQRADDAC(a[1], a[27]); SQRADDAC(a[2], a[26]); SQRADDAC(a[3], a[25]); SQRADDAC(a[4], a[24]); SQRADDAC(a[5], a[23]); SQRADDAC(a[6], a[22]); SQRADDAC(a[7], a[21]); SQRADDAC(a[8], a[20]); SQRADDAC(a[9], a[19]); SQRADDAC(a[10], a[18]); SQRADDAC(a[11], a[17]); SQRADDAC(a[12], a[16]); SQRADDAC(a[13], a[15]); SQRADDDB; SQRADD(a[14], a[14]);
+ COMBA_STORE(b[28]);
+
+ /* output 29 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[29]); SQRADDAC(a[1], a[28]); SQRADDAC(a[2], a[27]); SQRADDAC(a[3], a[26]); SQRADDAC(a[4], a[25]); SQRADDAC(a[5], a[24]); SQRADDAC(a[6], a[23]); SQRADDAC(a[7], a[22]); SQRADDAC(a[8], a[21]); SQRADDAC(a[9], a[20]); SQRADDAC(a[10], a[19]); SQRADDAC(a[11], a[18]); SQRADDAC(a[12], a[17]); SQRADDAC(a[13], a[16]); SQRADDAC(a[14], a[15]); SQRADDDB;
+ COMBA_STORE(b[29]);
+
+ /* output 30 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[30]); SQRADDAC(a[1], a[29]); SQRADDAC(a[2], a[28]); SQRADDAC(a[3], a[27]); SQRADDAC(a[4], a[26]); SQRADDAC(a[5], a[25]); SQRADDAC(a[6], a[24]); SQRADDAC(a[7], a[23]); SQRADDAC(a[8], a[22]); SQRADDAC(a[9], a[21]); SQRADDAC(a[10], a[20]); SQRADDAC(a[11], a[19]); SQRADDAC(a[12], a[18]); SQRADDAC(a[13], a[17]); SQRADDAC(a[14], a[16]); SQRADDDB; SQRADD(a[15], a[15]);
+ COMBA_STORE(b[30]);
+
+ /* output 31 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[31]); SQRADDAC(a[1], a[30]); SQRADDAC(a[2], a[29]); SQRADDAC(a[3], a[28]); SQRADDAC(a[4], a[27]); SQRADDAC(a[5], a[26]); SQRADDAC(a[6], a[25]); SQRADDAC(a[7], a[24]); SQRADDAC(a[8], a[23]); SQRADDAC(a[9], a[22]); SQRADDAC(a[10], a[21]); SQRADDAC(a[11], a[20]); SQRADDAC(a[12], a[19]); SQRADDAC(a[13], a[18]); SQRADDAC(a[14], a[17]); SQRADDAC(a[15], a[16]); SQRADDDB;
+ COMBA_STORE(b[31]);
+
+ /* output 32 */
+ CARRY_FORWARD;
+ SQRADDSC(a[1], a[31]); SQRADDAC(a[2], a[30]); SQRADDAC(a[3], a[29]); SQRADDAC(a[4], a[28]); SQRADDAC(a[5], a[27]); SQRADDAC(a[6], a[26]); SQRADDAC(a[7], a[25]); SQRADDAC(a[8], a[24]); SQRADDAC(a[9], a[23]); SQRADDAC(a[10], a[22]); SQRADDAC(a[11], a[21]); SQRADDAC(a[12], a[20]); SQRADDAC(a[13], a[19]); SQRADDAC(a[14], a[18]); SQRADDAC(a[15], a[17]); SQRADDDB; SQRADD(a[16], a[16]);
+ COMBA_STORE(b[32]);
+
+ /* output 33 */
+ CARRY_FORWARD;
+ SQRADDSC(a[2], a[31]); SQRADDAC(a[3], a[30]); SQRADDAC(a[4], a[29]); SQRADDAC(a[5], a[28]); SQRADDAC(a[6], a[27]); SQRADDAC(a[7], a[26]); SQRADDAC(a[8], a[25]); SQRADDAC(a[9], a[24]); SQRADDAC(a[10], a[23]); SQRADDAC(a[11], a[22]); SQRADDAC(a[12], a[21]); SQRADDAC(a[13], a[20]); SQRADDAC(a[14], a[19]); SQRADDAC(a[15], a[18]); SQRADDAC(a[16], a[17]); SQRADDDB;
+ COMBA_STORE(b[33]);
+
+ /* output 34 */
+ CARRY_FORWARD;
+ SQRADDSC(a[3], a[31]); SQRADDAC(a[4], a[30]); SQRADDAC(a[5], a[29]); SQRADDAC(a[6], a[28]); SQRADDAC(a[7], a[27]); SQRADDAC(a[8], a[26]); SQRADDAC(a[9], a[25]); SQRADDAC(a[10], a[24]); SQRADDAC(a[11], a[23]); SQRADDAC(a[12], a[22]); SQRADDAC(a[13], a[21]); SQRADDAC(a[14], a[20]); SQRADDAC(a[15], a[19]); SQRADDAC(a[16], a[18]); SQRADDDB; SQRADD(a[17], a[17]);
+ COMBA_STORE(b[34]);
+
+ /* output 35 */
+ CARRY_FORWARD;
+ SQRADDSC(a[4], a[31]); SQRADDAC(a[5], a[30]); SQRADDAC(a[6], a[29]); SQRADDAC(a[7], a[28]); SQRADDAC(a[8], a[27]); SQRADDAC(a[9], a[26]); SQRADDAC(a[10], a[25]); SQRADDAC(a[11], a[24]); SQRADDAC(a[12], a[23]); SQRADDAC(a[13], a[22]); SQRADDAC(a[14], a[21]); SQRADDAC(a[15], a[20]); SQRADDAC(a[16], a[19]); SQRADDAC(a[17], a[18]); SQRADDDB;
+ COMBA_STORE(b[35]);
+
+ /* output 36 */
+ CARRY_FORWARD;
+ SQRADDSC(a[5], a[31]); SQRADDAC(a[6], a[30]); SQRADDAC(a[7], a[29]); SQRADDAC(a[8], a[28]); SQRADDAC(a[9], a[27]); SQRADDAC(a[10], a[26]); SQRADDAC(a[11], a[25]); SQRADDAC(a[12], a[24]); SQRADDAC(a[13], a[23]); SQRADDAC(a[14], a[22]); SQRADDAC(a[15], a[21]); SQRADDAC(a[16], a[20]); SQRADDAC(a[17], a[19]); SQRADDDB; SQRADD(a[18], a[18]);
+ COMBA_STORE(b[36]);
+
+ /* output 37 */
+ CARRY_FORWARD;
+ SQRADDSC(a[6], a[31]); SQRADDAC(a[7], a[30]); SQRADDAC(a[8], a[29]); SQRADDAC(a[9], a[28]); SQRADDAC(a[10], a[27]); SQRADDAC(a[11], a[26]); SQRADDAC(a[12], a[25]); SQRADDAC(a[13], a[24]); SQRADDAC(a[14], a[23]); SQRADDAC(a[15], a[22]); SQRADDAC(a[16], a[21]); SQRADDAC(a[17], a[20]); SQRADDAC(a[18], a[19]); SQRADDDB;
+ COMBA_STORE(b[37]);
+
+ /* output 38 */
+ CARRY_FORWARD;
+ SQRADDSC(a[7], a[31]); SQRADDAC(a[8], a[30]); SQRADDAC(a[9], a[29]); SQRADDAC(a[10], a[28]); SQRADDAC(a[11], a[27]); SQRADDAC(a[12], a[26]); SQRADDAC(a[13], a[25]); SQRADDAC(a[14], a[24]); SQRADDAC(a[15], a[23]); SQRADDAC(a[16], a[22]); SQRADDAC(a[17], a[21]); SQRADDAC(a[18], a[20]); SQRADDDB; SQRADD(a[19], a[19]);
+ COMBA_STORE(b[38]);
+
+ /* output 39 */
+ CARRY_FORWARD;
+ SQRADDSC(a[8], a[31]); SQRADDAC(a[9], a[30]); SQRADDAC(a[10], a[29]); SQRADDAC(a[11], a[28]); SQRADDAC(a[12], a[27]); SQRADDAC(a[13], a[26]); SQRADDAC(a[14], a[25]); SQRADDAC(a[15], a[24]); SQRADDAC(a[16], a[23]); SQRADDAC(a[17], a[22]); SQRADDAC(a[18], a[21]); SQRADDAC(a[19], a[20]); SQRADDDB;
+ COMBA_STORE(b[39]);
+
+ /* output 40 */
+ CARRY_FORWARD;
+ SQRADDSC(a[9], a[31]); SQRADDAC(a[10], a[30]); SQRADDAC(a[11], a[29]); SQRADDAC(a[12], a[28]); SQRADDAC(a[13], a[27]); SQRADDAC(a[14], a[26]); SQRADDAC(a[15], a[25]); SQRADDAC(a[16], a[24]); SQRADDAC(a[17], a[23]); SQRADDAC(a[18], a[22]); SQRADDAC(a[19], a[21]); SQRADDDB; SQRADD(a[20], a[20]);
+ COMBA_STORE(b[40]);
+
+ /* output 41 */
+ CARRY_FORWARD;
+ SQRADDSC(a[10], a[31]); SQRADDAC(a[11], a[30]); SQRADDAC(a[12], a[29]); SQRADDAC(a[13], a[28]); SQRADDAC(a[14], a[27]); SQRADDAC(a[15], a[26]); SQRADDAC(a[16], a[25]); SQRADDAC(a[17], a[24]); SQRADDAC(a[18], a[23]); SQRADDAC(a[19], a[22]); SQRADDAC(a[20], a[21]); SQRADDDB;
+ COMBA_STORE(b[41]);
+
+ /* output 42 */
+ CARRY_FORWARD;
+ SQRADDSC(a[11], a[31]); SQRADDAC(a[12], a[30]); SQRADDAC(a[13], a[29]); SQRADDAC(a[14], a[28]); SQRADDAC(a[15], a[27]); SQRADDAC(a[16], a[26]); SQRADDAC(a[17], a[25]); SQRADDAC(a[18], a[24]); SQRADDAC(a[19], a[23]); SQRADDAC(a[20], a[22]); SQRADDDB; SQRADD(a[21], a[21]);
+ COMBA_STORE(b[42]);
+
+ /* output 43 */
+ CARRY_FORWARD;
+ SQRADDSC(a[12], a[31]); SQRADDAC(a[13], a[30]); SQRADDAC(a[14], a[29]); SQRADDAC(a[15], a[28]); SQRADDAC(a[16], a[27]); SQRADDAC(a[17], a[26]); SQRADDAC(a[18], a[25]); SQRADDAC(a[19], a[24]); SQRADDAC(a[20], a[23]); SQRADDAC(a[21], a[22]); SQRADDDB;
+ COMBA_STORE(b[43]);
+
+ /* output 44 */
+ CARRY_FORWARD;
+ SQRADDSC(a[13], a[31]); SQRADDAC(a[14], a[30]); SQRADDAC(a[15], a[29]); SQRADDAC(a[16], a[28]); SQRADDAC(a[17], a[27]); SQRADDAC(a[18], a[26]); SQRADDAC(a[19], a[25]); SQRADDAC(a[20], a[24]); SQRADDAC(a[21], a[23]); SQRADDDB; SQRADD(a[22], a[22]);
+ COMBA_STORE(b[44]);
+
+ /* output 45 */
+ CARRY_FORWARD;
+ SQRADDSC(a[14], a[31]); SQRADDAC(a[15], a[30]); SQRADDAC(a[16], a[29]); SQRADDAC(a[17], a[28]); SQRADDAC(a[18], a[27]); SQRADDAC(a[19], a[26]); SQRADDAC(a[20], a[25]); SQRADDAC(a[21], a[24]); SQRADDAC(a[22], a[23]); SQRADDDB;
+ COMBA_STORE(b[45]);
+
+ /* output 46 */
+ CARRY_FORWARD;
+ SQRADDSC(a[15], a[31]); SQRADDAC(a[16], a[30]); SQRADDAC(a[17], a[29]); SQRADDAC(a[18], a[28]); SQRADDAC(a[19], a[27]); SQRADDAC(a[20], a[26]); SQRADDAC(a[21], a[25]); SQRADDAC(a[22], a[24]); SQRADDDB; SQRADD(a[23], a[23]);
+ COMBA_STORE(b[46]);
+
+ /* output 47 */
+ CARRY_FORWARD;
+ SQRADDSC(a[16], a[31]); SQRADDAC(a[17], a[30]); SQRADDAC(a[18], a[29]); SQRADDAC(a[19], a[28]); SQRADDAC(a[20], a[27]); SQRADDAC(a[21], a[26]); SQRADDAC(a[22], a[25]); SQRADDAC(a[23], a[24]); SQRADDDB;
+ COMBA_STORE(b[47]);
+
+ /* output 48 */
+ CARRY_FORWARD;
+ SQRADDSC(a[17], a[31]); SQRADDAC(a[18], a[30]); SQRADDAC(a[19], a[29]); SQRADDAC(a[20], a[28]); SQRADDAC(a[21], a[27]); SQRADDAC(a[22], a[26]); SQRADDAC(a[23], a[25]); SQRADDDB; SQRADD(a[24], a[24]);
+ COMBA_STORE(b[48]);
+
+ /* output 49 */
+ CARRY_FORWARD;
+ SQRADDSC(a[18], a[31]); SQRADDAC(a[19], a[30]); SQRADDAC(a[20], a[29]); SQRADDAC(a[21], a[28]); SQRADDAC(a[22], a[27]); SQRADDAC(a[23], a[26]); SQRADDAC(a[24], a[25]); SQRADDDB;
+ COMBA_STORE(b[49]);
+
+ /* output 50 */
+ CARRY_FORWARD;
+ SQRADDSC(a[19], a[31]); SQRADDAC(a[20], a[30]); SQRADDAC(a[21], a[29]); SQRADDAC(a[22], a[28]); SQRADDAC(a[23], a[27]); SQRADDAC(a[24], a[26]); SQRADDDB; SQRADD(a[25], a[25]);
+ COMBA_STORE(b[50]);
+
+ /* output 51 */
+ CARRY_FORWARD;
+ SQRADDSC(a[20], a[31]); SQRADDAC(a[21], a[30]); SQRADDAC(a[22], a[29]); SQRADDAC(a[23], a[28]); SQRADDAC(a[24], a[27]); SQRADDAC(a[25], a[26]); SQRADDDB;
+ COMBA_STORE(b[51]);
+
+ /* output 52 */
+ CARRY_FORWARD;
+ SQRADDSC(a[21], a[31]); SQRADDAC(a[22], a[30]); SQRADDAC(a[23], a[29]); SQRADDAC(a[24], a[28]); SQRADDAC(a[25], a[27]); SQRADDDB; SQRADD(a[26], a[26]);
+ COMBA_STORE(b[52]);
+
+ /* output 53 */
+ CARRY_FORWARD;
+ SQRADDSC(a[22], a[31]); SQRADDAC(a[23], a[30]); SQRADDAC(a[24], a[29]); SQRADDAC(a[25], a[28]); SQRADDAC(a[26], a[27]); SQRADDDB;
+ COMBA_STORE(b[53]);
+
+ /* output 54 */
+ CARRY_FORWARD;
+ SQRADDSC(a[23], a[31]); SQRADDAC(a[24], a[30]); SQRADDAC(a[25], a[29]); SQRADDAC(a[26], a[28]); SQRADDDB; SQRADD(a[27], a[27]);
+ COMBA_STORE(b[54]);
+
+ /* output 55 */
+ CARRY_FORWARD;
+ SQRADDSC(a[24], a[31]); SQRADDAC(a[25], a[30]); SQRADDAC(a[26], a[29]); SQRADDAC(a[27], a[28]); SQRADDDB;
+ COMBA_STORE(b[55]);
+
+ /* output 56 */
+ CARRY_FORWARD;
+ SQRADDSC(a[25], a[31]); SQRADDAC(a[26], a[30]); SQRADDAC(a[27], a[29]); SQRADDDB; SQRADD(a[28], a[28]);
+ COMBA_STORE(b[56]);
+
+ /* output 57 */
+ CARRY_FORWARD;
+ SQRADDSC(a[26], a[31]); SQRADDAC(a[27], a[30]); SQRADDAC(a[28], a[29]); SQRADDDB;
+ COMBA_STORE(b[57]);
+
+ /* output 58 */
+ CARRY_FORWARD;
+ SQRADD2(a[27], a[31]); SQRADD2(a[28], a[30]); SQRADD(a[29], a[29]);
+ COMBA_STORE(b[58]);
+
+ /* output 59 */
+ CARRY_FORWARD;
+ SQRADD2(a[28], a[31]); SQRADD2(a[29], a[30]);
+ COMBA_STORE(b[59]);
+
+ /* output 60 */
+ CARRY_FORWARD;
+ SQRADD2(a[29], a[31]); SQRADD(a[30], a[30]);
+ COMBA_STORE(b[60]);
+
+ /* output 61 */
+ CARRY_FORWARD;
+ SQRADD2(a[30], a[31]);
+ COMBA_STORE(b[61]);
+
+ /* output 62 */
+ CARRY_FORWARD;
+ SQRADD(a[31], a[31]);
+ COMBA_STORE(b[62]);
+ COMBA_STORE2(b[63]);
+ COMBA_FINI;
+
+ B->used = 64;
+ B->sign = ZPOS;
+ memcpy(B->dp, b, 64 * sizeof(mp_digit));
+ mp_clamp(B);
+}
diff --git a/security/nss/lib/freebl/mpi/mp_comba_amd64_sun.s b/security/nss/lib/freebl/mpi/mp_comba_amd64_sun.s
new file mode 100644
index 000000000..a5181df33
--- /dev/null
+++ b/security/nss/lib/freebl/mpi/mp_comba_amd64_sun.s
@@ -0,0 +1,16097 @@
+//* TomsFastMath, a fast ISO C bignum library.
+/ *
+/ * This project is meant to fill in where LibTomMath
+/ * falls short. That is speed ;-)
+/ *
+/ * This project is public domain and free for all purposes.
+/ *
+/ * Tom St Denis, tomstdenis@iahu.ca
+/ */
+
+//*
+/ * The source file from which this assembly was derived
+/ * comes from TFM v0.03, which has the above license.
+/ * This source was compiled with an unnamed compiler at
+/ * the highest optimization level. Afterwards, the
+/ * trailing .section was removed because it causes errors
+/ * in the Studio 10 compiler on AMD 64.
+/ */
+
+ .file "mp_comba.c"
+ .text
+ .align 16
+.globl s_mp_mul_comba_4
+ .type s_mp_mul_comba_4, @function
+s_mp_mul_comba_4:
+.LFB2:
+ pushq %r12
+.LCFI0:
+ pushq %rbp
+.LCFI1:
+ pushq %rbx
+.LCFI2:
+ movq 16(%rdi), %r9
+ movq %rdx, %rbx
+ movq 16(%rsi), %rdx
+ movq (%r9), %rax
+ movq %rax, -64(%rsp)
+ movq 8(%r9), %r8
+ movq %r8, -56(%rsp)
+ movq 16(%r9), %rbp
+ movq %rbp, -48(%rsp)
+ movq 24(%r9), %r12
+ movq %r12, -40(%rsp)
+ movq (%rdx), %rcx
+ movq %rcx, -32(%rsp)
+ movq 8(%rdx), %r10
+ movq %r10, -24(%rsp)
+ movq 16(%rdx), %r11
+ xorl %r10d, %r10d
+ movq %r10, %r8
+ movq %r10, %r9
+ movq %r10, %rbp
+ movq %r11, -16(%rsp)
+ movq 16(%rbx), %r11
+ movq 24(%rdx), %rax
+ movq %rax, -8(%rsp)
+/APP
+ movq -64(%rsp),%rax
+ mulq -32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rbp
+
+/NO_APP
+ movq %r8, (%r11)
+ movq %rbp, %r8
+ movq %r10, %rbp
+/APP
+ movq -64(%rsp),%rax
+ mulq -24(%rsp)
+ addq %rax,%r9
+ adcq %rdx,%r8
+ adcq $0,%rbp
+
+/NO_APP
+ movq %rbp, %r12
+/APP
+ movq -56(%rsp),%rax
+ mulq -32(%rsp)
+ addq %rax,%r9
+ adcq %rdx,%r8
+ adcq $0,%r12
+
+/NO_APP
+ movq %r9, 8(%r11)
+ movq %r12, %r9
+ movq %r10, %r12
+/APP
+ movq -64(%rsp),%rax
+ mulq -16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%r12
+
+/NO_APP
+ movq %r12, %rcx
+/APP
+ movq -56(%rsp),%rax
+ mulq -24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -48(%rsp),%rax
+ mulq -32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 16(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -64(%rsp),%rax
+ mulq -8(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -56(%rsp),%rax
+ mulq -16(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -48(%rsp),%rax
+ mulq -24(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq -40(%rsp),%rax
+ mulq -32(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 24(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -56(%rsp),%rax
+ mulq -8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -48(%rsp),%rax
+ mulq -16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -40(%rsp),%rax
+ mulq -24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 32(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -48(%rsp),%rax
+ mulq -8(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r8, %r12
+ movq %r9, %rbp
+/APP
+ movq -40(%rsp),%rax
+ mulq -16(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 40(%r11)
+ movq %rbp, %r8
+ movq %r12, %rcx
+/APP
+ movq -40(%rsp),%rax
+ mulq -8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rcx
+ adcq $0,%r10
+
+/NO_APP
+ movq %r8, 48(%r11)
+ movl (%rsi), %esi
+ xorl (%rdi), %esi
+ testq %rcx, %rcx
+ movq %rcx, 56(%r11)
+ movl $8, 8(%rbx)
+ jne .L9
+ .align 16
+.L18:
+ movl 8(%rbx), %edx
+ leal -1(%rdx), %edi
+ testl %edi, %edi
+ movl %edi, 8(%rbx)
+ je .L9
+ leal -2(%rdx), %r10d
+ cmpq $0, (%r11,%r10,8)
+ je .L18
+.L9:
+ movl 8(%rbx), %edx
+ xorl %r11d, %r11d
+ testl %edx, %edx
+ cmovne %esi, %r11d
+ movl %r11d, (%rbx)
+ popq %rbx
+ popq %rbp
+ popq %r12
+ ret
+.LFE2:
+ .size s_mp_mul_comba_4, .-s_mp_mul_comba_4
+ .align 16
+.globl s_mp_mul_comba_8
+ .type s_mp_mul_comba_8, @function
+s_mp_mul_comba_8:
+.LFB3:
+ pushq %r12
+.LCFI3:
+ pushq %rbp
+.LCFI4:
+ pushq %rbx
+.LCFI5:
+ movq %rdx, %rbx
+ subq $8, %rsp
+.LCFI6:
+ movq 16(%rdi), %rdx
+ movq (%rdx), %r8
+ movq %r8, -120(%rsp)
+ movq 8(%rdx), %rbp
+ movq %rbp, -112(%rsp)
+ movq 16(%rdx), %r9
+ movq %r9, -104(%rsp)
+ movq 24(%rdx), %r12
+ movq %r12, -96(%rsp)
+ movq 32(%rdx), %rcx
+ movq %rcx, -88(%rsp)
+ movq 40(%rdx), %r10
+ movq %r10, -80(%rsp)
+ movq 48(%rdx), %r11
+ movq %r11, -72(%rsp)
+ movq 56(%rdx), %rax
+ movq 16(%rsi), %rdx
+ movq %rax, -64(%rsp)
+ movq (%rdx), %r8
+ movq %r8, -56(%rsp)
+ movq 8(%rdx), %rbp
+ movq %rbp, -48(%rsp)
+ movq 16(%rdx), %r9
+ movq %r9, -40(%rsp)
+ movq 24(%rdx), %r12
+ movq %r12, -32(%rsp)
+ movq 32(%rdx), %rcx
+ movq %rcx, -24(%rsp)
+ movq 40(%rdx), %r10
+ movq %r10, -16(%rsp)
+ movq 48(%rdx), %r11
+ xorl %r10d, %r10d
+ movq %r10, %r8
+ movq %r10, %r9
+ movq %r10, %rbp
+ movq %r11, -8(%rsp)
+ movq 16(%rbx), %r11
+ movq 56(%rdx), %rax
+ movq %rax, (%rsp)
+/APP
+ movq -120(%rsp),%rax
+ mulq -56(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rbp
+
+/NO_APP
+ movq %r8, (%r11)
+ movq %rbp, %r8
+ movq %r10, %rbp
+/APP
+ movq -120(%rsp),%rax
+ mulq -48(%rsp)
+ addq %rax,%r9
+ adcq %rdx,%r8
+ adcq $0,%rbp
+
+/NO_APP
+ movq %rbp, %r12
+/APP
+ movq -112(%rsp),%rax
+ mulq -56(%rsp)
+ addq %rax,%r9
+ adcq %rdx,%r8
+ adcq $0,%r12
+
+/NO_APP
+ movq %r9, 8(%r11)
+ movq %r12, %r9
+ movq %r10, %r12
+/APP
+ movq -120(%rsp),%rax
+ mulq -40(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%r12
+
+/NO_APP
+ movq %r12, %rcx
+/APP
+ movq -112(%rsp),%rax
+ mulq -48(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -104(%rsp),%rax
+ mulq -56(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 16(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -120(%rsp),%rax
+ mulq -32(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -112(%rsp),%rax
+ mulq -40(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -104(%rsp),%rax
+ mulq -48(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq -96(%rsp),%rax
+ mulq -56(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 24(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -120(%rsp),%rax
+ mulq -24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -112(%rsp),%rax
+ mulq -32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -104(%rsp),%rax
+ mulq -40(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -96(%rsp),%rax
+ mulq -48(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -88(%rsp),%rax
+ mulq -56(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 32(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -120(%rsp),%rax
+ mulq -16(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -112(%rsp),%rax
+ mulq -24(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -104(%rsp),%rax
+ mulq -32(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -96(%rsp),%rax
+ mulq -40(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -88(%rsp),%rax
+ mulq -48(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq -80(%rsp),%rax
+ mulq -56(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 40(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -120(%rsp),%rax
+ mulq -8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -112(%rsp),%rax
+ mulq -16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -104(%rsp),%rax
+ mulq -24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -96(%rsp),%rax
+ mulq -32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -88(%rsp),%rax
+ mulq -40(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -80(%rsp),%rax
+ mulq -48(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -72(%rsp),%rax
+ mulq -56(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 48(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -120(%rsp),%rax
+ mulq (%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -112(%rsp),%rax
+ mulq -8(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -104(%rsp),%rax
+ mulq -16(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -96(%rsp),%rax
+ mulq -24(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -88(%rsp),%rax
+ mulq -32(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -80(%rsp),%rax
+ mulq -40(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -72(%rsp),%rax
+ mulq -48(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq -64(%rsp),%rax
+ mulq -56(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 56(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -112(%rsp),%rax
+ mulq (%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -104(%rsp),%rax
+ mulq -8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -96(%rsp),%rax
+ mulq -16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -88(%rsp),%rax
+ mulq -24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -80(%rsp),%rax
+ mulq -32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -72(%rsp),%rax
+ mulq -40(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -64(%rsp),%rax
+ mulq -48(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 64(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -104(%rsp),%rax
+ mulq (%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -96(%rsp),%rax
+ mulq -8(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -88(%rsp),%rax
+ mulq -16(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -80(%rsp),%rax
+ mulq -24(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -72(%rsp),%rax
+ mulq -32(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq -64(%rsp),%rax
+ mulq -40(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 72(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -96(%rsp),%rax
+ mulq (%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -88(%rsp),%rax
+ mulq -8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -80(%rsp),%rax
+ mulq -16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -72(%rsp),%rax
+ mulq -24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -64(%rsp),%rax
+ mulq -32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 80(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -88(%rsp),%rax
+ mulq (%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -80(%rsp),%rax
+ mulq -8(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -72(%rsp),%rax
+ mulq -16(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq -64(%rsp),%rax
+ mulq -24(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 88(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -80(%rsp),%rax
+ mulq (%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -72(%rsp),%rax
+ mulq -8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -64(%rsp),%rax
+ mulq -16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 96(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -72(%rsp),%rax
+ mulq (%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r8, %r12
+ movq %r9, %rbp
+/APP
+ movq -64(%rsp),%rax
+ mulq -8(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 104(%r11)
+ movq %rbp, %r8
+ movq %r12, %rcx
+/APP
+ movq -64(%rsp),%rax
+ mulq (%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rcx
+ adcq $0,%r10
+
+/NO_APP
+ movq %r8, 112(%r11)
+ movl (%rsi), %esi
+ xorl (%rdi), %esi
+ testq %rcx, %rcx
+ movq %rcx, 120(%r11)
+ movl $16, 8(%rbx)
+ jne .L35
+ .align 16
+.L43:
+ movl 8(%rbx), %edx
+ leal -1(%rdx), %edi
+ testl %edi, %edi
+ movl %edi, 8(%rbx)
+ je .L35
+ leal -2(%rdx), %eax
+ cmpq $0, (%r11,%rax,8)
+ je .L43
+.L35:
+ movl 8(%rbx), %r11d
+ xorl %edx, %edx
+ testl %r11d, %r11d
+ cmovne %esi, %edx
+ movl %edx, (%rbx)
+ addq $8, %rsp
+ popq %rbx
+ popq %rbp
+ popq %r12
+ ret
+.LFE3:
+ .size s_mp_mul_comba_8, .-s_mp_mul_comba_8
+ .align 16
+.globl s_mp_mul_comba_16
+ .type s_mp_mul_comba_16, @function
+s_mp_mul_comba_16:
+.LFB4:
+ pushq %r12
+.LCFI7:
+ pushq %rbp
+.LCFI8:
+ pushq %rbx
+.LCFI9:
+ movq %rdx, %rbx
+ subq $136, %rsp
+.LCFI10:
+ movq 16(%rdi), %rax
+ movq (%rax), %r8
+ movq %r8, -120(%rsp)
+ movq 8(%rax), %rbp
+ movq %rbp, -112(%rsp)
+ movq 16(%rax), %r9
+ movq %r9, -104(%rsp)
+ movq 24(%rax), %r12
+ movq %r12, -96(%rsp)
+ movq 32(%rax), %rcx
+ movq %rcx, -88(%rsp)
+ movq 40(%rax), %r10
+ movq %r10, -80(%rsp)
+ movq 48(%rax), %rdx
+ movq %rdx, -72(%rsp)
+ movq 56(%rax), %r11
+ movq %r11, -64(%rsp)
+ movq 64(%rax), %r8
+ movq %r8, -56(%rsp)
+ movq 72(%rax), %rbp
+ movq %rbp, -48(%rsp)
+ movq 80(%rax), %r9
+ movq %r9, -40(%rsp)
+ movq 88(%rax), %r12
+ movq %r12, -32(%rsp)
+ movq 96(%rax), %rcx
+ movq %rcx, -24(%rsp)
+ movq 104(%rax), %r10
+ movq %r10, -16(%rsp)
+ movq 112(%rax), %rdx
+ movq %rdx, -8(%rsp)
+ movq 120(%rax), %r11
+ movq %r11, (%rsp)
+ movq 16(%rsi), %r11
+ movq (%r11), %r8
+ movq %r8, 8(%rsp)
+ movq 8(%r11), %rbp
+ movq %rbp, 16(%rsp)
+ movq 16(%r11), %r9
+ movq %r9, 24(%rsp)
+ movq 24(%r11), %r12
+ movq %r12, 32(%rsp)
+ movq 32(%r11), %rcx
+ movq %rcx, 40(%rsp)
+ movq 40(%r11), %r10
+ movq %r10, 48(%rsp)
+ movq 48(%r11), %rdx
+ movq %rdx, 56(%rsp)
+ movq 56(%r11), %rax
+ movq %rax, 64(%rsp)
+ movq 64(%r11), %r8
+ movq %r8, 72(%rsp)
+ movq 72(%r11), %rbp
+ movq %rbp, 80(%rsp)
+ movq 80(%r11), %r9
+ movq %r9, 88(%rsp)
+ movq 88(%r11), %r12
+ movq %r12, 96(%rsp)
+ movq 96(%r11), %rcx
+ movq %rcx, 104(%rsp)
+ movq 104(%r11), %r10
+ movq %r10, 112(%rsp)
+ movq 112(%r11), %rdx
+ xorl %r10d, %r10d
+ movq %r10, %r8
+ movq %r10, %r9
+ movq %r10, %rbp
+ movq %rdx, 120(%rsp)
+ movq 120(%r11), %rax
+ movq %rax, 128(%rsp)
+ movq 16(%rbx), %r11
+/APP
+ movq -120(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rbp
+
+/NO_APP
+ movq %r8, (%r11)
+ movq %rbp, %r8
+ movq %r10, %rbp
+/APP
+ movq -120(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%r9
+ adcq %rdx,%r8
+ adcq $0,%rbp
+
+/NO_APP
+ movq %rbp, %r12
+/APP
+ movq -112(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%r9
+ adcq %rdx,%r8
+ adcq $0,%r12
+
+/NO_APP
+ movq %r9, 8(%r11)
+ movq %r12, %r9
+ movq %r10, %r12
+/APP
+ movq -120(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%r12
+
+/NO_APP
+ movq %r12, %rcx
+/APP
+ movq -112(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -104(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 16(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -120(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -112(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -104(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq -96(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 24(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -120(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -112(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -104(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -96(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -88(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 32(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -120(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -112(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -104(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -96(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -88(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq -80(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 40(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -120(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -112(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -104(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -96(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -88(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -80(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -72(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 48(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -120(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -112(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -104(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -96(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -88(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -80(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -72(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq -64(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 56(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -120(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -112(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -104(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -96(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -88(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -80(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -72(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -64(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -56(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 64(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -120(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -112(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -104(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -96(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -88(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -80(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -72(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -64(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -56(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq -48(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 72(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -120(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -112(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -104(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -96(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -88(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -80(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -72(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -64(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -56(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -48(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -40(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 80(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -120(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -112(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -104(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -96(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -88(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -80(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -72(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -64(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -56(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -48(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -40(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq -32(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 88(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -120(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -112(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -104(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -96(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -88(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -80(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -72(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -64(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -56(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -48(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -40(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -32(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -24(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 96(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -120(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -112(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -104(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -96(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -88(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -80(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -72(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -64(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -56(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -48(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -40(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -32(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -24(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq -16(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 104(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -120(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -112(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -104(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -96(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -88(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -80(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -72(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -64(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -56(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -48(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -40(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -32(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -24(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -16(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq -8(%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 112(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -120(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -112(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -104(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -96(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -88(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -80(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -72(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -64(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -56(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -48(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -40(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -32(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -24(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -16(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -8(%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 8(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 120(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -112(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -104(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -96(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -88(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -80(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -72(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -64(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -56(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -48(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -40(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -32(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -24(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -16(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -8(%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 16(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 128(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -104(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -96(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -88(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -80(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -72(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -64(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -56(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -48(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -40(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -32(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -24(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -16(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -8(%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 24(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 136(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -96(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -88(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -80(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -72(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -64(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -56(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -48(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -40(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -32(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -24(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -16(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -8(%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 32(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 144(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -88(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -80(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -72(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -64(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -56(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -48(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -40(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -32(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -24(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -16(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -8(%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 40(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 152(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -80(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -72(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -64(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -56(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -48(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -40(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -32(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -24(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -16(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -8(%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 48(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 160(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -72(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -64(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -56(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -48(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -40(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -32(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -24(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -16(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -8(%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 56(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 168(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -64(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -56(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -48(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -40(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -32(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -24(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -16(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -8(%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 64(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 176(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -56(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -48(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -40(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -32(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -24(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -16(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -8(%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 72(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 184(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -48(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -40(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -32(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -24(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -16(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -8(%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 80(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 192(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -40(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -32(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -24(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -16(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -8(%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 88(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 200(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -32(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -24(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -16(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -8(%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 96(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 208(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -24(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -16(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+ movq -8(%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbp
+ movq %r8, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 104(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 216(%r11)
+ movq %r12, %r9
+ movq %rbp, %r8
+ movq %r10, %rcx
+/APP
+ movq -16(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+ movq -8(%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rcx
+
+/NO_APP
+ movq %r9, %rbp
+ movq %rcx, %r12
+/APP
+ movq (%rsp),%rax
+ mulq 112(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, 224(%r11)
+ movq %r12, %r9
+ movq %rbp, %rcx
+ movq %r10, %r8
+/APP
+ movq -8(%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r8, %r12
+ movq %r9, %rbp
+/APP
+ movq (%rsp),%rax
+ mulq 120(%rsp)
+ addq %rax,%rcx
+ adcq %rdx,%rbp
+ adcq $0,%r12
+
+/NO_APP
+ movq %rcx, 232(%r11)
+ movq %rbp, %r8
+ movq %r12, %rcx
+/APP
+ movq (%rsp),%rax
+ mulq 128(%rsp)
+ addq %rax,%r8
+ adcq %rdx,%rcx
+ adcq $0,%r10
+
+/NO_APP
+ movq %r8, 240(%r11)
+ movl (%rsi), %esi
+ xorl (%rdi), %esi
+ testq %rcx, %rcx
+ movq %rcx, 248(%r11)
+ movl $32, 8(%rbx)
+ jne .L76
+ .align 16
+.L84:
+ movl 8(%rbx), %edx
+ leal -1(%rdx), %edi
+ testl %edi, %edi
+ movl %edi, 8(%rbx)
+ je .L76
+ leal -2(%rdx), %eax
+ cmpq $0, (%r11,%rax,8)
+ je .L84
+.L76:
+ movl 8(%rbx), %edx
+ xorl %r11d, %r11d
+ testl %edx, %edx
+ cmovne %esi, %r11d
+ movl %r11d, (%rbx)
+ addq $136, %rsp
+ popq %rbx
+ popq %rbp
+ popq %r12
+ ret
+.LFE4:
+ .size s_mp_mul_comba_16, .-s_mp_mul_comba_16
+ .align 16
+.globl s_mp_mul_comba_32
+ .type s_mp_mul_comba_32, @function
+s_mp_mul_comba_32:
+.LFB5:
+ pushq %rbp
+.LCFI11:
+ movq %rsp, %rbp
+.LCFI12:
+ pushq %r13
+.LCFI13:
+ movq %rdx, %r13
+ movl $256, %edx
+ pushq %r12
+.LCFI14:
+ movq %rsi, %r12
+ pushq %rbx
+.LCFI15:
+ movq %rdi, %rbx
+ subq $520, %rsp
+.LCFI16:
+ movq 16(%rdi), %rsi
+ leaq -544(%rbp), %rdi
+ call memcpy@PLT
+ movq 16(%r12), %rsi
+ leaq -288(%rbp), %rdi
+ movl $256, %edx
+ call memcpy@PLT
+ movq 16(%r13), %r9
+ xorl %r8d, %r8d
+ movq %r8, %rsi
+ movq %r8, %rdi
+ movq %r8, %r10
+/APP
+ movq -544(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+/NO_APP
+ movq %rsi, (%r9)
+ movq %r10, %rsi
+ movq %r8, %r10
+/APP
+ movq -544(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%r10
+
+/NO_APP
+ movq %r10, %r11
+/APP
+ movq -536(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%r11
+
+/NO_APP
+ movq %rdi, 8(%r9)
+ movq %r11, %rdi
+ movq %r8, %r11
+/APP
+ movq -544(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%r11
+
+/NO_APP
+ movq %r11, %rcx
+/APP
+ movq -536(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -528(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 16(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -520(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 24(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -512(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 32(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -504(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 40(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -496(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 48(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -488(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 56(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -480(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 64(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -472(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 72(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -464(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 80(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -456(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 88(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -448(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 96(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -440(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 104(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -432(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 112(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -424(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 120(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -416(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 128(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -408(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 136(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -400(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 144(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -392(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 152(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -384(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 160(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -376(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 168(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -368(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 176(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -360(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 184(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -352(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 192(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -344(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 200(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -336(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 208(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -328(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 216(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -320(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 224(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -312(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 232(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -544(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -536(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -304(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 240(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -544(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -536(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -528(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -288(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 248(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -536(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -528(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -520(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -280(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 256(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -528(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -520(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -512(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -272(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 264(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -520(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -512(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -504(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -264(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 272(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -512(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -504(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -496(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -256(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 280(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -504(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -496(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -488(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -248(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 288(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -496(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -488(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -480(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -240(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 296(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -488(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -480(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -472(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -232(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 304(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -480(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -472(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -464(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -224(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 312(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -472(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -464(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -456(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -448(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -440(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -216(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 320(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -464(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -456(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -448(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -440(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -432(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -208(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 328(%r9)
+ movq %r11, %rdi
+ movq %r10, %r11
+ movq %r8, %r10
+/APP
+ movq -456(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -448(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -440(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -432(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -424(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -416(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -408(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -400(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -392(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -384(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -376(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -368(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -360(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -352(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -344(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -336(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -328(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -320(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -312(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -304(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+ movq -296(%rbp),%rax
+ mulq -200(%rbp)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%r10
+
+/NO_APP
+ movq %r11, 336(%r9)
+ movq %r10, %rsi
+ movq %r8, %r10
+/APP
+ movq -448(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%r10
+
+/NO_APP
+ movq %r10, %rcx
+/APP
+ movq -440(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -432(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rsi, %r11
+ movq %rcx, %r10
+/APP
+ movq -296(%rbp),%rax
+ mulq -192(%rbp)
+ addq %rax,%rdi
+ adcq %rdx,%r11
+ adcq $0,%r10
+
+/NO_APP
+ movq %rdi, 344(%r9)
+ movq %r11, %rcx
+ movq %r10, %rdi
+ movq %r8, %r11
+/APP
+ movq -440(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%r11
+
+/NO_APP
+ movq %r11, %rsi
+/APP
+ movq -432(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -424(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -184(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 352(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -432(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -424(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -416(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -176(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 360(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -424(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -416(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -408(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -168(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 368(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -416(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -408(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -400(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -160(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 376(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -408(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -400(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -392(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -152(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 384(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -400(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -392(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -384(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -144(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 392(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -392(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -384(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -376(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -136(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 400(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -384(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -376(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -368(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -128(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 408(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -376(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -368(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -360(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -120(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 416(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -368(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -360(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -352(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -112(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 424(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -360(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -352(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -344(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -104(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 432(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -352(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -344(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -336(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -96(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 440(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -344(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -336(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -328(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -88(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 448(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -336(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -328(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -320(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -80(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 456(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -328(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -320(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -312(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -72(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 464(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -320(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -312(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+ movq -304(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rcx, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -64(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 472(%r9)
+ movq %r11, %rdi
+ movq %r10, %rcx
+ movq %r8, %rsi
+/APP
+ movq -312(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq -304(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r10
+ movq %rsi, %r11
+/APP
+ movq -296(%rbp),%rax
+ mulq -56(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rcx, 480(%r9)
+ movq %r11, %rdi
+ movq %r10, %rsi
+ movq %r8, %rcx
+/APP
+ movq -304(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%rdi
+ adcq $0,%rcx
+
+/NO_APP
+ movq %rcx, %r11
+ movq %rdi, %r10
+/APP
+ movq -296(%rbp),%rax
+ mulq -48(%rbp)
+ addq %rax,%rsi
+ adcq %rdx,%r10
+ adcq $0,%r11
+
+/NO_APP
+ movq %rsi, 488(%r9)
+ movq %r10, %rcx
+ movq %r11, %rsi
+/APP
+ movq -296(%rbp),%rax
+ mulq -40(%rbp)
+ addq %rax,%rcx
+ adcq %rdx,%rsi
+ adcq $0,%r8
+
+/NO_APP
+ movq %rcx, 496(%r9)
+ movl (%r12), %ecx
+ xorl (%rbx), %ecx
+ testq %rsi, %rsi
+ movq %rsi, 504(%r9)
+ movl $64, 8(%r13)
+ jne .L149
+ .align 16
+.L157:
+ movl 8(%r13), %edx
+ leal -1(%rdx), %ebx
+ testl %ebx, %ebx
+ movl %ebx, 8(%r13)
+ je .L149
+ leal -2(%rdx), %r12d
+ cmpq $0, (%r9,%r12,8)
+ je .L157
+.L149:
+ movl 8(%r13), %r9d
+ xorl %edx, %edx
+ testl %r9d, %r9d
+ cmovne %ecx, %edx
+ movl %edx, (%r13)
+ addq $520, %rsp
+ popq %rbx
+ popq %r12
+ popq %r13
+ leave
+ ret
+.LFE5:
+ .size s_mp_mul_comba_32, .-s_mp_mul_comba_32
+ .align 16
+.globl s_mp_sqr_comba_4
+ .type s_mp_sqr_comba_4, @function
+s_mp_sqr_comba_4:
+.LFB6:
+ pushq %rbp
+.LCFI17:
+ movq %rsi, %r11
+ xorl %esi, %esi
+ movq %rsi, %r10
+ movq %rsi, %rbp
+ movq %rsi, %r8
+ pushq %rbx
+.LCFI18:
+ movq %rsi, %rbx
+ movq 16(%rdi), %rcx
+ movq %rsi, %rdi
+/APP
+ movq (%rcx),%rax
+ mulq %rax
+ addq %rax,%r10
+ adcq %rdx,%rbx
+ adcq $0,%rdi
+
+/NO_APP
+ movq %r10, -72(%rsp)
+/APP
+ movq (%rcx),%rax
+ mulq 8(%rcx)
+ addq %rax,%rbx
+ adcq %rdx,%rdi
+ adcq $0,%rbp
+ addq %rax,%rbx
+ adcq %rdx,%rdi
+ adcq $0,%rbp
+
+/NO_APP
+ movq %rbx, -64(%rsp)
+/APP
+ movq (%rcx),%rax
+ mulq 16(%rcx)
+ addq %rax,%rdi
+ adcq %rdx,%rbp
+ adcq $0,%r8
+ addq %rax,%rdi
+ adcq %rdx,%rbp
+ adcq $0,%r8
+
+/NO_APP
+ movq %rbp, %rbx
+ movq %r8, %rbp
+/APP
+ movq 8(%rcx),%rax
+ mulq %rax
+ addq %rax,%rdi
+ adcq %rdx,%rbx
+ adcq $0,%rbp
+
+/NO_APP
+ movq %rdi, -56(%rsp)
+ movq %rbp, %r9
+ movq %rbx, %r8
+ movq %rsi, %rdi
+/APP
+ movq (%rcx),%rax
+ mulq 24(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rdi
+ addq %rax,%r8
+ adcq %rdx,%r9
+ adcq $0,%rdi
+
+/NO_APP
+ movq %r9, %rbx
+ movq %rdi, %rbp
+/APP
+ movq 8(%rcx),%rax
+ mulq 16(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rbx
+ adcq $0,%rbp
+ addq %rax,%r8
+ adcq %rdx,%rbx
+ adcq $0,%rbp
+
+/NO_APP
+ movq %r8, -48(%rsp)
+ movq %rbp, %r9
+ movq %rbx, %rdi
+ movq %rsi, %r8
+ movl $8, 8(%r11)
+ movl $0, (%r11)
+/APP
+ movq 8(%rcx),%rax
+ mulq 24(%rcx)
+ addq %rax,%rdi
+ adcq %rdx,%r9
+ adcq $0,%r8
+ addq %rax,%rdi
+ adcq %rdx,%r9
+ adcq $0,%r8
+
+/NO_APP
+ movq %r9, %rbx
+ movq %r8, %rbp
+/APP
+ movq 16(%rcx),%rax
+ mulq %rax
+ addq %rax,%rdi
+ adcq %rdx,%rbx
+ adcq $0,%rbp
+
+/NO_APP
+ movq %rbp, %rax
+ movq %rdi, -40(%rsp)
+ movq %rbx, %rbp
+ movq %rax, %rdi
+ movq %rsi, %rbx
+/APP
+ movq 16(%rcx),%rax
+ mulq 24(%rcx)
+ addq %rax,%rbp
+ adcq %rdx,%rdi
+ adcq $0,%rbx
+ addq %rax,%rbp
+ adcq %rdx,%rdi
+ adcq $0,%rbx
+
+/NO_APP
+ movq %rbp, -32(%rsp)
+ movq %rbx, %r9
+/APP
+ movq 24(%rcx),%rax
+ mulq %rax
+ addq %rax,%rdi
+ adcq %rdx,%r9
+ adcq $0,%rsi
+
+/NO_APP
+ movq 16(%r11), %rdx
+ movq %rdi, -24(%rsp)
+ movq %r9, -16(%rsp)
+ movq %r10, (%rdx)
+ movq -64(%rsp), %r8
+ movq %r8, 8(%rdx)
+ movq -56(%rsp), %rbp
+ movq %rbp, 16(%rdx)
+ movq -48(%rsp), %rdi
+ movq %rdi, 24(%rdx)
+ movq -40(%rsp), %rsi
+ movq %rsi, 32(%rdx)
+ movq -32(%rsp), %rbx
+ movq %rbx, 40(%rdx)
+ movq -24(%rsp), %rcx
+ movq %rcx, 48(%rdx)
+ movq -16(%rsp), %rax
+ movq %rax, 56(%rdx)
+ movl 8(%r11), %edx
+ testl %edx, %edx
+ je .L168
+ leal -1(%rdx), %ecx
+ movq 16(%r11), %rsi
+ mov %ecx, %r10d
+ cmpq $0, (%rsi,%r10,8)
+ jne .L166
+ movl %ecx, %edx
+ .align 16
+.L167:
+ testl %edx, %edx
+ movl %edx, %ecx
+ je .L171
+ decl %edx
+ mov %edx, %eax
+ cmpq $0, (%rsi,%rax,8)
+ je .L167
+ movl %ecx, 8(%r11)
+ movl %ecx, %edx
+.L166:
+ testl %edx, %edx
+ je .L168
+ popq %rbx
+ popq %rbp
+ movl (%r11), %eax
+ movl %eax, (%r11)
+ ret
+.L171:
+ movl %edx, 8(%r11)
+ .align 16
+.L168:
+ popq %rbx
+ popq %rbp
+ xorl %eax, %eax
+ movl %eax, (%r11)
+ ret
+.LFE6:
+ .size s_mp_sqr_comba_4, .-s_mp_sqr_comba_4
+ .align 16
+.globl s_mp_sqr_comba_8
+ .type s_mp_sqr_comba_8, @function
+s_mp_sqr_comba_8:
+.LFB7:
+ pushq %r14
+.LCFI19:
+ xorl %r9d, %r9d
+ movq %r9, %r14
+ movq %r9, %r10
+ pushq %r13
+.LCFI20:
+ movq %r9, %r13
+ pushq %r12
+.LCFI21:
+ movq %r9, %r12
+ pushq %rbp
+.LCFI22:
+ movq %rsi, %rbp
+ movq %r9, %rsi
+ pushq %rbx
+.LCFI23:
+ movq %r9, %rbx
+ subq $8, %rsp
+.LCFI24:
+ movq 16(%rdi), %rcx
+/APP
+ movq (%rcx),%rax
+ mulq %rax
+ addq %rax,%r14
+ adcq %rdx,%rbx
+ adcq $0,%r12
+
+/NO_APP
+ movq %r14, -120(%rsp)
+/APP
+ movq (%rcx),%rax
+ mulq 8(%rcx)
+ addq %rax,%rbx
+ adcq %rdx,%r12
+ adcq $0,%r10
+ addq %rax,%rbx
+ adcq %rdx,%r12
+ adcq $0,%r10
+
+/NO_APP
+ movq %rbx, -112(%rsp)
+/APP
+ movq (%rcx),%rax
+ mulq 16(%rcx)
+ addq %rax,%r12
+ adcq %rdx,%r10
+ adcq $0,%r13
+ addq %rax,%r12
+ adcq %rdx,%r10
+ adcq $0,%r13
+
+/NO_APP
+ movq %r10, %rbx
+ movq %r13, %r10
+ movq %r9, %r13
+/APP
+ movq 8(%rcx),%rax
+ mulq %rax
+ addq %rax,%r12
+ adcq %rdx,%rbx
+ adcq $0,%r10
+
+/NO_APP
+ movq %r12, -104(%rsp)
+ movq %r10, %rdi
+ movq %rbx, %r11
+/APP
+ movq (%rcx),%rax
+ mulq 24(%rcx)
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+ addq %rax,%r11
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %rbx
+ movq %rsi, %r10
+ movq %r9, %rdi
+/APP
+ movq 8(%rcx),%rax
+ mulq 16(%rcx)
+ addq %rax,%r11
+ adcq %rdx,%rbx
+ adcq $0,%r10
+ addq %rax,%r11
+ adcq %rdx,%rbx
+ adcq $0,%r10
+
+/NO_APP
+ movq %r9, %rsi
+ movq %r11, -96(%rsp)
+ movq %r10, %r8
+ movq %rbx, %r12
+ movq %r9, %r11
+/APP
+ movq (%rcx),%rax
+ mulq 32(%rcx)
+ addq %rax,%r12
+ adcq %rdx,%r8
+ adcq $0,%r13
+ addq %rax,%r12
+ adcq %rdx,%r8
+ adcq $0,%r13
+
+ movq 8(%rcx),%rax
+ mulq 24(%rcx)
+ addq %rax,%r12
+ adcq %rdx,%r8
+ adcq $0,%r13
+ addq %rax,%r12
+ adcq %rdx,%r8
+ adcq $0,%r13
+
+/NO_APP
+ movq %r8, %rbx
+ movq %r13, %r10
+ movq %r9, %r8
+/APP
+ movq 16(%rcx),%rax
+ mulq %rax
+ addq %rax,%r12
+ adcq %rdx,%rbx
+ adcq $0,%r10
+
+/NO_APP
+ movq %r12, -88(%rsp)
+/APP
+ movq (%rcx),%rax
+ mulq 40(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 32(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 24(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%r11
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%r11
+
+/NO_APP
+ movq %rbx, -80(%rsp)
+/APP
+ movq (%rcx),%rax
+ mulq 48(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 40(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 32(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r9, %rax
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rax
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rax
+
+/NO_APP
+ movq %rax, %rdx
+ movq %r11, %rbx
+ movq %r13, %rdi
+ movq %rdx, %r11
+ movq %r12, %rsi
+/APP
+ movq 24(%rcx),%rax
+ mulq %rax
+ addq %rax,%r10
+ adcq %rdx,%rbx
+ adcq $0,%r11
+
+/NO_APP
+ movq %r10, -72(%rsp)
+ movq %r11, %r10
+/APP
+ movq (%rcx),%rax
+ mulq 56(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 40(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 32(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r9, %rax
+/APP
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%rax
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%rax
+
+/NO_APP
+ movq %rbx, -64(%rsp)
+ movq %rax, %r11
+ movq %r9, %rbx
+/APP
+ movq 8(%rcx),%rax
+ mulq 56(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 40(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rbx
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rbx
+
+/NO_APP
+ movq %rbx, %rsi
+ movq %r13, %rdi
+ movq %r11, %rbx
+ movq %r12, %r13
+ movq %rsi, %r11
+/APP
+ movq 32(%rcx),%rax
+ mulq %rax
+ addq %rax,%r10
+ adcq %rdx,%rbx
+ adcq $0,%r11
+
+/NO_APP
+ movq %r10, -56(%rsp)
+ movq %r9, %r10
+/APP
+ movq 16(%rcx),%rax
+ mulq 56(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %r13,%r13
+
+ movq 24(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%r13
+
+ movq 32(%rcx),%rax
+ mulq 40(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%r13
+
+/NO_APP
+ movq %rdi, %r12
+ movq %r13, %rax
+/APP
+ addq %r8,%rbx
+ adcq %r12,%r11
+ adcq %rax,%r10
+ addq %r8,%rbx
+ adcq %r12,%r11
+ adcq %rax,%r10
+
+/NO_APP
+ movq %rbx, -48(%rsp)
+ movq %r11, %r12
+ movq %r10, %rsi
+ movq %r9, %rbx
+ movq %r9, %r11
+/APP
+ movq 24(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r12
+ adcq %rdx,%rsi
+ adcq $0,%rbx
+ addq %rax,%r12
+ adcq %rdx,%rsi
+ adcq $0,%rbx
+
+/NO_APP
+ movq %rbx, %r13
+/APP
+ movq 32(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r12
+ adcq %rdx,%rsi
+ adcq $0,%r13
+ addq %rax,%r12
+ adcq %rdx,%rsi
+ adcq $0,%r13
+
+/NO_APP
+ movq %rsi, %r10
+ movq %r13, %rbx
+ movq %r9, %r13
+/APP
+ movq 40(%rcx),%rax
+ mulq %rax
+ addq %rax,%r12
+ adcq %rdx,%r10
+ adcq $0,%rbx
+
+/NO_APP
+ movq %r12, -40(%rsp)
+ movq %rbx, %r8
+ movq %r10, %rdi
+/APP
+ movq 32(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%rdi
+ adcq %rdx,%r8
+ adcq $0,%r11
+ addq %rax,%rdi
+ adcq %rdx,%r8
+ adcq $0,%r11
+
+/NO_APP
+ movq %r8, %r10
+ movq %r11, %rbx
+/APP
+ movq 40(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%rdi
+ adcq %rdx,%r10
+ adcq $0,%rbx
+ addq %rax,%rdi
+ adcq %rdx,%r10
+ adcq $0,%rbx
+
+/NO_APP
+ movq %rdi, -32(%rsp)
+ movq %rbx, %rsi
+ movq %r10, %r12
+/APP
+ movq 40(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r12
+ adcq %rdx,%rsi
+ adcq $0,%r13
+ addq %rax,%r12
+ adcq %rdx,%rsi
+ adcq $0,%r13
+
+/NO_APP
+ movq %rsi, %r10
+ movq %r13, %rbx
+/APP
+ movq 48(%rcx),%rax
+ mulq %rax
+ addq %rax,%r12
+ adcq %rdx,%r10
+ adcq $0,%rbx
+
+/NO_APP
+ movq %r12, -24(%rsp)
+ movq %r10, %rdi
+ movq %rbx, %rsi
+ movq %r9, %r10
+ movl $16, 8(%rbp)
+ movl $0, (%rbp)
+/APP
+ movq 48(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%r10
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%r10
+
+/NO_APP
+ movq %rdi, -16(%rsp)
+ movq %r10, %r8
+/APP
+ movq 56(%rcx),%rax
+ mulq %rax
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%r9
+
+/NO_APP
+ movq 16(%rbp), %rax
+ movq %rsi, -8(%rsp)
+ movq %r8, (%rsp)
+ movq %r14, (%rax)
+ movq -112(%rsp), %rbx
+ movq %rbx, 8(%rax)
+ movq -104(%rsp), %rcx
+ movq %rcx, 16(%rax)
+ movq -96(%rsp), %rdx
+ movq %rdx, 24(%rax)
+ movq -88(%rsp), %r14
+ movq %r14, 32(%rax)
+ movq -80(%rsp), %r13
+ movq %r13, 40(%rax)
+ movq -72(%rsp), %r12
+ movq %r12, 48(%rax)
+ movq -64(%rsp), %r11
+ movq %r11, 56(%rax)
+ movq -56(%rsp), %r10
+ movq %r10, 64(%rax)
+ movq -48(%rsp), %r9
+ movq %r9, 72(%rax)
+ movq -40(%rsp), %r8
+ movq %r8, 80(%rax)
+ movq -32(%rsp), %rdi
+ movq %rdi, 88(%rax)
+ movq -24(%rsp), %rsi
+ movq %rsi, 96(%rax)
+ movq -16(%rsp), %rbx
+ movq %rbx, 104(%rax)
+ movq -8(%rsp), %rcx
+ movq %rcx, 112(%rax)
+ movq (%rsp), %rdx
+ movq %rdx, 120(%rax)
+ movl 8(%rbp), %edx
+ testl %edx, %edx
+ je .L192
+ leal -1(%rdx), %ecx
+ movq 16(%rbp), %rsi
+ mov %ecx, %r14d
+ cmpq $0, (%rsi,%r14,8)
+ jne .L190
+ movl %ecx, %edx
+ .align 16
+.L191:
+ testl %edx, %edx
+ movl %edx, %ecx
+ je .L195
+ decl %edx
+ mov %edx, %r9d
+ cmpq $0, (%rsi,%r9,8)
+ je .L191
+ movl %ecx, 8(%rbp)
+ movl %ecx, %edx
+.L190:
+ testl %edx, %edx
+ je .L192
+ movl (%rbp), %eax
+ movl %eax, (%rbp)
+ addq $8, %rsp
+ popq %rbx
+ popq %rbp
+ popq %r12
+ popq %r13
+ popq %r14
+ ret
+.L195:
+ movl %edx, 8(%rbp)
+ .align 16
+.L192:
+ xorl %eax, %eax
+ movl %eax, (%rbp)
+ addq $8, %rsp
+ popq %rbx
+ popq %rbp
+ popq %r12
+ popq %r13
+ popq %r14
+ ret
+.LFE7:
+ .size s_mp_sqr_comba_8, .-s_mp_sqr_comba_8
+ .align 16
+.globl s_mp_sqr_comba_16
+ .type s_mp_sqr_comba_16, @function
+s_mp_sqr_comba_16:
+.LFB8:
+ pushq %rbp
+.LCFI25:
+ xorl %r9d, %r9d
+ movq %r9, %r8
+ movq %r9, %r11
+ movq %rsp, %rbp
+.LCFI26:
+ pushq %r14
+.LCFI27:
+ movq %rsi, %r14
+ movq %r9, %rsi
+ pushq %r13
+.LCFI28:
+ movq %r9, %r13
+ pushq %r12
+.LCFI29:
+ movq %r9, %r12
+ pushq %rbx
+.LCFI30:
+ movq %r9, %rbx
+ subq $256, %rsp
+.LCFI31:
+ movq 16(%rdi), %rcx
+/APP
+ movq (%rcx),%rax
+ mulq %rax
+ addq %rax,%r8
+ adcq %rdx,%rbx
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r8, -288(%rbp)
+/APP
+ movq (%rcx),%rax
+ mulq 8(%rcx)
+ addq %rax,%rbx
+ adcq %rdx,%rsi
+ adcq $0,%r12
+ addq %rax,%rbx
+ adcq %rdx,%rsi
+ adcq $0,%r12
+
+/NO_APP
+ movq %rbx, -280(%rbp)
+/APP
+ movq (%rcx),%rax
+ mulq 16(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r12
+ adcq $0,%r13
+ addq %rax,%rsi
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r12, %rbx
+ movq %r13, %r10
+/APP
+ movq 8(%rcx),%rax
+ mulq %rax
+ addq %rax,%rsi
+ adcq %rdx,%rbx
+ adcq $0,%r10
+
+/NO_APP
+ movq %rsi, -272(%rbp)
+ movq %r10, %rdi
+ movq %r9, %rsi
+ movq %rbx, %r10
+/APP
+ movq (%rcx),%rax
+ mulq 24(%rcx)
+ addq %rax,%r10
+ adcq %rdx,%rdi
+ adcq $0,%r11
+ addq %rax,%r10
+ adcq %rdx,%rdi
+ adcq $0,%r11
+
+/NO_APP
+ movq %rdi, %r12
+ movq %r11, %rbx
+ movq %r9, %rdi
+/APP
+ movq 8(%rcx),%rax
+ mulq 16(%rcx)
+ addq %rax,%r10
+ adcq %rdx,%r12
+ adcq $0,%rbx
+ addq %rax,%r10
+ adcq %rdx,%r12
+ adcq $0,%rbx
+
+/NO_APP
+ movq %r9, %r11
+ movq %r10, -264(%rbp)
+ movq %rbx, %r8
+ movq %r12, %r13
+ movq %r9, %r12
+/APP
+ movq (%rcx),%rax
+ mulq 32(%rcx)
+ addq %rax,%r13
+ adcq %rdx,%r8
+ adcq $0,%r12
+ addq %rax,%r13
+ adcq %rdx,%r8
+ adcq $0,%r12
+
+ movq 8(%rcx),%rax
+ mulq 24(%rcx)
+ addq %rax,%r13
+ adcq %rdx,%r8
+ adcq $0,%r12
+ addq %rax,%r13
+ adcq %rdx,%r8
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, %rbx
+ movq %r12, %r10
+ movq %r9, %r8
+/APP
+ movq 16(%rcx),%rax
+ mulq %rax
+ addq %rax,%r13
+ adcq %rdx,%rbx
+ adcq $0,%r10
+
+/NO_APP
+ movq %r13, -256(%rbp)
+/APP
+ movq (%rcx),%rax
+ mulq 40(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 32(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 24(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%r11
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%r11
+
+/NO_APP
+ movq %rbx, -248(%rbp)
+/APP
+ movq (%rcx),%rax
+ mulq 48(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 40(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 32(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r9, %rax
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rax
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rax
+
+/NO_APP
+ movq %rax, %rdx
+ movq %r11, %rbx
+ movq %r13, %rdi
+ movq %rdx, %r11
+ movq %r12, %rsi
+/APP
+ movq 24(%rcx),%rax
+ mulq %rax
+ addq %rax,%r10
+ adcq %rdx,%rbx
+ adcq $0,%r11
+
+/NO_APP
+ movq %r10, -240(%rbp)
+ movq %r11, %r10
+/APP
+ movq (%rcx),%rax
+ mulq 56(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 40(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 32(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r9, %rdx
+/APP
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%rdx
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%rdx
+
+/NO_APP
+ movq %rdx, %r11
+ movq %rbx, -232(%rbp)
+ movq %r9, %rbx
+/APP
+ movq (%rcx),%rax
+ mulq 64(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 40(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rbx
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rbx
+
+ movq 32(%rcx),%rax
+ mulq %rax
+ addq %rax,%r10
+ adcq %rdx,%r11
+ adcq $0,%rbx
+
+/NO_APP
+ movq %r13, %rdi
+ movq %r10, -224(%rbp)
+ movq %r12, %rsi
+ movq %rbx, %r10
+ movq %r9, %r12
+/APP
+ movq (%rcx),%rax
+ mulq 72(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 40(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%r11
+ adcq %rdi,%r10
+ adcq %rsi,%r12
+ addq %r8,%r11
+ adcq %rdi,%r10
+ adcq %rsi,%r12
+
+/NO_APP
+ movq %r11, -216(%rbp)
+ movq %r12, %rbx
+/APP
+ movq (%rcx),%rax
+ mulq 80(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r9, %rax
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r10
+ adcq %r13,%rbx
+ adcq %r12,%rax
+ addq %r8,%r10
+ adcq %r13,%rbx
+ adcq %r12,%rax
+
+/NO_APP
+ movq %rax, %rdx
+ movq %rbx, %r11
+ movq %r13, %rdi
+ movq %rdx, %rbx
+ movq %r12, %rsi
+/APP
+ movq 40(%rcx),%rax
+ mulq %rax
+ addq %rax,%r10
+ adcq %rdx,%r11
+ adcq $0,%rbx
+
+/NO_APP
+ movq %r10, -208(%rbp)
+ movq %rbx, %r10
+/APP
+ movq (%rcx),%rax
+ mulq 88(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r9, %rdx
+/APP
+ addq %r8,%r11
+ adcq %rdi,%r10
+ adcq %rsi,%rdx
+ addq %r8,%r11
+ adcq %rdi,%r10
+ adcq %rsi,%rdx
+
+/NO_APP
+ movq %rdx, %r13
+ movq %r11, -200(%rbp)
+ movq %r13, %r12
+/APP
+ movq (%rcx),%rax
+ mulq 96(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r9, %rax
+ movq %rdi, %rdx
+ movq %rsi, %r11
+/APP
+ addq %r8,%r10
+ adcq %rdx,%r12
+ adcq %r11,%rax
+ addq %r8,%r10
+ adcq %rdx,%r12
+ adcq %r11,%rax
+
+/NO_APP
+ movq %rdx, %rbx
+ movq %rax, %r13
+ movq %r11, %rsi
+/APP
+ movq 48(%rcx),%rax
+ mulq %rax
+ addq %rax,%r10
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %rbx, %rdi
+ movq %r10, -192(%rbp)
+ movq %r13, %r10
+/APP
+ movq (%rcx),%rax
+ mulq 104(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+/NO_APP
+ movq %r9, %r13
+/APP
+ movq 8(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%r12
+ adcq %rdi,%r10
+ adcq %rsi,%r13
+ addq %r8,%r12
+ adcq %rdi,%r10
+ adcq %rsi,%r13
+
+/NO_APP
+ movq %r12, -184(%rbp)
+ movq %r13, %r12
+/APP
+ movq (%rcx),%rax
+ mulq 112(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r9, %rax
+ movq %rdi, %rbx
+ movq %rsi, %rdx
+/APP
+ addq %r8,%r10
+ adcq %rbx,%r12
+ adcq %rdx,%rax
+ addq %r8,%r10
+ adcq %rbx,%r12
+ adcq %rdx,%rax
+
+/NO_APP
+ movq %rdx, %r11
+ movq %rax, %r13
+ movq %rbx, %rdi
+/APP
+ movq 56(%rcx),%rax
+ mulq %rax
+ addq %rax,%r10
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r11, %rsi
+ movq %r10, -176(%rbp)
+ movq %r13, %r10
+/APP
+ movq (%rcx),%rax
+ mulq 120(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+/NO_APP
+ movq %r9, %r13
+/APP
+ movq 8(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 56(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%r12
+ adcq %rdi,%r10
+ adcq %rsi,%r13
+ addq %r8,%r12
+ adcq %rdi,%r10
+ adcq %rsi,%r13
+
+/NO_APP
+ movq %r12, -168(%rbp)
+ movq %r13, %r12
+/APP
+ movq 8(%rcx),%rax
+ mulq 120(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 56(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r9, %rax
+ movq %rdi, %rbx
+ movq %rsi, %rdx
+/APP
+ addq %r8,%r10
+ adcq %rbx,%r12
+ adcq %rdx,%rax
+ addq %r8,%r10
+ adcq %rbx,%r12
+ adcq %rdx,%rax
+
+/NO_APP
+ movq %rdx, %r11
+ movq %rax, %r13
+ movq %rbx, %rdi
+/APP
+ movq 64(%rcx),%rax
+ mulq %rax
+ addq %rax,%r10
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r11, %rsi
+ movq %r10, -160(%rbp)
+ movq %r9, %r11
+/APP
+ movq 16(%rcx),%rax
+ mulq 120(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+/NO_APP
+ movq %r13, %r10
+ movq %r9, %rbx
+/APP
+ movq 24(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 56(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 64(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%r12
+ adcq %rdi,%r10
+ adcq %rsi,%r11
+ addq %r8,%r12
+ adcq %rdi,%r10
+ adcq %rsi,%r11
+
+/NO_APP
+ movq %r12, -152(%rbp)
+/APP
+ movq 24(%rcx),%rax
+ mulq 120(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 56(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 64(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rbx
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rbx
+
+/NO_APP
+ movq %rbx, %rdx
+ movq %r13, %rdi
+ movq %r11, %rbx
+ movq %r12, %rsi
+ movq %rdx, %r11
+ movq %r9, %r12
+/APP
+ movq 72(%rcx),%rax
+ mulq %rax
+ addq %rax,%r10
+ adcq %rdx,%rbx
+ adcq $0,%r11
+
+/NO_APP
+ movq %r10, -144(%rbp)
+ movq %r11, %r10
+/APP
+ movq 32(%rcx),%rax
+ mulq 120(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 56(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 64(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 72(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%r12
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%r12
+
+/NO_APP
+ movq %rbx, -136(%rbp)
+ movq %r12, %r11
+/APP
+ movq 40(%rcx),%rax
+ mulq 120(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 56(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 64(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 72(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r9, %rax
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rax
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rax
+
+/NO_APP
+ movq %rax, %rdx
+ movq %r11, %rbx
+ movq %r13, %rdi
+ movq %rdx, %r11
+ movq %r12, %rsi
+/APP
+ movq 80(%rcx),%rax
+ mulq %rax
+ addq %rax,%r10
+ adcq %rdx,%rbx
+ adcq $0,%r11
+
+/NO_APP
+ movq %r10, -128(%rbp)
+ movq %r11, %r10
+/APP
+ movq 48(%rcx),%rax
+ mulq 120(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 56(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 64(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 72(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 80(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r9, %rdx
+/APP
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%rdx
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%rdx
+
+/NO_APP
+ movq %rbx, -120(%rbp)
+ movq %rdx, %r11
+ movq %r9, %rbx
+/APP
+ movq 56(%rcx),%rax
+ mulq 120(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 64(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 72(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 80(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rbx
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rbx
+
+/NO_APP
+ movq %rbx, %rdx
+ movq %r13, %rdi
+ movq %r11, %rbx
+ movq %r12, %rsi
+ movq %rdx, %r11
+ movq %r9, %r12
+/APP
+ movq 88(%rcx),%rax
+ mulq %rax
+ addq %rax,%r10
+ adcq %rdx,%rbx
+ adcq $0,%r11
+
+/NO_APP
+ movq %r10, -112(%rbp)
+ movq %r11, %r10
+/APP
+ movq 64(%rcx),%rax
+ mulq 120(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 72(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 80(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 88(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%r12
+ addq %r8,%rbx
+ adcq %rdi,%r10
+ adcq %rsi,%r12
+
+/NO_APP
+ movq %rbx, -104(%rbp)
+ movq %r12, %r11
+/APP
+ movq 72(%rcx),%rax
+ mulq 120(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 80(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 88(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r9, %rax
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rax
+ addq %r8,%r10
+ adcq %r13,%r11
+ adcq %r12,%rax
+
+/NO_APP
+ movq %rax, %rdx
+ movq %r11, %rbx
+ movq %r13, %rdi
+ movq %rdx, %r11
+ movq %r12, %rsi
+/APP
+ movq 96(%rcx),%rax
+ mulq %rax
+ addq %rax,%r10
+ adcq %rdx,%rbx
+ adcq $0,%r11
+
+/NO_APP
+ movq %r10, -96(%rbp)
+ movq %r9, %r10
+/APP
+ movq 80(%rcx),%rax
+ mulq 120(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 88(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 96(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r12
+ movq %rsi, %rax
+ movq %r9, %rsi
+/APP
+ addq %r8,%rbx
+ adcq %r12,%r11
+ adcq %rax,%r10
+ addq %r8,%rbx
+ adcq %r12,%r11
+ adcq %rax,%r10
+
+/NO_APP
+ movq %r9, %r12
+ movq %rbx, -88(%rbp)
+ movq %r11, %r13
+ movq %r10, %r11
+/APP
+ movq 88(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%r13
+ adcq %rdx,%r11
+ adcq $0,%r12
+ addq %rax,%r13
+ adcq %rdx,%r11
+ adcq $0,%r12
+
+/NO_APP
+ movq %r12, %rdi
+/APP
+ movq 96(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r13
+ adcq %rdx,%r11
+ adcq $0,%rdi
+ addq %rax,%r13
+ adcq %rdx,%r11
+ adcq $0,%rdi
+
+/NO_APP
+ movq %r11, %rbx
+ movq %rdi, %r10
+ movq %r9, %r11
+/APP
+ movq 104(%rcx),%rax
+ mulq %rax
+ addq %rax,%r13
+ adcq %rdx,%rbx
+ adcq $0,%r10
+
+/NO_APP
+ movq %r13, -80(%rbp)
+ movq %r10, %r8
+ movq %rbx, %r10
+/APP
+ movq 96(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%r10
+ adcq %rdx,%r8
+ adcq $0,%rsi
+ addq %rax,%r10
+ adcq %rdx,%r8
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r8, %r12
+ movq %rsi, %rbx
+/APP
+ movq 104(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r10
+ adcq %rdx,%r12
+ adcq $0,%rbx
+ addq %rax,%r10
+ adcq %rdx,%r12
+ adcq $0,%rbx
+
+/NO_APP
+ movq %r10, -72(%rbp)
+ movq %rbx, %r13
+ movq %r12, %rbx
+/APP
+ movq 104(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%rbx
+ adcq %rdx,%r13
+ adcq $0,%r11
+ addq %rax,%rbx
+ adcq %rdx,%r13
+ adcq $0,%r11
+
+/NO_APP
+ movq %r11, %r12
+ movq %r13, %r10
+/APP
+ movq 112(%rcx),%rax
+ mulq %rax
+ addq %rax,%rbx
+ adcq %rdx,%r10
+ adcq $0,%r12
+
+/NO_APP
+ movq %rbx, -64(%rbp)
+ movq %r10, %rdi
+ movq %r9, %rbx
+ movq %r12, %rsi
+/APP
+ movq 112(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rbx
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%rbx
+
+/NO_APP
+ movq %rdi, -56(%rbp)
+ movq %rbx, %r8
+/APP
+ movq 120(%rcx),%rax
+ mulq %rax
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%r9
+
+/NO_APP
+ movq %rsi, -48(%rbp)
+ movq 16(%r14), %rdi
+ leaq -288(%rbp), %rsi
+ movl $256, %edx
+ movq %r8, -40(%rbp)
+ movl $32, 8(%r14)
+ movl $0, (%r14)
+ call memcpy@PLT
+ movl 8(%r14), %edx
+ testl %edx, %edx
+ je .L232
+ leal -1(%rdx), %ecx
+ movq 16(%r14), %rsi
+ mov %ecx, %r9d
+ cmpq $0, (%rsi,%r9,8)
+ jne .L230
+ movl %ecx, %edx
+ .align 16
+.L231:
+ testl %edx, %edx
+ movl %edx, %ecx
+ je .L235
+ decl %edx
+ mov %edx, %eax
+ cmpq $0, (%rsi,%rax,8)
+ je .L231
+ movl %ecx, 8(%r14)
+ movl %ecx, %edx
+.L230:
+ testl %edx, %edx
+ je .L232
+ movl (%r14), %eax
+ movl %eax, (%r14)
+ addq $256, %rsp
+ popq %rbx
+ popq %r12
+ popq %r13
+ popq %r14
+ leave
+ ret
+.L235:
+ movl %edx, 8(%r14)
+ .align 16
+.L232:
+ xorl %eax, %eax
+ movl %eax, (%r14)
+ addq $256, %rsp
+ popq %rbx
+ popq %r12
+ popq %r13
+ popq %r14
+ leave
+ ret
+.LFE8:
+ .size s_mp_sqr_comba_16, .-s_mp_sqr_comba_16
+ .align 16
+.globl s_mp_sqr_comba_32
+ .type s_mp_sqr_comba_32, @function
+s_mp_sqr_comba_32:
+.LFB9:
+ pushq %rbp
+.LCFI32:
+ xorl %r10d, %r10d
+ movq %r10, %r8
+ movq %r10, %r11
+ movq %rsp, %rbp
+.LCFI33:
+ pushq %r14
+.LCFI34:
+ movq %rsi, %r14
+ movq %r10, %rsi
+ pushq %r13
+.LCFI35:
+ movq %r10, %r13
+ pushq %r12
+.LCFI36:
+ movq %r10, %r12
+ pushq %rbx
+.LCFI37:
+ movq %r10, %rbx
+ subq $512, %rsp
+.LCFI38:
+ movq 16(%rdi), %rcx
+/APP
+ movq (%rcx),%rax
+ mulq %rax
+ addq %rax,%r8
+ adcq %rdx,%rbx
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r8, -544(%rbp)
+/APP
+ movq (%rcx),%rax
+ mulq 8(%rcx)
+ addq %rax,%rbx
+ adcq %rdx,%rsi
+ adcq $0,%r12
+ addq %rax,%rbx
+ adcq %rdx,%rsi
+ adcq $0,%r12
+
+/NO_APP
+ movq %rbx, -536(%rbp)
+/APP
+ movq (%rcx),%rax
+ mulq 16(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r12
+ adcq $0,%r13
+ addq %rax,%rsi
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r12, %rbx
+ movq %r13, %r9
+/APP
+ movq 8(%rcx),%rax
+ mulq %rax
+ addq %rax,%rsi
+ adcq %rdx,%rbx
+ adcq $0,%r9
+
+/NO_APP
+ movq %rsi, -528(%rbp)
+ movq %r9, %rdi
+ movq %r10, %rsi
+ movq %rbx, %r9
+/APP
+ movq (%rcx),%rax
+ mulq 24(%rcx)
+ addq %rax,%r9
+ adcq %rdx,%rdi
+ adcq $0,%r11
+ addq %rax,%r9
+ adcq %rdx,%rdi
+ adcq $0,%r11
+
+/NO_APP
+ movq %rdi, %r12
+ movq %r11, %r13
+ movq %r10, %rdi
+/APP
+ movq 8(%rcx),%rax
+ mulq 16(%rcx)
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r10, %r11
+ movq %r9, -520(%rbp)
+ movq %r13, %r8
+ movq %r12, %r13
+ movq %r10, %r12
+/APP
+ movq (%rcx),%rax
+ mulq 32(%rcx)
+ addq %rax,%r13
+ adcq %rdx,%r8
+ adcq $0,%r12
+ addq %rax,%r13
+ adcq %rdx,%r8
+ adcq $0,%r12
+
+ movq 8(%rcx),%rax
+ mulq 24(%rcx)
+ addq %rax,%r13
+ adcq %rdx,%r8
+ adcq $0,%r12
+ addq %rax,%r13
+ adcq %rdx,%r8
+ adcq $0,%r12
+
+/NO_APP
+ movq %r8, %rbx
+ movq %r12, %r9
+ movq %r10, %r8
+/APP
+ movq 16(%rcx),%rax
+ mulq %rax
+ addq %rax,%r13
+ adcq %rdx,%rbx
+ adcq $0,%r9
+
+/NO_APP
+ movq %r13, -512(%rbp)
+/APP
+ movq (%rcx),%rax
+ mulq 40(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 32(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 24(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%rbx
+ adcq %rdi,%r9
+ adcq %rsi,%r11
+ addq %r8,%rbx
+ adcq %rdi,%r9
+ adcq %rsi,%r11
+
+/NO_APP
+ movq %rbx, -504(%rbp)
+/APP
+ movq (%rcx),%rax
+ mulq 48(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 40(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 32(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r10, %rax
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r9
+ adcq %r13,%r11
+ adcq %r12,%rax
+ addq %r8,%r9
+ adcq %r13,%r11
+ adcq %r12,%rax
+
+/NO_APP
+ movq %rax, %rdx
+ movq %r11, %rbx
+ movq %r13, %rdi
+ movq %rdx, %r11
+ movq %r12, %rsi
+/APP
+ movq 24(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%rbx
+ adcq $0,%r11
+
+/NO_APP
+ movq %r9, -496(%rbp)
+ movq %r11, %r9
+/APP
+ movq (%rcx),%rax
+ mulq 56(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 40(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 32(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r10, %rdx
+/APP
+ addq %r8,%rbx
+ adcq %rdi,%r9
+ adcq %rsi,%rdx
+ addq %r8,%rbx
+ adcq %rdi,%r9
+ adcq %rsi,%rdx
+
+/NO_APP
+ movq %rdx, %r11
+ movq %rbx, -488(%rbp)
+ movq %r10, %rbx
+/APP
+ movq (%rcx),%rax
+ mulq 64(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 40(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r9
+ adcq %r13,%r11
+ adcq %r12,%rbx
+ addq %r8,%r9
+ adcq %r13,%r11
+ adcq %r12,%rbx
+
+ movq 32(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r11
+ adcq $0,%rbx
+
+/NO_APP
+ movq %r13, %rdi
+ movq %r9, -480(%rbp)
+ movq %r12, %rsi
+ movq %rbx, %r9
+ movq %r10, %r12
+/APP
+ movq (%rcx),%rax
+ mulq 72(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 40(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%r11
+ adcq %rdi,%r9
+ adcq %rsi,%r12
+ addq %r8,%r11
+ adcq %rdi,%r9
+ adcq %rsi,%r12
+
+/NO_APP
+ movq %r11, -472(%rbp)
+ movq %r12, %rbx
+/APP
+ movq (%rcx),%rax
+ mulq 80(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r10, %rax
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r9
+ adcq %r13,%rbx
+ adcq %r12,%rax
+ addq %r8,%r9
+ adcq %r13,%rbx
+ adcq %r12,%rax
+
+/NO_APP
+ movq %rax, %rdx
+ movq %rbx, %r11
+ movq %r13, %rdi
+ movq %rdx, %rbx
+ movq %r12, %rsi
+/APP
+ movq 40(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r11
+ adcq $0,%rbx
+
+/NO_APP
+ movq %r9, -464(%rbp)
+ movq %rbx, %r9
+/APP
+ movq (%rcx),%rax
+ mulq 88(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 48(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r10, %rdx
+/APP
+ addq %r8,%r11
+ adcq %rdi,%r9
+ adcq %rsi,%rdx
+ addq %r8,%r11
+ adcq %rdi,%r9
+ adcq %rsi,%rdx
+
+/NO_APP
+ movq %rdx, %r13
+ movq %r11, -456(%rbp)
+ movq %r13, %r12
+ movq %r10, %r13
+/APP
+ movq (%rcx),%rax
+ mulq 96(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %rax
+ movq %rsi, %r11
+/APP
+ addq %r8,%r9
+ adcq %rax,%r12
+ adcq %r11,%r13
+ addq %r8,%r9
+ adcq %rax,%r12
+ adcq %r11,%r13
+
+/NO_APP
+ movq %rax, %rbx
+ movq %r11, %rsi
+/APP
+ movq 48(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %rbx, %rdi
+ movq %r9, -448(%rbp)
+ movq %r13, %r9
+/APP
+ movq (%rcx),%rax
+ mulq 104(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+/NO_APP
+ movq %r10, %r13
+/APP
+ movq 8(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 56(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%r12
+ adcq %rdi,%r9
+ adcq %rsi,%r13
+ addq %r8,%r12
+ adcq %rdi,%r9
+ adcq %rsi,%r13
+
+/NO_APP
+ movq %r12, -440(%rbp)
+ movq %r10, %r12
+/APP
+ movq (%rcx),%rax
+ mulq 112(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r13, %rdx
+ movq %rdi, %rbx
+ movq %rsi, %r13
+/APP
+ addq %r8,%r9
+ adcq %rbx,%rdx
+ adcq %r13,%r12
+ addq %r8,%r9
+ adcq %rbx,%rdx
+ adcq %r13,%r12
+
+/NO_APP
+ movq %r12, %rax
+ movq %r13, %r11
+ movq %rdx, %r12
+ movq %rax, %r13
+ movq %rbx, %rdi
+ movq %r11, %rsi
+/APP
+ movq 56(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r9, -432(%rbp)
+ movq %r13, %r9
+ movq %r10, %r13
+/APP
+ movq (%rcx),%rax
+ mulq 120(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 8(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 56(%rcx),%rax
+ mulq 64(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r8, %rax
+ movq %rdi, %rdx
+ movq %rsi, %rbx
+/APP
+ addq %rax,%r12
+ adcq %rdx,%r9
+ adcq %rbx,%r13
+ addq %rax,%r12
+ adcq %rdx,%r9
+ adcq %rbx,%r13
+
+/NO_APP
+ movq %r12, -424(%rbp)
+ movq %rdx, %r8
+ movq %rax, %rsi
+ movq %rbx, %rdi
+ movq %r13, %r12
+ movq %r10, %r13
+/APP
+ movq (%rcx),%rax
+ mulq 128(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 8(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 16(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 24(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %rsi, %rax
+ movq %r8, %rbx
+ movq %rdi, %rdx
+/APP
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %rdx, %r11
+ movq %rax, %r8
+ movq %rbx, %rdi
+/APP
+ movq 64(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r11, %rsi
+ movq %r9, -416(%rbp)
+ movq %r13, %r9
+/APP
+ movq (%rcx),%rax
+ mulq 136(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+/NO_APP
+ movq %r10, %r13
+/APP
+ movq 8(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 56(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 64(%rcx),%rax
+ mulq 72(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r8, %rbx
+ movq %rdi, %rax
+ movq %rsi, %rdx
+/APP
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %r12, -408(%rbp)
+ movq %rdx, %rdi
+ movq %rax, %r8
+ movq %rbx, %rsi
+ movq %r13, %r12
+ movq %r10, %r13
+/APP
+ movq (%rcx),%rax
+ mulq 144(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 8(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 16(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 24(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %rsi, %rax
+ movq %r8, %rbx
+ movq %rdi, %rdx
+/APP
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %rdx, %r11
+ movq %rax, %r8
+ movq %rbx, %rdi
+/APP
+ movq 72(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r11, %rsi
+ movq %r9, -400(%rbp)
+ movq %r13, %r9
+/APP
+ movq (%rcx),%rax
+ mulq 152(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+/NO_APP
+ movq %r10, %r13
+/APP
+ movq 8(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 56(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 64(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 72(%rcx),%rax
+ mulq 80(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r8, %rbx
+ movq %rdi, %rax
+ movq %rsi, %rdx
+/APP
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %r12, -392(%rbp)
+ movq %rdx, %rdi
+ movq %rax, %r8
+ movq %rbx, %rsi
+ movq %r13, %r12
+ movq %r10, %r13
+/APP
+ movq (%rcx),%rax
+ mulq 160(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 8(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 16(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 24(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %rsi, %rax
+ movq %r8, %rbx
+ movq %rdi, %rdx
+/APP
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %rdx, %r11
+ movq %rax, %r8
+ movq %rbx, %rdi
+/APP
+ movq 80(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r11, %rsi
+ movq %r9, -384(%rbp)
+ movq %r13, %r9
+/APP
+ movq (%rcx),%rax
+ mulq 168(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+/NO_APP
+ movq %r10, %r13
+/APP
+ movq 8(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 56(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 64(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 72(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 80(%rcx),%rax
+ mulq 88(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r8, %rbx
+ movq %rdi, %rax
+ movq %rsi, %rdx
+/APP
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %r12, -376(%rbp)
+ movq %rdx, %rdi
+ movq %rax, %r8
+ movq %rbx, %rsi
+ movq %r13, %r12
+ movq %r10, %r13
+/APP
+ movq (%rcx),%rax
+ mulq 176(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 8(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 16(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 24(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %rsi, %rax
+ movq %r8, %rbx
+ movq %rdi, %rdx
+/APP
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %rdx, %r11
+ movq %rax, %r8
+ movq %rbx, %rdi
+/APP
+ movq 88(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r11, %rsi
+ movq %r9, -368(%rbp)
+ movq %r13, %r9
+/APP
+ movq (%rcx),%rax
+ mulq 184(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+/NO_APP
+ movq %r10, %r13
+/APP
+ movq 8(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 16(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 24(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 32(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 40(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 48(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 56(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 64(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 72(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 80(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 88(%rcx),%rax
+ mulq 96(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r8, %rbx
+ movq %rdi, %rax
+ movq %rsi, %rdx
+/APP
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %rdx, %rdi
+ movq %r12, -360(%rbp)
+ movq %rax, %r8
+ movq %rbx, %rsi
+ movq %r13, %r12
+ movq %r10, %r13
+/APP
+ movq (%rcx),%rax
+ mulq 192(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 8(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 16(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 24(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %r8, %rbx
+ movq %rdi, %rax
+/APP
+ addq %rsi,%r9
+ adcq %rbx,%r12
+ adcq %rax,%r13
+ addq %rsi,%r9
+ adcq %rbx,%r12
+ adcq %rax,%r13
+
+/NO_APP
+ movq %rax, %r11
+ movq %rbx, %r8
+/APP
+ movq 96(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r11, %rdi
+ movq %r9, -352(%rbp)
+ movq %r13, %r9
+/APP
+ movq (%rcx),%rax
+ mulq 200(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+/NO_APP
+ movq %r10, %r13
+/APP
+ movq 8(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 16(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 24(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 104(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ addq %rsi,%r12
+ adcq %r8,%r9
+ adcq %rdi,%r13
+ addq %rsi,%r12
+ adcq %r8,%r9
+ adcq %rdi,%r13
+
+/NO_APP
+ movq %r12, -344(%rbp)
+ movq %r10, %r12
+/APP
+ movq (%rcx),%rax
+ mulq 208(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 8(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 16(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 24(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %r13, %rdx
+ movq %r8, %rbx
+ movq %rdi, %r13
+/APP
+ addq %rsi,%r9
+ adcq %rbx,%rdx
+ adcq %r13,%r12
+ addq %rsi,%r9
+ adcq %rbx,%rdx
+ adcq %r13,%r12
+
+/NO_APP
+ movq %r12, %rax
+ movq %r13, %r11
+ movq %rdx, %r12
+ movq %rax, %r13
+ movq %rbx, %r8
+ movq %r11, %rdi
+/APP
+ movq 104(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r9, -336(%rbp)
+ movq %r13, %r9
+ movq %r10, %r13
+/APP
+ movq (%rcx),%rax
+ mulq 216(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 8(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 16(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 24(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 112(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ addq %rsi,%r12
+ adcq %r8,%r9
+ adcq %rdi,%r13
+ addq %rsi,%r12
+ adcq %r8,%r9
+ adcq %rdi,%r13
+
+/NO_APP
+ movq %r12, -328(%rbp)
+/APP
+ movq (%rcx),%rax
+ mulq 224(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 8(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 16(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 24(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %r13, %rax
+ movq %r10, %rdx
+ movq %r8, %rbx
+ movq %rdi, %r12
+/APP
+ addq %rsi,%r9
+ adcq %rbx,%rax
+ adcq %r12,%rdx
+ addq %rsi,%r9
+ adcq %rbx,%rax
+ adcq %r12,%rdx
+
+/NO_APP
+ movq %rdx, %rdi
+ movq %r12, %r11
+ movq %rbx, %r8
+ movq %rax, %r12
+ movq %rdi, %r13
+ movq %r11, %rdi
+/APP
+ movq 112(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r9, -320(%rbp)
+ movq %r13, %rbx
+ movq %r10, %r9
+/APP
+ movq (%rcx),%rax
+ mulq 232(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 8(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 16(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 24(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 112(%rcx),%rax
+ mulq 120(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ addq %rsi,%r12
+ adcq %r8,%rbx
+ adcq %rdi,%r9
+ addq %rsi,%r12
+ adcq %r8,%rbx
+ adcq %rdi,%r9
+
+/NO_APP
+ movq %r12, -312(%rbp)
+ movq %r9, %r13
+/APP
+ movq (%rcx),%rax
+ mulq 240(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 8(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 16(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 24(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 112(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %r10, %rax
+ movq %r8, %r11
+ movq %rdi, %rdx
+/APP
+ addq %rsi,%rbx
+ adcq %r11,%r13
+ adcq %rdx,%rax
+ addq %rsi,%rbx
+ adcq %r11,%r13
+ adcq %rdx,%rax
+
+/NO_APP
+ movq %rdx, %r9
+ movq %rax, %rdx
+ movq %r13, %r12
+ movq %r11, %r8
+ movq %rdx, %r13
+ movq %r9, %rdi
+/APP
+ movq 120(%rcx),%rax
+ mulq %rax
+ addq %rax,%rbx
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %rbx, -304(%rbp)
+ movq %r13, %rbx
+ movq %r10, %r13
+/APP
+ movq (%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 8(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 16(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 24(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 112(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 120(%rcx),%rax
+ mulq 128(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ addq %rsi,%r12
+ adcq %r8,%rbx
+ adcq %rdi,%r13
+ addq %rsi,%r12
+ adcq %r8,%rbx
+ adcq %rdi,%r13
+
+/NO_APP
+ movq %r12, -296(%rbp)
+ movq %r13, %r12
+ movq %r10, %r13
+/APP
+ movq 8(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 16(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 24(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 112(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 120(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %r8, %r11
+ movq %rdi, %rax
+/APP
+ addq %rsi,%rbx
+ adcq %r11,%r12
+ adcq %rax,%r13
+ addq %rsi,%rbx
+ adcq %r11,%r12
+ adcq %rax,%r13
+
+/NO_APP
+ movq %rax, %r9
+ movq %r11, %r8
+/APP
+ movq 128(%rcx),%rax
+ mulq %rax
+ addq %rax,%rbx
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r9, %rdi
+ movq %rbx, -288(%rbp)
+ movq %r13, %r9
+/APP
+ movq 16(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+/NO_APP
+ movq %r10, %r13
+/APP
+ movq 24(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 112(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 120(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 128(%rcx),%rax
+ mulq 136(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ addq %rsi,%r12
+ adcq %r8,%r9
+ adcq %rdi,%r13
+ addq %rsi,%r12
+ adcq %r8,%r9
+ adcq %rdi,%r13
+
+/NO_APP
+ movq %r12, -280(%rbp)
+ movq %r10, %r12
+/APP
+ movq 24(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 32(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 112(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 120(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 128(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %r13, %rdx
+ movq %r8, %rbx
+ movq %rdi, %r13
+/APP
+ addq %rsi,%r9
+ adcq %rbx,%rdx
+ adcq %r13,%r12
+ addq %rsi,%r9
+ adcq %rbx,%rdx
+ adcq %r13,%r12
+
+/NO_APP
+ movq %r12, %rax
+ movq %r13, %r11
+ movq %rdx, %r12
+ movq %rax, %r13
+ movq %rbx, %r8
+ movq %r11, %rdi
+/APP
+ movq 136(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r9, -272(%rbp)
+ movq %r13, %r9
+ movq %r10, %r13
+/APP
+ movq 32(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 40(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 112(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 120(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 128(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 136(%rcx),%rax
+ mulq 144(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ addq %rsi,%r12
+ adcq %r8,%r9
+ adcq %rdi,%r13
+ addq %rsi,%r12
+ adcq %r8,%r9
+ adcq %rdi,%r13
+
+/NO_APP
+ movq %r12, -264(%rbp)
+/APP
+ movq 40(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 48(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 112(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 120(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 128(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 136(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %r13, %rax
+ movq %r10, %rdx
+ movq %r8, %rbx
+ movq %rdi, %r12
+/APP
+ addq %rsi,%r9
+ adcq %rbx,%rax
+ adcq %r12,%rdx
+ addq %rsi,%r9
+ adcq %rbx,%rax
+ adcq %r12,%rdx
+
+/NO_APP
+ movq %rdx, %rdi
+ movq %r12, %r11
+ movq %rbx, %r8
+ movq %rax, %r12
+ movq %rdi, %r13
+ movq %r11, %rdi
+/APP
+ movq 144(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r10, %r11
+ movq %r9, -256(%rbp)
+ movq %r13, %r9
+/APP
+ movq 48(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 56(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 112(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 120(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 128(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 136(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 144(%rcx),%rax
+ mulq 152(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ addq %rsi,%r12
+ adcq %r8,%r9
+ adcq %rdi,%r11
+ addq %rsi,%r12
+ adcq %r8,%r9
+ adcq %rdi,%r11
+
+/NO_APP
+ movq %r12, -248(%rbp)
+ movq %r11, %r13
+/APP
+ movq 56(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 64(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 72(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 112(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 120(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 128(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 136(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 144(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %r10, %rax
+ movq %rsi, %rdx
+ movq %r8, %rbx
+ movq %rdi, %r12
+/APP
+ addq %rdx,%r9
+ adcq %rbx,%r13
+ adcq %r12,%rax
+ addq %rdx,%r9
+ adcq %rbx,%r13
+ adcq %r12,%rax
+
+/NO_APP
+ movq %r12, %r11
+ movq %rdx, %r8
+ movq %rax, %rdx
+ movq %r13, %r12
+ movq %rbx, %rdi
+ movq %rdx, %r13
+ movq %r11, %rsi
+/APP
+ movq 152(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r9, -240(%rbp)
+ movq %r13, %r9
+ movq %r10, %r13
+/APP
+ movq 64(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 72(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 80(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 88(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 96(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 104(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 112(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 120(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 128(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 136(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 144(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 152(%rcx),%rax
+ mulq 160(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r8, %rax
+ movq %rdi, %rdx
+ movq %rsi, %rbx
+/APP
+ addq %rax,%r12
+ adcq %rdx,%r9
+ adcq %rbx,%r13
+ addq %rax,%r12
+ adcq %rdx,%r9
+ adcq %rbx,%r13
+
+/NO_APP
+ movq %r12, -232(%rbp)
+ movq %rdx, %r8
+ movq %rax, %rsi
+ movq %rbx, %rdi
+ movq %r13, %r12
+ movq %r10, %r13
+/APP
+ movq 72(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 80(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 88(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 112(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 120(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 128(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 136(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 144(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 152(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %rsi, %rax
+ movq %r8, %rbx
+ movq %rdi, %rdx
+/APP
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %rdx, %r11
+ movq %rax, %r8
+ movq %rbx, %rdi
+/APP
+ movq 160(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r11, %rsi
+ movq %r9, -224(%rbp)
+ movq %r13, %r9
+/APP
+ movq 80(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+/NO_APP
+ movq %r10, %r13
+/APP
+ movq 88(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 96(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 104(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 112(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 120(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 128(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 136(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 144(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 152(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 160(%rcx),%rax
+ mulq 168(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r8, %rbx
+ movq %rdi, %rax
+ movq %rsi, %rdx
+/APP
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %r12, -216(%rbp)
+ movq %rdx, %rdi
+ movq %rax, %r8
+ movq %rbx, %rsi
+ movq %r13, %r12
+ movq %r10, %r13
+/APP
+ movq 88(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 96(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 104(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 112(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 120(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 128(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 136(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 144(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 152(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 160(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %rsi, %rax
+ movq %r8, %rbx
+ movq %rdi, %rdx
+/APP
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %rdx, %r11
+ movq %rax, %r8
+ movq %rbx, %rdi
+/APP
+ movq 168(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r11, %rsi
+ movq %r9, -208(%rbp)
+ movq %r13, %r9
+/APP
+ movq 96(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+/NO_APP
+ movq %r10, %r13
+/APP
+ movq 104(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 112(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 120(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 128(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 136(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 144(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 152(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 160(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 168(%rcx),%rax
+ mulq 176(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r8, %rbx
+ movq %rdi, %rax
+ movq %rsi, %rdx
+/APP
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %r12, -200(%rbp)
+ movq %rdx, %rdi
+ movq %rax, %r8
+ movq %rbx, %rsi
+ movq %r13, %r12
+ movq %r10, %r13
+/APP
+ movq 104(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 112(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 120(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 128(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 136(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 144(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 152(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 160(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 168(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %rsi, %rax
+ movq %r8, %rbx
+ movq %rdi, %rdx
+/APP
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %rdx, %r11
+ movq %rax, %r8
+ movq %rbx, %rdi
+/APP
+ movq 176(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r11, %rsi
+ movq %r9, -192(%rbp)
+ movq %r13, %r9
+/APP
+ movq 112(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+/NO_APP
+ movq %r10, %r13
+/APP
+ movq 120(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 128(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 136(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 144(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 152(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 160(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 168(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 176(%rcx),%rax
+ mulq 184(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r8, %rbx
+ movq %rdi, %rax
+ movq %rsi, %rdx
+/APP
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+ addq %rbx,%r12
+ adcq %rax,%r9
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %r12, -184(%rbp)
+ movq %rdx, %rdi
+ movq %rax, %r8
+ movq %rbx, %rsi
+ movq %r13, %r12
+ movq %r10, %r13
+/APP
+ movq 120(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%rsi
+ movq %rdx,%r8
+ xorq %rdi,%rdi
+
+ movq 128(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 136(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 144(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 152(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 160(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 168(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+ movq 176(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%rdi
+
+/NO_APP
+ movq %rsi, %rax
+ movq %r8, %rbx
+ movq %rdi, %rdx
+/APP
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+ addq %rax,%r9
+ adcq %rbx,%r12
+ adcq %rdx,%r13
+
+/NO_APP
+ movq %rdx, %r11
+ movq %rax, %r8
+ movq %rbx, %rdi
+/APP
+ movq 184(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r11, %rsi
+ movq %r9, -176(%rbp)
+ movq %r13, %r9
+/APP
+ movq 128(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+/NO_APP
+ movq %r10, %r13
+/APP
+ movq 136(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 144(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 152(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 160(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 168(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 176(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 184(%rcx),%rax
+ mulq 192(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%r12
+ adcq %rdi,%r9
+ adcq %rsi,%r13
+ addq %r8,%r12
+ adcq %rdi,%r9
+ adcq %rsi,%r13
+
+/NO_APP
+ movq %r12, -168(%rbp)
+ movq %r13, %r12
+ movq %r10, %r13
+/APP
+ movq 136(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 144(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 152(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 160(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 168(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 176(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 184(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %rbx
+ movq %rsi, %rax
+/APP
+ addq %r8,%r9
+ adcq %rbx,%r12
+ adcq %rax,%r13
+ addq %r8,%r9
+ adcq %rbx,%r12
+ adcq %rax,%r13
+
+/NO_APP
+ movq %rax, %r11
+ movq %rbx, %rdi
+ movq %r10, %rbx
+/APP
+ movq 192(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r11, %rsi
+ movq %r9, -160(%rbp)
+ movq %r13, %r9
+/APP
+ movq 144(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 152(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 160(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 168(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 176(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 184(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 192(%rcx),%rax
+ mulq 200(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%r12
+ adcq %rdi,%r9
+ adcq %rsi,%rbx
+ addq %r8,%r12
+ adcq %rdi,%r9
+ adcq %rsi,%rbx
+
+/NO_APP
+ movq %r12, -152(%rbp)
+/APP
+ movq 152(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 160(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 168(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 176(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 184(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 192(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r10, %rdx
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r9
+ adcq %r13,%rbx
+ adcq %r12,%rdx
+ addq %r8,%r9
+ adcq %r13,%rbx
+ adcq %r12,%rdx
+
+/NO_APP
+ movq %rdx, %rax
+ movq %r13, %rdi
+ movq %r12, %rsi
+ movq %rax, %r11
+ movq %r10, %r12
+/APP
+ movq 200(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%rbx
+ adcq $0,%r11
+
+/NO_APP
+ movq %r9, -144(%rbp)
+ movq %r11, %r9
+/APP
+ movq 160(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 168(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 176(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 184(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 192(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 200(%rcx),%rax
+ mulq 208(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%rbx
+ adcq %rdi,%r9
+ adcq %rsi,%r12
+ addq %r8,%rbx
+ adcq %rdi,%r9
+ adcq %rsi,%r12
+
+/NO_APP
+ movq %rbx, -136(%rbp)
+ movq %r12, %r11
+/APP
+ movq 168(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 176(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 184(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 192(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 200(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r10, %rax
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r9
+ adcq %r13,%r11
+ adcq %r12,%rax
+ addq %r8,%r9
+ adcq %r13,%r11
+ adcq %r12,%rax
+
+/NO_APP
+ movq %rax, %rdx
+ movq %r11, %rbx
+ movq %r13, %rdi
+ movq %rdx, %r11
+ movq %r12, %rsi
+/APP
+ movq 208(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%rbx
+ adcq $0,%r11
+
+/NO_APP
+ movq %r9, -128(%rbp)
+ movq %r11, %r9
+/APP
+ movq 176(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 184(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 192(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 200(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 208(%rcx),%rax
+ mulq 216(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r10, %rdx
+/APP
+ addq %r8,%rbx
+ adcq %rdi,%r9
+ adcq %rsi,%rdx
+ addq %r8,%rbx
+ adcq %rdi,%r9
+ adcq %rsi,%rdx
+
+/NO_APP
+ movq %rbx, -120(%rbp)
+ movq %rdx, %r11
+ movq %r10, %rbx
+/APP
+ movq 184(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 192(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 200(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 208(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r9
+ adcq %r13,%r11
+ adcq %r12,%rbx
+ addq %r8,%r9
+ adcq %r13,%r11
+ adcq %r12,%rbx
+
+/NO_APP
+ movq %rbx, %rdx
+ movq %r13, %rdi
+ movq %r11, %rbx
+ movq %r12, %rsi
+ movq %rdx, %r11
+ movq %r10, %r12
+/APP
+ movq 216(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%rbx
+ adcq $0,%r11
+
+/NO_APP
+ movq %r9, -112(%rbp)
+ movq %r11, %r9
+/APP
+ movq 192(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 200(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 208(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 216(%rcx),%rax
+ mulq 224(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ addq %r8,%rbx
+ adcq %rdi,%r9
+ adcq %rsi,%r12
+ addq %r8,%rbx
+ adcq %rdi,%r9
+ adcq %rsi,%r12
+
+/NO_APP
+ movq %rbx, -104(%rbp)
+ movq %r12, %r11
+/APP
+ movq 200(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 208(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 216(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %r10, %rax
+ movq %rdi, %r13
+ movq %rsi, %r12
+/APP
+ addq %r8,%r9
+ adcq %r13,%r11
+ adcq %r12,%rax
+ addq %r8,%r9
+ adcq %r13,%r11
+ adcq %r12,%rax
+
+/NO_APP
+ movq %rax, %rdx
+ movq %r11, %rbx
+ movq %r13, %rdi
+ movq %rdx, %r11
+ movq %r12, %rsi
+ movq %r10, %r12
+/APP
+ movq 224(%rcx),%rax
+ mulq %rax
+ addq %rax,%r9
+ adcq %rdx,%rbx
+ adcq $0,%r11
+
+/NO_APP
+ movq %r9, -96(%rbp)
+ movq %r10, %r9
+/APP
+ movq 208(%rcx),%rax
+ mulq 248(%rcx)
+ movq %rax,%r8
+ movq %rdx,%rdi
+ xorq %rsi,%rsi
+
+ movq 216(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+ movq 224(%rcx),%rax
+ mulq 232(%rcx)
+ addq %rax,%r8
+ adcq %rdx,%rdi
+ adcq $0,%rsi
+
+/NO_APP
+ movq %rdi, %r13
+ movq %rsi, %rax
+/APP
+ addq %r8,%rbx
+ adcq %r13,%r11
+ adcq %rax,%r9
+ addq %r8,%rbx
+ adcq %r13,%r11
+ adcq %rax,%r9
+
+/NO_APP
+ movq %rbx, -88(%rbp)
+ movq %r11, %rsi
+ movq %r9, %r8
+/APP
+ movq 216(%rcx),%rax
+ mulq 248(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%r12
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%r12
+
+/NO_APP
+ movq %r12, %r11
+/APP
+ movq 224(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%r11
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%r11
+
+/NO_APP
+ movq %r8, %r13
+ movq %r11, %rbx
+/APP
+ movq 232(%rcx),%rax
+ mulq %rax
+ addq %rax,%rsi
+ adcq %rdx,%r13
+ adcq $0,%rbx
+
+/NO_APP
+ movq %rsi, -80(%rbp)
+ movq %rbx, %r12
+ movq %r13, %rdi
+ movq %r10, %r13
+/APP
+ movq 224(%rcx),%rax
+ mulq 248(%rcx)
+ addq %rax,%rdi
+ adcq %rdx,%r12
+ adcq $0,%r13
+ addq %rax,%rdi
+ adcq %rdx,%r12
+ adcq $0,%r13
+
+/NO_APP
+ movq %r12, %r9
+ movq %r13, %r12
+/APP
+ movq 232(%rcx),%rax
+ mulq 240(%rcx)
+ addq %rax,%rdi
+ adcq %rdx,%r9
+ adcq $0,%r12
+ addq %rax,%rdi
+ adcq %rdx,%r9
+ adcq $0,%r12
+
+/NO_APP
+ movq %rdi, -72(%rbp)
+ movq %r9, %r11
+ movq %r12, %rbx
+ movq %r10, %r9
+/APP
+ movq 232(%rcx),%rax
+ mulq 248(%rcx)
+ addq %rax,%r11
+ adcq %rdx,%rbx
+ adcq $0,%r9
+ addq %rax,%r11
+ adcq %rdx,%rbx
+ adcq $0,%r9
+
+/NO_APP
+ movq %rbx, %r13
+ movq %r9, %rbx
+ movq %r10, %r9
+/APP
+ movq 240(%rcx),%rax
+ mulq %rax
+ addq %rax,%r11
+ adcq %rdx,%r13
+ adcq $0,%rbx
+
+/NO_APP
+ movq %r11, -64(%rbp)
+ movq %r13, %rdi
+ movq %rbx, %rsi
+/APP
+ movq 240(%rcx),%rax
+ mulq 248(%rcx)
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%r9
+ addq %rax,%rdi
+ adcq %rdx,%rsi
+ adcq $0,%r9
+
+/NO_APP
+ movq %rdi, -56(%rbp)
+ movq %r9, %r8
+/APP
+ movq 248(%rcx),%rax
+ mulq %rax
+ addq %rax,%rsi
+ adcq %rdx,%r8
+ adcq $0,%r10
+
+/NO_APP
+ movq %rsi, -48(%rbp)
+ movq 16(%r14), %rdi
+ leaq -544(%rbp), %rsi
+ movl $512, %edx
+ movq %r8, -40(%rbp)
+ movl $64, 8(%r14)
+ movl $0, (%r14)
+ call memcpy@PLT
+ movl 8(%r14), %edx
+ testl %edx, %edx
+ je .L304
+ leal -1(%rdx), %ecx
+ movq 16(%r14), %rsi
+ mov %ecx, %r10d
+ cmpq $0, (%rsi,%r10,8)
+ jne .L302
+ movl %ecx, %edx
+ .align 16
+.L303:
+ testl %edx, %edx
+ movl %edx, %ecx
+ je .L307
+ decl %edx
+ mov %edx, %eax
+ cmpq $0, (%rsi,%rax,8)
+ je .L303
+ movl %ecx, 8(%r14)
+ movl %ecx, %edx
+.L302:
+ testl %edx, %edx
+ je .L304
+ movl (%r14), %eax
+ movl %eax, (%r14)
+ addq $512, %rsp
+ popq %rbx
+ popq %r12
+ popq %r13
+ popq %r14
+ leave
+ ret
+.L307:
+ movl %edx, 8(%r14)
+ .align 16
+.L304:
+ xorl %eax, %eax
+ movl %eax, (%r14)
+ addq $512, %rsp
+ popq %rbx
+ popq %r12
+ popq %r13
+ popq %r14
+ leave
+ ret
+.LFE9:
+ .size s_mp_sqr_comba_32, .-s_mp_sqr_comba_32
diff --git a/security/nss/lib/freebl/mpi/mpcpucache.c b/security/nss/lib/freebl/mpi/mpcpucache.c
new file mode 100644
index 000000000..8adbd33c6
--- /dev/null
+++ b/security/nss/lib/freebl/mpi/mpcpucache.c
@@ -0,0 +1,773 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Red Hat, Inc
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Robert Relyea <rrelyea@redhat.com>
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "mpi.h"
+
+/*
+ * This file implements a single function: s_mpi_getProcessorLineSize();
+ * s_mpi_getProcessorLineSize() returns the size in bytes of the cache line
+ * if a cache exists, or zero if there is no cache. If more than one
+ * cache line exists, it should return the smallest line size (which is
+ * usually the L1 cache).
+ *
+ * mp_modexp uses this information to make sure that private key information
+ * isn't being leaked through the cache.
+ *
+ * Currently the file returns good data for most modern x86 processors, and
+ * reasonable data on 64-bit ppc processors. All other processors are assumed
+ * to have a cache line size of 32 bytes unless modified by target.mk.
+ *
+ */
+
+#if defined(i386) || defined(__i386) || defined(__X86__) || defined (_M_IX86) || defined(__x86_64__) || defined(__x86_64)
+/* X86 processors have special instructions that tell us about the cache */
+#include "string.h"
+
+#if defined(__x86_64__) || defined(__x86_64)
+#define AMD_64 1
+#endif
+
+/* Generic CPUID function */
+#if defined(AMD_64)
+static void cpuid(unsigned long op, unsigned long *eax,
+ unsigned long *ebx, unsigned long *ecx,
+ unsigned long *edx)
+{
+ __asm__("cpuid\n\t"
+ : "=a" (*eax),
+ "=b" (*ebx),
+ "=c" (*ecx),
+ "=d" (*edx)
+ : "0" (op));
+}
+#elif !defined(_MSC_VER)
+static void cpuid(unsigned long op, unsigned long *eax,
+ unsigned long *ebx, unsigned long *ecx,
+ unsigned long *edx)
+{
+/* sigh GCC isn't smart enough to save the ebx PIC register on it's own
+ * in this case, so do it by hand. */
+ __asm__("pushl %%ebx\n\t"
+ "cpuid\n\t"
+ "mov %%ebx,%1\n\t"
+ "popl %%ebx\n\t"
+ : "=a" (*eax),
+ "=r" (*ebx),
+ "=c" (*ecx),
+ "=d" (*edx)
+ : "0" (op));
+}
+
+/*
+ * try flipping a processor flag to determine CPU type
+ */
+static unsigned long changeFlag(unsigned long flag)
+{
+ unsigned long changedFlags, originalFlags;
+ __asm__("pushfl\n\t" /* get the flags */
+ "popl %0\n\t"
+ "movl %0,%1\n\t" /* save the original flags */
+ "xorl %2,%0\n\t" /* flip the bit */
+ "pushl %0\n\t" /* set the flags */
+ "popfl\n\t"
+ "pushfl\n\t" /* get the flags again (for return) */
+ "popl %0\n\t"
+ "pushl %1\n\t" /* restore the original flags */
+ "popfl\n\t"
+ : "=r" (changedFlags),
+ "=r" (originalFlags),
+ "=r" (flag)
+ : "2" (flag));
+ return changedFlags ^ originalFlags;
+}
+
+#else
+
+/*
+ * windows versions of the above assembler
+ */
+#define wcpuid __asm __emit 0fh __asm __emit 0a2h
+static void cpuid(unsigned long op, unsigned long *Reax,
+ unsigned long *Rebx, unsigned long *Recx, unsigned long *Redx)
+{
+ unsigned long Leax, Lebx, Lecx, Ledx;
+ __asm {
+ pushad
+ mov eax,op
+ wcpuid
+ mov Leax,eax
+ mov Lebx,ebx
+ mov Lecx,ecx
+ mov Ledx,edx
+ popad
+ }
+ *Reax = Leax;
+ *Rebx = Lebx;
+ *Recx = Lecx;
+ *Redx = Ledx;
+}
+
+static unsigned long changeFlag(unsigned long flag)
+{
+ unsigned long changedFlags, originalFlags;
+ __asm {
+ push eax
+ push ebx
+ pushfd /* get the flags */
+ pop eax
+ push eax /* save the flags on the stack */
+ mov originalFlags,eax /* save the original flags */
+ mov ebx,flag
+ xor eax,ebx /* flip the bit */
+ push eax /* set the flags */
+ popfd
+ pushfd /* get the flags again (for return) */
+ pop eax
+ popfd /* restore the original flags */
+ mov changedFlags,eax
+ pop ebx
+ pop eax
+ }
+ return changedFlags ^ originalFlags;
+}
+#endif
+
+#if !defined(AMD_64)
+#define AC_FLAG 0x40000
+#define ID_FLAG 0x200000
+
+/* 386 processors can't flip the AC_FLAG, intel AP Note AP-485 */
+static int is386()
+{
+ return changeFlag(AC_FLAG) == 0;
+}
+
+/* 486 processors can't flip the ID_FLAG, intel AP Note AP-485 */
+static int is486()
+{
+ return changeFlag(ID_FLAG) == 0;
+}
+#endif
+
+
+/*
+ * table for Intel Cache.
+ * See Intel Application Note AP-485 for more information
+ */
+
+typedef unsigned char CacheTypeEntry;
+
+typedef enum {
+ Cache_NONE = 0,
+ Cache_UNKNOWN = 1,
+ Cache_TLB = 2,
+ Cache_TLBi = 3,
+ Cache_TLBd = 4,
+ Cache_Trace = 5,
+ Cache_L1 = 6,
+ Cache_L1i = 7,
+ Cache_L1d = 8,
+ Cache_L2 = 9 ,
+ Cache_L2i = 10 ,
+ Cache_L2d = 11 ,
+ Cache_L3 = 12 ,
+ Cache_L3i = 13,
+ Cache_L3d = 14
+} CacheType;
+
+struct _cache {
+ CacheTypeEntry type;
+ unsigned char lineSize;
+};
+static const struct _cache CacheMap[256] = {
+/* 00 */ {Cache_NONE, 0 },
+/* 01 */ {Cache_TLBi, 0 },
+/* 02 */ {Cache_TLBi, 0 },
+/* 03 */ {Cache_TLBd, 0 },
+/* 04 */ {Cache_TLBd, },
+/* 05 */ {Cache_UNKNOWN, 0 },
+/* 06 */ {Cache_L1i, 32 },
+/* 07 */ {Cache_UNKNOWN, 0 },
+/* 08 */ {Cache_L1i, 32 },
+/* 09 */ {Cache_UNKNOWN, 0 },
+/* 0a */ {Cache_L1d, 32 },
+/* 0b */ {Cache_UNKNOWN, 0 },
+/* 0c */ {Cache_L1d, 32 },
+/* 0d */ {Cache_UNKNOWN, 0 },
+/* 0e */ {Cache_UNKNOWN, 0 },
+/* 0f */ {Cache_UNKNOWN, 0 },
+/* 10 */ {Cache_UNKNOWN, 0 },
+/* 11 */ {Cache_UNKNOWN, 0 },
+/* 12 */ {Cache_UNKNOWN, 0 },
+/* 13 */ {Cache_UNKNOWN, 0 },
+/* 14 */ {Cache_UNKNOWN, 0 },
+/* 15 */ {Cache_UNKNOWN, 0 },
+/* 16 */ {Cache_UNKNOWN, 0 },
+/* 17 */ {Cache_UNKNOWN, 0 },
+/* 18 */ {Cache_UNKNOWN, 0 },
+/* 19 */ {Cache_UNKNOWN, 0 },
+/* 1a */ {Cache_UNKNOWN, 0 },
+/* 1b */ {Cache_UNKNOWN, 0 },
+/* 1c */ {Cache_UNKNOWN, 0 },
+/* 1d */ {Cache_UNKNOWN, 0 },
+/* 1e */ {Cache_UNKNOWN, 0 },
+/* 1f */ {Cache_UNKNOWN, 0 },
+/* 20 */ {Cache_UNKNOWN, 0 },
+/* 21 */ {Cache_UNKNOWN, 0 },
+/* 22 */ {Cache_L3, 64 },
+/* 23 */ {Cache_L3, 64 },
+/* 24 */ {Cache_UNKNOWN, 0 },
+/* 25 */ {Cache_L3, 64 },
+/* 26 */ {Cache_UNKNOWN, 0 },
+/* 27 */ {Cache_UNKNOWN, 0 },
+/* 28 */ {Cache_UNKNOWN, 0 },
+/* 29 */ {Cache_L3, 64 },
+/* 2a */ {Cache_UNKNOWN, 0 },
+/* 2b */ {Cache_UNKNOWN, 0 },
+/* 2c */ {Cache_L1d, 64 },
+/* 2d */ {Cache_UNKNOWN, 0 },
+/* 2e */ {Cache_UNKNOWN, 0 },
+/* 2f */ {Cache_UNKNOWN, 0 },
+/* 30 */ {Cache_L1i, 64 },
+/* 31 */ {Cache_UNKNOWN, 0 },
+/* 32 */ {Cache_UNKNOWN, 0 },
+/* 33 */ {Cache_UNKNOWN, 0 },
+/* 34 */ {Cache_UNKNOWN, 0 },
+/* 35 */ {Cache_UNKNOWN, 0 },
+/* 36 */ {Cache_UNKNOWN, 0 },
+/* 37 */ {Cache_UNKNOWN, 0 },
+/* 38 */ {Cache_UNKNOWN, 0 },
+/* 39 */ {Cache_L2, 64 },
+/* 3a */ {Cache_UNKNOWN, 0 },
+/* 3b */ {Cache_L2, 64 },
+/* 3c */ {Cache_L2, 64 },
+/* 3d */ {Cache_UNKNOWN, 0 },
+/* 3e */ {Cache_UNKNOWN, 0 },
+/* 3f */ {Cache_UNKNOWN, 0 },
+/* 40 */ {Cache_L2, 0 },
+/* 41 */ {Cache_L2, 32 },
+/* 42 */ {Cache_L2, 32 },
+/* 43 */ {Cache_L2, 32 },
+/* 44 */ {Cache_L2, 32 },
+/* 45 */ {Cache_L2, 32 },
+/* 46 */ {Cache_UNKNOWN, 0 },
+/* 47 */ {Cache_UNKNOWN, 0 },
+/* 48 */ {Cache_UNKNOWN, 0 },
+/* 49 */ {Cache_UNKNOWN, 0 },
+/* 4a */ {Cache_UNKNOWN, 0 },
+/* 4b */ {Cache_UNKNOWN, 0 },
+/* 4c */ {Cache_UNKNOWN, 0 },
+/* 4d */ {Cache_UNKNOWN, 0 },
+/* 4e */ {Cache_UNKNOWN, 0 },
+/* 4f */ {Cache_UNKNOWN, 0 },
+/* 50 */ {Cache_TLBi, 0 },
+/* 51 */ {Cache_TLBi, 0 },
+/* 52 */ {Cache_TLBi, 0 },
+/* 53 */ {Cache_UNKNOWN, 0 },
+/* 54 */ {Cache_UNKNOWN, 0 },
+/* 55 */ {Cache_UNKNOWN, 0 },
+/* 56 */ {Cache_UNKNOWN, 0 },
+/* 57 */ {Cache_UNKNOWN, 0 },
+/* 58 */ {Cache_UNKNOWN, 0 },
+/* 59 */ {Cache_UNKNOWN, 0 },
+/* 5a */ {Cache_UNKNOWN, 0 },
+/* 5b */ {Cache_TLBd, 0 },
+/* 5c */ {Cache_TLBd, 0 },
+/* 5d */ {Cache_TLBd, 0 },
+/* 5e */ {Cache_UNKNOWN, 0 },
+/* 5f */ {Cache_UNKNOWN, 0 },
+/* 60 */ {Cache_UNKNOWN, 0 },
+/* 61 */ {Cache_UNKNOWN, 0 },
+/* 62 */ {Cache_UNKNOWN, 0 },
+/* 63 */ {Cache_UNKNOWN, 0 },
+/* 64 */ {Cache_UNKNOWN, 0 },
+/* 65 */ {Cache_UNKNOWN, 0 },
+/* 66 */ {Cache_L1d, 64 },
+/* 67 */ {Cache_L1d, 64 },
+/* 68 */ {Cache_L1d, 64 },
+/* 69 */ {Cache_UNKNOWN, 0 },
+/* 6a */ {Cache_UNKNOWN, 0 },
+/* 6b */ {Cache_UNKNOWN, 0 },
+/* 6c */ {Cache_UNKNOWN, 0 },
+/* 6d */ {Cache_UNKNOWN, 0 },
+/* 6e */ {Cache_UNKNOWN, 0 },
+/* 6f */ {Cache_UNKNOWN, 0 },
+/* 70 */ {Cache_Trace, 1 },
+/* 71 */ {Cache_Trace, 1 },
+/* 72 */ {Cache_Trace, 1 },
+/* 73 */ {Cache_UNKNOWN, 0 },
+/* 74 */ {Cache_UNKNOWN, 0 },
+/* 75 */ {Cache_UNKNOWN, 0 },
+/* 76 */ {Cache_UNKNOWN, 0 },
+/* 77 */ {Cache_UNKNOWN, 0 },
+/* 78 */ {Cache_UNKNOWN, 0 },
+/* 79 */ {Cache_L2, 64 },
+/* 7a */ {Cache_L2, 64 },
+/* 7b */ {Cache_L2, 64 },
+/* 7c */ {Cache_L2, 64 },
+/* 7d */ {Cache_UNKNOWN, 0 },
+/* 7e */ {Cache_UNKNOWN, 0 },
+/* 7f */ {Cache_UNKNOWN, 0 },
+/* 80 */ {Cache_UNKNOWN, 0 },
+/* 81 */ {Cache_UNKNOWN, 0 },
+/* 82 */ {Cache_L2, 32 },
+/* 83 */ {Cache_L2, 32 },
+/* 84 */ {Cache_L2, 32 },
+/* 85 */ {Cache_L2, 32 },
+/* 86 */ {Cache_L2, 64 },
+/* 87 */ {Cache_L2, 64 },
+/* 88 */ {Cache_UNKNOWN, 0 },
+/* 89 */ {Cache_UNKNOWN, 0 },
+/* 8a */ {Cache_UNKNOWN, 0 },
+/* 8b */ {Cache_UNKNOWN, 0 },
+/* 8c */ {Cache_UNKNOWN, 0 },
+/* 8d */ {Cache_UNKNOWN, 0 },
+/* 8e */ {Cache_UNKNOWN, 0 },
+/* 8f */ {Cache_UNKNOWN, 0 },
+/* 90 */ {Cache_UNKNOWN, 0 },
+/* 91 */ {Cache_UNKNOWN, 0 },
+/* 92 */ {Cache_UNKNOWN, 0 },
+/* 93 */ {Cache_UNKNOWN, 0 },
+/* 94 */ {Cache_UNKNOWN, 0 },
+/* 95 */ {Cache_UNKNOWN, 0 },
+/* 96 */ {Cache_UNKNOWN, 0 },
+/* 97 */ {Cache_UNKNOWN, 0 },
+/* 98 */ {Cache_UNKNOWN, 0 },
+/* 99 */ {Cache_UNKNOWN, 0 },
+/* 9a */ {Cache_UNKNOWN, 0 },
+/* 9b */ {Cache_UNKNOWN, 0 },
+/* 9c */ {Cache_UNKNOWN, 0 },
+/* 9d */ {Cache_UNKNOWN, 0 },
+/* 9e */ {Cache_UNKNOWN, 0 },
+/* 9f */ {Cache_UNKNOWN, 0 },
+/* a0 */ {Cache_UNKNOWN, 0 },
+/* a1 */ {Cache_UNKNOWN, 0 },
+/* a2 */ {Cache_UNKNOWN, 0 },
+/* a3 */ {Cache_UNKNOWN, 0 },
+/* a4 */ {Cache_UNKNOWN, 0 },
+/* a5 */ {Cache_UNKNOWN, 0 },
+/* a6 */ {Cache_UNKNOWN, 0 },
+/* a7 */ {Cache_UNKNOWN, 0 },
+/* a8 */ {Cache_UNKNOWN, 0 },
+/* a9 */ {Cache_UNKNOWN, 0 },
+/* aa */ {Cache_UNKNOWN, 0 },
+/* ab */ {Cache_UNKNOWN, 0 },
+/* ac */ {Cache_UNKNOWN, 0 },
+/* ad */ {Cache_UNKNOWN, 0 },
+/* ae */ {Cache_UNKNOWN, 0 },
+/* af */ {Cache_UNKNOWN, 0 },
+/* b0 */ {Cache_TLBi, 0 },
+/* b1 */ {Cache_UNKNOWN, 0 },
+/* b2 */ {Cache_UNKNOWN, 0 },
+/* b3 */ {Cache_TLBd, 0 },
+/* b4 */ {Cache_UNKNOWN, 0 },
+/* b5 */ {Cache_UNKNOWN, 0 },
+/* b6 */ {Cache_UNKNOWN, 0 },
+/* b7 */ {Cache_UNKNOWN, 0 },
+/* b8 */ {Cache_UNKNOWN, 0 },
+/* b9 */ {Cache_UNKNOWN, 0 },
+/* ba */ {Cache_UNKNOWN, 0 },
+/* bb */ {Cache_UNKNOWN, 0 },
+/* bc */ {Cache_UNKNOWN, 0 },
+/* bd */ {Cache_UNKNOWN, 0 },
+/* be */ {Cache_UNKNOWN, 0 },
+/* bf */ {Cache_UNKNOWN, 0 },
+/* c0 */ {Cache_UNKNOWN, 0 },
+/* c1 */ {Cache_UNKNOWN, 0 },
+/* c2 */ {Cache_UNKNOWN, 0 },
+/* c3 */ {Cache_UNKNOWN, 0 },
+/* c4 */ {Cache_UNKNOWN, 0 },
+/* c5 */ {Cache_UNKNOWN, 0 },
+/* c6 */ {Cache_UNKNOWN, 0 },
+/* c7 */ {Cache_UNKNOWN, 0 },
+/* c8 */ {Cache_UNKNOWN, 0 },
+/* c9 */ {Cache_UNKNOWN, 0 },
+/* ca */ {Cache_UNKNOWN, 0 },
+/* cb */ {Cache_UNKNOWN, 0 },
+/* cc */ {Cache_UNKNOWN, 0 },
+/* cd */ {Cache_UNKNOWN, 0 },
+/* ce */ {Cache_UNKNOWN, 0 },
+/* cf */ {Cache_UNKNOWN, 0 },
+/* d0 */ {Cache_UNKNOWN, 0 },
+/* d1 */ {Cache_UNKNOWN, 0 },
+/* d2 */ {Cache_UNKNOWN, 0 },
+/* d3 */ {Cache_UNKNOWN, 0 },
+/* d4 */ {Cache_UNKNOWN, 0 },
+/* d5 */ {Cache_UNKNOWN, 0 },
+/* d6 */ {Cache_UNKNOWN, 0 },
+/* d7 */ {Cache_UNKNOWN, 0 },
+/* d8 */ {Cache_UNKNOWN, 0 },
+/* d9 */ {Cache_UNKNOWN, 0 },
+/* da */ {Cache_UNKNOWN, 0 },
+/* db */ {Cache_UNKNOWN, 0 },
+/* dc */ {Cache_UNKNOWN, 0 },
+/* dd */ {Cache_UNKNOWN, 0 },
+/* de */ {Cache_UNKNOWN, 0 },
+/* df */ {Cache_UNKNOWN, 0 },
+/* e0 */ {Cache_UNKNOWN, 0 },
+/* e1 */ {Cache_UNKNOWN, 0 },
+/* e2 */ {Cache_UNKNOWN, 0 },
+/* e3 */ {Cache_UNKNOWN, 0 },
+/* e4 */ {Cache_UNKNOWN, 0 },
+/* e5 */ {Cache_UNKNOWN, 0 },
+/* e6 */ {Cache_UNKNOWN, 0 },
+/* e7 */ {Cache_UNKNOWN, 0 },
+/* e8 */ {Cache_UNKNOWN, 0 },
+/* e9 */ {Cache_UNKNOWN, 0 },
+/* ea */ {Cache_UNKNOWN, 0 },
+/* eb */ {Cache_UNKNOWN, 0 },
+/* ec */ {Cache_UNKNOWN, 0 },
+/* ed */ {Cache_UNKNOWN, 0 },
+/* ee */ {Cache_UNKNOWN, 0 },
+/* ef */ {Cache_UNKNOWN, 0 },
+/* f0 */ {Cache_UNKNOWN, 0 },
+/* f1 */ {Cache_UNKNOWN, 0 },
+/* f2 */ {Cache_UNKNOWN, 0 },
+/* f3 */ {Cache_UNKNOWN, 0 },
+/* f4 */ {Cache_UNKNOWN, 0 },
+/* f5 */ {Cache_UNKNOWN, 0 },
+/* f6 */ {Cache_UNKNOWN, 0 },
+/* f7 */ {Cache_UNKNOWN, 0 },
+/* f8 */ {Cache_UNKNOWN, 0 },
+/* f9 */ {Cache_UNKNOWN, 0 },
+/* fa */ {Cache_UNKNOWN, 0 },
+/* fb */ {Cache_UNKNOWN, 0 },
+/* fc */ {Cache_UNKNOWN, 0 },
+/* fd */ {Cache_UNKNOWN, 0 },
+/* fe */ {Cache_UNKNOWN, 0 },
+/* ff */ {Cache_UNKNOWN, 0 }
+};
+
+
+/*
+ * use the above table to determine the CacheEntryLineSize.
+ */
+static void
+getIntelCacheEntryLineSize(unsigned long val, int *level,
+ unsigned long *lineSize)
+{
+ CacheType type;
+
+ type = CacheMap[val].type;
+ /* only interested in data caches */
+ /* NOTE val = 0x40 is a special value that means no L2 or L3 cache.
+ * this data check has the side effect of rejecting that entry. If
+ * that wasn't the case, we could have to reject it explicitly */
+ if (CacheMap[val].lineSize == 0) {
+ return;
+ }
+ /* look at the caches, skip types we aren't interested in.
+ * if we already have a value for a lower level cache, skip the
+ * current entry */
+ if ((type == Cache_L1)|| (type == Cache_L1d)) {
+ *level = 1;
+ *lineSize = CacheMap[val].lineSize;
+ } else if ((*level >= 2) && ((type == Cache_L2) || (type == Cache_L2d))) {
+ *level = 2;
+ *lineSize = CacheMap[val].lineSize;
+ } else if ((*level >= 3) && ((type == Cache_L3) || (type == Cache_L3d))) {
+ *level = 3;
+ *lineSize = CacheMap[val].lineSize;
+ }
+ return;
+}
+
+
+static void
+getIntelRegisterCacheLineSize(unsigned long val,
+ int *level, unsigned long *lineSize)
+{
+ getIntelCacheEntryLineSize(val >> 24 & 0xff, level, lineSize);
+ getIntelCacheEntryLineSize(val >> 16 & 0xff, level, lineSize);
+ getIntelCacheEntryLineSize(val >> 8 & 0xff, level, lineSize);
+ getIntelCacheEntryLineSize(val & 0xff, level, lineSize);
+}
+
+/*
+ * returns '0' if no recognized cache is found, or if the cache
+ * information is supported by this processor
+ */
+static unsigned long
+getIntelCacheLineSize(int cpuidLevel)
+{
+ int level = 4;
+ unsigned long lineSize = 0;
+ unsigned long eax, ebx, ecx, edx;
+ int repeat, count;
+
+ if (cpuidLevel < 2) {
+ return 0;
+ }
+
+ /* command '2' of the cpuid is intel's cache info call. Each byte of the
+ * 4 registers contain a potential descriptor for the cache. The CacheMap
+ * table maps the cache entry with the processor cache. Register 'al'
+ * contains a count value that cpuid '2' needs to be called in order to
+ * find all the cache descriptors. Only registers with the high bit set
+ * to 'zero' have valid descriptors. This code loops through all the
+ * required calls to cpuid '2' and passes any valid descriptors it finds
+ * to the getIntelRegisterCacheLineSize code, which breaks the registers
+ * down into their component descriptors. In the end the lineSize of the
+ * lowest level cache data cache is returned. */
+ cpuid(2, &eax, &ebx, &ecx, &edx);
+ repeat = eax & 0xf;
+ for (count = 0; count < repeat; count++) {
+ if ((eax & 0x80000000) == 0) {
+ getIntelRegisterCacheLineSize(eax & 0xffffff00, &level, &lineSize);
+ }
+ if ((ebx & 0x80000000) == 0) {
+ getIntelRegisterCacheLineSize(ebx, &level, &lineSize);
+ }
+ if ((ecx & 0x80000000) == 0) {
+ getIntelRegisterCacheLineSize(ecx, &level, &lineSize);
+ }
+ if ((edx & 0x80000000) == 0) {
+ getIntelRegisterCacheLineSize(edx, &level, &lineSize);
+ }
+ if (count+1 != repeat) {
+ cpuid(2, &eax, &ebx, &ecx, &edx);
+ }
+ }
+ return lineSize;
+}
+
+/*
+ * returns '0' if the cache info is not supported by this processor.
+ * This is based on the AMD extended cache commands for cpuid.
+ * (see "AMD Processor Recognition Application Note" Publication 20734).
+ * Some other processors use the identical scheme.
+ * (see "Processor Recognition, Transmeta Corporation").
+ */
+static unsigned long
+getOtherCacheLineSize(unsigned long cpuidLevel)
+{
+ unsigned long lineSize = 0;
+ unsigned long eax, ebx, ecx, edx;
+
+ /* get the Extended CPUID level */
+ cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
+ cpuidLevel = eax;
+
+ if (cpuidLevel >= 0x80000005) {
+ cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
+ lineSize = ecx & 0xff; /* line Size, L1 Data Cache */
+ }
+ return lineSize;
+}
+
+static const char * const manMap[] = {
+#define INTEL 0
+ "GenuineIntel",
+#define AMD 1
+ "AuthenticAMD",
+#define CYRIX 2
+ "CyrixInstead",
+#define CENTAUR 2
+ "CentaurHauls",
+#define NEXGEN 3
+ "NexGenDriven",
+#define TRANSMETA 4
+ "GenuineTMx86",
+#define RISE 5
+ "RiseRiseRise",
+#define UMC 6
+ "UMC UMC UMC ",
+#define SIS 7
+ "Sis Sis Sis ",
+#define NATIONAL 8
+ "Geode by NSC",
+};
+
+static const int n_manufacturers = sizeof(manMap)/sizeof(manMap[0]);
+
+#define MAN_UNKNOWN 9
+
+
+unsigned long
+s_mpi_getProcessorLineSize()
+{
+ unsigned long eax, ebx, ecx, edx;
+ unsigned long cpuidLevel;
+ unsigned long cacheLineSize = 0;
+ int manufacturer = MAN_UNKNOWN;
+ int i;
+ char string[65];
+
+#if !defined(AMD_64)
+ if (is386()) {
+ return 0; /* 386 had no cache */
+ } if (is486()) {
+ return 32; /* really? need more info */
+ }
+#endif
+
+ /* Pentium, cpuid command is available */
+ cpuid(0, &eax, &ebx, &ecx, &edx);
+ cpuidLevel = eax;
+ *(int *)string = ebx;
+ *(int *)&string[4] = edx;
+ *(int *)&string[8] = ecx;
+ string[12] = 0;
+
+ manufacturer = MAN_UNKNOWN;
+ for (i=0; i < n_manufacturers; i++) {
+ if ( strcmp(manMap[i],string) == 0) {
+ manufacturer = i;
+ }
+ }
+
+ if (manufacturer == INTEL) {
+ cacheLineSize = getIntelCacheLineSize(cpuidLevel);
+ } else {
+ cacheLineSize = getOtherCacheLineSize(cpuidLevel);
+ }
+ /* doesn't support cache info based on cpuid. This means
+ * an old pentium class processor, which have cache lines of
+ * 32. If we learn differently, we can use a switch based on
+ * the Manufacturer id */
+ if (cacheLineSize == 0) {
+ cacheLineSize = 32;
+ }
+ return cacheLineSize;
+}
+#define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1
+#endif
+
+#if defined(__ppc64__)
+/*
+ * Sigh, The PPC has some really nice features to help us determine cache
+ * size, since it had lots of direct control functions to do so. The POWER
+ * processor even has an instruction to do this, but it was dropped in
+ * PowerPC. Unfortunately most of them are not available in user mode.
+ *
+ * The dcbz function would be a great way to determine cache line size except
+ * 1) it only works on write-back memory (it throws an exception otherwise),
+ * and 2) because so many mac programs 'knew' the processor cache size was
+ * 32 bytes, they used this instruction as a fast 'zero 32 bytes'. Now the new
+ * G5 processor has 128 byte cache, but dcbz only clears 32 bytes to keep
+ * these programs happy. dcbzl work if 64 bit instructions are supported.
+ * If you know 64 bit instructions are supported, and that stack is
+ * write-back, you can use this code.
+ */
+#include "memory.h"
+
+/* clear the cache line that contains 'array' */
+static inline void dcbzl(char *array)
+{
+ register char *a asm("r2") = array;
+ __asm__ __volatile__( "dcbzl %0,r0" : "=r" (a): "0"(a) );
+}
+
+
+#define PPC_DO_ALIGN(x,y) ((char *)\
+ ((((long long) (x))+((y)-1))&~((y)-1)))
+
+#define PPC_MAX_LINE_SIZE 256
+unsigned long
+s_mpi_getProcessorLineSize()
+{
+ char testArray[2*PPC_MAX_LINE_SIZE+1];
+ char *test;
+ int i;
+
+ /* align the array on a maximum line size boundary, so we
+ * know we are starting to clear from the first address */
+ test = PPC_DO_ALIGN(testArray, PPC_MAX_LINE_SIZE);
+ /* set all the values to 1's */
+ memset(test, 0xff, PPC_MAX_LINE_SIZE);
+ /* clear one cache block starting at 'test' */
+ dcbzl(test);
+
+ /* find the size of the cleared area, that's our block size */
+ for (i=PPC_MAX_LINE_SIZE; i != 0; i = i/2) {
+ if (test[i-1] == 0) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+#define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1
+#endif
+
+
+/*
+ * put other processor and platform specific cache code here
+ * return the smallest cache line size in bytes on the processor
+ * (usually the L1 cache). If the OS has a call, this would be
+ * a greate place to put it.
+ *
+ * If there is no cache, return 0;
+ *
+ * define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED so the generic functions
+ * below aren't compiled.
+ *
+ */
+
+
+/* target.mk can define MPI_CACHE_LINE_SIZE if it's common for the family or
+ * OS */
+#if defined(MPI_CACHE_LINE_SIZE) && !defined(MPI_GET_PROCESSOR_LINE_SIZE_DEFINED)
+
+unsigned long
+s_mpi_getProcessorLineSize()
+{
+ return MPI_CACHE_LINE_SIZE;
+}
+#define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1
+#endif
+
+
+/* If no way to get the processor cache line size has been defined, assume
+ * it's 32 bytes (most common value, does not significantly impact performance)
+ */
+#ifndef MPI_GET_PROCESSOR_LINE_SIZE_DEFINED
+unsigned long
+s_mpi_getProcessorLineSize()
+{
+ return 32;
+}
+#endif
+
+#ifdef TEST_IT
+#include <stdio.h>
+
+main()
+{
+ printf("line size = %d\n", s_mpi_getProcessorLineSize());
+}
+#endif
diff --git a/security/nss/lib/freebl/mpi/mpcpucache_amd64.s b/security/nss/lib/freebl/mpi/mpcpucache_amd64.s
new file mode 100644
index 000000000..240568475
--- /dev/null
+++ b/security/nss/lib/freebl/mpi/mpcpucache_amd64.s
@@ -0,0 +1,891 @@
+//* ***** BEGIN LICENSE BLOCK *****
+/ * 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 Initial Developer of the Original Code is
+/ * Red Hat, Inc.
+/ * Portions created by the Initial Developer are Copyright (C) 2005
+/ * the Initial Developer. All Rights Reserved.
+/ *
+/ * Contributor(s):
+/ * Robert Relyea <rrelyea@redhat.com>
+/ *
+/ * 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.
+/ *
+/ * ***** END LICENSE BLOCK ***** */
+
+ .file "mpcpucache.c"
+/ .section .rodata.str1.1,"aMS",@progbits,1
+ .section .rodata
+.LC0:
+ .string "GenuineIntel"
+.LC1:
+ .string "AuthenticAMD"
+.LC2:
+ .string "CyrixInstead"
+.LC3:
+ .string "CentaurHauls"
+.LC4:
+ .string "NexGenDriven"
+.LC5:
+ .string "GenuineTMx86"
+.LC6:
+ .string "RiseRiseRise"
+.LC7:
+ .string "UMC UMC UMC "
+.LC8:
+ .string "Sis Sis Sis "
+.LC9:
+ .string "Geode by NSC"
+ .section .data.rel.ro.local,"aw",@progbits
+ .align 32
+ .type manMap, @object
+ .size manMap, 80
+manMap:
+ .quad .LC0
+ .quad .LC1
+ .quad .LC2
+ .quad .LC3
+ .quad .LC4
+ .quad .LC5
+ .quad .LC6
+ .quad .LC7
+ .quad .LC8
+ .quad .LC9
+ .section .rodata
+ .align 32
+ .type CacheMap, @object
+ .size CacheMap, 512
+CacheMap:
+ .byte 0
+ .byte 0
+ .byte 3
+ .byte 0
+ .byte 3
+ .byte 0
+ .byte 4
+ .byte 0
+ .byte 4
+ .zero 1
+ .byte 1
+ .byte 0
+ .byte 7
+ .byte 32
+ .byte 1
+ .byte 0
+ .byte 7
+ .byte 32
+ .byte 1
+ .byte 0
+ .byte 8
+ .byte 32
+ .byte 1
+ .byte 0
+ .byte 8
+ .byte 32
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 12
+ .byte 64
+ .byte 12
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 12
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 12
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 8
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 7
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 9
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 9
+ .byte 64
+ .byte 9
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 9
+ .byte 0
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 3
+ .byte 0
+ .byte 3
+ .byte 0
+ .byte 3
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 4
+ .byte 0
+ .byte 4
+ .byte 0
+ .byte 4
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 8
+ .byte 64
+ .byte 8
+ .byte 64
+ .byte 8
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 5
+ .byte 1
+ .byte 5
+ .byte 1
+ .byte 5
+ .byte 1
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 9
+ .byte 64
+ .byte 9
+ .byte 64
+ .byte 9
+ .byte 64
+ .byte 9
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 64
+ .byte 9
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 3
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 4
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .text
+ .align 16
+ .type cpuid, @function
+cpuid:
+.LFB2:
+ movq %rdx, %r10
+ pushq %rbx
+.LCFI0:
+ movq %rcx, %r11
+ movq %rdi, %rax
+/APP
+ cpuid
+
+/NO_APP
+ movq %rax, (%rsi)
+ movq %rbx, (%r10)
+ popq %rbx
+ movq %rcx, (%r11)
+ movq %rdx, (%r8)
+ ret
+.LFE2:
+ .size cpuid, .-cpuid
+ .align 16
+ .type getIntelCacheEntryLineSize, @function
+getIntelCacheEntryLineSize:
+.LFB3:
+ leaq CacheMap(%rip), %r9
+ movq %rdx, %r10
+ movzbl 1(%r9,%rdi,2), %ecx
+ movzbl (%r9,%rdi,2), %r8d
+ testb %cl, %cl
+ je .L2
+ cmpl $6, %r8d
+ sete %dl
+ cmpl $8, %r8d
+ sete %al
+ orl %edx, %eax
+ testb $1, %al
+ je .L4
+ movl $1, (%rsi)
+.L9:
+ movzbl %cl, %eax
+ movq %rax, (%r10)
+ ret
+ .align 16
+.L4:
+ movl (%rsi), %r11d
+ cmpl $1, %r11d
+ jg .L11
+.L6:
+ cmpl $2, %r11d
+ jle .L2
+ cmpl $12, %r8d
+ sete %dl
+ cmpl $14, %r8d
+ sete %al
+ orl %edx, %eax
+ testb $1, %al
+ je .L2
+ movzbq 1(%r9,%rdi,2), %rax
+ movl $3, (%rsi)
+ movq %rax, (%r10)
+ .align 16
+.L2:
+ rep ; ret
+ .align 16
+.L11:
+ cmpl $9, %r8d
+ sete %dl
+ cmpl $11, %r8d
+ sete %al
+ orl %edx, %eax
+ testb $1, %al
+ je .L6
+ movl $2, (%rsi)
+ jmp .L9
+.LFE3:
+ .size getIntelCacheEntryLineSize, .-getIntelCacheEntryLineSize
+ .align 16
+ .type getIntelRegisterCacheLineSize, @function
+getIntelRegisterCacheLineSize:
+.LFB4:
+ pushq %rbp
+.LCFI1:
+ movq %rsp, %rbp
+.LCFI2:
+ movq %rbx, -24(%rbp)
+.LCFI3:
+ movq %rdi, %rbx
+ shrq $24, %rdi
+ movq %r12, -16(%rbp)
+.LCFI4:
+ movq %r13, -8(%rbp)
+.LCFI5:
+ andl $255, %edi
+ subq $24, %rsp
+.LCFI6:
+ movq %rsi, %r13
+ movq %rdx, %r12
+ call getIntelCacheEntryLineSize
+ movq %rbx, %rdi
+ movq %r12, %rdx
+ movq %r13, %rsi
+ shrq $16, %rdi
+ andl $255, %edi
+ call getIntelCacheEntryLineSize
+ movq %rbx, %rdi
+ movq %r12, %rdx
+ movq %r13, %rsi
+ shrq $8, %rdi
+ andl $255, %ebx
+ andl $255, %edi
+ call getIntelCacheEntryLineSize
+ movq %r12, %rdx
+ movq %r13, %rsi
+ movq %rbx, %rdi
+ movq 8(%rsp), %r12
+ movq (%rsp), %rbx
+ movq 16(%rsp), %r13
+ leave
+ jmp getIntelCacheEntryLineSize
+.LFE4:
+ .size getIntelRegisterCacheLineSize, .-getIntelRegisterCacheLineSize
+ .align 16
+.globl s_mpi_getProcessorLineSize
+ .type s_mpi_getProcessorLineSize, @function
+s_mpi_getProcessorLineSize:
+.LFB7:
+ pushq %rbp
+.LCFI7:
+ xorl %edi, %edi
+ movq %rsp, %rbp
+.LCFI8:
+ pushq %r15
+.LCFI9:
+ leaq -136(%rbp), %r8
+ leaq -144(%rbp), %rcx
+ leaq -152(%rbp), %rdx
+ pushq %r14
+.LCFI10:
+ leaq -160(%rbp), %rsi
+ leaq -128(%rbp), %r14
+ pushq %r13
+.LCFI11:
+ leaq manMap(%rip), %r13
+ pushq %r12
+.LCFI12:
+ movl $9, %r12d
+ pushq %rbx
+.LCFI13:
+ xorl %ebx, %ebx
+ subq $200, %rsp
+.LCFI14:
+ call cpuid
+ movq -152(%rbp), %rax
+ movq -160(%rbp), %r15
+ movb $0, -116(%rbp)
+ movl %eax, -128(%rbp)
+ movq -136(%rbp), %rax
+ movl %eax, -124(%rbp)
+ movq -144(%rbp), %rax
+ movl %eax, -120(%rbp)
+ .align 16
+.L18:
+ movslq %ebx,%rax
+ movq %r14, %rsi
+ movq (%r13,%rax,8), %rdi
+ call strcmp@PLT
+ testl %eax, %eax
+ cmove %ebx, %r12d
+ incl %ebx
+ cmpl $9, %ebx
+ jle .L18
+ testl %r12d, %r12d
+ jne .L19
+ xorl %eax, %eax
+ decl %r15d
+ movl $4, -204(%rbp)
+ movq $0, -200(%rbp)
+ jle .L21
+ leaq -168(%rbp), %r8
+ leaq -176(%rbp), %rcx
+ leaq -184(%rbp), %rdx
+ leaq -192(%rbp), %rsi
+ movl $2, %edi
+ xorl %ebx, %ebx
+ call cpuid
+ movq -192(%rbp), %rdi
+ movl %edi, %r12d
+ andl $15, %r12d
+ cmpl %r12d, %ebx
+ jl .L30
+ jmp .L38
+ .align 16
+.L25:
+ movq -184(%rbp), %rdi
+ testl $2147483648, %edi
+ je .L40
+.L26:
+ movq -176(%rbp), %rdi
+ testl $2147483648, %edi
+ je .L41
+.L27:
+ movq -168(%rbp), %rdi
+ testl $2147483648, %edi
+ je .L42
+.L28:
+ incl %ebx
+ cmpl %r12d, %ebx
+ je .L24
+ leaq -168(%rbp), %r8
+ leaq -176(%rbp), %rcx
+ leaq -184(%rbp), %rdx
+ leaq -192(%rbp), %rsi
+ movl $2, %edi
+ call cpuid
+.L24:
+ cmpl %r12d, %ebx
+ jge .L38
+ movq -192(%rbp), %rdi
+.L30:
+ testl $2147483648, %edi
+ jne .L25
+ leaq -200(%rbp), %rdx
+ leaq -204(%rbp), %rsi
+ andl $4294967040, %edi
+ call getIntelRegisterCacheLineSize
+ movq -184(%rbp), %rdi
+ testl $2147483648, %edi
+ jne .L26
+.L40:
+ leaq -200(%rbp), %rdx
+ leaq -204(%rbp), %rsi
+ call getIntelRegisterCacheLineSize
+ movq -176(%rbp), %rdi
+ testl $2147483648, %edi
+ jne .L27
+.L41:
+ leaq -200(%rbp), %rdx
+ leaq -204(%rbp), %rsi
+ call getIntelRegisterCacheLineSize
+ movq -168(%rbp), %rdi
+ testl $2147483648, %edi
+ jne .L28
+.L42:
+ leaq -200(%rbp), %rdx
+ leaq -204(%rbp), %rsi
+ call getIntelRegisterCacheLineSize
+ jmp .L28
+.L38:
+ movq -200(%rbp), %rax
+.L21:
+ movq %rax, %rdx
+ movl $32, %eax
+ testq %rdx, %rdx
+ cmoveq %rax, %rdx
+ addq $200, %rsp
+ popq %rbx
+ popq %r12
+ popq %r13
+ popq %r14
+ popq %r15
+ leave
+ movq %rdx, %rax
+ ret
+.L19:
+ leaq -216(%rbp), %r8
+ leaq -224(%rbp), %rcx
+ leaq -232(%rbp), %rdx
+ leaq -240(%rbp), %rsi
+ movl $2147483648, %edi
+ xorl %ebx, %ebx
+ call cpuid
+ movl $2147483652, %eax
+ cmpq %rax, -240(%rbp)
+ ja .L43
+.L32:
+ movq %rbx, %rdx
+ movl $32, %eax
+ testq %rdx, %rdx
+ cmoveq %rax, %rdx
+ addq $200, %rsp
+ popq %rbx
+ popq %r12
+ popq %r13
+ popq %r14
+ popq %r15
+ leave
+ movq %rdx, %rax
+ ret
+.L43:
+ leaq -216(%rbp), %r8
+ leaq -224(%rbp), %rcx
+ leaq -232(%rbp), %rdx
+ leaq -240(%rbp), %rsi
+ movl $2147483653, %edi
+ call cpuid
+ movzbq -224(%rbp), %rbx
+ jmp .L32
+.LFE7:
+ .size s_mpi_getProcessorLineSize, .-s_mpi_getProcessorLineSize
diff --git a/security/nss/lib/freebl/mpi/mpcpucache_x86.s b/security/nss/lib/freebl/mpi/mpcpucache_x86.s
new file mode 100644
index 000000000..4e7813993
--- /dev/null
+++ b/security/nss/lib/freebl/mpi/mpcpucache_x86.s
@@ -0,0 +1,931 @@
+//* ***** BEGIN LICENSE BLOCK *****
+/ * 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 Initial Developer of the Original Code is
+/ * Red Hat, Inc.
+/ * Portions created by the Initial Developer are Copyright (C) 2005
+/ * the Initial Developer. All Rights Reserved.
+/ *
+/ * Contributor(s):
+/ * Robert Relyea <rrelyea@redhat.com>
+/ *
+/ * 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.
+/ *
+/ * ***** END LICENSE BLOCK ***** */
+
+ .file "mpcpucache.c"
+/ .section .rodata.str1.1,"aMS",@progbits,1
+ .section .rodata
+.LC0:
+ .string "GenuineIntel"
+.LC1:
+ .string "AuthenticAMD"
+.LC2:
+ .string "CyrixInstead"
+.LC3:
+ .string "CentaurHauls"
+.LC4:
+ .string "NexGenDriven"
+.LC5:
+ .string "GenuineTMx86"
+.LC6:
+ .string "RiseRiseRise"
+.LC7:
+ .string "UMC UMC UMC "
+.LC8:
+ .string "Sis Sis Sis "
+.LC9:
+ .string "Geode by NSC"
+ .section .data.rel.ro.local,"aw",@progbits
+ .align 32
+ .type manMap, @object
+ .size manMap, 40
+manMap:
+ .long .LC0
+ .long .LC1
+ .long .LC2
+ .long .LC3
+ .long .LC4
+ .long .LC5
+ .long .LC6
+ .long .LC7
+ .long .LC8
+ .long .LC9
+ .section .rodata
+ .align 32
+ .type CacheMap, @object
+ .size CacheMap, 512
+CacheMap:
+ .byte 0
+ .byte 0
+ .byte 3
+ .byte 0
+ .byte 3
+ .byte 0
+ .byte 4
+ .byte 0
+ .byte 4
+ .zero 1
+ .byte 1
+ .byte 0
+ .byte 7
+ .byte 32
+ .byte 1
+ .byte 0
+ .byte 7
+ .byte 32
+ .byte 1
+ .byte 0
+ .byte 8
+ .byte 32
+ .byte 1
+ .byte 0
+ .byte 8
+ .byte 32
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 12
+ .byte 64
+ .byte 12
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 12
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 12
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 8
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 7
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 9
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 9
+ .byte 64
+ .byte 9
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 9
+ .byte 0
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 3
+ .byte 0
+ .byte 3
+ .byte 0
+ .byte 3
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 4
+ .byte 0
+ .byte 4
+ .byte 0
+ .byte 4
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 8
+ .byte 64
+ .byte 8
+ .byte 64
+ .byte 8
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 5
+ .byte 1
+ .byte 5
+ .byte 1
+ .byte 5
+ .byte 1
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 9
+ .byte 64
+ .byte 9
+ .byte 64
+ .byte 9
+ .byte 64
+ .byte 9
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 32
+ .byte 9
+ .byte 64
+ .byte 9
+ .byte 64
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 3
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 4
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .byte 1
+ .byte 0
+ .text
+ .align 4
+ .type cpuid, @function
+cpuid:
+ pushl %ebp
+ pushl %edi
+ pushl %esi
+ subl $8, %esp
+ movl %edx, %ebp
+/APP
+ pushl %ebx
+ cpuid
+ mov %ebx,%esi
+ popl %ebx
+
+/NO_APP
+ movl %eax, (%ebp)
+ movl 24(%esp), %eax
+ movl %esi, (%eax)
+ movl 28(%esp), %eax
+ movl %ecx, (%eax)
+ movl 32(%esp), %eax
+ movl %edx, (%eax)
+ addl $8, %esp
+ popl %esi
+ popl %edi
+ popl %ebp
+ ret
+ .size cpuid, .-cpuid
+ .align 4
+ .type changeFlag, @function
+changeFlag:
+/APP
+ pushfl
+ popl %edx
+ movl %edx,%ecx
+ xorl %eax,%edx
+ pushl %edx
+ popfl
+ pushfl
+ popl %edx
+ pushl %ecx
+ popfl
+
+/NO_APP
+ xorl %ecx, %edx
+ movl %edx, %eax
+ ret
+ .size changeFlag, .-changeFlag
+ .align 4
+ .type getIntelCacheEntryLineSize, @function
+getIntelCacheEntryLineSize:
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ call .L17
+.L17:
+ popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-.L17], %ebx
+ movzbl CacheMap@GOTOFF(%ebx,%eax,2), %ecx
+ movb 1+CacheMap@GOTOFF(%ebx,%eax,2), %al
+ testb %al, %al
+ movl 16(%esp), %edi
+ je .L3
+ cmpl $6, %ecx
+ je .L6
+ cmpl $8, %ecx
+ je .L6
+ movl (%edx), %esi
+ cmpl $1, %esi
+ jg .L15
+.L8:
+ cmpl $2, %esi
+ jle .L3
+ cmpl $12, %ecx
+ je .L12
+ cmpl $14, %ecx
+ je .L12
+ .align 4
+.L3:
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+ .align 4
+.L6:
+ movzbl %al, %eax
+ movl $1, (%edx)
+ movl %eax, (%edi)
+.L16:
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+ .align 4
+.L15:
+ cmpl $9, %ecx
+ je .L9
+ cmpl $11, %ecx
+ jne .L8
+.L9:
+ movzbl %al, %eax
+ movl $2, (%edx)
+ movl %eax, (%edi)
+ jmp .L16
+.L12:
+ movzbl %al, %eax
+ movl $3, (%edx)
+ movl %eax, (%edi)
+ jmp .L16
+ .size getIntelCacheEntryLineSize, .-getIntelCacheEntryLineSize
+ .align 4
+ .type getIntelRegisterCacheLineSize, @function
+getIntelRegisterCacheLineSize:
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %edi
+ pushl %esi
+ pushl %ecx
+ movl 8(%ebp), %edi
+ movl %eax, %esi
+ movl %edx, -12(%ebp)
+ shrl $24, %eax
+ pushl %edi
+ call getIntelCacheEntryLineSize
+ movl %esi, %eax
+ pushl %edi
+ shrl $16, %eax
+ movl -12(%ebp), %edx
+ andl $255, %eax
+ call getIntelCacheEntryLineSize
+ pushl %edi
+ movl %esi, %edx
+ movzbl %dh, %eax
+ movl -12(%ebp), %edx
+ call getIntelCacheEntryLineSize
+ andl $255, %esi
+ movl %edi, 8(%ebp)
+ movl -12(%ebp), %edx
+ addl $12, %esp
+ leal -8(%ebp), %esp
+ movl %esi, %eax
+ popl %esi
+ popl %edi
+ leave
+ jmp getIntelCacheEntryLineSize
+ .size getIntelRegisterCacheLineSize, .-getIntelRegisterCacheLineSize
+ .align 4
+.globl s_mpi_getProcessorLineSize
+ .type s_mpi_getProcessorLineSize, @function
+s_mpi_getProcessorLineSize:
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ subl $188, %esp
+ call .L52
+.L52:
+ popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-.L52], %ebx
+ movl $9, -168(%ebp)
+ movl $262144, %eax
+ call changeFlag
+ xorl %edx, %edx
+ testl %eax, %eax
+ jne .L50
+.L19:
+ leal -12(%ebp), %esp
+ popl %ebx
+ popl %esi
+ movl %edx, %eax
+ popl %edi
+ leave
+ ret
+ .align 4
+.L50:
+ movl $2097152, %eax
+ call changeFlag
+ testl %eax, %eax
+ movl $32, %edx
+ je .L19
+ leal -108(%ebp), %eax
+ pushl %eax
+ leal -112(%ebp), %eax
+ pushl %eax
+ leal -116(%ebp), %eax
+ pushl %eax
+ leal -120(%ebp), %edx
+ xorl %eax, %eax
+ call cpuid
+ movl -120(%ebp), %eax
+ movl %eax, -164(%ebp)
+ movl -116(%ebp), %eax
+ movl %eax, -104(%ebp)
+ movl -108(%ebp), %eax
+ movl %eax, -100(%ebp)
+ movl -112(%ebp), %eax
+ movl %eax, -96(%ebp)
+ movb $0, -92(%ebp)
+ xorl %esi, %esi
+ addl $12, %esp
+ leal -104(%ebp), %edi
+ .align 4
+.L28:
+ subl $8, %esp
+ pushl %edi
+ pushl manMap@GOTOFF(%ebx,%esi,4)
+ call strcmp@PLT
+ addl $16, %esp
+ testl %eax, %eax
+ jne .L26
+ movl %esi, -168(%ebp)
+.L26:
+ incl %esi
+ cmpl $9, %esi
+ jle .L28
+ movl -168(%ebp), %eax
+ testl %eax, %eax
+ jne .L29
+ xorl %eax, %eax
+ cmpl $1, -164(%ebp)
+ movl $4, -144(%ebp)
+ movl $0, -140(%ebp)
+ jle .L41
+ leal -124(%ebp), %edx
+ movl %edx, -188(%ebp)
+ leal -128(%ebp), %eax
+ pushl %edx
+ movl %eax, -184(%ebp)
+ leal -132(%ebp), %edx
+ pushl %eax
+ movl %edx, -180(%ebp)
+ movl $2, %eax
+ pushl %edx
+ leal -136(%ebp), %edx
+ call cpuid
+ movl -136(%ebp), %eax
+ movl %eax, %edi
+ andl $15, %edi
+ xorl %esi, %esi
+ addl $12, %esp
+ leal -140(%ebp), %edx
+ cmpl %edi, %esi
+ movl %edx, -176(%ebp)
+ jl .L40
+ jmp .L48
+ .align 4
+.L49:
+ movl -136(%ebp), %eax
+.L40:
+ testl %eax, %eax
+ js .L35
+ xorb %al, %al
+ pushl -176(%ebp)
+ leal -144(%ebp), %edx
+ call getIntelRegisterCacheLineSize
+ popl %eax
+.L35:
+ movl -132(%ebp), %eax
+ testl %eax, %eax
+ js .L36
+ pushl -176(%ebp)
+ leal -144(%ebp), %edx
+ call getIntelRegisterCacheLineSize
+ popl %eax
+.L36:
+ movl -128(%ebp), %eax
+ testl %eax, %eax
+ js .L37
+ pushl -176(%ebp)
+ leal -144(%ebp), %edx
+ call getIntelRegisterCacheLineSize
+ popl %eax
+.L37:
+ movl -124(%ebp), %eax
+ testl %eax, %eax
+ js .L38
+ pushl -176(%ebp)
+ leal -144(%ebp), %edx
+ call getIntelRegisterCacheLineSize
+ popl %eax
+.L38:
+ incl %esi
+ cmpl %edi, %esi
+ je .L34
+ pushl -188(%ebp)
+ pushl -184(%ebp)
+ pushl -180(%ebp)
+ leal -136(%ebp), %edx
+ movl $2, %eax
+ call cpuid
+ addl $12, %esp
+.L34:
+ cmpl %edi, %esi
+ jl .L49
+.L48:
+ movl -140(%ebp), %eax
+.L41:
+ testl %eax, %eax
+ jne .L44
+ movb $32, %al
+.L44:
+ leal -12(%ebp), %esp
+ popl %ebx
+ popl %esi
+ movl %eax, %edx
+ movl %edx, %eax
+ popl %edi
+ leave
+ ret
+.L29:
+ leal -148(%ebp), %eax
+ movl %eax, -192(%ebp)
+ movl $0, -172(%ebp)
+ leal -152(%ebp), %edi
+ pushl %eax
+ pushl %edi
+ leal -156(%ebp), %esi
+ pushl %esi
+ leal -160(%ebp), %edx
+ movl $-2147483648, %eax
+ call cpuid
+ addl $12, %esp
+ cmpl $-2147483644, -160(%ebp)
+ ja .L51
+.L42:
+ movl -172(%ebp), %eax
+ jmp .L41
+.L51:
+ pushl -192(%ebp)
+ pushl %edi
+ pushl %esi
+ leal -160(%ebp), %edx
+ movl $-2147483643, %eax
+ call cpuid
+ movzbl -152(%ebp), %edx
+ addl $12, %esp
+ movl %edx, -172(%ebp)
+ jmp .L42
+ .size s_mpi_getProcessorLineSize, .-s_mpi_getProcessorLineSize
diff --git a/security/nss/lib/freebl/mpi/mpi-priv.h b/security/nss/lib/freebl/mpi/mpi-priv.h
index 69f3c1aa9..e033a5e24 100644
--- a/security/nss/lib/freebl/mpi/mpi-priv.h
+++ b/security/nss/lib/freebl/mpi/mpi-priv.h
@@ -231,6 +231,22 @@ mp_err s_mp_invmod_odd_m( const mp_int *a, const mp_int *m, mp_int *c);
mp_err s_mp_invmod_2d( const mp_int *a, mp_size k, mp_int *c);
mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c);
+#ifdef NSS_USE_COMBA
+
+#define IS_POWER_OF_2(a) ((a) && !((a) & ((a)-1)))
+
+void s_mp_mul_comba_4(const mp_int *A, const mp_int *B, mp_int *C);
+void s_mp_mul_comba_8(const mp_int *A, const mp_int *B, mp_int *C);
+void s_mp_mul_comba_16(const mp_int *A, const mp_int *B, mp_int *C);
+void s_mp_mul_comba_32(const mp_int *A, const mp_int *B, mp_int *C);
+
+void s_mp_sqr_comba_4(const mp_int *A, mp_int *B);
+void s_mp_sqr_comba_8(const mp_int *A, mp_int *B);
+void s_mp_sqr_comba_16(const mp_int *A, mp_int *B);
+void s_mp_sqr_comba_32(const mp_int *A, mp_int *B);
+
+#endif /* end NSS_USE_COMBA */
+
/* ------ mpv functions, operate on arrays of digits, not on mp_int's ------ */
#if defined (__OS2__) && defined (__IBMC__)
#define MPI_ASM_DECL __cdecl
@@ -284,6 +300,19 @@ mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c,
mp_mont_modulus *mmm);
mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm);
+/*
+ * s_mpi_getProcessorLineSize() returns the size in bytes of the cache line
+ * if a cache exists, or zero if there is no cache. If more than one
+ * cache line exists, it should return the smallest line size (which is
+ * usually the L1 cache).
+ *
+ * mp_modexp uses this information to make sure that private key information
+ * isn't being leaked through the cache.
+ *
+ * see mpcpucache.c for the implementation.
+ */
+unsigned long s_mpi_getProcessorLineSize();
+
/* }}} */
#endif
diff --git a/security/nss/lib/freebl/mpi/mpi.c b/security/nss/lib/freebl/mpi/mpi.c
index 4caa6d224..2ea3ad15e 100644
--- a/security/nss/lib/freebl/mpi/mpi.c
+++ b/security/nss/lib/freebl/mpi/mpi.c
@@ -844,6 +844,27 @@ mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int * c)
if((res = s_mp_pad(c, USED(a) + USED(b))) != MP_OKAY)
goto CLEANUP;
+#ifdef NSS_USE_COMBA
+ if ((MP_USED(a) == MP_USED(b)) && IS_POWER_OF_2(MP_USED(b))) {
+ if (MP_USED(a) == 4) {
+ s_mp_mul_comba_4(a, b, c);
+ goto CLEANUP;
+ }
+ if (MP_USED(a) == 8) {
+ s_mp_mul_comba_8(a, b, c);
+ goto CLEANUP;
+ }
+ if (MP_USED(a) == 16) {
+ s_mp_mul_comba_16(a, b, c);
+ goto CLEANUP;
+ }
+ if (MP_USED(a) == 32) {
+ s_mp_mul_comba_32(a, b, c);
+ goto CLEANUP;
+ }
+ }
+#endif
+
pb = MP_DIGITS(b);
s_mpv_mul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c));
@@ -914,6 +935,27 @@ mp_err mp_sqr(const mp_int *a, mp_int *sqr)
MP_USED(sqr) = ix;
MP_DIGIT(sqr, 0) = 0;
+#ifdef NSS_USE_COMBA
+ if (IS_POWER_OF_2(MP_USED(a))) {
+ if (MP_USED(a) == 4) {
+ s_mp_sqr_comba_4(a, sqr);
+ goto CLEANUP;
+ }
+ if (MP_USED(a) == 8) {
+ s_mp_sqr_comba_8(a, sqr);
+ goto CLEANUP;
+ }
+ if (MP_USED(a) == 16) {
+ s_mp_sqr_comba_16(a, sqr);
+ goto CLEANUP;
+ }
+ if (MP_USED(a) == 32) {
+ s_mp_sqr_comba_32(a, sqr);
+ goto CLEANUP;
+ }
+ }
+#endif
+
pa = MP_DIGITS(a);
count = MP_USED(a) - 1;
if (count > 0) {
@@ -4717,6 +4759,8 @@ mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
str[pos++] = x;
}
}
+ if (!pos)
+ str[pos++] = 0;
return pos;
} /* end mp_to_unsigned_octets() */
/* }}} */
@@ -4755,6 +4799,8 @@ mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
str[pos++] = x;
}
}
+ if (!pos)
+ str[pos++] = 0;
return pos;
} /* end mp_to_signed_octets() */
/* }}} */
@@ -4790,6 +4836,8 @@ mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
str[pos++] = x;
}
}
+ if (!pos)
+ str[pos++] = 0;
return MP_OKAY;
} /* end mp_to_fixlen_octets() */
/* }}} */
diff --git a/security/nss/lib/freebl/mpi/mpi_amd64_gas.s b/security/nss/lib/freebl/mpi/mpi_amd64_gas.s
index 7515ac20a..86e16e362 100644
--- a/security/nss/lib/freebl/mpi/mpi_amd64_gas.s
+++ b/security/nss/lib/freebl/mpi/mpi_amd64_gas.s
@@ -416,3 +416,7 @@
ret
.size s_mpv_mul_add_vec64, [.-s_mpv_mul_add_vec64]
+
+# Magic indicating no need for an executable stack
+.section .note.GNU-stack, "", @progbits
+.previous
diff --git a/security/nss/lib/freebl/mpi/mpmontg.c b/security/nss/lib/freebl/mpi/mpmontg.c
index 8879454ae..7b0bdd3d3 100644
--- a/security/nss/lib/freebl/mpi/mpmontg.c
+++ b/security/nss/lib/freebl/mpi/mpmontg.c
@@ -47,7 +47,7 @@
* published by Springer Verlag.
*/
-/* #define MP_USING_MONT_MULF 1 */
+#define MP_USING_CACHE_SAFE_MOD_EXP 1
#include <string.h>
#include "mpi-priv.h"
#include "mplogic.h"
@@ -55,11 +55,19 @@
#ifdef MP_USING_MONT_MULF
#include "montmulf.h"
#endif
+#include <stddef.h> /* ptrdiff_t */
+
+/* if MP_CHAR_STORE_SLOW is defined, we */
+/* need to know endianness of this platform. */
+#ifdef MP_CHAR_STORE_SLOW
+#if !defined(MPI_IS_BIG_ENDIAN) && !defined(MPI_IS_LITTLE_ENDIAN)
+#error "You must define MPI_IS_BIG_ENDIAN or MPI_IS_LITTLE_ENDIAN\n" \
+ " if you define MP_CHAR_STORE_SLOW."
+#endif
+#endif
#define STATIC
-/* #define DEBUG 1 */
-#define MAX_WINDOW_BITS 6
#define MAX_ODD_INTS 32 /* 2 ** (WINDOW_BITS - 1) */
#if defined(_WIN32_WCE)
@@ -174,6 +182,13 @@ CLEANUP:
#ifdef MP_USING_MONT_MULF
+/* the floating point multiply is already cache safe,
+ * don't turn on cache safe unless we specifically
+ * force it */
+#ifndef MP_FORCE_CACHE_SAFE
+#undef MP_USING_CACHE_SAFE_MOD_EXP
+#endif
+
unsigned int mp_using_mont_mulf = 1;
/* computes montgomery square of the integer in mResult */
@@ -504,6 +519,564 @@ CLEANUP:
#undef SQR
#undef MUL
+#ifdef MP_USING_CACHE_SAFE_MOD_EXP
+unsigned int mp_using_cache_safe_exp = 1;
+#endif
+
+mp_err mp_set_safe_modexp(int value)
+{
+#ifdef MP_USING_CACHE_SAFE_MOD_EXP
+ mp_using_cache_safe_exp = value;
+ return MP_OKAY;
+#else
+ if (value == 0) {
+ return MP_OKAY;
+ }
+ return MP_BADARG;
+#endif
+}
+
+#ifdef MP_USING_CACHE_SAFE_MOD_EXP
+#define WEAVE_WORD_SIZE 4
+
+#ifndef MP_CHAR_STORE_SLOW
+/*
+ * mpi_to_weave takes MPI data and stores in into a byte array interleaved.
+ *
+ * The purpose of this interleaving is to hide our access to the array of
+ * modulus powers from and attacker snooping on cache hits and misses. Because
+ * the array is interleaved, each reference will cause exactly the same cache
+ * lines to reload.
+ *
+ * There are 2 different implementations in this file, one which works with just
+ * byte loads and stores, the second which works with mp_weave_word loads and
+ * stores. These 2 implementations have DIFFERENT results in exactly which byte
+ * of an mp_digit winds up in which location in the byte array. That is why
+ * there are 2 sets of explanations for how the array is set up.
+ *
+ *
+ * a is an array of WEAVE_WORD_SIZE mp_ints (that is 4).
+ * It is a partial window into a logical array mp_int p[count] containing
+ * the base to the 0 through count-1 powers. Ideally this code would be
+ * simpler if we stored one element of that array at a time, but on some
+ * platforms the cost of storing a byte incurs a full read modify write cycle
+ * and increases the memory bandwidth cost by a factor of 4 or 8. By collecting
+ * for mp_ints together, we can arrange to store all 4 values in a single
+ * word write.
+ *
+ * b is the targeted weaved location. b[0] points to the first byte where
+ * first byte of the a array needs to be stored. Each b is an offset into the
+ * weave array.
+ *
+ * count is 2^window size.
+ *
+ * b_size is the size in mp_digits of each mp_int in the array. mp_ints
+ * with less than b_size elements are logically padded with zeros before
+ * storing.
+ *
+ *
+ * Data is stored as follows :
+ * The mp_int array is treated as a byte array.
+ *
+ *
+ * we want to eventually store the logical array mp_int p[count] into the
+ * weave array as follows:
+
+ * p[count].digit is treated as a byte array (rather than * an mp_digit array),
+ * N is count, and n is b_size * *sizeof(mp_digit):
+ *
+ * p[0].digit[0] p[1].digit[0] ...... p[N-2].digit[0] p[N-1].digit[0]
+ * p[0].digit[1] p[1].digit[1] ...... p[N-2].digit[1] p[N-1].digit[1]
+ * . .
+ * . .
+ * p[0].digit[n-2] p[1].digit[n-2] ...... p[N-2].digit[n-2] p[N-1].digit[n-2]
+ * p[0].digit[n-1] p[1].digit[n-1] ...... p[N-2].digit[n-1] p[N-1].digit[n-1]
+ *
+ * This function stores that a window of p in each call.
+ */
+mp_err mpi_to_weave(const mp_int *a, unsigned char *b,
+ mp_size b_size, mp_size count)
+{
+ mp_size i, j;
+ unsigned char *bsave = b;
+
+ for (i=0; i < WEAVE_WORD_SIZE; i++) {
+ unsigned char *pb = (unsigned char *)MP_DIGITS(&a[i]);
+ mp_size useda = MP_USED(&a[i]);
+ mp_size zero = b_size - useda;
+ unsigned char *end = pb+ (useda*sizeof(mp_digit));
+ b = bsave+i;
+
+
+ ARGCHK(MP_SIGN(&a[i]) == MP_ZPOS, MP_BADARG);
+ ARGCHK(useda <= b_size, MP_BADARG);
+
+ for (; pb < end; pb++) {
+ *b = *pb;
+ b += count;
+ }
+ for (j=0; j < zero; j++) {
+ *b = 0;
+ b += count;
+ }
+ }
+
+ return MP_OKAY;
+}
+
+/* reverse the operation above for one entry.
+ * b points to the offset into the weave array of the power we are
+ * calculating */
+mp_err weave_to_mpi(mp_int *a, const unsigned char *b,
+ mp_size b_size, mp_size count)
+{
+ unsigned char *pb = (unsigned char *)MP_DIGITS(a);
+ unsigned char *end = pb+ (b_size*sizeof(mp_digit));
+
+ MP_SIGN(a) = MP_ZPOS;
+ MP_USED(a) = b_size;
+
+ for (; pb < end; b+=count, pb++) {
+ *pb = *b;
+ }
+ s_mp_clamp(a);
+ return MP_OKAY;
+}
+#else
+/* Need a primitive that we know is 32 bits long... */
+/* this is true on all modern processors we know of today*/
+typedef unsigned int mp_weave_word;
+
+/*
+ * on some platforms character stores into memory is very expensive since they
+ * generate a read/modify/write operation on the bus. On those platforms
+ * we need to do integer writes to the bus. Because of some unrolled code,
+ * in this current code the size of mp_weave_word must be four. The code that
+ * makes this assumption explicity is called out. (on some platforms a write
+ * of 4 bytes still requires a single read-modify-write operation.
+ *
+ * This function is takes the identical parameters as the function above,
+ * however it lays out the final array differently. Where the previous function
+ * treats the mpi_int as an byte array, this function treats it as an array of
+ * mp_digits where each digit is stored in big endian order.
+ *
+ * since we need to interleave on a byte by byte basis, we need to collect
+ * several mpi structures together into a single uint32 before we write. We
+ * also need to make sure the uint32 is arranged so that the first value of
+ * the first array winds up in b[0]. This means construction of that uint32
+ * is endian specific (even though the layout of the mp_digits in the array
+ * is always big endian).
+ *
+ * The final data is stored as follows :
+ *
+ * Our same logical array p array, m is sizeof(mp_digit),
+ * N is still count and n is now b_size. If we define p[i].digit[j]0 as the
+ * most significant byte of the word p[i].digit[j], p[i].digit[j]1 as
+ * the next most significant byte of p[i].digit[j], ... and p[i].digit[j]m-1
+ * is the least significant byte.
+ * Our array would look like:
+ * p[0].digit[0]0 p[1].digit[0]0 ... p[N-2].digit[0]0 p[N-1].digit[0]0
+ * p[0].digit[0]1 p[1].digit[0]1 ... p[N-2].digit[0]1 p[N-1].digit[0]1
+ * . .
+ * p[0].digit[0]m-1 p[1].digit[0]m-1 ... p[N-2].digit[0]m-1 p[N-1].digit[0]m-1
+ * p[0].digit[1]0 p[1].digit[1]0 ... p[N-2].digit[1]0 p[N-1].digit[1]0
+ * . .
+ * . .
+ * p[0].digit[n-1]m-2 p[1].digit[n-1]m-2 ... p[N-2].digit[n-1]m-2 p[N-1].digit[n-1]m-2
+ * p[0].digit[n-1]m-1 p[1].digit[n-1]m-1 ... p[N-2].digit[n-1]m-1 p[N-1].digit[n-1]m-1
+ *
+ */
+mp_err mpi_to_weave(const mp_int *a, unsigned char *b,
+ mp_size b_size, mp_size count)
+{
+ mp_size i;
+ mp_digit *digitsa0;
+ mp_digit *digitsa1;
+ mp_digit *digitsa2;
+ mp_digit *digitsa3;
+ mp_size useda0;
+ mp_size useda1;
+ mp_size useda2;
+ mp_size useda3;
+ mp_weave_word *weaved = (mp_weave_word *)b;
+
+ count = count/sizeof(mp_weave_word);
+
+ /* this code pretty much depends on this ! */
+#if MP_ARGCHK < 2
+ assert(WEAVE_WORD_SIZE == 4);
+ assert(sizeof(mp_weave_word) == 4);
+#endif
+
+ digitsa0 = MP_DIGITS(&a[0]);
+ digitsa1 = MP_DIGITS(&a[1]);
+ digitsa2 = MP_DIGITS(&a[2]);
+ digitsa3 = MP_DIGITS(&a[3]);
+ useda0 = MP_USED(&a[0]);
+ useda1 = MP_USED(&a[1]);
+ useda2 = MP_USED(&a[2]);
+ useda3 = MP_USED(&a[3]);
+
+ ARGCHK(MP_SIGN(&a[0]) == MP_ZPOS, MP_BADARG);
+ ARGCHK(MP_SIGN(&a[1]) == MP_ZPOS, MP_BADARG);
+ ARGCHK(MP_SIGN(&a[2]) == MP_ZPOS, MP_BADARG);
+ ARGCHK(MP_SIGN(&a[3]) == MP_ZPOS, MP_BADARG);
+ ARGCHK(useda0 <= b_size, MP_BADARG);
+ ARGCHK(useda1 <= b_size, MP_BADARG);
+ ARGCHK(useda2 <= b_size, MP_BADARG);
+ ARGCHK(useda3 <= b_size, MP_BADARG);
+
+#define SAFE_FETCH(digit, used, word) ((word) < (used) ? (digit[word]) : 0)
+
+ for (i=0; i < b_size; i++) {
+ mp_digit d0 = SAFE_FETCH(digitsa0,useda0,i);
+ mp_digit d1 = SAFE_FETCH(digitsa1,useda1,i);
+ mp_digit d2 = SAFE_FETCH(digitsa2,useda2,i);
+ mp_digit d3 = SAFE_FETCH(digitsa3,useda3,i);
+ register mp_weave_word acc;
+
+/*
+ * ONE_STEP takes the MSB of each of our current digits and places that
+ * byte in the appropriate position for writing to the weaved array.
+ * On little endian:
+ * b3 b2 b1 b0
+ * On big endian:
+ * b0 b1 b2 b3
+ * When the data is written it would always wind up:
+ * b[0] = b0
+ * b[1] = b1
+ * b[2] = b2
+ * b[3] = b3
+ *
+ * Once we've written the MSB, we shift the whole digit up left one
+ * byte, putting the Next Most Significant Byte in the MSB position,
+ * so we we repeat the next one step that byte will be written.
+ * NOTE: This code assumes sizeof(mp_weave_word) and MP_WEAVE_WORD_SIZE
+ * is 4.
+ */
+#ifdef IS_LITTLE_ENDIAN
+#define MPI_WEAVE_ONE_STEP \
+ acc = (d0 >> (MP_DIGIT_BITS-8)) & 0x000000ff; d0 <<= 8; /*b0*/ \
+ acc |= (d1 >> (MP_DIGIT_BITS-16)) & 0x0000ff00; d1 <<= 8; /*b1*/ \
+ acc |= (d2 >> (MP_DIGIT_BITS-24)) & 0x00ff0000; d2 <<= 8; /*b2*/ \
+ acc |= (d3 >> (MP_DIGIT_BITS-32)) & 0xff000000; d3 <<= 8; /*b3*/ \
+ *weaved = acc; weaved += count;
+#else
+#define MPI_WEAVE_ONE_STEP \
+ acc = (d0 >> (MP_DIGIT_BITS-32)) & 0xff000000; d0 <<= 8; /*b0*/ \
+ acc |= (d1 >> (MP_DIGIT_BITS-24)) & 0x00ff0000; d1 <<= 8; /*b1*/ \
+ acc |= (d2 >> (MP_DIGIT_BITS-16)) & 0x0000ff00; d2 <<= 8; /*b2*/ \
+ acc |= (d3 >> (MP_DIGIT_BITS-8)) & 0x000000ff; d3 <<= 8; /*b3*/ \
+ *weaved = acc; weaved += count;
+#endif
+ switch (sizeof(mp_digit)) {
+ case 32:
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ case 16:
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ case 8:
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ case 4:
+ MPI_WEAVE_ONE_STEP
+ MPI_WEAVE_ONE_STEP
+ case 2:
+ MPI_WEAVE_ONE_STEP
+ case 1:
+ MPI_WEAVE_ONE_STEP
+ break;
+ }
+ }
+
+ return MP_OKAY;
+}
+
+/* reverse the operation above for one entry.
+ * b points to the offset into the weave array of the power we are
+ * calculating */
+mp_err weave_to_mpi(mp_int *a, const unsigned char *b,
+ mp_size b_size, mp_size count)
+{
+ mp_digit *pb = MP_DIGITS(a);
+ mp_digit *end = &pb[b_size];
+
+ MP_SIGN(a) = MP_ZPOS;
+ MP_USED(a) = b_size;
+
+ for (; pb < end; pb++) {
+ register mp_digit digit;
+
+ digit = *b << 8; b += count;
+#define MPI_UNWEAVE_ONE_STEP digit |= *b; b += count; digit = digit << 8;
+ switch (sizeof(mp_digit)) {
+ case 32:
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ case 16:
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ case 8:
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ case 4:
+ MPI_UNWEAVE_ONE_STEP
+ MPI_UNWEAVE_ONE_STEP
+ case 2:
+ break;
+ }
+ digit |= *b; b += count;
+
+ *pb = digit;
+ }
+ s_mp_clamp(a);
+ return MP_OKAY;
+}
+#endif
+
+
+#define SQR(a,b) \
+ MP_CHECKOK( mp_sqr(a, b) );\
+ MP_CHECKOK( s_mp_redc(b, mmm) )
+
+#if defined(MP_MONT_USE_MP_MUL)
+#define MUL_NOWEAVE(x,a,b) \
+ MP_CHECKOK( mp_mul(a, x, b) ); \
+ MP_CHECKOK( s_mp_redc(b, mmm) )
+#else
+#define MUL_NOWEAVE(x,a,b) \
+ MP_CHECKOK( s_mp_mul_mont(a, x, b, mmm) )
+#endif
+
+#define MUL(x,a,b) \
+ MP_CHECKOK( weave_to_mpi(&tmp, powers + (x), nLen, num_powers) ); \
+ MUL_NOWEAVE(&tmp,a,b)
+
+#define SWAPPA ptmp = pa1; pa1 = pa2; pa2 = ptmp
+#define MP_ALIGN(x,y) ((((ptrdiff_t)(x))+((y)-1))&(((ptrdiff_t)0)-(y)))
+
+/* Do modular exponentiation using integer multiply code. */
+mp_err mp_exptmod_safe_i(const mp_int * montBase,
+ const mp_int * exponent,
+ const mp_int * modulus,
+ mp_int * result,
+ mp_mont_modulus *mmm,
+ int nLen,
+ mp_size bits_in_exponent,
+ mp_size window_bits,
+ mp_size num_powers)
+{
+ mp_int *pa1, *pa2, *ptmp;
+ mp_size i;
+ mp_size first_window;
+ mp_err res;
+ int expOff;
+ mp_int accum1, accum2, accum[WEAVE_WORD_SIZE];
+ mp_int tmp;
+ unsigned char *powersArray;
+ unsigned char *powers;
+
+ powersArray = (unsigned char *)malloc(num_powers*(nLen*sizeof(mp_digit)+1));
+ if (powersArray == NULL) {
+ res = MP_MEM;
+ goto CLEANUP;
+ }
+
+ /* powers[i] = base ** (i); */
+ powers = (unsigned char *)MP_ALIGN(powersArray,num_powers);
+
+ MP_DIGITS(&accum1) = 0;
+ MP_DIGITS(&accum2) = 0;
+ MP_DIGITS(&accum[0]) = 0;
+ MP_DIGITS(&accum[1]) = 0;
+ MP_DIGITS(&accum[2]) = 0;
+ MP_DIGITS(&accum[3]) = 0;
+
+ /* grab the first window value. This allows us to preload accumulator1
+ * and save a conversion, some squares and a multiple*/
+ MP_CHECKOK( mpl_get_bits(exponent,
+ bits_in_exponent-window_bits, window_bits) );
+ first_window = (mp_size)res;
+
+ MP_CHECKOK( mp_init_size(&accum1, 3 * nLen + 2) );
+ MP_CHECKOK( mp_init_size(&accum2, 3 * nLen + 2) );
+ MP_DIGITS(&tmp) = 0;
+ MP_CHECKOK( mp_init_size(&tmp, 3 * nLen + 2) );
+
+ /* build the first WEAVE_WORD powers inline */
+ /* if WEAVE_WORD_SIZE is not 4, this code will have to change */
+ if (num_powers > 2) {
+ MP_CHECKOK( mp_init_size(&accum[0], 3 * nLen + 2) );
+ MP_CHECKOK( mp_init_size(&accum[1], 3 * nLen + 2) );
+ MP_CHECKOK( mp_init_size(&accum[2], 3 * nLen + 2) );
+ MP_CHECKOK( mp_init_size(&accum[3], 3 * nLen + 2) );
+ mp_set(&accum[0], 1);
+ MP_CHECKOK( s_mp_to_mont(&accum[0], mmm, &accum[0]) );
+ MP_CHECKOK( mp_copy(montBase, &accum[1]) );
+ SQR(montBase, &accum[2]);
+ MUL_NOWEAVE(montBase, &accum[2], &accum[3]);
+ MP_CHECKOK( mpi_to_weave(accum, powers, nLen, num_powers) );
+ if (first_window < 4) {
+ MP_CHECKOK( mp_copy(&accum[first_window], &accum1) );
+ first_window = num_powers;
+ }
+ } else {
+ if (first_window == 0) {
+ mp_set(&accum1, 1);
+ MP_CHECKOK( s_mp_to_mont(&accum1, mmm, &accum1) );
+ } else {
+ /* assert first_window == 1? */
+ MP_CHECKOK( mp_copy(montBase, &accum1) );
+ }
+ }
+
+ /*
+ * calculate all the powers in the powers array.
+ * this adds 2**(k-1)-2 square operations over just calculating the
+ * odd powers where k is the window size in the two other mp_modexpt
+ * implementations in this file. We will get some of that
+ * back by not needing the first 'k' squares and one multiply for the
+ * first window */
+ for (i = WEAVE_WORD_SIZE; i < num_powers; i++) {
+ int acc_index = i & (WEAVE_WORD_SIZE-1); /* i % WEAVE_WORD_SIZE */
+ if ( i & 1 ) {
+ MUL_NOWEAVE(montBase, &accum[acc_index-1] , &accum[acc_index]);
+ /* we've filled the array do our 'per array' processing */
+ if (acc_index == (WEAVE_WORD_SIZE-1)) {
+ MP_CHECKOK( mpi_to_weave(accum, powers + i - (WEAVE_WORD_SIZE-1),
+ nLen, num_powers) );
+
+ if (first_window <= i) {
+ MP_CHECKOK( mp_copy(&accum[first_window & (WEAVE_WORD_SIZE-1)],
+ &accum1) );
+ first_window = num_powers;
+ }
+ }
+ } else {
+ /* up to 8 we can find 2^i-1 in the accum array, but at 8 we our source
+ * and target are the same so we need to copy.. After that, the
+ * value is overwritten, so we need to fetch it from the stored
+ * weave array */
+ if (i > 2* WEAVE_WORD_SIZE) {
+ MP_CHECKOK(weave_to_mpi(&accum2, powers+i/2, nLen, num_powers));
+ SQR(&accum2, &accum[acc_index]);
+ } else {
+ int half_power_index = (i/2) & (WEAVE_WORD_SIZE-1);
+ if (half_power_index == acc_index) {
+ /* copy is cheaper than weave_to_mpi */
+ MP_CHECKOK(mp_copy(&accum[half_power_index], &accum2));
+ SQR(&accum2,&accum[acc_index]);
+ } else {
+ SQR(&accum[half_power_index],&accum[acc_index]);
+ }
+ }
+ }
+ }
+ /* if the accum1 isn't set, Then there is something wrong with our logic
+ * above and is an internal programming error.
+ */
+#if MP_ARGCHK == 2
+ assert(MP_USED(&accum1) != 0);
+#endif
+
+ /* set accumulator to montgomery residue of 1 */
+ pa1 = &accum1;
+ pa2 = &accum2;
+
+ for (expOff = bits_in_exponent - window_bits*2; expOff >= 0; expOff -= window_bits) {
+ mp_size smallExp;
+ MP_CHECKOK( mpl_get_bits(exponent, expOff, window_bits) );
+ smallExp = (mp_size)res;
+
+ /* handle unroll the loops */
+ switch (window_bits) {
+ case 1:
+ if (!smallExp) {
+ SQR(pa1,pa2); SWAPPA;
+ } else if (smallExp & 1) {
+ SQR(pa1,pa2); MUL_NOWEAVE(montBase,pa2,pa1);
+ } else {
+ ABORT;
+ }
+ break;
+ case 6:
+ SQR(pa1,pa2); SQR(pa2,pa1);
+ /* fall through */
+ case 4:
+ SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
+ MUL(smallExp, pa1,pa2); SWAPPA;
+ break;
+ case 5:
+ SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
+ SQR(pa1,pa2); MUL(smallExp,pa2,pa1);
+ break;
+ default:
+ ABORT; /* could do a loop? */
+ }
+ }
+
+ res = s_mp_redc(pa1, mmm);
+ mp_exch(pa1, result);
+
+CLEANUP:
+ mp_clear(&accum1);
+ mp_clear(&accum2);
+ mp_clear(&accum[0]);
+ mp_clear(&accum[1]);
+ mp_clear(&accum[2]);
+ mp_clear(&accum[3]);
+ /* PORT_Memset(powers,0,num_powers*nLen*sizeof(mp_digit)); */
+ free(powersArray);
+ return res;
+}
+#undef SQR
+#undef MUL
+#endif
mp_err mp_exptmod(const mp_int *inBase, const mp_int *exponent,
const mp_int *modulus, mp_int *result)
@@ -514,6 +1087,9 @@ mp_err mp_exptmod(const mp_int *inBase, const mp_int *exponent,
int nLen;
mp_int montBase, goodBase;
mp_mont_modulus mmm;
+#ifdef MP_USING_CACHE_SAFE_MOD_EXP
+ static unsigned int max_window_bits;
+#endif
/* function for computing n0prime only works if n0 is odd */
if (!mp_isodd(modulus))
@@ -546,6 +1122,21 @@ mp_err mp_exptmod(const mp_int *inBase, const mp_int *exponent,
MP_CHECKOK( s_mp_to_mont(base, &mmm, &montBase) );
bits_in_exponent = mpl_significant_bits(exponent);
+#ifdef MP_USING_CACHE_SAFE_MOD_EXP
+ if (mp_using_cache_safe_exp) {
+ if (bits_in_exponent > 780)
+ window_bits = 6;
+ else if (bits_in_exponent > 256)
+ window_bits = 5;
+ else if (bits_in_exponent > 20)
+ window_bits = 4;
+ /* RSA public key exponents are typically under 20 bits (common values
+ * are: 3, 17, 65537) and a 4-bit window is inefficient
+ */
+ else
+ window_bits = 1;
+ } else
+#endif
if (bits_in_exponent > 480)
window_bits = 6;
else if (bits_in_exponent > 160)
@@ -557,6 +1148,35 @@ mp_err mp_exptmod(const mp_int *inBase, const mp_int *exponent,
*/
else
window_bits = 1;
+
+#ifdef MP_USING_CACHE_SAFE_MOD_EXP
+ /*
+ * clamp the window size based on
+ * the cache line size.
+ */
+ if (!max_window_bits) {
+ unsigned long cache_size = s_mpi_getProcessorLineSize();
+ /* processor has no cache, use 'fast' code always */
+ if (cache_size == 0) {
+ mp_using_cache_safe_exp = 0;
+ }
+ if ((cache_size == 0) || (cache_size >= 64)) {
+ max_window_bits = 6;
+ } else if (cache_size >= 32) {
+ max_window_bits = 5;
+ } else if (cache_size >= 16) {
+ max_window_bits = 4;
+ } else max_window_bits = 1; /* should this be an assert? */
+ }
+
+ /* clamp the window size down before we caclulate bits_in_exponent */
+ if (mp_using_cache_safe_exp) {
+ if (window_bits > max_window_bits) {
+ window_bits = max_window_bits;
+ }
+ }
+#endif
+
odd_ints = 1 << (window_bits - 1);
i = bits_in_exponent % window_bits;
if (i != 0) {
@@ -570,6 +1190,12 @@ mp_err mp_exptmod(const mp_int *inBase, const mp_int *exponent,
bits_in_exponent, window_bits, odd_ints);
} else
#endif
+#ifdef MP_USING_CACHE_SAFE_MOD_EXP
+ if (mp_using_cache_safe_exp) {
+ res = mp_exptmod_safe_i(&montBase, exponent, modulus, result, &mmm, nLen,
+ bits_in_exponent, window_bits, 1 << window_bits);
+ } else
+#endif
res = mp_exptmod_i(&montBase, exponent, modulus, result, &mmm, nLen,
bits_in_exponent, window_bits, odd_ints);
diff --git a/security/nss/lib/freebl/mpi/mpv_sparcv8.s b/security/nss/lib/freebl/mpi/mpv_sparcv8.s
index 81fdd1b93..8cfa4d0c4 100644
--- a/security/nss/lib/freebl/mpi/mpv_sparcv8.s
+++ b/security/nss/lib/freebl/mpi/mpv_sparcv8.s
@@ -1,36 +1,39 @@
-!/*
-! * 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 a SPARC/VIS optimized multiply and add function
-! *
-! * The Initial Developer of the Original Code is Sun Microsystems Inc.
-! * Portions created by Sun Microsystems Inc. are
-! * Copyright (C) 1999-2000 Sun Microsystems Inc. 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.
-! * $Id$
-! */
-
+! Inner multiply loop functions for hybrid 32/64-bit Sparc v8plus CPUs.
+! ***** BEGIN LICENSE BLOCK *****
+! 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 a SPARC v8plus+VIS optimized multiply and add function
+!
+! The Initial Developer of the Original Code is Sun Microsystems Inc.
+! Portions created by Sun Microsystems Inc. are
+! Copyright (C) 2000-2005 Sun Microsystems Inc. All Rights Reserved.
+!
+! Contributor(s):
+!
+! 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.
+!
+! ***** END LICENSE BLOCK *****
+! $Id$
.section ".text",#alloc,#execinstr
/* 000000 3 ( 0 0) */ .file "mpv_sparc.c"
@@ -40,7 +43,7 @@
!
! OFFSET SOURCE LINE LABEL INSTRUCTION (ISSUE TIME) (COMPLETION TIME)
- .L_const_seg_900000106: /* frequency 1.0 confidence 0.0 */
+ .L_const_seg_900000106: /* frequency 1.0 confidence 0.0 */
/* 000000 19 ( 0 0) */ .word 1127219200,0
/* 0x0008 20 ( 0 0) */ .word 1105199103,-4194304
/* 0x0010 21 ( 0 0) */ .align 16
@@ -50,8 +53,8 @@
! ENTRY mul_add
!
- .global mul_add
- mul_add: /* frequency 1.0 confidence 0.0 */
+ .global mul_add
+ mul_add: /* frequency 1.0 confidence 0.0 */
/* 0x0010 29 ( 0 1) */ sethi %hi(0x1800),%g1
/* 0x0014 30 ( 0 1) */ sethi %hi(mask_cnst),%g2
/* 0x0018 31 ( 1 2) */ xor %g1,-984,%g1
@@ -62,7 +65,7 @@
! ENTRY .L900000154
!
- .L900000154: /* frequency 1.0 confidence 0.0 */
+ .L900000154: /* frequency 1.0 confidence 0.0 */
/* 0x0024 35 ( 0 2) */ call (.+0x8) ! params = ! Result =
/* 0x0028 ( 1 2) */ sethi %hi((_GLOBAL_OFFSET_TABLE_-(.L900000154-.))),%g5
/* 0x002c 177 ( 2 3) */ sethi %hi(.L_const_seg_900000106),%g3
@@ -190,7 +193,7 @@
! ENTRY .L77000037
!
- .L77000037: /* frequency 1.0 confidence 0.0 */
+ .L77000037: /* frequency 1.0 confidence 0.0 */
/* 0x020c 307 ( 0 1) */ subcc %o2,16,%g0
/* 0x0210 308 ( 0 1) */ bne,pn %icc,.L77000076 ! tprob=0.50
/* 0x0214 ( 1 5) */ ldd [%o0],%f8
@@ -411,7 +414,7 @@
! ENTRY .L77000076
!
- .L77000076: /* frequency 1.0 confidence 0.0 */
+ .L77000076: /* frequency 1.0 confidence 0.0 */
/* 0x0568 540 ( 0 4) */ ldd [%o0],%f6
/* 0x056c 546 ( 0 1) */ add %o2,1,%g2
/* 0x0570 547 ( 0 3) */ fmovd %f0,%f14
@@ -454,7 +457,7 @@
! ENTRY .L900000149
!
- .L900000149: /* frequency 1.0 confidence 0.0 */
+ .L900000149: /* frequency 1.0 confidence 0.0 */
/* 0x05fc 586 ( 0 4) */ fxnor %f14,%f12,%f22
/* 0x0600 587 ( 0 5) */ fmuld %f4,%f16,%f4
/* 0x0604 588 ( 0 1) */ add %g2,2,%g2
@@ -491,7 +494,7 @@
! ENTRY .L900000152
!
- .L900000152: /* frequency 1.0 confidence 0.0 */
+ .L900000152: /* frequency 1.0 confidence 0.0 */
/* 0x0678 618 ( 0 4) */ fxnor %f14,%f12,%f12
/* 0x067c 619 ( 0 5) */ fmuld %f0,%f16,%f22
/* 0x0680 620 ( 0 1) */ add %o5,80,%o5
@@ -548,14 +551,14 @@
! ENTRY .L77000077
!
- .L77000077: /* frequency 1.0 confidence 0.0 */
+ .L77000077: /* frequency 1.0 confidence 0.0 */
/* 0x0744 670 ( 0 4) */ ldd [%g5],%f0
!
! ENTRY .L900000160
!
- .L900000160: /* frequency 1.0 confidence 0.0 */
+ .L900000160: /* frequency 1.0 confidence 0.0 */
/* 0x0748 672 ( 0 4) */ fxnor %f14,%f0,%f0
/* 0x074c 673 ( 0 1) */ add %g2,1,%g2
/* 0x0750 674 ( 0 1) */ add %g5,8,%g5
@@ -579,14 +582,14 @@
! ENTRY .L77000043
!
- .L77000043: /* frequency 1.0 confidence 0.0 */
+ .L77000043: /* frequency 1.0 confidence 0.0 */
/* 0x0790 696 ( 0 1) */ subcc %o3,0,%g0
!
! ENTRY .L900000161
!
- .L900000161: /* frequency 1.0 confidence 0.0 */
+ .L900000161: /* frequency 1.0 confidence 0.0 */
/* 0x0794 698 ( 0 1) */ ble,a,pt %icc,.L900000159 ! tprob=0.50
/* 0x0798 ( 0 1) */ or %g0,%o7,%i0
/* 0x079c 703 ( 0 2) */ ldx [%fp-2256],%o2
@@ -614,7 +617,7 @@
! ENTRY .L900000145
!
- .L900000145: /* frequency 1.0 confidence 0.0 */
+ .L900000145: /* frequency 1.0 confidence 0.0 */
/* 0x07ec 724 ( 0 2) */ ld [%g3],%o7
/* 0x07f0 725 ( 0 1) */ add %o2,%o3,%o2
/* 0x07f4 726 ( 0 1) */ sra %o0,0,%o3
@@ -647,7 +650,7 @@
! ENTRY .L900000148
!
- .L900000148: /* frequency 1.0 confidence 0.0 */
+ .L900000148: /* frequency 1.0 confidence 0.0 */
/* 0x0858 752 ( 0 1) */ add %o2,%o3,%o2
/* 0x085c 753 ( 0 1) */ sra %o0,0,%o3
/* 0x0860 754 ( 0 2) */ ld [%g3],%o0
@@ -667,14 +670,14 @@
! ENTRY .L77000078
!
- .L77000078: /* frequency 1.0 confidence 0.0 */
+ .L77000078: /* frequency 1.0 confidence 0.0 */
/* 0x0890 767 ( 0 2) */ ld [%g3],%o2
!
! ENTRY .L900000158
!
- .L900000158: /* frequency 1.0 confidence 0.0 */
+ .L900000158: /* frequency 1.0 confidence 0.0 */
/* 0x0894 769 ( 0 2) */ ldx [%g5],%o0
/* 0x0898 770 ( 0 1) */ sra %o7,0,%o1
/* 0x089c 771 ( 0 1) */ add %g4,1,%g4
@@ -693,7 +696,7 @@
! ENTRY .L77000047
!
- .L77000047: /* frequency 1.0 confidence 0.0 */
+ .L77000047: /* frequency 1.0 confidence 0.0 */
/* 0x08c8 783 ( 0 1) */ or %g0,%o7,%i0
/* 0x08cc ( 1 8) */ ret ! Result = %o1 %o0 %f0 %f1
/* 0x08d0 ( 3 5) */ restore %g0,%g0,%g0
@@ -702,7 +705,7 @@
! ENTRY .L77000048
!
- .L77000048: /* frequency 1.0 confidence 0.0 */
+ .L77000048: /* frequency 1.0 confidence 0.0 */
/* 0x08d4 794 ( 0 1) */ bne,pn %icc,.L77000050 ! tprob=0.50
/* 0x08d8 ( 0 1) */ sethi %hi(0xfff80000),%g2
/* 0x08dc 796 ( 0 4) */ ldd [%g5],%f4
@@ -872,7 +875,7 @@
! ENTRY .L77000050
!
- .L77000050: /* frequency 1.0 confidence 0.0 */
+ .L77000050: /* frequency 1.0 confidence 0.0 */
/* 0x0b64 978 ( 0 1) */ subcc %o2,16,%g0
/* 0x0b68 979 ( 0 1) */ bne,pn %icc,.L77000073 ! tprob=0.50
/* 0x0b6c ( 0 1) */ sethi %hi(0xfff80000),%g2
@@ -1180,14 +1183,14 @@
! ENTRY .L77000061
!
- .L77000061: /* frequency 1.0 confidence 0.0 */
+ .L77000061: /* frequency 1.0 confidence 0.0 */
/* 0x119c 1437 ( 0 1) */ or %g0,%o7,%i0
!
! ENTRY .L900000159
!
- .L900000159: /* frequency 1.0 confidence 0.0 */
+ .L900000159: /* frequency 1.0 confidence 0.0 */
/* 0x11a0 ( 0 7) */ ret ! Result = %o1 %o0 %f0 %f1
/* 0x11a4 ( 2 4) */ restore %g0,%g0,%g0
@@ -1195,9 +1198,7 @@
! ENTRY .L77000073
!
- .L77000073: /* frequency 1.0 confidence 0.0 */
-
-
+ .L77000073: /* frequency 1.0 confidence 0.0 */
or %g0, %i4, %o2
or %g0, %o0, %o1
or %g0, %i3, %o0
@@ -1206,7 +1207,7 @@
! ENTRY .L77000052
!
- .L77000052: /* frequency 1.0 confidence 0.0 */
+ .L77000052: /* frequency 1.0 confidence 0.0 */
/* 0x1028 1318 ( 0 1) */ andn %o2,%g2,%g2
/* 0x102c 1319 ( 0 1) */ st %g2,[%sp+96]
/* 0x1030 1325 ( 0 1) */ add %o0,1,%g3
@@ -1269,7 +1270,7 @@
! ENTRY .L990000154
!
- .L990000154: /* frequency 1.0 confidence 0.0 */
+ .L990000154: /* frequency 1.0 confidence 0.0 */
/* 0x110c 1384 ( 0 3) */ ldd [%o1],%f24
/* 0x1110 1385 ( 0 1) */ add %g4,3,%g4
/* 0x1114 1386 ( 0 1) */ add %o4,96,%o4
@@ -1339,7 +1340,7 @@
! ENTRY .L990000157
!
- .L990000157: /* frequency 1.0 confidence 0.0 */
+ .L990000157: /* frequency 1.0 confidence 0.0 */
/* 0x120c 1449 ( 0 3) */ fitod %f12,%f28
/* 0x1210 1450 ( 0 3) */ fmuld %f6,%f18,%f24
/* 0x1214 1451 ( 0 1) */ add %g3,128,%g3
@@ -1409,14 +1410,14 @@
! ENTRY .L77000054
!
- .L77000054: /* frequency 1.0 confidence 0.0 */
+ .L77000054: /* frequency 1.0 confidence 0.0 */
/* 0x130c 1514 ( 0 3) */ ldd [%o1],%f0
!
! ENTRY .L990000161
!
- .L990000161: /* frequency 1.0 confidence 0.0 */
+ .L990000161: /* frequency 1.0 confidence 0.0 */
/* 0x1310 1516 ( 0 2) */ fxnor %f14,%f0,%f0
/* 0x1314 1517 ( 0 1) */ add %g4,1,%g4
/* 0x1318 1518 ( 0 1) */ add %o1,8,%o1
@@ -1448,14 +1449,14 @@
! ENTRY .L77000056
!
- .L77000056: /* frequency 1.0 confidence 0.0 */
+ .L77000056: /* frequency 1.0 confidence 0.0 */
/* 0x1378 1548 ( 0 1) */ subcc %o0,0,%g0
!
! ENTRY .L990000162
!
- .L990000162: /* frequency 1.0 confidence 0.0 */
+ .L990000162: /* frequency 1.0 confidence 0.0 */
/* 0x137c 1550 ( 0 1) */ bleu,pt %icc,.L77770061 ! tprob=0.50
/* 0x1380 ( 0 1) */ nop
/* 0x1384 1555 ( 0 1) */ sethi %hi(0x1800),%g1
@@ -1500,7 +1501,7 @@
! ENTRY .L990000142
!
- .L990000142: /* frequency 1.0 confidence 0.0 */
+ .L990000142: /* frequency 1.0 confidence 0.0 */
/* 0x1418 1593 ( 0 1) */ add %o2,%o3,%o2
/* 0x141c 1594 ( 0 1) */ add %i2,4,%i2
/* 0x1420 1595 ( 0 2) */ ld [%g4],%o3
@@ -1550,7 +1551,7 @@
! ENTRY .L990000145
!
- .L990000145: /* frequency 1.0 confidence 0.0 */
+ .L990000145: /* frequency 1.0 confidence 0.0 */
/* 0x14c8 1638 ( 0 1) */ add %o2,%o3,%o3
/* 0x14cc 1639 ( 0 1) */ add %g3,4,%g3
/* 0x14d0 1640 ( 1 2) */ srl %o0,0,%o2
@@ -1565,14 +1566,14 @@
! ENTRY .L77000058
!
- .L77000058: /* frequency 1.0 confidence 0.0 */
+ .L77000058: /* frequency 1.0 confidence 0.0 */
/* 0x14ec 1648 ( 0 2) */ ldx [%g2],%o2
!
! ENTRY .L990000160
!
- .L990000160: /* frequency 1.0 confidence 0.0 */
+ .L990000160: /* frequency 1.0 confidence 0.0 */
/* 0x14f0 1650 ( 0 1) */ sllx %o2,19,%o3
/* 0x14f4 1651 ( 0 2) */ ldx [%g5],%o0
/* 0x14f8 1652 ( 0 1) */ add %i2,1,%i2
@@ -1595,13 +1596,10 @@
! ENTRY .L77770061
!
- .L77770061: /* frequency 1.0 confidence 0.0 */
+ .L77770061: /* frequency 1.0 confidence 0.0 */
/* 0x1534 ( 0 2) */ ret ! Result = %o1 %o0 %f0 %f1
/* 0x1538 ( 2 3) */ restore %g0,%o5,%o0
-
-
-
/* 0x11a8 1441 ( 0 0) */ .type mul_add,2
/* 0x11a8 1442 ( 0 0) */ .size mul_add,(.-mul_add)
/* 0x11a8 1445 ( 0 0) */ .align 16
@@ -1611,8 +1609,8 @@
! ENTRY mul_add_inp
!
- .global mul_add_inp
- mul_add_inp: /* frequency 1.0 confidence 0.0 */
+ .global mul_add_inp
+ mul_add_inp: /* frequency 1.0 confidence 0.0 */
/* 0x11b0 1453 ( 0 1) */ or %g0,%o2,%g1
/* 0x11b4 1454 ( 0 1) */ or %g0,%o3,%o4
/* 0x11b8 1455 ( 1 2) */ or %g0,%o0,%g3
@@ -1633,7 +1631,7 @@
! ENTRY mask_cnst
!
- mask_cnst: /* frequency 1.0 confidence 0.0 */
+ mask_cnst: /* frequency 1.0 confidence 0.0 */
/* 0x11d8 8 ( 0 0) */ .word -2147483648
/* 0x11dc 9 ( 0 0) */ .word -2147483648
/* 0x11e0 10 ( 0 0) */ .type mask_cnst,#object
diff --git a/security/nss/lib/freebl/mpi/mpv_sparcv8x.s b/security/nss/lib/freebl/mpi/mpv_sparcv8x.s
new file mode 100644
index 000000000..154d69965
--- /dev/null
+++ b/security/nss/lib/freebl/mpi/mpv_sparcv8x.s
@@ -0,0 +1,175 @@
+! Inner multiply loop functions for pure 32-bit Sparc v8 CPUs.
+! ***** BEGIN LICENSE BLOCK *****
+! 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 a SPARC v8 optimized multiply and add function
+!
+! The Initial Developer of the Original Code is Sun Microsystems Inc.
+! Portions created by Sun Microsystems Inc. are
+! Copyright (C) 2000-2005 Sun Microsystems Inc. All Rights Reserved.
+!
+! Contributor(s):
+!
+! 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.
+!
+! ***** END LICENSE BLOCK *****
+
+! $Id$
+
+ .file "mpv_sparcv8x.s"
+ .align 8
+
+ .section ".text",#alloc,#execinstr
+ .global s_mpv_mul_d
+ s_mpv_mul_d:
+ save %sp, -0x60, %sp
+ mov %i0, %o0
+ clr %g4
+ cmp %i1, 0x0
+ be .L103
+ sub %i1, 0x1, %o5
+ ld [%o0], %g1
+.L101:
+ umul %g1, %i2, %g2
+ rd %y, %g1
+ add %g2, %g4, %g3
+ mov %g1, %o4
+ add %o0, 0x4, %o0
+ cmp %g3, %g4
+ blu,a .L102
+ add %g1, 0x1, %o4
+.L102:
+ st %g3, [%i3]
+ mov %o5, %g1
+ add %i3, 0x4, %i3
+ cmp %g1, 0x0
+ mov %o4, %g4
+ sub %o5, 0x1, %o5
+ bne,a .L101
+ ld [%o0], %g1
+.L103:
+ st %g4, [%i3]
+ ret
+ restore
+
+ .type s_mpv_mul_d,2
+ .size s_mpv_mul_d,(.-s_mpv_mul_d)
+
+ .align 16
+ .global s_mpv_mul_d_add
+ s_mpv_mul_d_add:
+
+ save %sp, -0x60, %sp
+ mov %i0, %o0
+ clr %g4
+ cmp %i1, 0x0
+ be .L204
+ sub %i1, 0x1, %o5
+ ld [%o0], %g1
+.L201:
+ umul %g1, %i2, %g2
+ rd %y, %g1
+ add %g2, %g4, %g3
+ mov %g1, %o4
+ add %o0, 0x4, %o0
+ cmp %g3, %g4
+ blu,a .L202
+ add %g1, 0x1, %o4
+.L202:
+ ld [%i3], %g2
+ add %g3, %g2, %g1
+ cmp %g1, %g2
+ blu,a .L203
+ add %o4, 0x1, %o4
+.L203:
+ st %g1, [%i3]
+ mov %o5, %g1
+ add %i3, 0x4, %i3
+ cmp %g1, 0x0
+ mov %o4, %g4
+ sub %o5, 0x1, %o5
+ bne,a .L201
+ ld [%o0], %g1
+.L204:
+ st %g4, [%i3]
+ ret
+ restore
+
+ .type s_mpv_mul_d_add,2
+ .size s_mpv_mul_d_add,(.-s_mpv_mul_d_add)
+
+ .align 16
+ .global s_mpv_mul_d_add_prop
+ s_mpv_mul_d_add_prop:
+
+ save %sp, -0x60, %sp
+ mov %i0, %o0
+ clr %o5
+ cmp %i1, 0x0
+ be .L30x70
+ sub %i1, 0x1, %g4
+ ld [%o0], %g1
+.L30x1c:
+ umul %g1, %i2, %g2
+ rd %y, %g1
+ add %g2, %o5, %g3
+ mov %g1, %o4
+ add %o0, 0x4, %o0
+ cmp %g3, %o5
+ blu,a .L30x3c
+ add %g1, 0x1, %o4
+.L30x3c:
+ ld [%i3], %g2
+ add %g3, %g2, %g1
+ cmp %g1, %g2
+ blu,a .L30x50
+ add %o4, 0x1, %o4
+.L30x50:
+ st %g1, [%i3]
+ mov %g4, %g1
+ add %i3, 0x4, %i3
+ cmp %g1, 0x0
+ mov %o4, %o5
+ sub %g4, 0x1, %g4
+ bne,a .L30x1c
+ ld [%o0], %g1
+.L30x70:
+ cmp %o5, 0x0
+ be .L30xa0
+ nop
+ ld [%i3], %g1
+.L30x80:
+ add %o5, %g1, %g2
+ st %g2, [%i3]
+ add %i3, 0x4, %i3
+ cmp %g2, %g1
+ addx %g0, 0x0, %o5
+ cmp %o5, 0x0
+ bne,a .L30x80
+ ld [%i3], %g1
+.L30xa0:
+ ret
+ restore
+
+ .type s_mpv_mul_d_add_prop,2
+ .size s_mpv_mul_d_add_prop,(.-s_mpv_mul_d_add_prop)
diff --git a/security/nss/lib/freebl/mpi/target.mk b/security/nss/lib/freebl/mpi/target.mk
index 0edaf8813..c17854819 100644
--- a/security/nss/lib/freebl/mpi/target.mk
+++ b/security/nss/lib/freebl/mpi/target.mk
@@ -206,7 +206,7 @@ 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
+MPICMN += -DMP_MONT_USE_MP_MUL -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
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)
@@ -222,6 +222,7 @@ ifeq ($(TARGET),AMD64SOLARIS)
ASFLAGS += -xarch=generic64
AS_OBJS = mpi_amd64.o mpi_amd64_sun.o
MP_CONFIG = -DMP_ASSEMBLY_MULTIPLY -DMPI_AMD64
+MP_CONFIG += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
CFLAGS = -xarch=generic64 -xO4 -I. -DMP_API_COMPATIBLE -DMP_IOFUNC $(MP_CONFIG)
MPICMN += $(MP_CONFIG)
diff --git a/security/nss/lib/freebl/pqg.c b/security/nss/lib/freebl/pqg.c
index 4f9f15362..c3e92c62d 100644
--- a/security/nss/lib/freebl/pqg.c
+++ b/security/nss/lib/freebl/pqg.c
@@ -76,13 +76,11 @@ static const unsigned char fips_186_1_a5_pqseed[] = {
** global random number generator.
*/
static SECStatus
-getPQseed(SECItem *seed)
+getPQseed(SECItem *seed, PRArenaPool* arena)
{
- if (seed->data) {
- PORT_Free(seed->data);
- seed->data = NULL;
+ if (!seed->data) {
+ seed->data = (unsigned char*)PORT_ArenaZAlloc(arena, seed->len);
}
- seed->data = (unsigned char*)PORT_ZAlloc(seed->len);
if (!seed->data) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure;
@@ -455,7 +453,7 @@ step_1:
goto cleanup;
}
seed->len = seedBytes;
- CHECK_SEC_OK( getPQseed(seed) );
+ CHECK_SEC_OK( getPQseed(seed, verify->arena) );
/* ******************************************************************
** Step 2.
** "Compute U = SHA[SEED] XOR SHA[(SEED+1) mod 2**g]."
@@ -569,6 +567,9 @@ cleanup:
PORT_FreeArena(params->arena, PR_TRUE);
PORT_FreeArena(verify->arena, PR_TRUE);
}
+ if (hit.data) {
+ SECITEM_FreeItem(&hit, PR_FALSE);
+ }
return rv;
}
diff --git a/security/nss/lib/freebl/prng_fips1861.c b/security/nss/lib/freebl/prng_fips1861.c
index bcc85a79d..900b98ab8 100644
--- a/security/nss/lib/freebl/prng_fips1861.c
+++ b/security/nss/lib/freebl/prng_fips1861.c
@@ -47,6 +47,7 @@
#include "secitem.h"
#include "sha_fast.h"
#include "secrng.h" /* for RNG_GetNoise() */
+#include "secmpi.h"
/*
* The minimum amount of seed data required before the generator will
@@ -63,57 +64,93 @@
#define MIN_SEED_COUNT 1024
/*
- * Steps taken from FIPS 186-1 Appendix 3.1
+ * Steps taken from Algorithm 1 of FIPS 186-2 Change Notice 1
*/
/*
- * According to FIPS 186-1, 160 <= b <= 512
- * For our purposes, we will assume b == 160
+ * According to FIPS 186-2, 160 <= b <= 512.
+ * For our purposes, we will assume b == 160,
+ * 256, or 512 (the output size of SHA-1,
+ * SHA-256, or SHA-512).
*/
-#define FIPS_B 160
-#define BSIZE FIPS_B / BITS_PER_BYTE
+#define FIPS_B 256
+#define B_HASH_BUF SHA256_HashBuf
+#define BSIZE (FIPS_B / PR_BITS_PER_BYTE)
+
+/* Output size of the G function */
+#define FIPS_G 160
+#define GSIZE (FIPS_G / PR_BITS_PER_BYTE)
/*
- * Add two 160-bit numbers represented as arrays of 20 bytes.
+ * Add two b-bit numbers represented as arrays of BSIZE bytes.
* The numbers are big-endian, MSB first, so addition is done
* from the end of the buffer to the beginning.
*/
-#define ADD_160BIT_PLUS_CARRY(dest, add1, add2, cy) \
+#define ADD_B_BIT_PLUS_CARRY(dest, add1, add2, cy) \
carry = cy; \
- for (i=BSIZE-1; i>=0; --i) { \
- carry += add1[i] + add2[i]; \
- dest[i] = (PRUint8)carry; \
+ for (k=BSIZE-1; k>=0; --k) { \
+ carry += add1[k] + add2[k]; \
+ dest[k] = (PRUint8)carry; \
carry >>= 8; \
}
-#define ADD_160BIT_2(dest, add1, add2) \
- ADD_160BIT_PLUS_CARRY(dest, add1, add2, 0)
+#define ADD_B_BIT_2(dest, add1, add2) \
+ ADD_B_BIT_PLUS_CARRY(dest, add1, add2, 0)
/*
- * FIPS requires result from Step 3c to be reduced mod q when generating
+ * FIPS requires result from Step 3.3 to be reduced mod q when generating
* random numbers for DSA.
- * by definition q >= 2^159 + 1, thus xj < 2q
- * thus reducing mod q is simple subtraction when xj > q
+ *
+ * Input: w, 2*GSIZE bytes
+ * q, DSA_SUBPRIME_LEN bytes
+ * Output: xj, DSA_SUBPRIME_LEN bytes
*/
-#define dsa_reduce_mod_q(xj, q) \
- PORT_Assert(q[0] >= 0x80); \
- if (memcmp(xj,q,BSIZE) > 0) { \
- carry = 0; \
- for (i=BSIZE-1; i>=0; --i) { \
- carry += (signed int)xj[i] - (signed int)q[i]; \
- xj[i] = (PRUint8)carry; \
- carry >>= 8; \
- } \
+static SECStatus
+dsa_reduce_mod_q(const unsigned char *w, const unsigned char *q,
+ unsigned char *xj)
+{
+ mp_int W, Q, Xj;
+ mp_err err;
+ SECStatus rv = SECSuccess;
+
+ /* Initialize MPI integers. */
+ MP_DIGITS(&W) = 0;
+ MP_DIGITS(&Q) = 0;
+ MP_DIGITS(&Xj) = 0;
+ CHECK_MPI_OK( mp_init(&W) );
+ CHECK_MPI_OK( mp_init(&Q) );
+ CHECK_MPI_OK( mp_init(&Xj) );
+ /*
+ * Convert input arguments into MPI integers.
+ */
+ CHECK_MPI_OK( mp_read_unsigned_octets(&W, w, 2*GSIZE) );
+ CHECK_MPI_OK( mp_read_unsigned_octets(&Q, q, DSA_SUBPRIME_LEN) );
+ /*
+ * Algorithm 1 of FIPS 186-2 Change Notice 1, Step 3.3
+ *
+ * xj = (w0 || w1) mod q
+ */
+ CHECK_MPI_OK( mp_mod(&W, &Q, &Xj) );
+ CHECK_MPI_OK( mp_to_fixlen_octets(&Xj, xj, DSA_SUBPRIME_LEN) );
+cleanup:
+ mp_clear(&W);
+ mp_clear(&Q);
+ mp_clear(&Xj);
+ if (err) {
+ MP_TO_SEC_ERROR(err);
+ rv = SECFailure;
}
+ return rv;
+}
/*
* Specialized SHA1-like function. This function appends zeroes to a
* single input block and runs a single instance of the compression function,
- * as specified in FIPS 186-1 appendix 3.3.
+ * as specified in FIPS 186-2 appendix 3.3.
*/
-void
-RNG_UpdateAndEnd_FIPS186_1(SHA1Context *ctx,
+static void
+RNG_UpdateAndEnd_FIPS186_2(SHA1Context *ctx,
unsigned char *input, unsigned int inputLen,
unsigned char *hashout, unsigned int *pDigestLen,
unsigned int maxDigestLen);
@@ -123,9 +160,9 @@ RNG_UpdateAndEnd_FIPS186_1(SHA1Context *ctx,
*/
struct RNGContextStr {
PRUint8 XKEY[BSIZE]; /* Seed for next SHA iteration */
- PRUint8 Xj[BSIZE]; /* Output from previous operation */
+ PRUint8 Xj[2*GSIZE]; /* Output from previous operation. */
PZLock *lock; /* Lock to serialize access to global rng */
- PRUint8 avail; /* # bytes of output available, [0...20] */
+ PRUint8 avail; /* # bytes of output available, [0...2*GSIZE] */
PRUint32 seedCount; /* number of seed bytes given to generator */
PRBool isValid; /* false if RNG reaches an invalid state */
};
@@ -144,79 +181,115 @@ freeRNGContext()
}
/*
- * Implementation of the algorithm in FIPS 186-1 appendix 3.1, heretofore
- * called alg3_1(). It is assumed a lock for the global rng context has
- * already been acquired.
+ * Implementation of Algorithm 1 of FIPS 186-2 Change Notice 1,
+ * hereinafter called alg_cn_1(). It is assumed a lock for the global
+ * rng context has already been acquired.
* Calling this function with XSEEDj == NULL is equivalent to saying there
* is no optional user input, which is further equivalent to saying that
* the optional user input is 0.
*/
static SECStatus
-alg_fips186_1_x3_1(RNGContext *rng,
- const unsigned char *XSEEDj, unsigned char *q)
+alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj)
{
/* SHA1 context for G(t, XVAL) function */
SHA1Context sha1cx;
+ /* XKEY for iteration 1 */
+ PRUint8 XKEY_1[BSIZE];
+ const PRUint8 *XKEY_old;
+ PRUint8 *XKEY_new;
/* input to hash function */
PRUint8 XVAL[BSIZE];
/* store a copy of the output to compare with the previous output */
- PRUint8 x_j[BSIZE];
- /* used by ADD_160BIT macros */
- int i, carry;
+ PRUint8 x_j[2*GSIZE];
+ /* used by ADD_B_BIT macros */
+ int k, carry;
+ /* store the output of G(t, XVAL) in the rightmost GSIZE bytes */
+ PRUint8 w_i[BSIZE];
+ int i;
unsigned int len;
+ SECStatus rv = SECSuccess;
+
if (!rng->isValid) {
/* RNG has alread entered an invalid state. */
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
+#if GSIZE < BSIZE
+ /* zero the leftmost bytes so we can pass it to ADD_B_BIT_PLUS_CARRY */
+ memset(w_i, 0, BSIZE - GSIZE);
+#endif
/*
- * <Step 2> Initialize t, taken care of in SHA-1 (same initial values)
- */
- SHA1_Begin(&sha1cx);
- /*
- * <Step 3a> XSEEDj is optional user input
- *
- * <Step 3b> XVAL = (XKEY + XSEEDj) mod 2^b
- * :always reduced mod 2^b, since storing as 160-bit value
- */
- if (XSEEDj) {
- /* XSEEDj > 0 */
- ADD_160BIT_2(XVAL, rng->XKEY, XSEEDj);
- } else {
- /* XSEEDj == 0 */
- memcpy(XVAL, rng->XKEY, BSIZE);
- }
- /*
- * <Step 3c> Xj = G(t, XVAL) mod q
- * :In this code, (mod q) is only understood for DSA ops,
- * :not general RNG (what would q be in non-DSA uses?).
- * :If a q is specified, use it.
- * :FIPS 186-1 specifies a different padding than the SHA1 180-1
- * :specification, this function is implemented below.
+ * <Step 2> Initialize t, taken care of in SHA-1 (same initial values)
+ *
+ * <Step 3.1> XSEEDj is optional user input
*/
- RNG_UpdateAndEnd_FIPS186_1(&sha1cx, XVAL, BSIZE, x_j, &len, BSIZE);
- if (q != NULL) {
- dsa_reduce_mod_q(x_j, q);
+ for (i = 0; i < 2; i++) {
+ /* only update rng->XKEY when both iterations have been completed */
+ if (i == 0) {
+ /* for iteration 0 */
+ XKEY_old = rng->XKEY;
+ XKEY_new = XKEY_1;
+ } else {
+ /* for iteration 1 */
+ XKEY_old = XKEY_1;
+ XKEY_new = rng->XKEY;
+ }
+ /*
+ * <Step 3.2a> XVAL = (XKEY + XSEEDj) mod 2^b
+ * :always reduced mod 2^b, since storing as b-bit value
+ */
+ if (XSEEDj) {
+ /* XSEEDj > 0 */
+ if (memcmp(XKEY_old, XSEEDj, BSIZE) == 0) {
+ /* Should we add the error code SEC_ERROR_BAD_RNG_SEED? */
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ goto done;
+ }
+ ADD_B_BIT_2(XVAL, XKEY_old, XSEEDj);
+ } else {
+ /* XSEEDj == 0 */
+ memcpy(XVAL, XKEY_old, BSIZE);
+ }
+ /*
+ * <Step 3.2b> Wi = G(t, XVAL)
+ * :FIPS 186-2 specifies a different padding than the SHA1 180-1
+ * :specification, this function is implemented in
+ * :RNG_UpdateAndEnd_FIPS186_2 below.
+ */
+ SHA1_Begin(&sha1cx);
+ RNG_UpdateAndEnd_FIPS186_2(&sha1cx, XVAL, BSIZE,
+ &w_i[BSIZE - GSIZE], &len, GSIZE);
+ /*
+ * <Step 3.2c> XKEY = (1 + XKEY + Wi) mod 2^b
+ * :always reduced mod 2^b, since storing as 160-bit value
+ */
+ ADD_B_BIT_PLUS_CARRY(XKEY_new, XKEY_old, w_i, 1);
+ /*
+ * <Step 3.3> Xj = (W0 || W1)
+ */
+ memcpy(&x_j[i*GSIZE], &w_i[BSIZE - GSIZE], GSIZE);
}
- /* [FIPS 140-1] verify output does not match previous output */
- if (memcmp(x_j, rng->Xj, BSIZE) == 0) {
- /* failed FIPS 140-1 continuous RNG condition. RNG now invalid. */
+ /* [FIPS 140-2] verify output does not match previous output */
+ if (memcmp(x_j, rng->Xj, 2*GSIZE) == 0) {
+ /* failed FIPS 140-2 continuous RNG test. RNG now invalid. */
rng->isValid = PR_FALSE;
- return SECFailure;
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ rv = SECFailure;
+ goto done;
}
/* Xj is the output */
- memcpy(rng->Xj, x_j, BSIZE);
- /*
- * <Step 3d> XKEY = (1 + XKEY + Xj) mod 2^b
- * :always reduced mod 2^b, since storing as 160-bit value
- */
- ADD_160BIT_PLUS_CARRY(rng->XKEY, rng->XKEY, x_j, 1);
- /* Always have a full buffer after executing alg3_1() */
- rng->avail = BSIZE;
+ memcpy(rng->Xj, x_j, 2*GSIZE);
+ /* Always have a full buffer after executing alg_cn_1() */
+ rng->avail = 2*GSIZE;
+
+done:
/* housekeeping */
- memset(x_j, 0, BSIZE);
+ memset(&w_i[BSIZE - GSIZE], 0, GSIZE);
+ memset(x_j, 0, 2*GSIZE);
memset(XVAL, 0, BSIZE);
- return SECSuccess;
+ memset(XKEY_1, 0, BSIZE);
+ return rv;
}
/* Use NSPR to prevent RNG_RNGInit from being called from separate
@@ -237,6 +310,8 @@ static PRStatus rng_init(void)
/* create a lock for it */
globalrng->lock = PZ_NewLock(nssILockOther);
if (globalrng->lock == NULL) {
+ PORT_Free(globalrng);
+ globalrng = NULL;
PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
return PR_FAILURE;
}
@@ -246,7 +321,7 @@ static PRStatus rng_init(void)
numBytes = RNG_GetNoise(bytes, sizeof bytes);
RNG_RandomUpdate(bytes, numBytes);
}
- return (globalrng != NULL) ? PR_SUCCESS : PR_FAILURE;
+ return PR_SUCCESS;
}
/*
@@ -271,9 +346,8 @@ RNG_RNGInit(void)
** Update the global random number generator with more seeding
** material
*/
-SECStatus
-prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes,
- unsigned char *q)
+static SECStatus
+prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes)
{
SECStatus rv = SECSuccess;
unsigned char inputhash[BSIZE];
@@ -292,9 +366,9 @@ prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes,
if (bytes == BSIZE)
memcpy(inputhash, data, BSIZE);
else
- rv = SHA1_HashBuf(inputhash, data, bytes);
+ rv = B_HASH_BUF(inputhash, data, bytes);
if (rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ /* B_HASH_BUF set error */
return SECFailure;
}
/* --- LOCKED --- */
@@ -303,13 +377,13 @@ prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes,
* Random information is initially supplied by a call to
* RNG_SystemInfoForRNG(). That function collects entropy from
* the system and calls RNG_RandomUpdate() to seed the generator.
- * FIPS 186-1 3.1 step 1 specifies that a secret value for the
- * seed-key must be chosen before the generator can begin. The
- * size of XKEY is b-bytes, so fill it with the first b-bytes
- * sent to RNG_RandomUpdate().
+ * Algorithm 1 of FIPS 186-2 Change Notice 1, step 1 specifies that
+ * a secret value for the seed-key must be chosen before the
+ * generator can begin. The size of XKEY is b bits, so fill it
+ * with the first b bits sent to RNG_RandomUpdate().
*/
if (rng->seedCount == 0) {
- /* This is the first call to RandomUpdate(). Use a SHA1 hash
+ /* This is the first call to RandomUpdate(). Use a hash
* of the input to set the seed, XKEY.
*
* <Step 1> copy seed bytes into context's XKEY
@@ -320,19 +394,20 @@ prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes,
* initialize XKEY, the "optional user input" at this stage
* will be a pad of zeros, XSEEDj = 0.
*/
- rv = alg_fips186_1_x3_1(rng, NULL, q);
- /* As per FIPS 140-1 continuous RNG requirement, the first
+ rv = alg_fips186_2_cn_1(rng, NULL);
+ /* As per FIPS 140-2 continuous RNG test requirement, the first
* iteration of output is discarded. So here there is really
- * no output available. This forces another execution of alg3_1()
+ * no output available. This forces another execution of alg_cn_1()
* before any bytes can be extracted from the generator.
*/
rng->avail = 0;
} else {
- /* Execute the algorithm from FIPS 186-1 appendix 3.1 */
- rv = alg_fips186_1_x3_1(rng, inputhash, q);
+ /* Execute the algorithm from FIPS 186-2 Change Notice 1 */
+ rv = alg_fips186_2_cn_1(rng, inputhash);
}
/* If got this far, have added bytes of seed data. */
- rng->seedCount += bytes;
+ if (rv == SECSuccess)
+ rng->seedCount += bytes;
PZ_Unlock(rng->lock);
/* --- UNLOCKED --- */
/* housekeeping */
@@ -342,12 +417,12 @@ prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes,
/*
** Update the global random number generator with more seeding
-** material. Not DSA, so no q.
+** material.
*/
SECStatus
RNG_RandomUpdate(const void *data, size_t bytes)
{
- return prng_RandomUpdate(globalrng, data, bytes, NULL);
+ return prng_RandomUpdate(globalrng, data, bytes);
}
/*
@@ -356,7 +431,7 @@ RNG_RandomUpdate(const void *data, size_t bytes)
*/
SECStatus
prng_GenerateGlobalRandomBytes(RNGContext *rng,
- void *dest, size_t len, unsigned char *q)
+ void *dest, size_t len)
{
PRUint8 num;
SECStatus rv = SECSuccess;
@@ -379,18 +454,21 @@ prng_GenerateGlobalRandomBytes(RNGContext *rng,
}
/*
* If there are enough bytes of random data, send back Xj,
- * else call alg3_1() with 0's to generate more random data.
+ * else call alg_cn_1() with 0's to generate more random data.
*/
while (len > 0 && rv == SECSuccess) {
if (rng->avail == 0) {
/* All available bytes are used, so generate more. */
- rv = alg_fips186_1_x3_1(rng, NULL, q);
+ rv = alg_fips186_2_cn_1(rng, NULL);
}
- /* number of bytes to obtain on this iteration (max of 20) */
+ /* number of bytes to obtain on this iteration (max of 40) */
num = PR_MIN(rng->avail, len);
- /* if avail < BSIZE, the first avail bytes have already been used. */
+ /*
+ * if avail < 2*GSIZE, the first 2*GSIZE - avail bytes have
+ * already been used.
+ */
if (num) {
- memcpy(output, rng->Xj + (BSIZE - rng->avail), num);
+ memcpy(output, rng->Xj + (2*GSIZE - rng->avail), num);
rng->avail -= num;
len -= num;
output += num;
@@ -403,12 +481,12 @@ prng_GenerateGlobalRandomBytes(RNGContext *rng,
/*
** Generate some random bytes, using the global random number generator
-** object. Not DSA, so no q.
+** object.
*/
SECStatus
RNG_GenerateGlobalRandomBytes(void *dest, size_t len)
{
- return prng_GenerateGlobalRandomBytes(globalrng, dest, len, NULL);
+ return prng_GenerateGlobalRandomBytes(globalrng, dest, len);
}
void
@@ -417,7 +495,8 @@ RNG_RNGShutdown(void)
/* check for a valid global RNG context */
PORT_Assert(globalrng != NULL);
if (globalrng == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ /* Should set a "not initialized" error code. */
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return;
}
/* clear */
@@ -429,20 +508,20 @@ RNG_RNGShutdown(void)
/*
* SHA: Generate hash value from context
* Specialized function for PRNG
- * The PRNG specified in FIPS 186-1 3.3 uses a function, G,
+ * The PRNG specified in FIPS 186-2 3.3 uses a function, G,
* which has the same initialization and compression functions
- * as SHA1 180-1, but uses different padding. FIPS 186-1 3.3
+ * as SHA1 180-1, but uses different padding. FIPS 186-2 3.3
* specifies that the message be padded with 0's until the size
* reaches 512 bits.
*/
-void
-RNG_UpdateAndEnd_FIPS186_1(SHA1Context *ctx,
+static void
+RNG_UpdateAndEnd_FIPS186_2(SHA1Context *ctx,
unsigned char *input, unsigned int inputLen,
unsigned char *hashout, unsigned int *pDigestLen,
unsigned int maxDigestLen)
{
-#if defined(IS_LITTLE_ENDIAN)
- register PRUint32 A;
+#if defined(SHA_NEED_TMP_VARIABLE)
+ register PRUint32 tmp;
#endif
static const unsigned char bulk_pad0[64] = { 0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -465,55 +544,43 @@ RNG_UpdateAndEnd_FIPS186_1(SHA1Context *ctx,
/*
* Output hash
*/
-#if defined(IS_LITTLE_ENDIAN)
- SHA_BYTESWAP(ctx->H[0]);
- SHA_BYTESWAP(ctx->H[1]);
- SHA_BYTESWAP(ctx->H[2]);
- SHA_BYTESWAP(ctx->H[3]);
- SHA_BYTESWAP(ctx->H[4]);
-#endif
- memcpy(hashout, ctx->H, SHA1_LENGTH);
+ SHA_STORE_RESULT;
*pDigestLen = SHA1_LENGTH;
-
- /*
- * Re-initialize the context (also zeroizes contents)
- */
- SHA1_Begin(ctx);
}
/*
* Specialized RNG for DSA
*
- * As per FIPS 186-1 appendix 3.1, in step 5 the value Xj should
- * be reduced mod q, a 160-bit prime number. Since this parameter is
- * only meaningful in the context of DSA, the above RNG functions
+ * As per Algorithm 1 of FIPS 186-2 Change Notice 1, in step 3.3 the value
+ * Xj should be reduced mod q, a 160-bit prime number. Since this parameter
+ * is only meaningful in the context of DSA, the above RNG functions
* were implemented without it. They are re-implemented below for use
* with DSA.
*
*/
/*
-** Update the global random number generator with more seeding
-** material. DSA needs a q parameter.
-*/
-SECStatus
-DSA_RandomUpdate(void *data, size_t bytes, unsigned char *q)
-{
- if( q && (*q == 0) ) {
- ++q;
- }
- return prng_RandomUpdate(globalrng, data, bytes, q);
-}
-
-/*
** Generate some random bytes, using the global random number generator
** object. In DSA mode, so there is a q.
*/
SECStatus
-DSA_GenerateGlobalRandomBytes(void *dest, size_t len, unsigned char *q)
+DSA_GenerateGlobalRandomBytes(void *dest, size_t len, const unsigned char *q)
{
- if( q && (*q == 0) ) {
+ SECStatus rv;
+ unsigned char w[2*GSIZE];
+
+ PORT_Assert(q && len == DSA_SUBPRIME_LEN);
+ if (len != DSA_SUBPRIME_LEN) {
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
+ }
+ if (*q == 0) {
++q;
}
- return prng_GenerateGlobalRandomBytes(globalrng, dest, len, q);
+ rv = prng_GenerateGlobalRandomBytes(globalrng, w, 2*GSIZE);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ dsa_reduce_mod_q(w, q, (unsigned char *)dest);
+ return rv;
}
diff --git a/security/nss/lib/softoken/rawhash.c b/security/nss/lib/freebl/rawhash.c
index 7757cebbd..a3efe9b30 100644
--- a/security/nss/lib/softoken/rawhash.c
+++ b/security/nss/lib/freebl/rawhash.c
@@ -37,7 +37,7 @@
#include "nspr.h"
#include "sechash.h"
#include "blapi.h" /* below the line */
-
+#include "secerr.h"
static void *
null_hash_new_context(void)
@@ -84,7 +84,9 @@ const SECHashObject SECRawHashObjects[] = {
(void (*)(void *)) null_hash_begin,
(void (*)(void *, const unsigned char *, unsigned int)) null_hash_update,
(void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) null_hash_end
+ unsigned int)) null_hash_end,
+ 0,
+ HASH_AlgNULL
},
{ MD2_LENGTH,
(void * (*)(void)) MD2_NewContext,
@@ -92,7 +94,9 @@ const SECHashObject SECRawHashObjects[] = {
(void (*)(void *, PRBool)) MD2_DestroyContext,
(void (*)(void *)) MD2_Begin,
(void (*)(void *, const unsigned char *, unsigned int)) MD2_Update,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD2_End
+ (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD2_End,
+ MD2_BLOCK_LENGTH,
+ HASH_AlgMD2
},
{ MD5_LENGTH,
(void * (*)(void)) MD5_NewContext,
@@ -100,7 +104,9 @@ const SECHashObject SECRawHashObjects[] = {
(void (*)(void *, PRBool)) MD5_DestroyContext,
(void (*)(void *)) MD5_Begin,
(void (*)(void *, const unsigned char *, unsigned int)) MD5_Update,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD5_End
+ (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD5_End,
+ MD5_BLOCK_LENGTH,
+ HASH_AlgMD5
},
{ SHA1_LENGTH,
(void * (*)(void)) SHA1_NewContext,
@@ -108,7 +114,9 @@ const SECHashObject SECRawHashObjects[] = {
(void (*)(void *, PRBool)) SHA1_DestroyContext,
(void (*)(void *)) SHA1_Begin,
(void (*)(void *, const unsigned char *, unsigned int)) SHA1_Update,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) SHA1_End
+ (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) SHA1_End,
+ SHA1_BLOCK_LENGTH,
+ HASH_AlgSHA1
},
{ SHA256_LENGTH,
(void * (*)(void)) SHA256_NewContext,
@@ -116,7 +124,10 @@ const SECHashObject SECRawHashObjects[] = {
(void (*)(void *, PRBool)) SHA256_DestroyContext,
(void (*)(void *)) SHA256_Begin,
(void (*)(void *, const unsigned char *, unsigned int)) SHA256_Update,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) SHA256_End
+ (void (*)(void *, unsigned char *, unsigned int *,
+ unsigned int)) SHA256_End,
+ SHA256_BLOCK_LENGTH,
+ HASH_AlgSHA256
},
{ SHA384_LENGTH,
(void * (*)(void)) SHA384_NewContext,
@@ -124,7 +135,10 @@ const SECHashObject SECRawHashObjects[] = {
(void (*)(void *, PRBool)) SHA384_DestroyContext,
(void (*)(void *)) SHA384_Begin,
(void (*)(void *, const unsigned char *, unsigned int)) SHA384_Update,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) SHA384_End
+ (void (*)(void *, unsigned char *, unsigned int *,
+ unsigned int)) SHA384_End,
+ SHA384_BLOCK_LENGTH,
+ HASH_AlgSHA384
},
{ SHA512_LENGTH,
(void * (*)(void)) SHA512_NewContext,
@@ -132,7 +146,19 @@ const SECHashObject SECRawHashObjects[] = {
(void (*)(void *, PRBool)) SHA512_DestroyContext,
(void (*)(void *)) SHA512_Begin,
(void (*)(void *, const unsigned char *, unsigned int)) SHA512_Update,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) SHA512_End
+ (void (*)(void *, unsigned char *, unsigned int *,
+ unsigned int)) SHA512_End,
+ SHA512_BLOCK_LENGTH,
+ HASH_AlgSHA512
},
};
+const SECHashObject *
+HASH_GetRawHashObject(HASH_HashType hashType)
+{
+ if (hashType < HASH_AlgNULL || hashType >= HASH_AlgTOTAL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
+ return &SECRawHashObjects[hashType];
+}
diff --git a/security/nss/lib/util/ret_cr16.s b/security/nss/lib/freebl/ret_cr16.s
index d1fffc577..d1fffc577 100644
--- a/security/nss/lib/util/ret_cr16.s
+++ b/security/nss/lib/freebl/ret_cr16.s
diff --git a/security/nss/lib/freebl/rijndael.c b/security/nss/lib/freebl/rijndael.c
index 569500408..58f5e5cdf 100644
--- a/security/nss/lib/freebl/rijndael.c
+++ b/security/nss/lib/freebl/rijndael.c
@@ -969,16 +969,16 @@ rijndael_decryptCBC(AESContext *cx, unsigned char *output,
*
***********************************************************************/
-/* AES_CreateContext
- *
- * create a new context for Rijndael operations
- */
-AESContext *
-AES_CreateContext(const unsigned char *key, const unsigned char *iv,
- int mode, int encrypt,
- unsigned int keysize, unsigned int blocksize)
+AESContext * AES_AllocateContext(void)
+{
+ return PORT_ZNew(AESContext);
+}
+
+SECStatus
+AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
+ const unsigned char *iv, int mode, unsigned int encrypt,
+ unsigned int blocksize)
{
- AESContext *cx;
unsigned int Nk;
/* According to Rijndael AES Proposal, section 12.1, block and key
* lengths between 128 and 256 bits are supported, as long as the
@@ -992,20 +992,19 @@ AES_CreateContext(const unsigned char *key, const unsigned char *iv,
blocksize > RIJNDAEL_MAX_BLOCKSIZE ||
blocksize % 4 != 0) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ return SECFailure;
}
if (mode != NSS_AES && mode != NSS_AES_CBC) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ return SECFailure;
}
if (mode == NSS_AES_CBC && iv == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
+ return SECFailure;
}
- cx = PORT_ZNew(AESContext);
if (!cx) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
/* Nb = (block size in bits) / 32 */
cx->Nb = blocksize / 4;
@@ -1020,10 +1019,9 @@ AES_CreateContext(const unsigned char *key, const unsigned char *iv,
} else {
cx->worker = (encrypt) ? &rijndael_encryptECB : &rijndael_decryptECB;
}
- /* Allocate memory for the expanded key */
- cx->expandedKey = PORT_ZNewArray(PRUint32, cx->Nb * (cx->Nr + 1));
- if (!cx->expandedKey) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
+ PORT_Assert((cx->Nb * (cx->Nr + 1)) <= RIJNDAEL_MAX_EXP_KEY_SIZE);
+ if ((cx->Nb * (cx->Nr + 1)) > RIJNDAEL_MAX_EXP_KEY_SIZE) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
goto cleanup;
}
/* Generate expanded key */
@@ -1034,12 +1032,31 @@ AES_CreateContext(const unsigned char *key, const unsigned char *iv,
if (rijndael_invkey_expansion(cx, key, Nk) != SECSuccess)
goto cleanup;
}
- return cx;
+ return SECSuccess;
cleanup:
- if (cx->expandedKey)
- PORT_ZFree(cx->expandedKey, cx->Nb * (cx->Nr + 1));
- PORT_ZFree(cx, sizeof *cx);
- return NULL;
+ return SECFailure;
+}
+
+
+/* AES_CreateContext
+ *
+ * create a new context for Rijndael operations
+ */
+AESContext *
+AES_CreateContext(const unsigned char *key, const unsigned char *iv,
+ int mode, int encrypt,
+ unsigned int keysize, unsigned int blocksize)
+{
+ AESContext *cx = AES_AllocateContext();
+ if (cx) {
+ SECStatus rv = AES_InitContext(cx, key, keysize, iv, mode, encrypt,
+ blocksize);
+ if (rv != SECSuccess) {
+ AES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ }
+ }
+ return cx;
}
/*
@@ -1051,8 +1068,7 @@ cleanup:
void
AES_DestroyContext(AESContext *cx, PRBool freeit)
{
- PORT_ZFree(cx->expandedKey, cx->Nb * (cx->Nr + 1));
- memset(cx, 0, sizeof *cx);
+/* memset(cx, 0, sizeof *cx); */
if (freeit)
PORT_Free(cx);
}
diff --git a/security/nss/lib/freebl/rijndael.h b/security/nss/lib/freebl/rijndael.h
index 71a3a7768..4ace67528 100644
--- a/security/nss/lib/freebl/rijndael.h
+++ b/security/nss/lib/freebl/rijndael.h
@@ -50,6 +50,29 @@ typedef SECStatus AESBlockFunc(AESContext *cx,
unsigned char *output,
const unsigned char *input);
+/* RIJNDAEL_NUM_ROUNDS
+ *
+ * Number of rounds per execution
+ * Nk - number of key bytes
+ * Nb - blocksize (in bytes)
+ */
+#define RIJNDAEL_NUM_ROUNDS(Nk, Nb) \
+ (PR_MAX(Nk, Nb) + 6)
+
+/* RIJNDAEL_MAX_STATE_SIZE
+ *
+ * Maximum number of bytes in the state (spec includes up to 256-bit block
+ * size)
+ */
+#define RIJNDAEL_MAX_STATE_SIZE 32
+
+/*
+ * This magic number is (Nb_max * (Nr_max + 1))
+ * where Nb_max is the maximum block size in 32-bit words,
+ * Nr_max is the maximum number of rounds, which is Nb_max + 6
+ */
+#define RIJNDAEL_MAX_EXP_KEY_SIZE (8 * 15)
+
/* AESContextStr
*
* Values which maintain the state for Rijndael encryption/decryption.
@@ -64,25 +87,9 @@ struct AESContextStr
{
unsigned int Nb;
unsigned int Nr;
- PRUint32 *expandedKey;
AESFunc *worker;
unsigned char iv[RIJNDAEL_MAX_BLOCKSIZE];
+ PRUint32 expandedKey[RIJNDAEL_MAX_EXP_KEY_SIZE];
};
-/* RIJNDAEL_NUM_ROUNDS
- *
- * Number of rounds per execution
- * Nk - number of key bytes
- * Nb - blocksize (in bytes)
- */
-#define RIJNDAEL_NUM_ROUNDS(Nk, Nb) \
- (PR_MAX(Nk, Nb) + 6)
-
-/* RIJNDAEL_NUM_ROUNDS
- *
- * Maximum number of bytes in the state (spec includes up to 256-bit block
- * size)
- */
-#define RIJNDAEL_MAX_STATE_SIZE 32
-
#endif /* _RIJNDAEL_H_ */
diff --git a/security/nss/lib/freebl/secmpi.h b/security/nss/lib/freebl/secmpi.h
index 6b7a926b7..e343fb894 100644
--- a/security/nss/lib/freebl/secmpi.h
+++ b/security/nss/lib/freebl/secmpi.h
@@ -48,6 +48,7 @@
#define MPINT_TO_SECITEM(mp, it, arena) \
SECITEM_AllocItem(arena, (it), mp_unsigned_octet_size(mp)); \
+ if ((it)->data == NULL) {err = MP_MEM; goto cleanup;} \
err = mp_to_unsigned_octets(mp, (it)->data, (it)->len); \
if (err < 0) goto cleanup; else err = MP_OKAY;
diff --git a/security/nss/lib/freebl/sha-fast-amd64-sun.s b/security/nss/lib/freebl/sha-fast-amd64-sun.s
new file mode 100644
index 000000000..7c43f554b
--- /dev/null
+++ b/security/nss/lib/freebl/sha-fast-amd64-sun.s
@@ -0,0 +1,2142 @@
+//* ***** BEGIN LICENSE BLOCK *****
+/ * 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 SHA 180-1 Reference Implementation (Optimized).
+/ *
+/ * The Initial Developer of the Original Code is
+/ * Paul Kocher of Cryptography Research.
+/ * Portions created by the Initial Developer are Copyright (C) 1995-9
+/ * the Initial Developer. All Rights Reserved.
+/ *
+/ * Contributor(s):
+/ *
+/ * 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.
+/ *
+/ * ***** END LICENSE BLOCK ***** */
+
+ .file "sha_fast.c"
+ .text
+ .align 16
+.globl SHA1_Begin
+ .type SHA1_Begin, @function
+SHA1_Begin:
+.LFB4:
+ movl $4023233417, %ecx
+ movl $2562383102, %edx
+ movl $3285377520, %eax
+ movq $0, 64(%rdi)
+ movq $1732584193, 72(%rdi)
+ movq %rcx, 80(%rdi)
+ movq %rdx, 88(%rdi)
+ movq $271733878, 96(%rdi)
+ movq %rax, 104(%rdi)
+ ret
+.LFE4:
+ .size SHA1_Begin, .-SHA1_Begin
+ .align 16
+ .type shaCompress, @function
+shaCompress:
+.LFB7:
+ pushq %r15
+.LCFI0:
+ pushq %r14
+.LCFI1:
+ pushq %r13
+.LCFI2:
+ pushq %r12
+.LCFI3:
+ movq -88(%rdi), %r12
+ movq -80(%rdi), %r10
+ movq -72(%rdi), %r13
+ movq -64(%rdi), %r8
+ pushq %rbx
+.LCFI4:
+ movq -56(%rdi), %rcx
+ movl (%rsi), %eax
+ movl %r12d, %edx
+ movq %r13, %r9
+ roll $5, %edx
+ movl 4(%rsi), %ebx
+ xorq %r8, %r9
+/APP
+ bswap %eax
+/NO_APP
+ andq %r10, %r9
+ mov %eax, %r15d
+ roll $30, %r10d
+ movq %r15, -48(%rdi)
+ xorq %r8, %r9
+ movq -48(%rdi), %r14
+ addq %r9, %rdx
+ movq %r10, %rax
+ movl %r12d, %r15d
+ addq %rcx, %rdx
+ xorq %r13, %rax
+ roll $30, %r15d
+ leaq 1518500249(%rdx,%r14), %rdx
+ andq %r12, %rax
+ movq %r15, %r12
+/APP
+ bswap %ebx
+/NO_APP
+ movl %edx, %ecx
+ mov %ebx, %r11d
+ xorq %r13, %rax
+ movq %r11, -40(%rdi)
+ roll $5, %ecx
+ movq -40(%rdi), %r9
+ addq %rax, %rcx
+ xorq %r10, %r12
+ movl 8(%rsi), %r14d
+ addq %r8, %rcx
+ andq %rdx, %r12
+ movl %edx, %r11d
+ leaq 1518500249(%rcx,%r9), %rcx
+ xorq %r10, %r12
+ roll $30, %r11d
+/APP
+ bswap %r14d
+/NO_APP
+ movl %ecx, %r8d
+ mov %r14d, %ebx
+ movl 12(%rsi), %r9d
+ movq %rbx, -32(%rdi)
+ roll $5, %r8d
+ movq -32(%rdi), %rax
+ addq %r12, %r8
+ movq %r11, %r12
+ movl %ecx, %ebx
+ addq %r13, %r8
+ xorq %r15, %r12
+ roll $30, %ebx
+ leaq 1518500249(%r8,%rax), %r8
+ andq %rcx, %r12
+ movl 16(%rsi), %eax
+/APP
+ bswap %r9d
+/NO_APP
+ movl %r8d, %edx
+ mov %r9d, %r14d
+ xorq %r15, %r12
+ movq %r14, -24(%rdi)
+ roll $5, %edx
+ movq -24(%rdi), %r13
+ addq %r12, %rdx
+ movq %rbx, %r12
+ movl %r8d, %r14d
+ addq %r10, %rdx
+ leaq 1518500249(%rdx,%r13), %rdx
+ movl 20(%rsi), %r13d
+/APP
+ bswap %eax
+/NO_APP
+ movl %edx, %ecx
+ mov %eax, %r9d
+ roll $5, %ecx
+ xorq %r11, %r12
+ movq %r9, -16(%rdi)
+ andq %r8, %r12
+ movq -16(%rdi), %r10
+ roll $30, %r14d
+ xorq %r11, %r12
+ movq %r14, %rax
+ movl %edx, %r9d
+ addq %r12, %rcx
+ xorq %rbx, %rax
+ roll $30, %r9d
+ addq %r15, %rcx
+ andq %rdx, %rax
+ leaq 1518500249(%rcx,%r10), %rcx
+ xorq %rbx, %rax
+ movl 24(%rsi), %r10d
+/APP
+ bswap %r13d
+/NO_APP
+ movl %ecx, %r8d
+ mov %r13d, %r15d
+ movq %r15, -8(%rdi)
+ roll $5, %r8d
+ movq -8(%rdi), %r12
+ addq %rax, %r8
+ movl %ecx, %r15d
+ addq %r11, %r8
+ movq %r9, %r11
+ roll $30, %r15d
+ leaq 1518500249(%r8,%r12), %r8
+ xorq %r14, %r11
+ movl 28(%rsi), %r12d
+/APP
+ bswap %r10d
+/NO_APP
+ andq %rcx, %r11
+ mov %r10d, %r13d
+ movl %r8d, %edx
+ movq %r13, (%rdi)
+ xorq %r14, %r11
+ movq (%rdi), %rax
+ roll $5, %edx
+ movq %r15, %r10
+ movl %r8d, %r13d
+ addq %r11, %rdx
+ xorq %r9, %r10
+ roll $30, %r13d
+ addq %rbx, %rdx
+ andq %r8, %r10
+ leaq 1518500249(%rdx,%rax), %rdx
+ xorq %r9, %r10
+ movl 32(%rsi), %eax
+/APP
+ bswap %r12d
+/NO_APP
+ movl %edx, %ecx
+ mov %r12d, %ebx
+ movq %rbx, 8(%rdi)
+ roll $5, %ecx
+ movq 8(%rdi), %r11
+ addq %r10, %rcx
+ movq %r13, %r10
+ movl %edx, %ebx
+ addq %r14, %rcx
+ leaq 1518500249(%rcx,%r11), %rcx
+/APP
+ bswap %eax
+/NO_APP
+ movl %ecx, %r8d
+ mov %eax, %r12d
+ roll $5, %r8d
+ xorq %r15, %r10
+ movq %r12, 16(%rdi)
+ andq %rdx, %r10
+ movq 16(%rdi), %r14
+ roll $30, %ebx
+ xorq %r15, %r10
+ movq %rbx, %rax
+ movl 36(%rsi), %r11d
+ addq %r10, %r8
+ xorq %r13, %rax
+ movl %ecx, %r12d
+ addq %r9, %r8
+ andq %rcx, %rax
+ roll $30, %r12d
+ leaq 1518500249(%r8,%r14), %r8
+ xorq %r13, %rax
+ movl 40(%rsi), %r14d
+/APP
+ bswap %r11d
+/NO_APP
+ movl %r8d, %edx
+ mov %r11d, %r9d
+ movq %r12, %r11
+ movq %r9, 24(%rdi)
+ roll $5, %edx
+ movq 24(%rdi), %r10
+ addq %rax, %rdx
+ xorq %rbx, %r11
+ movl %r8d, %r9d
+ addq %r15, %rdx
+ andq %r8, %r11
+ roll $30, %r9d
+ leaq 1518500249(%rdx,%r10), %rdx
+ xorq %rbx, %r11
+ movl 44(%rsi), %r10d
+/APP
+ bswap %r14d
+/NO_APP
+ movl %edx, %ecx
+ mov %r14d, %r15d
+ movq %r15, 32(%rdi)
+ roll $5, %ecx
+ movq 32(%rdi), %rax
+ addq %r11, %rcx
+ movq %r9, %r11
+ movl %edx, %r15d
+ addq %r13, %rcx
+ xorq %r12, %r11
+ roll $30, %r15d
+ leaq 1518500249(%rcx,%rax), %rcx
+ andq %rdx, %r11
+ movl 48(%rsi), %eax
+/APP
+ bswap %r10d
+/NO_APP
+ movl %ecx, %r8d
+ mov %r10d, %r14d
+ xorq %r12, %r11
+ movq %r14, 40(%rdi)
+ roll $5, %r8d
+ movq 40(%rdi), %r13
+ addq %r11, %r8
+ movq %r15, %r10
+ movl %ecx, %r14d
+ addq %rbx, %r8
+ xorq %r9, %r10
+ leaq 1518500249(%r8,%r13), %r8
+ movl 52(%rsi), %r13d
+/APP
+ bswap %eax
+/NO_APP
+ movl %r8d, %edx
+ mov %eax, %ebx
+ roll $5, %edx
+ andq %rcx, %r10
+ movq %rbx, 48(%rdi)
+ xorq %r9, %r10
+ movq 48(%rdi), %r11
+ roll $30, %r14d
+ addq %r10, %rdx
+ movq %r14, %rax
+ movl %r8d, %ebx
+ addq %r12, %rdx
+ xorq %r15, %rax
+ roll $30, %ebx
+ leaq 1518500249(%rdx,%r11), %rdx
+ andq %r8, %rax
+ movl 56(%rsi), %r11d
+/APP
+ bswap %r13d
+/NO_APP
+ movl %edx, %ecx
+ mov %r13d, %r12d
+ xorq %r15, %rax
+ movq %r12, 56(%rdi)
+ roll $5, %ecx
+ movq 56(%rdi), %r10
+ addq %rax, %rcx
+ movl %edx, %r12d
+ addq %r9, %rcx
+ movq %rbx, %r9
+ roll $30, %r12d
+ leaq 1518500249(%rcx,%r10), %rcx
+ xorq %r14, %r9
+ movl 60(%rsi), %r10d
+/APP
+ bswap %r11d
+/NO_APP
+ andq %rdx, %r9
+ mov %r11d, %r13d
+ movl %ecx, %r8d
+ movq %r13, 64(%rdi)
+ xorq %r14, %r9
+ movq 64(%rdi), %rax
+ roll $5, %r8d
+ movq %r12, %r11
+ movl %ecx, %r13d
+ addq %r9, %r8
+ xorq %rbx, %r11
+ roll $30, %r13d
+ addq %r15, %r8
+ andq %rcx, %r11
+ leaq 1518500249(%r8,%rax), %r8
+ xorq %rbx, %r11
+/APP
+ bswap %r10d
+/NO_APP
+ movl %r8d, %esi
+ mov %r10d, %r15d
+ movq %r15, 72(%rdi)
+ roll $5, %esi
+ movq 72(%rdi), %r9
+ movq 56(%rdi), %r10
+ movq 16(%rdi), %rcx
+ addq %r11, %rsi
+ movq -32(%rdi), %rdx
+ addq %r14, %rsi
+ movq -48(%rdi), %rax
+ leaq 1518500249(%rsi,%r9), %r14
+ movq %r13, %r11
+ movl %r8d, %r15d
+ xorq %rcx, %r10
+ xorq %rdx, %r10
+ movl %r14d, %ecx
+ xorl %eax, %r10d
+ roll %r10d
+ roll $5, %ecx
+ xorq %r12, %r11
+ andq %r8, %r11
+ movq %r10, -48(%rdi)
+ movq -48(%rdi), %r9
+ xorq %r12, %r11
+ roll $30, %r15d
+ movl %r14d, %r10d
+ addq %r11, %rcx
+ movq 64(%rdi), %r11
+ movq 24(%rdi), %rdx
+ addq %rbx, %rcx
+ movq -24(%rdi), %rbx
+ movq -40(%rdi), %rax
+ leaq 1518500249(%rcx,%r9), %rcx
+ movq %r15, %r8
+ roll $30, %r10d
+ xorq %rdx, %r11
+ xorq %r13, %r8
+ xorq %rbx, %r11
+ andq %r14, %r8
+ movl %ecx, %r9d
+ xorl %eax, %r11d
+ xorq %r13, %r8
+ roll $5, %r9d
+ roll %r11d
+ addq %r8, %r9
+ movq %r10, %rax
+ movq %r11, -40(%rdi)
+ movq -40(%rdi), %rsi
+ addq %r12, %r9
+ movq 72(%rdi), %rbx
+ movq 32(%rdi), %rdx
+ xorq %r15, %rax
+ movq -16(%rdi), %r14
+ movq -32(%rdi), %r12
+ andq %rcx, %rax
+ leaq 1518500249(%r9,%rsi), %r9
+ xorq %r15, %rax
+ movl %ecx, %r11d
+ xorq %rdx, %rbx
+ roll $30, %r11d
+ xorq %r14, %rbx
+ movl %r9d, %esi
+ xorl %r12d, %ebx
+ roll $5, %esi
+ roll %ebx
+ addq %rax, %rsi
+ movq %rbx, -32(%rdi)
+ movq -32(%rdi), %r8
+ addq %r13, %rsi
+ movq -48(%rdi), %r12
+ movq 40(%rdi), %rdx
+ movq %r11, %r13
+ movq -8(%rdi), %r14
+ movq -24(%rdi), %rcx
+ movl %r9d, %ebx
+ leaq 1518500249(%rsi,%r8), %rsi
+ xorq %rdx, %r12
+ xorq %r14, %r12
+ movl %esi, %r8d
+ xorl %ecx, %r12d
+ roll %r12d
+ roll $5, %r8d
+ xorq %r10, %r13
+ andq %r9, %r13
+ movq %r12, -24(%rdi)
+ movq -24(%rdi), %rax
+ xorq %r10, %r13
+ roll $30, %ebx
+ movl %esi, %r12d
+ addq %r13, %r8
+ xorq %rbx, %rsi
+ roll $30, %r12d
+ addq %r15, %r8
+ movq -40(%rdi), %r15
+ movq 48(%rdi), %rdx
+ movq (%rdi), %r14
+ movq -16(%rdi), %r9
+ leaq 1518500249(%r8,%rax), %r13
+ xorq %r11, %rsi
+ xorq %rdx, %r15
+ movl %r13d, %ecx
+ xorq %r14, %r15
+ roll $5, %ecx
+ xorl %r9d, %r15d
+ addq %rsi, %rcx
+ roll %r15d
+ addq %r10, %rcx
+ movq %r15, -16(%rdi)
+ movq -16(%rdi), %rsi
+ movl %r13d, %r15d
+ movq -32(%rdi), %r14
+ movq 56(%rdi), %rax
+ xorq %r12, %r13
+ movq 8(%rdi), %rdx
+ movq -8(%rdi), %r10
+ xorq %rbx, %r13
+ leaq 1859775393(%rcx,%rsi), %r9
+ roll $30, %r15d
+ xorq %rax, %r14
+ xorq %rdx, %r14
+ movl %r9d, %esi
+ xorl %r10d, %r14d
+ roll $5, %esi
+ roll %r14d
+ addq %r13, %rsi
+ movq %r14, -8(%rdi)
+ movq -8(%rdi), %r8
+ addq %r11, %rsi
+ movq -24(%rdi), %r13
+ movq 64(%rdi), %rax
+ movl %r9d, %r14d
+ movq 16(%rdi), %rdx
+ movq (%rdi), %r11
+ xorq %r15, %r9
+ leaq 1859775393(%rsi,%r8), %r10
+ xorq %rax, %r13
+ xorq %rdx, %r13
+ movl %r10d, %r8d
+ xorl %r11d, %r13d
+ roll $5, %r8d
+ roll %r13d
+ xorq %r12, %r9
+ roll $30, %r14d
+ addq %r9, %r8
+ movq %r13, (%rdi)
+ movq (%rdi), %rcx
+ addq %rbx, %r8
+ movq -16(%rdi), %rbx
+ movq 72(%rdi), %rax
+ movq 24(%rdi), %rdx
+ movq 8(%rdi), %r9
+ movl %r10d, %r13d
+ leaq 1859775393(%r8,%rcx), %r11
+ xorq %r14, %r10
+ roll $30, %r13d
+ xorq %rax, %rbx
+ xorq %r15, %r10
+ xorq %rdx, %rbx
+ movl %r11d, %ecx
+ xorl %r9d, %ebx
+ roll $5, %ecx
+ roll %ebx
+ addq %r10, %rcx
+ movq %rbx, 8(%rdi)
+ movq 8(%rdi), %rsi
+ addq %r12, %rcx
+ movq -8(%rdi), %r12
+ movq -48(%rdi), %rax
+ movl %r11d, %ebx
+ movq 32(%rdi), %rdx
+ movq 16(%rdi), %r9
+ xorq %r13, %r11
+ leaq 1859775393(%rcx,%rsi), %r10
+ xorq %r14, %r11
+ roll $30, %ebx
+ xorq %rax, %r12
+ xorq %rdx, %r12
+ movl %r10d, %esi
+ xorl %r9d, %r12d
+ roll $5, %esi
+ roll %r12d
+ addq %r11, %rsi
+ movq %r12, 16(%rdi)
+ addq %r15, %rsi
+ movq 16(%rdi), %r8
+ movq (%rdi), %r15
+ movq -40(%rdi), %rax
+ movl %r10d, %r12d
+ movq 40(%rdi), %rdx
+ movq 24(%rdi), %r9
+ xorq %rbx, %r10
+ leaq 1859775393(%rsi,%r8), %r11
+ xorq %r13, %r10
+ xorq %rax, %r15
+ xorq %rdx, %r15
+ movl %r11d, %r8d
+ xorl %r9d, %r15d
+ roll $5, %r8d
+ roll %r15d
+ addq %r10, %r8
+ movq %r15, 24(%rdi)
+ movq 24(%rdi), %rcx
+ addq %r14, %r8
+ movq 8(%rdi), %r14
+ movq -32(%rdi), %rax
+ roll $30, %r12d
+ movq 48(%rdi), %rdx
+ movq 32(%rdi), %r10
+ movl %r11d, %r15d
+ leaq 1859775393(%r8,%rcx), %r9
+ xorq %r12, %r11
+ roll $30, %r15d
+ xorq %rax, %r14
+ xorq %rbx, %r11
+ xorq %rdx, %r14
+ movl %r9d, %ecx
+ xorl %r10d, %r14d
+ roll $5, %ecx
+ roll %r14d
+ addq %r11, %rcx
+ movq %r14, 32(%rdi)
+ addq %r13, %rcx
+ movq 32(%rdi), %rsi
+ movq 16(%rdi), %r13
+ movq -24(%rdi), %rax
+ movl %r9d, %r14d
+ movq 56(%rdi), %rdx
+ movq 40(%rdi), %r11
+ xorq %r15, %r9
+ leaq 1859775393(%rcx,%rsi), %r10
+ xorq %r12, %r9
+ roll $30, %r14d
+ xorq %rax, %r13
+ xorq %rdx, %r13
+ movl %r10d, %esi
+ xorl %r11d, %r13d
+ roll $5, %esi
+ roll %r13d
+ addq %r9, %rsi
+ movq %r13, 40(%rdi)
+ movq 40(%rdi), %r8
+ addq %rbx, %rsi
+ movq 24(%rdi), %rbx
+ movq -16(%rdi), %rax
+ movl %r10d, %r13d
+ movq 64(%rdi), %rdx
+ movq 48(%rdi), %r9
+ xorq %r14, %r10
+ leaq 1859775393(%rsi,%r8), %r11
+ xorq %r15, %r10
+ roll $30, %r13d
+ xorq %rax, %rbx
+ xorq %rdx, %rbx
+ movl %r11d, %r8d
+ xorl %r9d, %ebx
+ roll $5, %r8d
+ roll %ebx
+ addq %r10, %r8
+ movq %rbx, 48(%rdi)
+ addq %r12, %r8
+ movq 48(%rdi), %rcx
+ movq 32(%rdi), %r12
+ movq -8(%rdi), %rax
+ movl %r11d, %ebx
+ movq 72(%rdi), %rdx
+ movq 56(%rdi), %r9
+ leaq 1859775393(%r8,%rcx), %r10
+ xorq %rax, %r12
+ xorq %rdx, %r12
+ movl %r10d, %ecx
+ xorl %r9d, %r12d
+ xorq %r13, %r11
+ roll $5, %ecx
+ xorq %r14, %r11
+ roll %r12d
+ roll $30, %ebx
+ addq %r11, %rcx
+ movq %r12, 56(%rdi)
+ movq 56(%rdi), %rsi
+ addq %r15, %rcx
+ movq 40(%rdi), %r15
+ movq (%rdi), %rax
+ movq -48(%rdi), %rdx
+ movq 64(%rdi), %r9
+ movl %r10d, %r12d
+ leaq 1859775393(%rcx,%rsi), %r11
+ xorq %rbx, %r10
+ roll $30, %r12d
+ xorq %rax, %r15
+ xorq %r13, %r10
+ xorq %rdx, %r15
+ movl %r11d, %esi
+ xorl %r9d, %r15d
+ roll $5, %esi
+ roll %r15d
+ addq %r10, %rsi
+ movq %r15, 64(%rdi)
+ movq 64(%rdi), %r8
+ addq %r14, %rsi
+ movq 48(%rdi), %r14
+ movq 8(%rdi), %rax
+ movl %r11d, %r15d
+ movq -40(%rdi), %rdx
+ movq 72(%rdi), %r10
+ xorq %r12, %r11
+ leaq 1859775393(%rsi,%r8), %r9
+ xorq %rbx, %r11
+ roll $30, %r15d
+ xorq %rax, %r14
+ xorq %rdx, %r14
+ movl %r9d, %r8d
+ xorl %r10d, %r14d
+ roll $5, %r8d
+ roll %r14d
+ addq %r11, %r8
+ movq %r14, 72(%rdi)
+ addq %r13, %r8
+ movq 72(%rdi), %rcx
+ movq 56(%rdi), %r13
+ movq 16(%rdi), %rax
+ movl %r9d, %r14d
+ movq -32(%rdi), %rdx
+ movq -48(%rdi), %r11
+ leaq 1859775393(%r8,%rcx), %r10
+ xorq %rax, %r13
+ xorq %rdx, %r13
+ movl %r10d, %ecx
+ xorl %r11d, %r13d
+ roll $5, %ecx
+ roll %r13d
+ xorq %r15, %r9
+ roll $30, %r14d
+ xorq %r12, %r9
+ movq %r13, -48(%rdi)
+ movq -48(%rdi), %rsi
+ addq %r9, %rcx
+ movl %r10d, %r13d
+ xorq %r14, %r10
+ addq %rbx, %rcx
+ movq 64(%rdi), %rbx
+ movq 24(%rdi), %rax
+ movq -24(%rdi), %rdx
+ leaq 1859775393(%rcx,%rsi), %r11
+ movq -40(%rdi), %r9
+ xorq %r15, %r10
+ roll $30, %r13d
+ xorq %rax, %rbx
+ movl %r11d, %esi
+ xorq %rdx, %rbx
+ roll $5, %esi
+ xorl %r9d, %ebx
+ addq %r10, %rsi
+ roll %ebx
+ addq %r12, %rsi
+ movq %rbx, -40(%rdi)
+ movq -40(%rdi), %r8
+ movl %r11d, %ebx
+ movq 72(%rdi), %r12
+ movq 32(%rdi), %rax
+ xorq %r13, %r11
+ movq -16(%rdi), %rdx
+ movq -32(%rdi), %r9
+ xorq %r14, %r11
+ leaq 1859775393(%rsi,%r8), %r10
+ roll $30, %ebx
+ xorq %rax, %r12
+ xorq %rdx, %r12
+ movl %r10d, %r8d
+ xorl %r9d, %r12d
+ roll $5, %r8d
+ roll %r12d
+ addq %r11, %r8
+ movq %r12, -32(%rdi)
+ movq -32(%rdi), %rcx
+ addq %r15, %r8
+ movq -48(%rdi), %r15
+ movq 40(%rdi), %rax
+ movl %r10d, %r12d
+ movq -8(%rdi), %rdx
+ movq -24(%rdi), %r9
+ xorq %rbx, %r10
+ leaq 1859775393(%r8,%rcx), %r11
+ xorq %r13, %r10
+ xorq %rax, %r15
+ xorq %rdx, %r15
+ movl %r11d, %ecx
+ xorl %r9d, %r15d
+ roll $5, %ecx
+ roll %r15d
+ addq %r10, %rcx
+ addq %r14, %rcx
+ movq %r15, -24(%rdi)
+ movq -24(%rdi), %rsi
+ movq -40(%rdi), %r14
+ movq 48(%rdi), %rax
+ roll $30, %r12d
+ movq (%rdi), %rdx
+ movq -16(%rdi), %r10
+ movl %r11d, %r15d
+ leaq 1859775393(%rcx,%rsi), %r9
+ xorq %r12, %r11
+ roll $30, %r15d
+ xorq %rax, %r14
+ xorq %rbx, %r11
+ xorq %rdx, %r14
+ movl %r9d, %esi
+ xorl %r10d, %r14d
+ roll $5, %esi
+ roll %r14d
+ addq %r11, %rsi
+ movq %r14, -16(%rdi)
+ movq -16(%rdi), %r8
+ addq %r13, %rsi
+ movq -32(%rdi), %r11
+ movq 56(%rdi), %rax
+ movl %r9d, %r14d
+ movq 8(%rdi), %rdx
+ movq -8(%rdi), %r10
+ xorq %r15, %r9
+ leaq 1859775393(%rsi,%r8), %r13
+ xorq %r12, %r9
+ roll $30, %r14d
+ xorq %rax, %r11
+ xorq %rdx, %r11
+ movl %r13d, %r8d
+ xorl %r10d, %r11d
+ roll $5, %r8d
+ movl %r13d, %r10d
+ roll %r11d
+ addq %r9, %r8
+ xorq %r14, %r13
+ movq %r11, -8(%rdi)
+ addq %rbx, %r8
+ movq -8(%rdi), %rbx
+ movq -24(%rdi), %r9
+ movq 64(%rdi), %rax
+ xorq %r15, %r13
+ movq 16(%rdi), %rdx
+ movq (%rdi), %rcx
+ leaq 1859775393(%r8,%rbx), %r11
+ xorq %rax, %r9
+ xorq %rdx, %r9
+ movl %r11d, %ebx
+ xorl %ecx, %r9d
+ roll $5, %ebx
+ roll %r9d
+ addq %r13, %rbx
+ movq %r9, (%rdi)
+ movq (%rdi), %rsi
+ addq %r12, %rbx
+ movq -16(%rdi), %r12
+ movq 72(%rdi), %r13
+ movl %r11d, %r9d
+ leaq 1859775393(%rbx,%rsi), %rcx
+ movl %r10d, %ebx
+ movq 24(%rdi), %r10
+ movq 8(%rdi), %rax
+ xorq %r13, %r12
+ roll $30, %ebx
+ movl %ecx, %esi
+ xorq %r10, %r12
+ xorq %rbx, %r11
+ roll $5, %esi
+ xorl %eax, %r12d
+ xorq %r14, %r11
+ roll $30, %r9d
+ roll %r12d
+ addq %r11, %rsi
+ movq %rcx, %rax
+ movq %r12, 8(%rdi)
+ movq 8(%rdi), %rdx
+ addq %r15, %rsi
+ movq -8(%rdi), %r11
+ movq -48(%rdi), %r13
+ movl %ecx, %r12d
+ movq 32(%rdi), %r10
+ movq 16(%rdi), %r8
+ orq %r9, %rcx
+ leaq 1859775393(%rsi,%rdx), %rsi
+ andq %rbx, %rcx
+ andq %r9, %rax
+ xorq %r13, %r11
+ orq %rcx, %rax
+ roll $30, %r12d
+ xorq %r10, %r11
+ movq %rsi, %r10
+ xorl %r8d, %r11d
+ movl %esi, %r8d
+ andq %r12, %r10
+ roll %r11d
+ roll $5, %r8d
+ movq %r11, 16(%rdi)
+ addq %rax, %r8
+ movq 16(%rdi), %r15
+ movq (%rdi), %r13
+ movq -40(%rdi), %rdx
+ addq %r14, %r8
+ movq 40(%rdi), %r14
+ movq 24(%rdi), %rcx
+ movl %esi, %r11d
+ addq %r15, %r8
+ movl $2400959708, %r15d
+ orq %r12, %rsi
+ xorq %rdx, %r13
+ addq %r15, %r8
+ andq %r9, %rsi
+ xorq %r14, %r13
+ orq %rsi, %r10
+ xorl %ecx, %r13d
+ movl %r8d, %ecx
+ roll %r13d
+ roll $5, %ecx
+ movq %r13, 24(%rdi)
+ addq %r10, %rcx
+ movq 24(%rdi), %rax
+ movq 8(%rdi), %r14
+ movq -32(%rdi), %rdx
+ addq %rbx, %rcx
+ movq 48(%rdi), %rbx
+ movq 32(%rdi), %rsi
+ roll $30, %r11d
+ addq %rax, %rcx
+ movl %r8d, %r13d
+ movq %r8, %r10
+ xorq %rdx, %r14
+ addq %r15, %rcx
+ orq %r11, %r8
+ xorq %rbx, %r14
+ andq %r12, %r8
+ andq %r11, %r10
+ xorl %esi, %r14d
+ movl %ecx, %esi
+ orq %r8, %r10
+ roll $5, %esi
+ roll %r14d
+ roll $30, %r13d
+ addq %r10, %rsi
+ movq %r14, 32(%rdi)
+ movq 32(%rdi), %rax
+ addq %r9, %rsi
+ movq 16(%rdi), %r9
+ movq -24(%rdi), %rdx
+ movq 56(%rdi), %rbx
+ movq 40(%rdi), %r8
+ movl %ecx, %r14d
+ addq %rax, %rsi
+ movq %rcx, %r10
+ orq %r13, %rcx
+ xorq %rdx, %r9
+ addq %r15, %rsi
+ andq %r11, %rcx
+ xorq %rbx, %r9
+ andq %r13, %r10
+ roll $30, %r14d
+ xorl %r8d, %r9d
+ movl %esi, %r8d
+ orq %rcx, %r10
+ roll %r9d
+ roll $5, %r8d
+ movq %r9, 40(%rdi)
+ addq %r10, %r8
+ movq 40(%rdi), %rax
+ movq 24(%rdi), %r10
+ movq -16(%rdi), %rdx
+ addq %r12, %r8
+ movq 64(%rdi), %rbx
+ movq 48(%rdi), %rcx
+ movl %esi, %r9d
+ addq %rax, %r8
+ movq %rsi, %r12
+ xorq %rdx, %r10
+ addq %r15, %r8
+ xorq %rbx, %r10
+ orq %r14, %rsi
+ andq %r14, %r12
+ andq %r13, %rsi
+ xorl %ecx, %r10d
+ movl %r8d, %ecx
+ orq %rsi, %r12
+ roll %r10d
+ roll $5, %ecx
+ movq %r10, 48(%rdi)
+ addq %r12, %rcx
+ movq 48(%rdi), %rax
+ movq 32(%rdi), %r12
+ movq -8(%rdi), %rdx
+ addq %r11, %rcx
+ movq 72(%rdi), %rbx
+ movq 56(%rdi), %rsi
+ roll $30, %r9d
+ addq %rax, %rcx
+ movl %r8d, %r10d
+ movq %r8, %r11
+ xorq %rdx, %r12
+ addq %r15, %rcx
+ orq %r9, %r8
+ xorq %rbx, %r12
+ andq %r14, %r8
+ andq %r9, %r11
+ xorl %esi, %r12d
+ movl %ecx, %esi
+ orq %r8, %r11
+ roll %r12d
+ roll $5, %esi
+ roll $30, %r10d
+ movq %r12, 56(%rdi)
+ addq %r11, %rsi
+ movq 56(%rdi), %rax
+ movq 40(%rdi), %r11
+ movq (%rdi), %rdx
+ addq %r13, %rsi
+ movq -48(%rdi), %rbx
+ movq 64(%rdi), %r8
+ movq %rcx, %r13
+ addq %rax, %rsi
+ andq %r10, %r13
+ movl %ecx, %r12d
+ xorq %rdx, %r11
+ addq %r15, %rsi
+ xorq %rbx, %r11
+ xorl %r8d, %r11d
+ movl %esi, %r8d
+ roll %r11d
+ roll $5, %r8d
+ orq %r10, %rcx
+ andq %r9, %rcx
+ movq %r11, 64(%rdi)
+ movq 64(%rdi), %rax
+ orq %rcx, %r13
+ roll $30, %r12d
+ movl %esi, %r11d
+ addq %r13, %r8
+ movq 48(%rdi), %r13
+ movq 8(%rdi), %rdx
+ movq -40(%rdi), %rbx
+ addq %r14, %r8
+ movq 72(%rdi), %rcx
+ addq %rax, %r8
+ movq %rsi, %r14
+ orq %r12, %rsi
+ xorq %rdx, %r13
+ addq %r15, %r8
+ andq %r10, %rsi
+ xorq %rbx, %r13
+ andq %r12, %r14
+ roll $30, %r11d
+ xorl %ecx, %r13d
+ movl %r8d, %ecx
+ orq %rsi, %r14
+ roll %r13d
+ roll $5, %ecx
+ movq %r13, 72(%rdi)
+ addq %r14, %rcx
+ movq 72(%rdi), %rax
+ movq 56(%rdi), %r14
+ movq 16(%rdi), %rdx
+ addq %r9, %rcx
+ movq -32(%rdi), %rbx
+ movq -48(%rdi), %rsi
+ movl %r8d, %r13d
+ addq %rax, %rcx
+ movq %r8, %r9
+ orq %r11, %r8
+ xorq %rdx, %r14
+ addq %r15, %rcx
+ andq %r12, %r8
+ xorq %rbx, %r14
+ andq %r11, %r9
+ xorl %esi, %r14d
+ movl %ecx, %esi
+ orq %r8, %r9
+ roll $5, %esi
+ roll %r14d
+ addq %r9, %rsi
+ movq %r14, -48(%rdi)
+ movq -48(%rdi), %rax
+ addq %r10, %rsi
+ movq 64(%rdi), %r10
+ movq 24(%rdi), %rdx
+ movq -24(%rdi), %rbx
+ movq -40(%rdi), %r8
+ movl %ecx, %r14d
+ addq %rax, %rsi
+ roll $30, %r13d
+ movq %rcx, %r9
+ xorq %rdx, %r10
+ addq %r15, %rsi
+ orq %r13, %rcx
+ xorq %rbx, %r10
+ andq %r11, %rcx
+ andq %r13, %r9
+ xorl %r8d, %r10d
+ movl %esi, %r8d
+ orq %rcx, %r9
+ roll $5, %r8d
+ roll %r10d
+ roll $30, %r14d
+ addq %r9, %r8
+ movq %r10, -40(%rdi)
+ movq -40(%rdi), %rax
+ addq %r12, %r8
+ movq 72(%rdi), %r12
+ movq 32(%rdi), %rdx
+ movq -16(%rdi), %rbx
+ movq -32(%rdi), %rcx
+ movl %esi, %r10d
+ addq %rax, %r8
+ movq %rsi, %r9
+ orq %r14, %rsi
+ xorq %rdx, %r12
+ addq %r15, %r8
+ andq %r13, %rsi
+ xorq %rbx, %r12
+ andq %r14, %r9
+ roll $30, %r10d
+ xorl %ecx, %r12d
+ movl %r8d, %ecx
+ orq %rsi, %r9
+ roll $5, %ecx
+ roll %r12d
+ addq %r9, %rcx
+ movq %r12, -32(%rdi)
+ movq -32(%rdi), %rax
+ addq %r11, %rcx
+ movq -48(%rdi), %r11
+ movq 40(%rdi), %rdx
+ movq -8(%rdi), %rbx
+ movq -24(%rdi), %rsi
+ movl %r8d, %r12d
+ addq %rax, %rcx
+ movq %r8, %r9
+ xorq %rdx, %r11
+ addq %r15, %rcx
+ xorq %rbx, %r11
+ xorl %esi, %r11d
+ orq %r10, %r8
+ andq %r10, %r9
+ andq %r14, %r8
+ movl %ecx, %esi
+ roll %r11d
+ orq %r8, %r9
+ roll $5, %esi
+ movq %r11, -24(%rdi)
+ addq %r9, %rsi
+ movq -24(%rdi), %rax
+ roll $30, %r12d
+ addq %r13, %rsi
+ movq -40(%rdi), %r13
+ movq 48(%rdi), %rdx
+ movq (%rdi), %rbx
+ movq -16(%rdi), %r8
+ movl %ecx, %r11d
+ addq %rax, %rsi
+ movq %rcx, %r9
+ orq %r12, %rcx
+ xorq %rdx, %r13
+ addq %r15, %rsi
+ andq %r10, %rcx
+ xorq %rbx, %r13
+ andq %r12, %r9
+ roll $30, %r11d
+ xorl %r8d, %r13d
+ movl %esi, %r8d
+ orq %rcx, %r9
+ roll %r13d
+ roll $5, %r8d
+ movq %r13, -16(%rdi)
+ addq %r9, %r8
+ movq -16(%rdi), %rax
+ movq -32(%rdi), %r9
+ movq 56(%rdi), %rdx
+ addq %r14, %r8
+ movq 8(%rdi), %rcx
+ movq -8(%rdi), %rbx
+ movl %esi, %r13d
+ addq %rax, %r8
+ movq %rsi, %r14
+ orq %r11, %rsi
+ xorq %rdx, %r9
+ addq %r15, %r8
+ andq %r11, %r14
+ xorq %rcx, %r9
+ xorl %ebx, %r9d
+ movl %r8d, %ebx
+ roll %r9d
+ roll $5, %ebx
+ andq %r12, %rsi
+ orq %rsi, %r14
+ movq %r9, -8(%rdi)
+ movq -8(%rdi), %rax
+ addq %r14, %rbx
+ movq -24(%rdi), %r14
+ movq 64(%rdi), %rdx
+ movq 16(%rdi), %rcx
+ addq %r10, %rbx
+ movq (%rdi), %rsi
+ roll $30, %r13d
+ addq %rax, %rbx
+ movl %r8d, %r9d
+ xorq %rdx, %r14
+ addq %r15, %rbx
+ movq %r8, %r10
+ xorq %rcx, %r14
+ orq %r13, %r8
+ andq %r13, %r10
+ andq %r11, %r8
+ xorl %esi, %r14d
+ movl %ebx, %esi
+ orq %r8, %r10
+ roll $5, %esi
+ roll %r14d
+ addq %r10, %rsi
+ movq %r14, (%rdi)
+ movq (%rdi), %rax
+ addq %r12, %rsi
+ movq -16(%rdi), %r12
+ movq 72(%rdi), %rdx
+ movq 24(%rdi), %rcx
+ movq 8(%rdi), %r8
+ roll $30, %r9d
+ addq %rax, %rsi
+ movl %ebx, %r14d
+ movq %rbx, %r10
+ xorq %rdx, %r12
+ addq %r15, %rsi
+ orq %r9, %rbx
+ xorq %rcx, %r12
+ andq %r13, %rbx
+ andq %r9, %r10
+ xorl %r8d, %r12d
+ movl %esi, %r8d
+ orq %rbx, %r10
+ roll %r12d
+ roll $5, %r8d
+ movq %r12, 8(%rdi)
+ movq 8(%rdi), %rax
+ addq %r10, %r8
+ movq -8(%rdi), %rbx
+ movq -48(%rdi), %rdx
+ addq %r11, %r8
+ movq 32(%rdi), %r11
+ movq 16(%rdi), %rcx
+ movl %esi, %r12d
+ addq %rax, %r8
+ movq %rsi, %r10
+ addq %r15, %r8
+ xorq %rdx, %rbx
+ roll $30, %r14d
+ xorq %r11, %rbx
+ orq %r14, %rsi
+ andq %r14, %r10
+ xorl %ecx, %ebx
+ andq %r9, %rsi
+ movl %r8d, %ecx
+ roll %ebx
+ orq %rsi, %r10
+ roll $5, %ecx
+ movq %rbx, 16(%rdi)
+ movq 16(%rdi), %rsi
+ addq %r10, %rcx
+ movq (%rdi), %r11
+ movq -40(%rdi), %rax
+ addq %r13, %rcx
+ movq 40(%rdi), %rdx
+ movq 24(%rdi), %r13
+ roll $30, %r12d
+ addq %rsi, %rcx
+ movl %r8d, %ebx
+ movq %r8, %r10
+ xorq %rax, %r11
+ addq %r15, %rcx
+ orq %r12, %r8
+ xorq %rdx, %r11
+ andq %r14, %r8
+ andq %r12, %r10
+ xorl %r13d, %r11d
+ movl %ecx, %r13d
+ orq %r8, %r10
+ roll %r11d
+ roll $5, %r13d
+ roll $30, %ebx
+ movq %r11, 24(%rdi)
+ addq %r10, %r13
+ movq 24(%rdi), %rsi
+ movq 8(%rdi), %r10
+ movq -32(%rdi), %rax
+ addq %r9, %r13
+ movq 48(%rdi), %rdx
+ movq 32(%rdi), %r8
+ movl %ecx, %r11d
+ addq %rsi, %r13
+ movq %rcx, %r9
+ xorq %rax, %r10
+ addq %r15, %r13
+ xorq %rdx, %r10
+ xorl %r8d, %r10d
+ movl %r13d, %r8d
+ roll %r10d
+ orq %rbx, %rcx
+ andq %rbx, %r9
+ movq %r10, 32(%rdi)
+ andq %r12, %rcx
+ movl %r13d, %r10d
+ orq %rcx, %r9
+ roll $5, %r10d
+ movq 32(%rdi), %rsi
+ addq %r9, %r10
+ roll $30, %r11d
+ movq %r13, %rcx
+ addq %r14, %r10
+ movq 16(%rdi), %r14
+ movq -24(%rdi), %rax
+ movq 56(%rdi), %rdx
+ movq 40(%rdi), %r9
+ addq %rsi, %r10
+ addq %r15, %r10
+ orq %r11, %r13
+ andq %r11, %rcx
+ xorq %rax, %r14
+ andq %rbx, %r13
+ xorq %rdx, %r14
+ orq %r13, %rcx
+ xorl %r9d, %r14d
+ movl %r10d, %r9d
+ roll %r14d
+ roll $5, %r9d
+ movq %r14, 40(%rdi)
+ movq 40(%rdi), %rsi
+ addq %rcx, %r9
+ movq 24(%rdi), %r13
+ addq %r12, %r9
+ movq -16(%rdi), %r12
+ movq 64(%rdi), %rax
+ movl %r10d, %r14d
+ addq %rsi, %r9
+ movl %r8d, %esi
+ addq %r15, %r9
+ movq 48(%rdi), %r15
+ xorq %r12, %r13
+ roll $30, %esi
+ xorq %rax, %r13
+ xorq %rsi, %r10
+ xorl %r15d, %r13d
+ movl %r9d, %r15d
+ xorq %r11, %r10
+ roll $5, %r15d
+ roll %r13d
+ addq %r10, %r15
+ movq %r13, 48(%rdi)
+ movq 48(%rdi), %r10
+ addq %rbx, %r15
+ movq 32(%rdi), %rbx
+ movq -8(%rdi), %r8
+ movq 72(%rdi), %rdx
+ movq 56(%rdi), %rcx
+ roll $30, %r14d
+ addq %r10, %r15
+ movl $3395469782, %r10d
+ movl %r9d, %r13d
+ xorq %r8, %rbx
+ addq %r10, %r15
+ xorq %r14, %r9
+ xorq %rdx, %rbx
+ xorq %rsi, %r9
+ roll $30, %r13d
+ xorl %ecx, %ebx
+ movl %r15d, %ecx
+ roll %ebx
+ roll $5, %ecx
+ movq %rbx, 56(%rdi)
+ addq %r9, %rcx
+ movq 56(%rdi), %r12
+ movq 40(%rdi), %r9
+ movq (%rdi), %rax
+ addq %r11, %rcx
+ movq -48(%rdi), %r8
+ movq 64(%rdi), %r11
+ movl %r15d, %ebx
+ addq %r12, %rcx
+ xorq %r13, %r15
+ roll $30, %ebx
+ xorq %rax, %r9
+ addq %r10, %rcx
+ xorq %r14, %r15
+ xorq %r8, %r9
+ xorl %r11d, %r9d
+ movl %ecx, %r11d
+ roll %r9d
+ roll $5, %r11d
+ movq %r9, 64(%rdi)
+ addq %r15, %r11
+ movq 64(%rdi), %rdx
+ movq 48(%rdi), %r15
+ movq 8(%rdi), %r12
+ addq %rsi, %r11
+ movq -40(%rdi), %rax
+ movq 72(%rdi), %r8
+ movl %ecx, %r9d
+ addq %rdx, %r11
+ xorq %r12, %r15
+ addq %r10, %r11
+ xorq %rax, %r15
+ xorl %r8d, %r15d
+ movl %r11d, %r8d
+ roll %r15d
+ roll $5, %r8d
+ xorq %rbx, %rcx
+ xorq %r13, %rcx
+ movq %r15, 72(%rdi)
+ movq 72(%rdi), %rsi
+ addq %rcx, %r8
+ movq 56(%rdi), %r12
+ movq 16(%rdi), %rcx
+ movq -32(%rdi), %rdx
+ addq %r14, %r8
+ movq -48(%rdi), %r14
+ addq %rsi, %r8
+ roll $30, %r9d
+ movl %r11d, %r15d
+ xorq %rcx, %r12
+ addq %r10, %r8
+ xorq %r9, %r11
+ xorq %rdx, %r12
+ xorq %rbx, %r11
+ roll $30, %r15d
+ xorl %r14d, %r12d
+ movl %r8d, %r14d
+ roll $5, %r14d
+ roll %r12d
+ addq %r11, %r14
+ movq %r12, -48(%rdi)
+ movq -48(%rdi), %rax
+ addq %r13, %r14
+ movq 64(%rdi), %r13
+ movq 24(%rdi), %rsi
+ movq -24(%rdi), %rcx
+ movq -40(%rdi), %r11
+ movl %r8d, %r12d
+ addq %rax, %r14
+ xorq %r15, %r8
+ roll $30, %r12d
+ xorq %rsi, %r13
+ addq %r10, %r14
+ xorq %r9, %r8
+ xorq %rcx, %r13
+ xorl %r11d, %r13d
+ movl %r14d, %r11d
+ roll $5, %r11d
+ roll %r13d
+ addq %r8, %r11
+ movq %r13, -40(%rdi)
+ movq -40(%rdi), %rdx
+ addq %rbx, %r11
+ movq 72(%rdi), %rbx
+ movq 32(%rdi), %rax
+ movq -16(%rdi), %rsi
+ movq -32(%rdi), %r8
+ movl %r14d, %r13d
+ addq %rdx, %r11
+ xorq %rax, %rbx
+ addq %r10, %r11
+ xorq %rsi, %rbx
+ xorl %r8d, %ebx
+ xorq %r12, %r14
+ movl %r11d, %r8d
+ xorq %r15, %r14
+ roll %ebx
+ roll $5, %r8d
+ movq %rbx, -32(%rdi)
+ addq %r14, %r8
+ movq -32(%rdi), %rcx
+ movq -48(%rdi), %r14
+ movq 40(%rdi), %rdx
+ addq %r9, %r8
+ movq -8(%rdi), %rax
+ movq -24(%rdi), %r9
+ roll $30, %r13d
+ addq %rcx, %r8
+ movl %r11d, %ebx
+ xorq %r13, %r11
+ xorq %rdx, %r14
+ addq %r10, %r8
+ xorq %r12, %r11
+ xorq %rax, %r14
+ roll $30, %ebx
+ xorl %r9d, %r14d
+ movl %r8d, %r9d
+ roll $5, %r9d
+ roll %r14d
+ addq %r11, %r9
+ movq %r14, -24(%rdi)
+ movq -24(%rdi), %rsi
+ addq %r15, %r9
+ movq -40(%rdi), %r15
+ movq 48(%rdi), %rcx
+ movq (%rdi), %rdx
+ movq -16(%rdi), %r11
+ movl %r8d, %r14d
+ addq %rsi, %r9
+ xorq %rbx, %r8
+ xorq %rcx, %r15
+ addq %r10, %r9
+ xorq %r13, %r8
+ xorq %rdx, %r15
+ xorl %r11d, %r15d
+ movl %r9d, %r11d
+ roll %r15d
+ roll $5, %r11d
+ movq %r15, -16(%rdi)
+ addq %r8, %r11
+ movq -16(%rdi), %rax
+ addq %r12, %r11
+ movq -32(%rdi), %r12
+ movq 56(%rdi), %rsi
+ movq 8(%rdi), %rcx
+ movq -8(%rdi), %r8
+ movl %r9d, %r15d
+ addq %rax, %r11
+ addq %r10, %r11
+ roll $30, %r14d
+ xorq %rsi, %r12
+ xorq %rcx, %r12
+ xorq %r14, %r9
+ roll $30, %r15d
+ xorl %r8d, %r12d
+ movl %r11d, %r8d
+ xorq %rbx, %r9
+ roll $5, %r8d
+ roll %r12d
+ addq %r9, %r8
+ movq %r12, -8(%rdi)
+ movq -8(%rdi), %rdx
+ addq %r13, %r8
+ movq -24(%rdi), %r13
+ movq 64(%rdi), %rax
+ movq 16(%rdi), %rsi
+ movq (%rdi), %rcx
+ movl %r11d, %r12d
+ addq %rdx, %r8
+ xorq %r15, %r11
+ roll $30, %r12d
+ xorq %rax, %r13
+ addq %r10, %r8
+ xorq %r14, %r11
+ xorq %rsi, %r13
+ xorl %ecx, %r13d
+ movl %r8d, %ecx
+ roll $5, %ecx
+ roll %r13d
+ addq %r11, %rcx
+ movq %r13, (%rdi)
+ movq (%rdi), %r9
+ addq %rbx, %rcx
+ movq -16(%rdi), %rbx
+ movq 72(%rdi), %rdx
+ movq 24(%rdi), %rax
+ movq 8(%rdi), %rsi
+ movl %r8d, %r13d
+ addq %r9, %rcx
+ xorq %r12, %r8
+ xorq %rdx, %rbx
+ addq %r10, %rcx
+ xorq %r15, %r8
+ xorq %rax, %rbx
+ xorl %esi, %ebx
+ movl %ecx, %esi
+ roll $5, %esi
+ roll %ebx
+ addq %r8, %rsi
+ movq %rbx, 8(%rdi)
+ movq 8(%rdi), %r11
+ addq %r14, %rsi
+ movq -8(%rdi), %r14
+ movq -48(%rdi), %r9
+ movq 32(%rdi), %rdx
+ movq 16(%rdi), %r8
+ roll $30, %r13d
+ addq %r11, %rsi
+ movl %ecx, %ebx
+ xorq %r13, %rcx
+ xorq %r9, %r14
+ addq %r10, %rsi
+ xorq %r12, %rcx
+ xorq %rdx, %r14
+ roll $30, %ebx
+ xorl %r8d, %r14d
+ movl %esi, %r8d
+ roll $5, %r8d
+ roll %r14d
+ addq %rcx, %r8
+ movq %r14, 16(%rdi)
+ movq 16(%rdi), %rax
+ addq %r15, %r8
+ movq (%rdi), %r15
+ movq -40(%rdi), %r11
+ movq 40(%rdi), %r9
+ movq 24(%rdi), %rcx
+ movl %esi, %r14d
+ addq %rax, %r8
+ xorq %rbx, %rsi
+ roll $30, %r14d
+ xorq %r11, %r15
+ addq %r10, %r8
+ xorq %r13, %rsi
+ xorq %r9, %r15
+ xorl %ecx, %r15d
+ movl %r8d, %ecx
+ roll %r15d
+ roll $5, %ecx
+ movq %r15, 24(%rdi)
+ addq %rsi, %rcx
+ movq 24(%rdi), %rdx
+ movq 8(%rdi), %r11
+ movq -32(%rdi), %rax
+ addq %r12, %rcx
+ movq 48(%rdi), %r12
+ movq 32(%rdi), %rsi
+ movl %r8d, %r15d
+ addq %rdx, %rcx
+ xorq %rax, %r11
+ addq %r10, %rcx
+ xorq %r12, %r11
+ xorl %esi, %r11d
+ movl %ecx, %esi
+ roll %r11d
+ movq %r11, 32(%rdi)
+ movl %ecx, %r11d
+ movq 32(%rdi), %r9
+ roll $5, %r11d
+ xorq %r14, %r8
+ movq 16(%rdi), %r12
+ xorq %rbx, %r8
+ movq -24(%rdi), %rdx
+ movq 56(%rdi), %rax
+ addq %r8, %r11
+ movq 40(%rdi), %r8
+ roll $30, %r15d
+ addq %r13, %r11
+ xorq %r15, %rcx
+ addq %r9, %r11
+ xorq %rdx, %r12
+ xorq %r14, %rcx
+ addq %r10, %r11
+ xorq %rax, %r12
+ xorl %r8d, %r12d
+ movl %r11d, %r8d
+ roll $5, %r8d
+ roll %r12d
+ addq %rcx, %r8
+ movq %r12, 40(%rdi)
+ movq 40(%rdi), %r13
+ addq %rbx, %r8
+ movq 24(%rdi), %rbx
+ movq -16(%rdi), %r9
+ movq 64(%rdi), %rdx
+ movq 48(%rdi), %rcx
+ movl %r11d, %r12d
+ addq %r13, %r8
+ movl %esi, %r13d
+ roll $30, %r12d
+ xorq %r9, %rbx
+ addq %r10, %r8
+ roll $30, %r13d
+ xorq %rdx, %rbx
+ xorq %r13, %r11
+ xorl %ecx, %ebx
+ movl %r8d, %ecx
+ xorq %r15, %r11
+ roll %ebx
+ roll $5, %ecx
+ movq %rbx, 48(%rdi)
+ addq %r11, %rcx
+ movq 48(%rdi), %rax
+ movq 32(%rdi), %r11
+ movq -8(%rdi), %rsi
+ addq %r14, %rcx
+ movq 72(%rdi), %r9
+ movq 56(%rdi), %r14
+ movl %r8d, %ebx
+ addq %rax, %rcx
+ xorq %rsi, %r11
+ addq %r10, %rcx
+ xorq %r9, %r11
+ xorl %r14d, %r11d
+ xorq %r12, %r8
+ movl %ecx, %r14d
+ xorq %r13, %r8
+ roll %r11d
+ roll $5, %r14d
+ movq %r11, 56(%rdi)
+ addq %r8, %r14
+ movq 56(%rdi), %rdx
+ movq 40(%rdi), %r8
+ movq (%rdi), %rax
+ addq %r15, %r14
+ movq -48(%rdi), %r15
+ movq 64(%rdi), %rsi
+ roll $30, %ebx
+ addq %rdx, %r14
+ movl %ecx, %r11d
+ xorq %rbx, %rcx
+ xorq %rax, %r8
+ addq %r10, %r14
+ xorq %r12, %rcx
+ xorq %r15, %r8
+ roll $30, %r11d
+ xorl %esi, %r8d
+ movl %r14d, %esi
+ roll %r8d
+ roll $5, %esi
+ movq %r8, 64(%rdi)
+ movq 64(%rdi), %r9
+ addq %rcx, %rsi
+ movq 48(%rdi), %r15
+ movq 8(%rdi), %rcx
+ addq %r13, %rsi
+ movq -40(%rdi), %rdx
+ movq 72(%rdi), %rax
+ movl %r14d, %r8d
+ addq %r9, %rsi
+ xorq %r11, %r14
+ addq %r10, %rsi
+ xorq %rcx, %r15
+ xorq %rbx, %r14
+ xorq %rdx, %r15
+ movl %esi, %r13d
+ xorl %eax, %r15d
+ roll $5, %r13d
+ roll %r15d
+ addq %r14, %r13
+ movq %r15, 72(%rdi)
+ addq %r12, %r13
+ movq 72(%rdi), %r12
+ addq %r12, %r13
+ addq %r10, %r13
+ movq -88(%rdi), %r10
+ roll $30, %r8d
+ addq %r13, %r10
+ movq %r10, -88(%rdi)
+ movq -80(%rdi), %r9
+ addq %rsi, %r9
+ movq %r9, -80(%rdi)
+ movq -72(%rdi), %rcx
+ addq %r8, %rcx
+ movq %rcx, -72(%rdi)
+ movq -64(%rdi), %rdx
+ addq %r11, %rdx
+ movq %rdx, -64(%rdi)
+ movq -56(%rdi), %rax
+ addq %rbx, %rax
+ popq %rbx
+ popq %r12
+ popq %r13
+ popq %r14
+ popq %r15
+ movq %rax, -56(%rdi)
+ ret
+.LFE7:
+ .size shaCompress, .-shaCompress
+ .align 16
+.globl SHA1_Update
+ .type SHA1_Update, @function
+SHA1_Update:
+.LFB5:
+ pushq %rbp
+.LCFI5:
+ movq %rsp, %rbp
+.LCFI6:
+ movq %r13, -24(%rbp)
+.LCFI7:
+ movq %r14, -16(%rbp)
+.LCFI8:
+ movl %edx, %r13d
+ movq %r15, -8(%rbp)
+.LCFI9:
+ movq %rbx, -40(%rbp)
+.LCFI10:
+ movq %rdi, %r15
+ movq %r12, -32(%rbp)
+.LCFI11:
+ subq $48, %rsp
+.LCFI12:
+ testl %edx, %edx
+ movq %rsi, %r14
+ je .L243
+ movq 64(%rdi), %rdx
+ mov %r13d, %ecx
+ leaq (%rdx,%rcx), %rax
+ movq %rax, 64(%rdi)
+ movl %edx, %eax
+ andl $63, %eax
+ movl %eax, -44(%rbp)
+ jne .L256
+.L245:
+ cmpl $63, %r13d
+ jbe .L253
+ leaq 160(%r15), %rbx
+ .align 16
+.L250:
+ movq %r14, %rsi
+ subl $64, %r13d
+ movq %rbx, %rdi
+ call shaCompress
+ addq $64, %r14
+ cmpl $63, %r13d
+ ja .L250
+.L253:
+ testl %r13d, %r13d
+ je .L243
+ mov %r13d, %edx
+ movq %r14, %rsi
+ movq %r15, %rdi
+ movq -40(%rbp), %rbx
+ movq -32(%rbp), %r12
+ movq -24(%rbp), %r13
+ movq -16(%rbp), %r14
+ movq -8(%rbp), %r15
+ leave
+ jmp memcpy@PLT
+ .align 16
+.L243:
+ movq -40(%rbp), %rbx
+ movq -32(%rbp), %r12
+ movq -24(%rbp), %r13
+ movq -16(%rbp), %r14
+ movq -8(%rbp), %r15
+ leave
+ ret
+.L256:
+ movl $64, %ebx
+ mov %eax, %edi
+ subl %eax, %ebx
+ cmpl %ebx, %r13d
+ cmovb %r13d, %ebx
+ addq %r15, %rdi
+ mov %ebx, %r12d
+ subl %ebx, %r13d
+ movq %r12, %rdx
+ addq %r12, %r14
+ call memcpy@PLT
+ addl -44(%rbp), %ebx
+ andl $63, %ebx
+ jne .L245
+ leaq 160(%r15), %rdi
+ movq %r15, %rsi
+ call shaCompress
+ jmp .L245
+.LFE5:
+ .size SHA1_Update, .-SHA1_Update
+ .section .rodata
+ .align 32
+ .type bulk_pad.0, @object
+ .size bulk_pad.0, 64
+bulk_pad.0:
+ .byte -128
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .byte 0
+ .text
+ .align 16
+.globl SHA1_End
+ .type SHA1_End, @function
+SHA1_End:
+.LFB6:
+ pushq %rbp
+.LCFI13:
+ movq %rsp, %rbp
+.LCFI14:
+ movq %r12, -24(%rbp)
+.LCFI15:
+ movq %r13, -16(%rbp)
+.LCFI16:
+ movq %rsi, %r13
+ movq %r14, -8(%rbp)
+.LCFI17:
+ movq %rbx, -32(%rbp)
+.LCFI18:
+ subq $32, %rsp
+.LCFI19:
+ movq 64(%rdi), %rbx
+ movq %rdx, %r14
+ movl $119, %edx
+ leaq bulk_pad.0(%rip), %rsi
+ movq %rdi, %r12
+ movl %ebx, %r8d
+ salq $3, %rbx
+ andl $63, %r8d
+ subl %r8d, %edx
+ andl $63, %edx
+ incl %edx
+ call SHA1_Update@PLT
+ movq %rbx, %rdi
+ movq %r12, %rsi
+ shrq $32, %rdi
+/APP
+ bswap %edi
+/NO_APP
+ movl %edi, 56(%r12)
+ leaq 160(%r12), %rdi
+/APP
+ bswap %ebx
+/NO_APP
+ movl %ebx, 60(%r12)
+ call shaCompress
+ movl 72(%r12), %esi
+ movl 80(%r12), %ebx
+ movl 88(%r12), %ecx
+ movl 96(%r12), %edx
+ movl 104(%r12), %eax
+ movq 8(%rsp), %r12
+/APP
+ bswap %ebx
+ bswap %esi
+/NO_APP
+ movl %ebx, 4(%r13)
+ movl %esi, (%r13)
+/APP
+ bswap %ecx
+ bswap %edx
+/NO_APP
+ movl %ecx, 8(%r13)
+ movl %edx, 12(%r13)
+/APP
+ bswap %eax
+/NO_APP
+ movq (%rsp), %rbx
+ movl %eax, 16(%r13)
+ movl $20, (%r14)
+ movq 16(%rsp), %r13
+ movq 24(%rsp), %r14
+ leave
+ ret
+.LFE6:
+ .size SHA1_End, .-SHA1_End
+ .align 16
+.globl SHA1_NewContext
+ .type SHA1_NewContext, @function
+SHA1_NewContext:
+.LFB8:
+ movl $248, %edi
+ jmp PORT_Alloc@PLT
+.LFE8:
+ .size SHA1_NewContext, .-SHA1_NewContext
+ .align 16
+.globl SHA1_DestroyContext
+ .type SHA1_DestroyContext, @function
+SHA1_DestroyContext:
+.LFB9:
+ pushq %rbp
+.LCFI20:
+ movl $248, %edx
+ movq %rsp, %rbp
+.LCFI21:
+ movq %rbx, -16(%rbp)
+.LCFI22:
+ movq %r12, -8(%rbp)
+.LCFI23:
+ movl %esi, %ebx
+ subq $16, %rsp
+.LCFI24:
+ xorl %esi, %esi
+ movq %rdi, %r12
+ call memset@PLT
+ testl %ebx, %ebx
+ jne .L268
+ movq (%rsp), %rbx
+ movq 8(%rsp), %r12
+ leave
+ ret
+ .align 16
+.L268:
+ movq %r12, %rdi
+ movq (%rsp), %rbx
+ movq 8(%rsp), %r12
+ leave
+ jmp PORT_Free@PLT
+.LFE9:
+ .size SHA1_DestroyContext, .-SHA1_DestroyContext
+ .align 16
+.globl SHA1_HashBuf
+ .type SHA1_HashBuf, @function
+SHA1_HashBuf:
+.LFB10:
+ pushq %rbp
+.LCFI25:
+ movq %rsp, %rbp
+.LCFI26:
+ movq %rbx, -32(%rbp)
+.LCFI27:
+ leaq -288(%rbp), %rbx
+ movq %r12, -24(%rbp)
+.LCFI28:
+ movq %r13, -16(%rbp)
+.LCFI29:
+ movq %r14, -8(%rbp)
+.LCFI30:
+ movq %rsi, %r13
+ subq $304, %rsp
+.LCFI31:
+ movq %rdi, %r14
+ movl %edx, %r12d
+ movq %rbx, %rdi
+ call SHA1_Begin@PLT
+ movl %r12d, %edx
+ movq %r13, %rsi
+ movq %rbx, %rdi
+ call SHA1_Update@PLT
+ leaq -292(%rbp), %rdx
+ movq %r14, %rsi
+ movq %rbx, %rdi
+ movl $20, %ecx
+ call SHA1_End@PLT
+ movq -32(%rbp), %rbx
+ movq -24(%rbp), %r12
+ xorl %eax, %eax
+ movq -16(%rbp), %r13
+ movq -8(%rbp), %r14
+ leave
+ ret
+.LFE10:
+ .size SHA1_HashBuf, .-SHA1_HashBuf
+ .align 16
+.globl SHA1_Hash
+ .type SHA1_Hash, @function
+SHA1_Hash:
+.LFB11:
+ pushq %rbp
+.LCFI32:
+ movq %rsp, %rbp
+.LCFI33:
+ movq %rbx, -16(%rbp)
+.LCFI34:
+ movq %r12, -8(%rbp)
+.LCFI35:
+ movq %rsi, %rbx
+ subq $16, %rsp
+.LCFI36:
+ movq %rdi, %r12
+ movq %rsi, %rdi
+ call strlen@PLT
+ movq %rbx, %rsi
+ movq %r12, %rdi
+ movq (%rsp), %rbx
+ movq 8(%rsp), %r12
+ leave
+ movl %eax, %edx
+ jmp SHA1_HashBuf@PLT
+.LFE11:
+ .size SHA1_Hash, .-SHA1_Hash
+ .align 16
+.globl SHA1_FlattenSize
+ .type SHA1_FlattenSize, @function
+SHA1_FlattenSize:
+.LFB12:
+ movl $248, %eax
+ ret
+.LFE12:
+ .size SHA1_FlattenSize, .-SHA1_FlattenSize
+ .align 16
+.globl SHA1_Flatten
+ .type SHA1_Flatten, @function
+SHA1_Flatten:
+.LFB13:
+ pushq %rbp
+.LCFI37:
+ movq %rsi, %rax
+ movl $248, %edx
+ movq %rdi, %rsi
+ movq %rax, %rdi
+ movq %rsp, %rbp
+.LCFI38:
+ call memcpy@PLT
+ leave
+ xorl %eax, %eax
+ ret
+.LFE13:
+ .size SHA1_Flatten, .-SHA1_Flatten
+ .align 16
+.globl SHA1_Resurrect
+ .type SHA1_Resurrect, @function
+SHA1_Resurrect:
+.LFB14:
+ pushq %rbp
+.LCFI39:
+ movq %rsp, %rbp
+.LCFI40:
+ movq %rbx, -16(%rbp)
+.LCFI41:
+ movq %r12, -8(%rbp)
+.LCFI42:
+ subq $16, %rsp
+.LCFI43:
+ movq %rdi, %r12
+ call SHA1_NewContext@PLT
+ movq %rax, %rbx
+ xorl %eax, %eax
+ testq %rbx, %rbx
+ je .L273
+ movl $248, %edx
+ movq %r12, %rsi
+ movq %rbx, %rdi
+ call memcpy@PLT
+ movq %rbx, %rax
+.L273:
+ movq (%rsp), %rbx
+ movq 8(%rsp), %r12
+ leave
+ ret
+.LFE14:
+ .size SHA1_Resurrect, .-SHA1_Resurrect
+ .align 16
+.globl SHA1_Clone
+ .type SHA1_Clone, @function
+SHA1_Clone:
+.LFB15:
+ movl $248, %edx
+ jmp memcpy@PLT
+.LFE15:
+ .size SHA1_Clone, .-SHA1_Clone
+ .align 16
+.globl SHA1_TraceState
+ .type SHA1_TraceState, @function
+SHA1_TraceState:
+.LFB16:
+ movl $-5992, %edi
+ jmp PORT_SetError@PLT
+.LFE16:
+ .size SHA1_TraceState, .-SHA1_TraceState
diff --git a/security/nss/lib/freebl/sha512.c b/security/nss/lib/freebl/sha512.c
index ada93e62f..672aa9a0f 100644
--- a/security/nss/lib/freebl/sha512.c
+++ b/security/nss/lib/freebl/sha512.c
@@ -515,6 +515,11 @@ SHA256_Resurrect(unsigned char *space, void *arg)
return ctx;
}
+void SHA256_Clone(SHA256Context *dest, SHA256Context *src)
+{
+ memcpy(dest, src, sizeof *dest);
+}
+
/* ======= SHA512 and SHA384 common constants and defines ================= */
@@ -1168,6 +1173,11 @@ SHA512_Resurrect(unsigned char *space, void *arg)
return ctx;
}
+void SHA512_Clone(SHA512Context *dest, SHA512Context *src)
+{
+ memcpy(dest, src, sizeof *dest);
+}
+
/* ======================================================================= */
/* SHA384 uses a SHA512Context as the real context.
** The only differences between SHA384 an SHA512 are:
@@ -1265,6 +1275,11 @@ SHA384_Resurrect(unsigned char *space, void *arg)
return SHA512_Resurrect(space, arg);
}
+void SHA384_Clone(SHA384Context *dest, SHA384Context *src)
+{
+ memcpy(dest, src, sizeof *dest);
+}
+
/* ======================================================================= */
#ifdef SELFTEST
#include <stdio.h>
diff --git a/security/nss/lib/freebl/sha_fast.c b/security/nss/lib/freebl/sha_fast.c
index 7bdb0824c..b59e3ce39 100644
--- a/security/nss/lib/freebl/sha_fast.c
+++ b/security/nss/lib/freebl/sha_fast.c
@@ -43,56 +43,26 @@
#include "ssltrace.h"
#endif
-#if defined(IS_LITTLE_ENDIAN) && defined(_MSC_VER) && defined(_X86_)
-#undef SHA_HTONL
-#ifndef FORCEINLINE
-#if (MSC_VER >= 1200)
-#define FORCEINLINE __forceinline
-#else
-#define FORCEINLINE __inline
-#endif
-#endif
-#define FASTCALL __fastcall
-
-static FORCEINLINE PRUint32 FASTCALL
-swap4b(PRUint32 dwd)
-{
- __asm {
- mov eax,dwd
- bswap eax
- }
-}
-
-#define SHA_HTONL(x) swap4b(x)
-#endif
-
-static void shaCompress(SHA1Context *ctx);
+static void shaCompress(volatile SHA_HW_t *X, const PRUint32 * datain);
#define W u.w
#define B u.b
-#if defined(_MSC_VER) && defined(_X86_)
-#pragma intrinsic (_lrotr, _lrotl)
-#define SHA_ROTL(x,n) _lrotl(x,n)
-#else
-#define SHA_ROTL(X,n) (((X) << (n)) | ((X) >> (32-(n))))
-#endif
+
#define SHA_F1(X,Y,Z) ((((Y)^(Z))&(X))^(Z))
#define SHA_F2(X,Y,Z) ((X)^(Y)^(Z))
#define SHA_F3(X,Y,Z) (((X)&(Y))|((Z)&((X)|(Y))))
#define SHA_F4(X,Y,Z) ((X)^(Y)^(Z))
-#define SHA_MIX(t) ctx->W[t] = \
- (A = ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], SHA_ROTL(A, 1))
+#define SHA_MIX(n,a,b,c) XW(n) = SHA_ROTL(XW(a)^XW(b)^XW(c)^XW(n), 1)
/*
- * SHA: Zeroize and initialize context
+ * SHA: initialize context
*/
void
SHA1_Begin(SHA1Context *ctx)
{
- memset(ctx, 0, sizeof(SHA1Context));
-
+ ctx->size = 0;
/*
* Initialize H with constants from FIPS180-1.
*/
@@ -103,6 +73,43 @@ SHA1_Begin(SHA1Context *ctx)
ctx->H[4] = 0xc3d2e1f0L;
}
+/* Explanation of H array and index values:
+ * The context's H array is actually the concatenation of two arrays
+ * defined by SHA1, the H array of state variables (5 elements),
+ * and the W array of intermediate values, of which there are 16 elements.
+ * The W array starts at H[5], that is W[0] is H[5].
+ * Although these values are defined as 32-bit values, we use 64-bit
+ * variables to hold them because the AMD64 stores 64 bit values in
+ * memory MUCH faster than it stores any smaller values.
+ *
+ * Rather than passing the context structure to shaCompress, we pass
+ * this combined array of H and W values. We do not pass the address
+ * of the first element of this array, but rather pass the address of an
+ * element in the middle of the array, element X. Presently X[0] is H[11].
+ * So we pass the address of H[11] as the address of array X to shaCompress.
+ * Then shaCompress accesses the members of the array using positive AND
+ * negative indexes.
+ *
+ * Pictorially: (each element is 8 bytes)
+ * H | H0 H1 H2 H3 H4 W0 W1 W2 W3 W4 W5 W6 W7 W8 W9 Wa Wb Wc Wd We Wf |
+ * X |-11-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 |
+ *
+ * The byte offset from X[0] to any member of H and W is always
+ * representable in a signed 8-bit value, which will be encoded
+ * as a single byte offset in the X86-64 instruction set.
+ * If we didn't pass the address of H[11], and instead passed the
+ * address of H[0], the offsets to elements H[16] and above would be
+ * greater than 127, not representable in a signed 8-bit value, and the
+ * x86-64 instruction set would encode every such offset as a 32-bit
+ * signed number in each instruction that accessed element H[16] or
+ * higher. This results in much bigger and slower code.
+ */
+#if !defined(SHA_PUT_W_IN_STACK)
+#define H2X 11 /* X[0] is H[11], and H[0] is X[-11] */
+#define W2X 6 /* X[0] is W[6], and W[0] is X[-6] */
+#else
+#define H2X 0
+#endif
/*
* SHA: Add data to context.
@@ -110,36 +117,48 @@ SHA1_Begin(SHA1Context *ctx)
void
SHA1_Update(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len)
{
- register unsigned int lenB = ctx->sizeLo & 63;
+ register unsigned int lenB;
register unsigned int togo;
if (!len)
return;
/* accumulate the byte count. */
- ctx->sizeLo += len;
- ctx->sizeHi += (ctx->sizeLo < len);
+ lenB = (unsigned int)(ctx->size) & 63U;
+
+ ctx->size += len;
/*
* Read the data into W and process blocks as they get full
*/
if (lenB > 0) {
- togo = 64 - lenB;
+ togo = 64U - lenB;
if (len < togo)
togo = len;
memcpy(ctx->B + lenB, dataIn, togo);
len -= togo;
dataIn += togo;
- lenB = (lenB + togo) & 63;
+ lenB = (lenB + togo) & 63U;
if (!lenB) {
- shaCompress(ctx);
+ shaCompress(&ctx->H[H2X], ctx->W);
}
}
- while (len >= 64) {
- memcpy(ctx->B, dataIn, 64);
- dataIn += 64;
- len -= 64;
- shaCompress(ctx);
+#if !defined(SHA_ALLOW_UNALIGNED_ACCESS)
+ if ((ptrdiff_t)dataIn % sizeof(PRUint32)) {
+ while (len >= 64U) {
+ memcpy(ctx->B, dataIn, 64);
+ len -= 64U;
+ shaCompress(&ctx->H[H2X], ctx->W);
+ dataIn += 64U;
+ }
+ } else
+#endif
+ {
+ while (len >= 64U) {
+ len -= 64U;
+ shaCompress(&ctx->H[H2X], (PRUint32 *)dataIn);
+ dataIn += 64U;
+ }
}
if (len) {
memcpy(ctx->B, dataIn, len);
@@ -154,194 +173,221 @@ void
SHA1_End(SHA1Context *ctx, unsigned char *hashout,
unsigned int *pDigestLen, unsigned int maxDigestLen)
{
- register PRUint32 sizeHi, sizeLo, lenB;
+ register PRUint64 size;
+ register PRUint32 lenB;
+
static const unsigned char bulk_pad[64] = { 0x80,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
-#define A lenB
+#define tmp lenB
PORT_Assert (maxDigestLen >= SHA1_LENGTH);
/*
* Pad with a binary 1 (e.g. 0x80), then zeroes, then length in bits
*/
- sizeHi = ctx->sizeHi;
- sizeLo = ctx->sizeLo;
- lenB = sizeLo & 63;
- SHA1_Update(ctx, bulk_pad, (((55+64) - lenB) & 63) + 1);
- PORT_Assert((ctx->sizeLo & 63) == 56);
-
- /* Convert size{Hi,Lo} from bytes to bits. */
- sizeHi = (sizeHi << 3) | (sizeLo >> 29);
- sizeLo <<= 3;
+ size = ctx->size;
- ctx->W[14] = SHA_HTONL(sizeHi);
- ctx->W[15] = SHA_HTONL(sizeLo);
- shaCompress(ctx);
+ lenB = (PRUint32)size & 63;
+ SHA1_Update(ctx, bulk_pad, (((55+64) - lenB) & 63) + 1);
+ PORT_Assert(((PRUint32)ctx->size & 63) == 56);
+ /* Convert size from bytes to bits. */
+ size <<= 3;
+ ctx->W[14] = SHA_HTONL((PRUint32)(size >> 32));
+ ctx->W[15] = SHA_HTONL((PRUint32)size);
+ shaCompress(&ctx->H[H2X], ctx->W);
/*
* Output hash
*/
-#if defined(IS_LITTLE_ENDIAN)
- SHA_BYTESWAP(ctx->H[0]);
- SHA_BYTESWAP(ctx->H[1]);
- SHA_BYTESWAP(ctx->H[2]);
- SHA_BYTESWAP(ctx->H[3]);
- SHA_BYTESWAP(ctx->H[4]);
-#endif
- memcpy(hashout, ctx->H, SHA1_LENGTH);
+ SHA_STORE_RESULT;
*pDigestLen = SHA1_LENGTH;
- /*
- * Re-initialize the context (also zeroizes contents)
- */
- SHA1_Begin(ctx);
}
-#undef A
#undef B
+#undef tmp
/*
* SHA: Compression function, unrolled.
+ *
+ * Some operations in shaCompress are done as 5 groups of 16 operations.
+ * Others are done as 4 groups of 20 operations.
+ * The code below shows that structure.
+ *
+ * The functions that compute the new values of the 5 state variables
+ * A-E are done in 4 groups of 20 operations (or you may also think
+ * of them as being done in 16 groups of 5 operations). They are
+ * done by the SHA_RNDx macros below, in the right column.
+ *
+ * The functions that set the 16 values of the W array are done in
+ * 5 groups of 16 operations. The first group is done by the
+ * LOAD macros below, the latter 4 groups are done by SHA_MIX below,
+ * in the left column.
+ *
+ * gcc's optimizer observes that each member of the W array is assigned
+ * a value 5 times in this code. It reduces the number of store
+ * operations done to the W array in the context (that is, in the X array)
+ * by creating a W array on the stack, and storing the W values there for
+ * the first 4 groups of operations on W, and storing the values in the
+ * context's W array only in the fifth group. This is undesirable.
+ * It is MUCH bigger code than simply using the context's W array, because
+ * all the offsets to the W array in the stack are 32-bit signed offsets,
+ * and it is no faster than storing the values in the context's W array.
+ *
+ * The original code for sha_fast.c prevented this creation of a separate
+ * W array in the stack by creating a W array of 80 members, each of
+ * whose elements is assigned only once. It also separated the computations
+ * of the W array values and the computations of the values for the 5
+ * state variables into two separate passes, W's, then A-E's so that the
+ * second pass could be done all in registers (except for accessing the W
+ * array) on machines with fewer registers. The method is suboptimal
+ * for machines with enough registers to do it all in one pass, and it
+ * necessitates using many instructions with 32-bit offsets.
+ *
+ * This code eliminates the separate W array on the stack by a completely
+ * different means: by declaring the X array volatile. This prevents
+ * the optimizer from trying to reduce the use of the X array by the
+ * creation of a MORE expensive W array on the stack. The result is
+ * that all instructions use signed 8-bit offsets and not 32-bit offsets.
+ *
+ * The combination of this code and the -O3 optimizer flag on GCC 3.4.3
+ * results in code that is 3 times faster than the previous NSS sha_fast
+ * code on AMD64.
*/
static void
-shaCompress(SHA1Context *ctx)
+shaCompress(volatile SHA_HW_t *X, const PRUint32 *inbuf)
{
- register PRUint32 A, B, C, D, E;
-
-#if defined(IS_LITTLE_ENDIAN)
- SHA_BYTESWAP(ctx->W[0]);
- SHA_BYTESWAP(ctx->W[1]);
- SHA_BYTESWAP(ctx->W[2]);
- SHA_BYTESWAP(ctx->W[3]);
- SHA_BYTESWAP(ctx->W[4]);
- SHA_BYTESWAP(ctx->W[5]);
- SHA_BYTESWAP(ctx->W[6]);
- SHA_BYTESWAP(ctx->W[7]);
- SHA_BYTESWAP(ctx->W[8]);
- SHA_BYTESWAP(ctx->W[9]);
- SHA_BYTESWAP(ctx->W[10]);
- SHA_BYTESWAP(ctx->W[11]);
- SHA_BYTESWAP(ctx->W[12]);
- SHA_BYTESWAP(ctx->W[13]);
- SHA_BYTESWAP(ctx->W[14]);
- SHA_BYTESWAP(ctx->W[15]);
+ register SHA_HW_t A, B, C, D, E;
+
+#if defined(SHA_NEED_TMP_VARIABLE)
+ register PRUint32 tmp;
#endif
- /*
- * This can be moved into the main code block below, but doing
- * so can cause some compilers to run out of registers and resort
- * to storing intermediates in RAM.
- */
+#if !defined(SHA_PUT_W_IN_STACK)
+#define XH(n) X[n-H2X]
+#define XW(n) X[n-W2X]
+#else
+ SHA_HW_t w_0, w_1, w_2, w_3, w_4, w_5, w_6, w_7,
+ w_8, w_9, w_10, w_11, w_12, w_13, w_14, w_15;
+#define XW(n) w_ ## n
+#define XH(n) X[n]
+#endif
- SHA_MIX(16); SHA_MIX(17); SHA_MIX(18); SHA_MIX(19);
- SHA_MIX(20); SHA_MIX(21); SHA_MIX(22); SHA_MIX(23); SHA_MIX(24);
- SHA_MIX(25); SHA_MIX(26); SHA_MIX(27); SHA_MIX(28); SHA_MIX(29);
- SHA_MIX(30); SHA_MIX(31); SHA_MIX(32); SHA_MIX(33); SHA_MIX(34);
- SHA_MIX(35); SHA_MIX(36); SHA_MIX(37); SHA_MIX(38); SHA_MIX(39);
- SHA_MIX(40); SHA_MIX(41); SHA_MIX(42); SHA_MIX(43); SHA_MIX(44);
- SHA_MIX(45); SHA_MIX(46); SHA_MIX(47); SHA_MIX(48); SHA_MIX(49);
- SHA_MIX(50); SHA_MIX(51); SHA_MIX(52); SHA_MIX(53); SHA_MIX(54);
- SHA_MIX(55); SHA_MIX(56); SHA_MIX(57); SHA_MIX(58); SHA_MIX(59);
- SHA_MIX(60); SHA_MIX(61); SHA_MIX(62); SHA_MIX(63); SHA_MIX(64);
- SHA_MIX(65); SHA_MIX(66); SHA_MIX(67); SHA_MIX(68); SHA_MIX(69);
- SHA_MIX(70); SHA_MIX(71); SHA_MIX(72); SHA_MIX(73); SHA_MIX(74);
- SHA_MIX(75); SHA_MIX(76); SHA_MIX(77); SHA_MIX(78); SHA_MIX(79);
-
- A = ctx->H[0];
- B = ctx->H[1];
- C = ctx->H[2];
- D = ctx->H[3];
- E = ctx->H[4];
-
- E = SHA_ROTL(A,5)+SHA_F1(B,C,D)+E+ctx->W[ 0]+0x5a827999L; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F1(A,B,C)+D+ctx->W[ 1]+0x5a827999L; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F1(E,A,B)+C+ctx->W[ 2]+0x5a827999L; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F1(D,E,A)+B+ctx->W[ 3]+0x5a827999L; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F1(C,D,E)+A+ctx->W[ 4]+0x5a827999L; C=SHA_ROTL(C,30);
- E = SHA_ROTL(A,5)+SHA_F1(B,C,D)+E+ctx->W[ 5]+0x5a827999L; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F1(A,B,C)+D+ctx->W[ 6]+0x5a827999L; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F1(E,A,B)+C+ctx->W[ 7]+0x5a827999L; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F1(D,E,A)+B+ctx->W[ 8]+0x5a827999L; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F1(C,D,E)+A+ctx->W[ 9]+0x5a827999L; C=SHA_ROTL(C,30);
- E = SHA_ROTL(A,5)+SHA_F1(B,C,D)+E+ctx->W[10]+0x5a827999L; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F1(A,B,C)+D+ctx->W[11]+0x5a827999L; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F1(E,A,B)+C+ctx->W[12]+0x5a827999L; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F1(D,E,A)+B+ctx->W[13]+0x5a827999L; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F1(C,D,E)+A+ctx->W[14]+0x5a827999L; C=SHA_ROTL(C,30);
- E = SHA_ROTL(A,5)+SHA_F1(B,C,D)+E+ctx->W[15]+0x5a827999L; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F1(A,B,C)+D+ctx->W[16]+0x5a827999L; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F1(E,A,B)+C+ctx->W[17]+0x5a827999L; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F1(D,E,A)+B+ctx->W[18]+0x5a827999L; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F1(C,D,E)+A+ctx->W[19]+0x5a827999L; C=SHA_ROTL(C,30);
-
- E = SHA_ROTL(A,5)+SHA_F2(B,C,D)+E+ctx->W[20]+0x6ed9eba1L; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F2(A,B,C)+D+ctx->W[21]+0x6ed9eba1L; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F2(E,A,B)+C+ctx->W[22]+0x6ed9eba1L; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F2(D,E,A)+B+ctx->W[23]+0x6ed9eba1L; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F2(C,D,E)+A+ctx->W[24]+0x6ed9eba1L; C=SHA_ROTL(C,30);
- E = SHA_ROTL(A,5)+SHA_F2(B,C,D)+E+ctx->W[25]+0x6ed9eba1L; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F2(A,B,C)+D+ctx->W[26]+0x6ed9eba1L; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F2(E,A,B)+C+ctx->W[27]+0x6ed9eba1L; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F2(D,E,A)+B+ctx->W[28]+0x6ed9eba1L; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F2(C,D,E)+A+ctx->W[29]+0x6ed9eba1L; C=SHA_ROTL(C,30);
- E = SHA_ROTL(A,5)+SHA_F2(B,C,D)+E+ctx->W[30]+0x6ed9eba1L; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F2(A,B,C)+D+ctx->W[31]+0x6ed9eba1L; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F2(E,A,B)+C+ctx->W[32]+0x6ed9eba1L; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F2(D,E,A)+B+ctx->W[33]+0x6ed9eba1L; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F2(C,D,E)+A+ctx->W[34]+0x6ed9eba1L; C=SHA_ROTL(C,30);
- E = SHA_ROTL(A,5)+SHA_F2(B,C,D)+E+ctx->W[35]+0x6ed9eba1L; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F2(A,B,C)+D+ctx->W[36]+0x6ed9eba1L; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F2(E,A,B)+C+ctx->W[37]+0x6ed9eba1L; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F2(D,E,A)+B+ctx->W[38]+0x6ed9eba1L; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F2(C,D,E)+A+ctx->W[39]+0x6ed9eba1L; C=SHA_ROTL(C,30);
-
- E = SHA_ROTL(A,5)+SHA_F3(B,C,D)+E+ctx->W[40]+0x8f1bbcdcL; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F3(A,B,C)+D+ctx->W[41]+0x8f1bbcdcL; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F3(E,A,B)+C+ctx->W[42]+0x8f1bbcdcL; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F3(D,E,A)+B+ctx->W[43]+0x8f1bbcdcL; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F3(C,D,E)+A+ctx->W[44]+0x8f1bbcdcL; C=SHA_ROTL(C,30);
- E = SHA_ROTL(A,5)+SHA_F3(B,C,D)+E+ctx->W[45]+0x8f1bbcdcL; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F3(A,B,C)+D+ctx->W[46]+0x8f1bbcdcL; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F3(E,A,B)+C+ctx->W[47]+0x8f1bbcdcL; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F3(D,E,A)+B+ctx->W[48]+0x8f1bbcdcL; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F3(C,D,E)+A+ctx->W[49]+0x8f1bbcdcL; C=SHA_ROTL(C,30);
- E = SHA_ROTL(A,5)+SHA_F3(B,C,D)+E+ctx->W[50]+0x8f1bbcdcL; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F3(A,B,C)+D+ctx->W[51]+0x8f1bbcdcL; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F3(E,A,B)+C+ctx->W[52]+0x8f1bbcdcL; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F3(D,E,A)+B+ctx->W[53]+0x8f1bbcdcL; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F3(C,D,E)+A+ctx->W[54]+0x8f1bbcdcL; C=SHA_ROTL(C,30);
- E = SHA_ROTL(A,5)+SHA_F3(B,C,D)+E+ctx->W[55]+0x8f1bbcdcL; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F3(A,B,C)+D+ctx->W[56]+0x8f1bbcdcL; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F3(E,A,B)+C+ctx->W[57]+0x8f1bbcdcL; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F3(D,E,A)+B+ctx->W[58]+0x8f1bbcdcL; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F3(C,D,E)+A+ctx->W[59]+0x8f1bbcdcL; C=SHA_ROTL(C,30);
-
- E = SHA_ROTL(A,5)+SHA_F4(B,C,D)+E+ctx->W[60]+0xca62c1d6L; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F4(A,B,C)+D+ctx->W[61]+0xca62c1d6L; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F4(E,A,B)+C+ctx->W[62]+0xca62c1d6L; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F4(D,E,A)+B+ctx->W[63]+0xca62c1d6L; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F4(C,D,E)+A+ctx->W[64]+0xca62c1d6L; C=SHA_ROTL(C,30);
- E = SHA_ROTL(A,5)+SHA_F4(B,C,D)+E+ctx->W[65]+0xca62c1d6L; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F4(A,B,C)+D+ctx->W[66]+0xca62c1d6L; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F4(E,A,B)+C+ctx->W[67]+0xca62c1d6L; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F4(D,E,A)+B+ctx->W[68]+0xca62c1d6L; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F4(C,D,E)+A+ctx->W[69]+0xca62c1d6L; C=SHA_ROTL(C,30);
- E = SHA_ROTL(A,5)+SHA_F4(B,C,D)+E+ctx->W[70]+0xca62c1d6L; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F4(A,B,C)+D+ctx->W[71]+0xca62c1d6L; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F4(E,A,B)+C+ctx->W[72]+0xca62c1d6L; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F4(D,E,A)+B+ctx->W[73]+0xca62c1d6L; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F4(C,D,E)+A+ctx->W[74]+0xca62c1d6L; C=SHA_ROTL(C,30);
- E = SHA_ROTL(A,5)+SHA_F4(B,C,D)+E+ctx->W[75]+0xca62c1d6L; B=SHA_ROTL(B,30);
- D = SHA_ROTL(E,5)+SHA_F4(A,B,C)+D+ctx->W[76]+0xca62c1d6L; A=SHA_ROTL(A,30);
- C = SHA_ROTL(D,5)+SHA_F4(E,A,B)+C+ctx->W[77]+0xca62c1d6L; E=SHA_ROTL(E,30);
- B = SHA_ROTL(C,5)+SHA_F4(D,E,A)+B+ctx->W[78]+0xca62c1d6L; D=SHA_ROTL(D,30);
- A = SHA_ROTL(B,5)+SHA_F4(C,D,E)+A+ctx->W[79]+0xca62c1d6L; C=SHA_ROTL(C,30);
-
- ctx->H[0] += A;
- ctx->H[1] += B;
- ctx->H[2] += C;
- ctx->H[3] += D;
- ctx->H[4] += E;
+#define K0 0x5a827999L
+#define K1 0x6ed9eba1L
+#define K2 0x8f1bbcdcL
+#define K3 0xca62c1d6L
+
+#define SHA_RND1(a,b,c,d,e,n) \
+ a = SHA_ROTL(b,5)+SHA_F1(c,d,e)+a+XW(n)+K0; c=SHA_ROTL(c,30)
+#define SHA_RND2(a,b,c,d,e,n) \
+ a = SHA_ROTL(b,5)+SHA_F2(c,d,e)+a+XW(n)+K1; c=SHA_ROTL(c,30)
+#define SHA_RND3(a,b,c,d,e,n) \
+ a = SHA_ROTL(b,5)+SHA_F3(c,d,e)+a+XW(n)+K2; c=SHA_ROTL(c,30)
+#define SHA_RND4(a,b,c,d,e,n) \
+ a = SHA_ROTL(b,5)+SHA_F4(c,d,e)+a+XW(n)+K3; c=SHA_ROTL(c,30)
+
+#define LOAD(n) XW(n) = SHA_HTONL(inbuf[n])
+
+ A = XH(0);
+ B = XH(1);
+ C = XH(2);
+ D = XH(3);
+ E = XH(4);
+
+ LOAD(0); SHA_RND1(E,A,B,C,D, 0);
+ LOAD(1); SHA_RND1(D,E,A,B,C, 1);
+ LOAD(2); SHA_RND1(C,D,E,A,B, 2);
+ LOAD(3); SHA_RND1(B,C,D,E,A, 3);
+ LOAD(4); SHA_RND1(A,B,C,D,E, 4);
+ LOAD(5); SHA_RND1(E,A,B,C,D, 5);
+ LOAD(6); SHA_RND1(D,E,A,B,C, 6);
+ LOAD(7); SHA_RND1(C,D,E,A,B, 7);
+ LOAD(8); SHA_RND1(B,C,D,E,A, 8);
+ LOAD(9); SHA_RND1(A,B,C,D,E, 9);
+ LOAD(10); SHA_RND1(E,A,B,C,D,10);
+ LOAD(11); SHA_RND1(D,E,A,B,C,11);
+ LOAD(12); SHA_RND1(C,D,E,A,B,12);
+ LOAD(13); SHA_RND1(B,C,D,E,A,13);
+ LOAD(14); SHA_RND1(A,B,C,D,E,14);
+ LOAD(15); SHA_RND1(E,A,B,C,D,15);
+
+ SHA_MIX( 0, 13, 8, 2); SHA_RND1(D,E,A,B,C, 0);
+ SHA_MIX( 1, 14, 9, 3); SHA_RND1(C,D,E,A,B, 1);
+ SHA_MIX( 2, 15, 10, 4); SHA_RND1(B,C,D,E,A, 2);
+ SHA_MIX( 3, 0, 11, 5); SHA_RND1(A,B,C,D,E, 3);
+
+ SHA_MIX( 4, 1, 12, 6); SHA_RND2(E,A,B,C,D, 4);
+ SHA_MIX( 5, 2, 13, 7); SHA_RND2(D,E,A,B,C, 5);
+ SHA_MIX( 6, 3, 14, 8); SHA_RND2(C,D,E,A,B, 6);
+ SHA_MIX( 7, 4, 15, 9); SHA_RND2(B,C,D,E,A, 7);
+ SHA_MIX( 8, 5, 0, 10); SHA_RND2(A,B,C,D,E, 8);
+ SHA_MIX( 9, 6, 1, 11); SHA_RND2(E,A,B,C,D, 9);
+ SHA_MIX(10, 7, 2, 12); SHA_RND2(D,E,A,B,C,10);
+ SHA_MIX(11, 8, 3, 13); SHA_RND2(C,D,E,A,B,11);
+ SHA_MIX(12, 9, 4, 14); SHA_RND2(B,C,D,E,A,12);
+ SHA_MIX(13, 10, 5, 15); SHA_RND2(A,B,C,D,E,13);
+ SHA_MIX(14, 11, 6, 0); SHA_RND2(E,A,B,C,D,14);
+ SHA_MIX(15, 12, 7, 1); SHA_RND2(D,E,A,B,C,15);
+
+ SHA_MIX( 0, 13, 8, 2); SHA_RND2(C,D,E,A,B, 0);
+ SHA_MIX( 1, 14, 9, 3); SHA_RND2(B,C,D,E,A, 1);
+ SHA_MIX( 2, 15, 10, 4); SHA_RND2(A,B,C,D,E, 2);
+ SHA_MIX( 3, 0, 11, 5); SHA_RND2(E,A,B,C,D, 3);
+ SHA_MIX( 4, 1, 12, 6); SHA_RND2(D,E,A,B,C, 4);
+ SHA_MIX( 5, 2, 13, 7); SHA_RND2(C,D,E,A,B, 5);
+ SHA_MIX( 6, 3, 14, 8); SHA_RND2(B,C,D,E,A, 6);
+ SHA_MIX( 7, 4, 15, 9); SHA_RND2(A,B,C,D,E, 7);
+
+ SHA_MIX( 8, 5, 0, 10); SHA_RND3(E,A,B,C,D, 8);
+ SHA_MIX( 9, 6, 1, 11); SHA_RND3(D,E,A,B,C, 9);
+ SHA_MIX(10, 7, 2, 12); SHA_RND3(C,D,E,A,B,10);
+ SHA_MIX(11, 8, 3, 13); SHA_RND3(B,C,D,E,A,11);
+ SHA_MIX(12, 9, 4, 14); SHA_RND3(A,B,C,D,E,12);
+ SHA_MIX(13, 10, 5, 15); SHA_RND3(E,A,B,C,D,13);
+ SHA_MIX(14, 11, 6, 0); SHA_RND3(D,E,A,B,C,14);
+ SHA_MIX(15, 12, 7, 1); SHA_RND3(C,D,E,A,B,15);
+
+ SHA_MIX( 0, 13, 8, 2); SHA_RND3(B,C,D,E,A, 0);
+ SHA_MIX( 1, 14, 9, 3); SHA_RND3(A,B,C,D,E, 1);
+ SHA_MIX( 2, 15, 10, 4); SHA_RND3(E,A,B,C,D, 2);
+ SHA_MIX( 3, 0, 11, 5); SHA_RND3(D,E,A,B,C, 3);
+ SHA_MIX( 4, 1, 12, 6); SHA_RND3(C,D,E,A,B, 4);
+ SHA_MIX( 5, 2, 13, 7); SHA_RND3(B,C,D,E,A, 5);
+ SHA_MIX( 6, 3, 14, 8); SHA_RND3(A,B,C,D,E, 6);
+ SHA_MIX( 7, 4, 15, 9); SHA_RND3(E,A,B,C,D, 7);
+ SHA_MIX( 8, 5, 0, 10); SHA_RND3(D,E,A,B,C, 8);
+ SHA_MIX( 9, 6, 1, 11); SHA_RND3(C,D,E,A,B, 9);
+ SHA_MIX(10, 7, 2, 12); SHA_RND3(B,C,D,E,A,10);
+ SHA_MIX(11, 8, 3, 13); SHA_RND3(A,B,C,D,E,11);
+
+ SHA_MIX(12, 9, 4, 14); SHA_RND4(E,A,B,C,D,12);
+ SHA_MIX(13, 10, 5, 15); SHA_RND4(D,E,A,B,C,13);
+ SHA_MIX(14, 11, 6, 0); SHA_RND4(C,D,E,A,B,14);
+ SHA_MIX(15, 12, 7, 1); SHA_RND4(B,C,D,E,A,15);
+
+ SHA_MIX( 0, 13, 8, 2); SHA_RND4(A,B,C,D,E, 0);
+ SHA_MIX( 1, 14, 9, 3); SHA_RND4(E,A,B,C,D, 1);
+ SHA_MIX( 2, 15, 10, 4); SHA_RND4(D,E,A,B,C, 2);
+ SHA_MIX( 3, 0, 11, 5); SHA_RND4(C,D,E,A,B, 3);
+ SHA_MIX( 4, 1, 12, 6); SHA_RND4(B,C,D,E,A, 4);
+ SHA_MIX( 5, 2, 13, 7); SHA_RND4(A,B,C,D,E, 5);
+ SHA_MIX( 6, 3, 14, 8); SHA_RND4(E,A,B,C,D, 6);
+ SHA_MIX( 7, 4, 15, 9); SHA_RND4(D,E,A,B,C, 7);
+ SHA_MIX( 8, 5, 0, 10); SHA_RND4(C,D,E,A,B, 8);
+ SHA_MIX( 9, 6, 1, 11); SHA_RND4(B,C,D,E,A, 9);
+ SHA_MIX(10, 7, 2, 12); SHA_RND4(A,B,C,D,E,10);
+ SHA_MIX(11, 8, 3, 13); SHA_RND4(E,A,B,C,D,11);
+ SHA_MIX(12, 9, 4, 14); SHA_RND4(D,E,A,B,C,12);
+ SHA_MIX(13, 10, 5, 15); SHA_RND4(C,D,E,A,B,13);
+ SHA_MIX(14, 11, 6, 0); SHA_RND4(B,C,D,E,A,14);
+ SHA_MIX(15, 12, 7, 1); SHA_RND4(A,B,C,D,E,15);
+
+ XH(0) += A;
+ XH(1) += B;
+ XH(2) += C;
+ XH(3) += D;
+ XH(4) += E;
}
/*************************************************************************
@@ -358,11 +404,13 @@ SHA1_NewContext(void)
return cx;
}
+/* Zero and free the context */
void
SHA1_DestroyContext(SHA1Context *cx, PRBool freeit)
{
+ memset(cx, 0, sizeof *cx);
if (freeit) {
- PORT_ZFree(cx, sizeof(SHA1Context));
+ PORT_Free(cx);
}
}
@@ -375,7 +423,6 @@ SHA1_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
SHA1_Begin(&ctx);
SHA1_Update(&ctx, src, src_length);
SHA1_End(&ctx, dest, &outLen, SHA1_LENGTH);
-
return SECSuccess;
}
@@ -413,38 +460,13 @@ SHA1_Resurrect(unsigned char *space,void *arg)
return cx;
}
+void SHA1_Clone(SHA1Context *dest, SHA1Context *src)
+{
+ memcpy(dest, src, sizeof *dest);
+}
+
void
SHA1_TraceState(SHA1Context *ctx)
{
-#ifdef TRACING_SSL
- uint32 W;
- int i;
- int len;
- int fixWord = -1;
- int remainder; /* bytes in last word */
- unsigned char buf[64 * 4];
-
- SSL_TRC(99, ("%d: SSL: SHA1 state: %08x %08x %08x %08x %08x", SSL_GETPID(),
- ctx->H[0], ctx->H[1], ctx->H[2], ctx->H[3], ctx->H[4]));
-
- len = (int)(ctx->sizeLo & 63);
- remainder = len % 4;
- if (remainder)
- fixWord = len - remainder;
- for (i = 0; i < len; i++) {
- if (0 == (i % 4)) {
- W = ctx->W[i / 4];
- if (i == fixWord) {
- W <<= 8 * (4 - remainder);
- }
- }
- buf[i] = (unsigned char)(W >> 24);
- W <<= 8;
- }
-
- PRINT_BUF(99, (0, "SHA1_TraceState: buffered input", buf, len));
-
-#else
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
-#endif
}
diff --git a/security/nss/lib/freebl/sha_fast.h b/security/nss/lib/freebl/sha_fast.h
index d92c374f6..6243471b0 100644
--- a/security/nss/lib/freebl/sha_fast.h
+++ b/security/nss/lib/freebl/sha_fast.h
@@ -37,24 +37,142 @@
#ifndef _SHA_FAST_H_
#define _SHA_FAST_H_
+#include "prlong.h"
+
#define SHA1_INPUT_LEN 64
+#if defined(IS_64) && !defined(__sparc)
+typedef PRUint64 SHA_HW_t;
+#define SHA1_USING_64_BIT 1
+#else
+typedef PRUint32 SHA_HW_t;
+#endif
+
struct SHA1ContextStr {
union {
- PRUint32 w[80]; /* input buffer, plus 64 words */
- PRUint8 b[320];
+ PRUint32 w[16]; /* input buffer */
+ PRUint8 b[64];
} u;
- PRUint32 H[5]; /* 5 state variables */
- PRUint32 sizeHi,sizeLo; /* 64-bit count of hashed bytes. */
+ PRUint64 size; /* count of hashed bytes. */
+ SHA_HW_t H[22]; /* 5 state variables, 16 tmp values, 1 extra */
};
+#if defined(_MSC_VER) && defined(_X86_)
+#if defined(IS_LITTLE_ENDIAN)
+#ifndef FORCEINLINE
+#if (_MSC_VER >= 1200)
+#define FORCEINLINE __forceinline
+#else
+#define FORCEINLINE __inline
+#endif /* _MSC_VER */
+#endif /* !defined FORCEINLINE */
+#define FASTCALL __fastcall
+
+static FORCEINLINE PRUint32 FASTCALL
+swap4b(PRUint32 dwd)
+{
+ __asm {
+ mov eax,dwd
+ bswap eax
+ }
+}
+
+#define SHA_HTONL(x) swap4b(x)
+#endif /* IS_LITTLE_ENDIAN */
+
+#pragma intrinsic (_lrotr, _lrotl)
+#define SHA_ROTL(x,n) _lrotl(x,n)
+#define SHA_ROTL_IS_DEFINED 1
+#endif /* _MSC_VER && _X86_ */
+
+#if defined(__GNUC__)
+/* __x86_64__ and __x86_64 are defined by GCC on x86_64 CPUs */
+
+#if defined( SHA1_USING_64_BIT )
+static __inline__ PRUint64 SHA_ROTL(PRUint64 x, PRUint32 n)
+{
+ PRUint32 t = (PRUint32)x;
+ return ((t << n) | (t >> (32 - n)));
+}
+#else
+static __inline__ PRUint32 SHA_ROTL(PRUint32 t, PRUint32 n)
+{
+ return ((t << n) | (t >> (32 - n)));
+}
+#endif
+#define SHA_ROTL_IS_DEFINED 1
+
+#if defined(_X86_) || defined(__x86_64__) || defined(__x86_64)
+static __inline__ PRUint32 swap4b(PRUint32 value)
+{
+ __asm__("bswap %0" : "+r" (value));
+ return (value);
+}
+#define SHA_HTONL(x) swap4b(x)
+#endif /* x86 family */
+
+#endif /* __GNUC__ */
+
+#if !defined(SHA_ROTL_IS_DEFINED)
+#define SHA_NEED_TMP_VARIABLE 1
+#define SHA_ROTL(X,n) (tmp = (X), ((tmp) << (n)) | ((tmp) >> (32-(n))))
+#endif
+
+#if defined(_X86_) || defined(__x86_64__) || defined(__x86_64)
+#define SHA_ALLOW_UNALIGNED_ACCESS 1
+#endif
+
+#if !defined(SHA_HTONL)
#define SHA_MASK 0x00FF00FF
#if defined(IS_LITTLE_ENDIAN)
-#define SHA_HTONL(x) (A = (x), A = (A << 16) | (A >> 16), \
- ((A & SHA_MASK) << 8) | ((A >> 8) & SHA_MASK))
+#undef SHA_NEED_TMP_VARIABLE
+#define SHA_NEED_TMP_VARIABLE 1
+#define SHA_HTONL(x) (tmp = (x), tmp = (tmp << 16) | (tmp >> 16), \
+ ((tmp & SHA_MASK) << 8) | ((tmp >> 8) & SHA_MASK))
#else
#define SHA_HTONL(x) (x)
#endif
+#endif
+
#define SHA_BYTESWAP(x) x = SHA_HTONL(x)
+#define SHA_STORE(n) ((PRUint32*)hashout)[n] = SHA_HTONL(ctx->H[n])
+#if defined(SHA_ALLOW_UNALIGNED_ACCESS)
+#define SHA_STORE_RESULT \
+ SHA_STORE(0); \
+ SHA_STORE(1); \
+ SHA_STORE(2); \
+ SHA_STORE(3); \
+ SHA_STORE(4);
+
+#elif defined(IS_LITTLE_ENDIAN) || defined( SHA1_USING_64_BIT )
+#define SHA_STORE_RESULT \
+ if (!((ptrdiff_t)hashout % sizeof(PRUint32))) { \
+ SHA_STORE(0); \
+ SHA_STORE(1); \
+ SHA_STORE(2); \
+ SHA_STORE(3); \
+ SHA_STORE(4); \
+ } else { \
+ ctx->u.w[0] = SHA_HTONL(ctx->H[0]); \
+ ctx->u.w[1] = SHA_HTONL(ctx->H[1]); \
+ ctx->u.w[2] = SHA_HTONL(ctx->H[2]); \
+ ctx->u.w[3] = SHA_HTONL(ctx->H[3]); \
+ ctx->u.w[4] = SHA_HTONL(ctx->H[4]); \
+ memcpy(hashout, ctx->u.w, SHA1_LENGTH); \
+ }
+
+#else
+#define SHA_STORE_RESULT \
+ if (!((ptrdiff_t)hashout % sizeof(PRUint32))) { \
+ SHA_STORE(0); \
+ SHA_STORE(1); \
+ SHA_STORE(2); \
+ SHA_STORE(3); \
+ SHA_STORE(4); \
+ } else { \
+ memcpy(hashout, ctx->H, SHA1_LENGTH); \
+ }
+#endif
+
#endif /* _SHA_FAST_H_ */
diff --git a/security/nss/lib/freebl/tlsprfalg.c b/security/nss/lib/freebl/tlsprfalg.c
new file mode 100644
index 000000000..05f3f0d76
--- /dev/null
+++ b/security/nss/lib/freebl/tlsprfalg.c
@@ -0,0 +1,164 @@
+/* tlsprfalg.c - TLS Pseudo Random Function (PRF) implementation
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/* $Id$ */
+
+#include "sechash.h"
+#include "alghmac.h"
+#include "blapi.h"
+
+#define PHASH_STATE_MAX_LEN SHA1_LENGTH
+
+/* TLS P_hash function */
+static SECStatus
+sftk_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,
+ SECItem *seed, SECItem *result, PRBool isFIPS)
+{
+ unsigned char state[PHASH_STATE_MAX_LEN];
+ unsigned char outbuf[PHASH_STATE_MAX_LEN];
+ unsigned int state_len = 0, label_len = 0, outbuf_len = 0, chunk_size;
+ unsigned int remaining;
+ unsigned char *res;
+ SECStatus status;
+ HMACContext *cx;
+ SECStatus rv = SECFailure;
+ const SECHashObject *hashObj = HASH_GetRawHashObject(hashType);
+
+ PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
+ PORT_Assert((seed != NULL) && (seed->data != NULL));
+ PORT_Assert((result != NULL) && (result->data != NULL));
+
+ remaining = result->len;
+ res = result->data;
+
+ if (label != NULL)
+ label_len = PORT_Strlen(label);
+
+ cx = HMAC_Create(hashObj, secret->data, secret->len, isFIPS);
+ if (cx == NULL)
+ goto loser;
+
+ /* initialize the state = A(1) = HMAC_hash(secret, seed) */
+ HMAC_Begin(cx);
+ HMAC_Update(cx, (unsigned char *)label, label_len);
+ HMAC_Update(cx, seed->data, seed->len);
+ status = HMAC_Finish(cx, state, &state_len, sizeof(state));
+ if (status != SECSuccess)
+ goto loser;
+
+ /* generate a block at a time until we're done */
+ while (remaining > 0) {
+
+ HMAC_Begin(cx);
+ HMAC_Update(cx, state, state_len);
+ if (label_len)
+ HMAC_Update(cx, (unsigned char *)label, label_len);
+ HMAC_Update(cx, seed->data, seed->len);
+ status = HMAC_Finish(cx, outbuf, &outbuf_len, sizeof(outbuf));
+ if (status != SECSuccess)
+ goto loser;
+
+ /* Update the state = A(i) = HMAC_hash(secret, A(i-1)) */
+ HMAC_Begin(cx);
+ HMAC_Update(cx, state, state_len);
+ status = HMAC_Finish(cx, state, &state_len, sizeof(state));
+ if (status != SECSuccess)
+ goto loser;
+
+ chunk_size = PR_MIN(outbuf_len, remaining);
+ PORT_Memcpy(res, &outbuf, chunk_size);
+ res += chunk_size;
+ remaining -= chunk_size;
+ }
+
+ rv = SECSuccess;
+
+loser:
+ /* clear out state so it's not left on the stack */
+ if (cx)
+ HMAC_Destroy(cx, PR_TRUE);
+ PORT_Memset(state, 0, sizeof(state));
+ PORT_Memset(outbuf, 0, sizeof(outbuf));
+ return rv;
+}
+
+SECStatus
+TLS_PRF(const SECItem *secret, const char *label, SECItem *seed,
+ SECItem *result, PRBool isFIPS)
+{
+ SECStatus rv = SECFailure, status;
+ unsigned int i;
+ SECItem tmp = { siBuffer, NULL, 0};
+ SECItem S1;
+ SECItem S2;
+
+ PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
+ PORT_Assert((seed != NULL) && (seed->data != NULL));
+ PORT_Assert((result != NULL) && (result->data != NULL));
+
+ S1.type = siBuffer;
+ S1.len = (secret->len / 2) + (secret->len & 1);
+ S1.data = secret->data;
+
+ S2.type = siBuffer;
+ S2.len = S1.len;
+ S2.data = secret->data + (secret->len - S2.len);
+
+ tmp.data = (unsigned char*)PORT_Alloc(result->len);
+ if (tmp.data == NULL)
+ goto loser;
+ tmp.len = result->len;
+
+ status = sftk_P_hash(HASH_AlgMD5, &S1, label, seed, result, isFIPS);
+ if (status != SECSuccess)
+ goto loser;
+
+ status = sftk_P_hash(HASH_AlgSHA1, &S2, label, seed, &tmp, isFIPS);
+ if (status != SECSuccess)
+ goto loser;
+
+ for (i = 0; i < result->len; i++)
+ result->data[i] ^= tmp.data[i];
+
+ rv = SECSuccess;
+
+loser:
+ if (tmp.data != NULL)
+ PORT_ZFree(tmp.data, tmp.len);
+ return rv;
+}
+
diff --git a/security/nss/lib/manifest.mn b/security/nss/lib/manifest.mn
index 108f188f0..268ff0496 100644
--- a/security/nss/lib/manifest.mn
+++ b/security/nss/lib/manifest.mn
@@ -47,7 +47,6 @@ DEPTH = ../..
# smime
# ckfw (builtins module)
# crmf jar (not dll's)
-# fortcrypt
DIRS = util freebl softoken \
base asn1 dev pki pki1 \
certdb certhigh pk11wrap cryptohi nss \
@@ -55,9 +54,10 @@ DIRS = util freebl softoken \
pkcs12 pkcs7 smime \
crmf jar \
ckfw \
- fortcrypt \
$(NULL)
+# fortcrypt is no longer built
+
# NSS 4.0 build - pure stan libraries
ifdef PURE_STAN_BUILD
DIRS = base asn1 dev pki pki1
diff --git a/security/nss/lib/nss/config.mk b/security/nss/lib/nss/config.mk
index 0e70604d7..5cdb444e5 100644
--- a/security/nss/lib/nss/config.mk
+++ b/security/nss/lib/nss/config.mk
@@ -54,6 +54,7 @@ ifdef NS_USE_GCC
EXTRA_SHARED_LIBS += \
-L$(DIST)/lib \
-lsoftokn3 \
+ -L$(NSPR_LIB_DIR) \
-lplc4 \
-lplds4 \
-lnspr4\
@@ -61,9 +62,9 @@ EXTRA_SHARED_LIBS += \
else # ! NS_USE_GCC
EXTRA_SHARED_LIBS += \
$(DIST)/lib/softokn3.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)nspr4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
$(NULL)
endif # NS_USE_GCC
@@ -72,8 +73,9 @@ else
# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib/ \
+ -L$(DIST)/lib \
-lsoftokn3 \
+ -L$(NSPR_LIB_DIR) \
-lplc4 \
-lplds4 \
-lnspr4 \
diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def
index 208638a77..b02dd61ef 100644
--- a/security/nss/lib/nss/nss.def
+++ b/security/nss/lib/nss/nss.def
@@ -857,3 +857,18 @@ PK11_GenerateKeyPairWithFlags;
;+ local:
;+ *;
;+};
+;+NSS_3.11 { # NSS 3.11 release
+;+ global:
+CERT_CompareValidityTimes;
+PK11_CopyTokenPrivKeyToSessionPrivKey;
+PK11_FreeSlotListElement;
+PK11_GenerateRandomOnSlot;
+PK11_GetSymKeyUserData;
+PK11_MapSignKeyType;
+PK11_SetSymKeyUserData;
+SECMOD_CloseUserDB;
+SECMOD_HasRootCerts;
+SECMOD_OpenUserDB;
+;+ local:
+;+ *;
+;+};
diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h
index 0a5ed026c..9ced4592a 100644
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -52,11 +52,11 @@ SEC_BEGIN_PROTOS
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>] [<Beta>]"
*/
-#define NSS_VERSION "3.10.2"
+#define NSS_VERSION "3.11.1 Beta"
#define NSS_VMAJOR 3
-#define NSS_VMINOR 10
-#define NSS_VPATCH 2
-#define NSS_BETA PR_FALSE
+#define NSS_VMINOR 11
+#define NSS_VPATCH 1
+#define NSS_BETA PR_TRUE
/*
@@ -119,6 +119,36 @@ extern SECStatus NSS_InitReadWrite(const char *configdir);
* NSS_INIT_NOROOTINIT - Don't try to look for the root certs module
* automatically.
* NSS_INIT_OPTIMIZESPACE - Use smaller tables and caches.
+ * NSS_INIT_PK11THREADSAFE - only load PKCS#11 modules that are
+ * thread-safe, ie. that support locking - either OS
+ * locking or NSS-provided locks . If a PKCS#11
+ * module isn't thread-safe, don't serialize its
+ * calls; just don't load it instead. This is necessary
+ * if another piece of code is using the same PKCS#11
+ * modules that NSS is accessing without going through
+ * NSS, for example the Java SunPKCS11 provider.
+ * NSS_INIT_PK11RELOAD - ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED
+ * error when loading PKCS#11 modules. This is necessary
+ * if another piece of code is using the same PKCS#11
+ * modules that NSS is accessing without going through
+ * NSS, for example Java SunPKCS11 provider.
+ * NSS_INIT_NOPK11FINALIZE - never call C_Finalize on any
+ * PKCS#11 module. This may be necessary in order to
+ * ensure continuous operation and proper shutdown
+ * sequence if another piece of code is using the same
+ * PKCS#11 modules that NSS is accessing without going
+ * through NSS, for example Java SunPKCS11 provider.
+ * The following limitation applies when this is set :
+ * SECMOD_WaitForAnyTokenEvent will not use
+ * C_WaitForSlotEvent, in order to prevent the need for
+ * C_Finalize. This call will be emulated instead.
+ * NSS_INIT_RESERVED - Currently has no effect, but may be used in the
+ * future to trigger better cooperation between PKCS#11
+ * modules used by both NSS and the Java SunPKCS11
+ * provider. This should occur after a new flag is defined
+ * for C_Initialize by the PKCS#11 working group.
+ * NSS_INIT_COOPERATE - Sets 4 recommended options for applications that
+ * use both NSS and the Java SunPKCS11 provider.
*
* Also NOTE: This is not the recommended method for initializing NSS.
* The prefered method is NSS_init().
@@ -129,6 +159,15 @@ extern SECStatus NSS_InitReadWrite(const char *configdir);
#define NSS_INIT_FORCEOPEN 0x8
#define NSS_INIT_NOROOTINIT 0x10
#define NSS_INIT_OPTIMIZESPACE 0x20
+#define NSS_INIT_PK11THREADSAFE 0x40
+#define NSS_INIT_PK11RELOAD 0x80
+#define NSS_INIT_NOPK11FINALIZE 0x100
+#define NSS_INIT_RESERVED 0x200
+
+#define NSS_INIT_COOPERATE NSS_INIT_PK11THREADSAFE | \
+ NSS_INIT_PK11RELOAD | \
+ NSS_INIT_NOPK11FINALIZE | \
+ NSS_INIT_RESERVED
#ifdef macintosh
#define SECMOD_DB "Security Modules"
diff --git a/security/nss/lib/nss/nssinit.c b/security/nss/lib/nss/nssinit.c
index a7693b55c..adf3efb04 100644
--- a/security/nss/lib/nss/nssinit.c
+++ b/security/nss/lib/nss/nssinit.c
@@ -285,7 +285,7 @@ done:
static const char *dllname =
#if defined(XP_WIN32) || defined(XP_OS2)
"nssckbi.dll";
-#elif defined(HPUX)
+#elif defined(HPUX) && !defined(__ia64) /* HP-UX PA-RISC */
"libnssckbi.sl";
#elif defined(DARWIN)
"libnssckbi.dylib";
@@ -400,7 +400,9 @@ static SECStatus
nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
const char *secmodName, PRBool readOnly, PRBool noCertDB,
PRBool noModDB, PRBool forceOpen, PRBool noRootInit,
- PRBool optimizeSpace)
+ PRBool optimizeSpace, PRBool noSingleThreadedModules,
+ PRBool allowAlreadyInitializedModules,
+ PRBool dontFinalizeModules)
{
char *moduleSpec = NULL;
char *flags = NULL;
@@ -442,6 +444,12 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
if (lsecmodName == NULL) {
goto loser;
}
+ if (noSingleThreadedModules || allowAlreadyInitializedModules ||
+ dontFinalizeModules) {
+ pk11_setGlobalOptions(noSingleThreadedModules,
+ allowAlreadyInitializedModules,
+ dontFinalizeModules);
+ }
moduleSpec = PR_smprintf("name=\"%s\" parameters=\"configdir='%s' certPrefix='%s' keyPrefix='%s' secmod='%s' flags=%s %s\" NSS=\"flags=internal,moduleDB,moduleDBOnly,critical\"",
pk11_config_name ? pk11_config_name : NSS_DEFAULT_MOD_NAME,
@@ -493,14 +501,14 @@ SECStatus
NSS_Init(const char *configdir)
{
return nss_Init(configdir, "", "", SECMOD_DB, PR_TRUE,
- PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_TRUE);
+ PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE);
}
SECStatus
NSS_InitReadWrite(const char *configdir)
{
return nss_Init(configdir, "", "", SECMOD_DB, PR_FALSE,
- PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_TRUE);
+ PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE);
}
/*
@@ -520,6 +528,36 @@ NSS_InitReadWrite(const char *configdir)
* initialize the PKCS #11 module.
* NSS_INIT_FORCEOPEN - Continue to force initializations even if the
* databases cannot be opened.
+ * NSS_INIT_PK11THREADSAFE - only load PKCS#11 modules that are
+ * thread-safe, ie. that support locking - either OS
+ * locking or NSS-provided locks . If a PKCS#11
+ * module isn't thread-safe, don't serialize its
+ * calls; just don't load it instead. This is necessary
+ * if another piece of code is using the same PKCS#11
+ * modules that NSS is accessing without going through
+ * NSS, for example the Java SunPKCS11 provider.
+ * NSS_INIT_PK11RELOAD - ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED
+ * error when loading PKCS#11 modules. This is necessary
+ * if another piece of code is using the same PKCS#11
+ * modules that NSS is accessing without going through
+ * NSS, for example Java SunPKCS11 provider.
+ * NSS_INIT_NOPK11FINALIZE - never call C_Finalize on any
+ * PKCS#11 module. This may be necessary in order to
+ * ensure continuous operation and proper shutdown
+ * sequence if another piece of code is using the same
+ * PKCS#11 modules that NSS is accessing without going
+ * through NSS, for example Java SunPKCS11 provider.
+ * The following limitation applies when this is set :
+ * SECMOD_WaitForAnyTokenEvent will not use
+ * C_WaitForSlotEvent, in order to prevent the need for
+ * C_Finalize. This call will be emulated instead.
+ * NSS_INIT_RESERVED - Currently has no effect, but may be used in the
+ * future to trigger better cooperation between PKCS#11
+ * modules used by both NSS and the Java SunPKCS11
+ * provider. This should occur after a new flag is defined
+ * for C_Initialize by the PKCS#11 working group.
+ * NSS_INIT_COOPERATE - Sets 4 recommended options for applications that
+ * use both NSS and the Java SunPKCS11 provider.
*/
SECStatus
NSS_Initialize(const char *configdir, const char *certPrefix,
@@ -531,7 +569,10 @@ NSS_Initialize(const char *configdir, const char *certPrefix,
((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB),
((flags & NSS_INIT_FORCEOPEN) == NSS_INIT_FORCEOPEN),
((flags & NSS_INIT_NOROOTINIT) == NSS_INIT_NOROOTINIT),
- ((flags & NSS_INIT_OPTIMIZESPACE) == NSS_INIT_OPTIMIZESPACE));
+ ((flags & NSS_INIT_OPTIMIZESPACE) == NSS_INIT_OPTIMIZESPACE),
+ ((flags & NSS_INIT_PK11THREADSAFE) == NSS_INIT_PK11THREADSAFE),
+ ((flags & NSS_INIT_PK11RELOAD) == NSS_INIT_PK11RELOAD),
+ ((flags & NSS_INIT_NOPK11FINALIZE) == NSS_INIT_NOPK11FINALIZE));
}
/*
@@ -541,7 +582,8 @@ SECStatus
NSS_NoDB_Init(const char * configdir)
{
return nss_Init("","","","",
- PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE);
+ PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,
+ PR_FALSE,PR_FALSE,PR_FALSE);
}
extern const NSSError NSS_ERROR_BUSY;
diff --git a/security/nss/lib/pk11wrap/manifest.mn b/security/nss/lib/pk11wrap/manifest.mn
index fca5fb7b2..b0de09bec 100644
--- a/security/nss/lib/pk11wrap/manifest.mn
+++ b/security/nss/lib/pk11wrap/manifest.mn
@@ -86,8 +86,3 @@ LIBRARY_NAME = pk11wrap
ifdef DEBUG_PKCS11
DEFINES += -DDEBUG_MODULE
endif
-
-ifdef NSS_ENABLE_ECC
-DEFINES += -DNSS_ENABLE_ECC
-endif
-
diff --git a/security/nss/lib/pk11wrap/pk11akey.c b/security/nss/lib/pk11wrap/pk11akey.c
index 55db33995..a6189cf43 100644
--- a/security/nss/lib/pk11wrap/pk11akey.c
+++ b/security/nss/lib/pk11wrap/pk11akey.c
@@ -59,10 +59,6 @@
#include "secpkcs5.h"
#include "ec.h"
-#define PAIRWISE_SECITEM_TYPE siBuffer
-#define PAIRWISE_DIGEST_LENGTH SHA1_LENGTH /* 160-bits */
-#define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */
-
/*
* import a public key into the desired slot
*/
@@ -156,7 +152,6 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.dh.publicValue.data,
pubKey->u.dh.publicValue.len); attrs++;
break;
-#ifdef NSS_ENABLE_ECC
case ecKey:
keyType = CKK_EC;
PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++;
@@ -168,7 +163,6 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
PK11_SETATTRS(attrs, CKA_EC_POINT, pubKey->u.ec.publicValue.data,
pubKey->u.ec.publicValue.len); attrs++;
break;
-#endif /* NSS_ENABLE_ECC */
default:
PORT_SetError( SEC_ERROR_BAD_KEY );
return CK_INVALID_HANDLE;
@@ -225,9 +219,7 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
CK_ATTRIBUTE template[8];
CK_ATTRIBUTE *attrs= template;
CK_ATTRIBUTE *modulus,*exponent,*base,*prime,*subprime,*value;
-#ifdef NSS_ENABLE_ECC
CK_ATTRIBUTE *ecparams;
-#endif /* NSS_ENABLE_ECC */
/* if we didn't know the key type, get it */
if (keyType== nullKey) {
@@ -246,11 +238,9 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
case CKK_DH:
keyType = dhKey;
break;
-#ifdef NSS_ENABLE_ECC
case CKK_EC:
keyType = ecKey;
break;
-#endif /* NSS_ENABLE_ECC */
default:
PORT_SetError( SEC_ERROR_BAD_KEY );
return NULL;
@@ -355,7 +345,6 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
crv = pk11_Attr2SecItem(arena,value,&pubKey->u.dh.publicValue);
if (crv != CKR_OK) break;
break;
-#ifdef NSS_ENABLE_ECC
case ecKey:
pubKey->u.ec.size = 0;
ecparams = attrs;
@@ -378,7 +367,6 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
crv = pk11_Attr2SecItem(arena,value,&pubKey->u.ec.publicValue);
if (crv != CKR_OK) break;
break;
-#endif /* NSS_ENABLE_ECC */
case fortezzaKey:
case nullKey:
default:
@@ -421,9 +409,7 @@ PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
case CKK_DSA: keyType = dsaKey; break;
case CKK_DH: keyType = dhKey; break;
case CKK_KEA: keyType = fortezzaKey; break;
-#ifdef NSS_ENABLE_ECC
case CKK_EC: keyType = ecKey; break;
-#endif /* NSS_ENABLE_ECC */
default:
break;
}
@@ -507,258 +493,6 @@ PK11_GetPrivateModulusLen(SECKEYPrivateKey *key)
return -1;
}
-/*
- * PKCS #11 pairwise consistency check utilized to validate key pair.
- */
-static SECStatus
-pk11_PairwiseConsistencyCheck(SECKEYPublicKey *pubKey,
- SECKEYPrivateKey *privKey, CK_MECHANISM *mech, void* wincx )
-{
- /* Variables used for Encrypt/Decrypt functions. */
- unsigned char *known_message = (unsigned char *)"Known Crypto Message";
- CK_BBOOL isEncryptable = CK_FALSE;
- CK_BBOOL canSignVerify = CK_FALSE;
- CK_BBOOL isDerivable = CK_FALSE;
- unsigned char plaintext[PAIRWISE_MESSAGE_LENGTH];
- CK_ULONG bytes_decrypted;
- PK11SlotInfo *slot;
- CK_OBJECT_HANDLE id;
- unsigned char *ciphertext;
- unsigned char *text_compared;
- CK_ULONG max_bytes_encrypted;
- CK_ULONG bytes_encrypted;
- CK_ULONG bytes_compared;
- CK_RV crv;
-
- /* Variables used for Signature/Verification functions. */
- unsigned char *known_digest = (unsigned char *)"Mozilla Rules World!";
- SECItem signature;
- SECItem digest; /* always uses SHA-1 digest */
- int signature_length;
- SECStatus rv;
-
- /**************************************************/
- /* Pairwise Consistency Check of Encrypt/Decrypt. */
- /**************************************************/
-
- isEncryptable = PK11_HasAttributeSet( privKey->pkcs11Slot,
- privKey->pkcs11ID, CKA_DECRYPT );
-
- /* If the encryption attribute is set; attempt to encrypt */
- /* with the public key and decrypt with the private key. */
- if( isEncryptable ) {
- /* Find a module to encrypt against */
- slot = PK11_GetBestSlot(pk11_mapWrapKeyType(privKey->keyType),wincx);
- if (slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return SECFailure;
- }
-
- id = PK11_ImportPublicKey(slot,pubKey,PR_FALSE);
- if (id == CK_INVALID_HANDLE) {
- PK11_FreeSlot(slot);
- return SECFailure;
- }
-
- /* Compute max bytes encrypted from modulus length of private key. */
- max_bytes_encrypted = PK11_GetPrivateModulusLen( privKey );
-
-
- /* Prepare for encryption using the public key. */
- PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB( slot )->C_EncryptInit( slot->session,
- mech, id );
- if( crv != CKR_OK ) {
- PK11_ExitSlotMonitor(slot);
- PORT_SetError( PK11_MapError( crv ) );
- PK11_FreeSlot(slot);
- return SECFailure;
- }
-
- /* Allocate space for ciphertext. */
- ciphertext = (unsigned char *) PORT_Alloc( max_bytes_encrypted );
- if( ciphertext == NULL ) {
- PK11_ExitSlotMonitor(slot);
- PORT_SetError( SEC_ERROR_NO_MEMORY );
- PK11_FreeSlot(slot);
- return SECFailure;
- }
-
- /* Initialize bytes encrypted to max bytes encrypted. */
- bytes_encrypted = max_bytes_encrypted;
-
- /* Encrypt using the public key. */
- crv = PK11_GETTAB( slot )->C_Encrypt( slot->session,
- known_message,
- PAIRWISE_MESSAGE_LENGTH,
- ciphertext,
- &bytes_encrypted );
- PK11_ExitSlotMonitor(slot);
- PK11_FreeSlot(slot);
- if( crv != CKR_OK ) {
- PORT_SetError( PK11_MapError( crv ) );
- PORT_Free( ciphertext );
- return SECFailure;
- }
-
- /* Always use the smaller of these two values . . . */
- bytes_compared = ( bytes_encrypted > PAIRWISE_MESSAGE_LENGTH )
- ? PAIRWISE_MESSAGE_LENGTH
- : bytes_encrypted;
-
- /* If there was a failure, the plaintext */
- /* goes at the end, therefore . . . */
- text_compared = ( bytes_encrypted > PAIRWISE_MESSAGE_LENGTH )
- ? (ciphertext + bytes_encrypted -
- PAIRWISE_MESSAGE_LENGTH )
- : ciphertext;
-
- /* Check to ensure that ciphertext does */
- /* NOT EQUAL known input message text */
- /* per FIPS PUB 140-1 directive. */
- if( ( bytes_encrypted != max_bytes_encrypted ) ||
- ( PORT_Memcmp( text_compared, known_message,
- bytes_compared ) == 0 ) ) {
- /* Set error to Invalid PRIVATE Key. */
- PORT_SetError( SEC_ERROR_INVALID_KEY );
- PORT_Free( ciphertext );
- return SECFailure;
- }
-
- slot = privKey->pkcs11Slot;
- /* Prepare for decryption using the private key. */
- PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB( slot )->C_DecryptInit( slot->session,
- mech,
- privKey->pkcs11ID );
- if( crv != CKR_OK ) {
- PK11_ExitSlotMonitor(slot);
- PORT_SetError( PK11_MapError(crv) );
- PORT_Free( ciphertext );
- return SECFailure;
- }
-
- /* Initialize bytes decrypted to be the */
- /* expected PAIRWISE_MESSAGE_LENGTH. */
- bytes_decrypted = PAIRWISE_MESSAGE_LENGTH;
-
- /* Decrypt using the private key. */
- /* NOTE: No need to reset the */
- /* value of bytes_encrypted. */
- crv = PK11_GETTAB( slot )->C_Decrypt( slot->session,
- ciphertext,
- bytes_encrypted,
- plaintext,
- &bytes_decrypted );
- PK11_ExitSlotMonitor(slot);
-
- /* Finished with ciphertext; free it. */
- PORT_Free( ciphertext );
-
- if( crv != CKR_OK ) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
-
- /* Check to ensure that the output plaintext */
- /* does EQUAL known input message text. */
- if( ( bytes_decrypted != PAIRWISE_MESSAGE_LENGTH ) ||
- ( PORT_Memcmp( plaintext, known_message,
- PAIRWISE_MESSAGE_LENGTH ) != 0 ) ) {
- /* Set error to Bad PUBLIC Key. */
- PORT_SetError( SEC_ERROR_BAD_KEY );
- return SECFailure;
- }
- }
-
- /**********************************************/
- /* Pairwise Consistency Check of Sign/Verify. */
- /**********************************************/
-
- canSignVerify = PK11_HasAttributeSet ( privKey->pkcs11Slot,
- privKey->pkcs11ID, CKA_SIGN);
-
- if (canSignVerify)
- {
- /* Initialize signature and digest data. */
- signature.data = NULL;
- digest.data = NULL;
-
- /* Determine length of signature. */
- signature_length = PK11_SignatureLen( privKey );
- if( signature_length == 0 )
- goto failure;
-
- /* Allocate space for signature data. */
- signature.data = (unsigned char *) PORT_Alloc( signature_length );
- if( signature.data == NULL ) {
- PORT_SetError( SEC_ERROR_NO_MEMORY );
- goto failure;
- }
-
- /* Allocate space for known digest data. */
- digest.data = (unsigned char *) PORT_Alloc( PAIRWISE_DIGEST_LENGTH );
- if( digest.data == NULL ) {
- PORT_SetError( SEC_ERROR_NO_MEMORY );
- goto failure;
- }
-
- /* "Fill" signature type and length. */
- signature.type = PAIRWISE_SECITEM_TYPE;
- signature.len = signature_length;
-
- /* "Fill" digest with known SHA-1 digest parameters. */
- digest.type = PAIRWISE_SECITEM_TYPE;
- PORT_Memcpy( digest.data, known_digest, PAIRWISE_DIGEST_LENGTH );
- digest.len = PAIRWISE_DIGEST_LENGTH;
-
- /* Sign the known hash using the private key. */
- rv = PK11_Sign( privKey, &signature, &digest );
- if( rv != SECSuccess )
- goto failure;
-
- /* Verify the known hash using the public key. */
- rv = PK11_Verify( pubKey, &signature, &digest, wincx );
- if( rv != SECSuccess )
- goto failure;
-
- /* Free signature and digest data. */
- PORT_Free( signature.data );
- PORT_Free( digest.data );
- }
-
-
-
- /**********************************************/
- /* Pairwise Consistency Check for Derivation */
- /**********************************************/
-
- isDerivable = PK11_HasAttributeSet ( privKey->pkcs11Slot,
- privKey->pkcs11ID, CKA_DERIVE);
-
- if (isDerivable)
- {
- /*
- * We are not doing consistency check for Diffie-Hellman Key -
- * otherwise it would be here
- * This is also true for Elliptic Curve Diffie-Hellman keys
- * NOTE: EC keys are currently subjected to pairwise
- * consistency check for signing/verification.
- */
-
- }
-
- return SECSuccess;
-
-failure:
- if( signature.data != NULL )
- PORT_Free( signature.data );
- if( digest.data != NULL )
- PORT_Free( digest.data );
-
- return SECFailure;
-}
-
/*
@@ -846,12 +580,10 @@ pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
ap->type = CKA_BASE; ap++; count++; extra_count++;
ap->type = CKA_VALUE; ap++; count++; extra_count++;
break;
-#ifdef NSS_ENABLE_ECC
case ecKey:
ap->type = CKA_EC_PARAMS; ap++; count++; extra_count++;
ap->type = CKA_VALUE; ap++; count++; extra_count++;
break;
-#endif /* NSS_ENABLE_ECC */
default:
count = 0;
extra_count = 0;
@@ -909,135 +641,22 @@ pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
objectID, privKey->wincx);
}
-SECKEYPrivateKey *
+static SECKEYPrivateKey *
pk11_loadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive)
{
- CK_ATTRIBUTE privTemplate[] = {
- /* class must be first */
- { CKA_CLASS, NULL, 0 },
- { CKA_KEY_TYPE, NULL, 0 },
- /* these three must be next */
- { CKA_TOKEN, NULL, 0 },
- { CKA_PRIVATE, NULL, 0 },
- { CKA_SENSITIVE, NULL, 0 },
- { CKA_ID, NULL, 0 },
-#ifdef notdef
- { CKA_LABEL, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 },
-#endif
- /* RSA */
- { CKA_MODULUS, NULL, 0 },
- { CKA_PRIVATE_EXPONENT, NULL, 0 },
- { CKA_PUBLIC_EXPONENT, NULL, 0 },
- { CKA_PRIME_1, NULL, 0 },
- { CKA_PRIME_2, NULL, 0 },
- { CKA_EXPONENT_1, NULL, 0 },
- { CKA_EXPONENT_2, NULL, 0 },
- { CKA_COEFFICIENT, NULL, 0 },
- };
- CK_ATTRIBUTE *attrs = NULL, *ap;
- int templateSize = sizeof(privTemplate)/sizeof(privTemplate[0]);
- PRArenaPool *arena;
- CK_OBJECT_HANDLE objectID;
- int i, count = 0;
- int extra_count = 0;
- CK_RV crv;
- SECStatus rv;
-
- for (i=0; i < templateSize; i++) {
- if (privTemplate[i].type == CKA_MODULUS) {
- attrs= &privTemplate[i];
- count = i;
- break;
- }
+ PK11AttrFlags attrFlags = 0;
+ if (token) {
+ attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE);
+ } else {
+ attrFlags |= (PK11_ATTR_SESSION | PK11_ATTR_PUBLIC);
}
- PORT_Assert(attrs != NULL);
- if (attrs == NULL) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
+ if (sensitive) {
+ attrFlags |= PK11_ATTR_SENSITIVE;
+ } else {
+ attrFlags |= PK11_ATTR_INSENSITIVE;
}
-
- ap = attrs;
-
- switch (privKey->keyType) {
- case rsaKey:
- count = templateSize;
- extra_count = templateSize - (attrs - privTemplate);
- break;
- case dsaKey:
- ap->type = CKA_PRIME; ap++; count++; extra_count++;
- ap->type = CKA_SUBPRIME; ap++; count++; extra_count++;
- ap->type = CKA_BASE; ap++; count++; extra_count++;
- ap->type = CKA_VALUE; ap++; count++; extra_count++;
- break;
- case dhKey:
- ap->type = CKA_PRIME; ap++; count++; extra_count++;
- ap->type = CKA_BASE; ap++; count++; extra_count++;
- ap->type = CKA_VALUE; ap++; count++; extra_count++;
- break;
-#ifdef NSS_ENABLE_ECC
- case ecKey:
- ap->type = CKA_EC_PARAMS; ap++; count++; extra_count++;
- ap->type = CKA_VALUE; ap++; count++; extra_count++;
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- count = 0;
- extra_count = 0;
- break;
- }
-
- if (count == 0) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) return NULL;
- /*
- * read out the old attributes.
- */
- crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID,
- privTemplate,count);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- PORT_FreeArena(arena, PR_TRUE);
- return NULL;
- }
-
- /* Reset sensitive, token, and private */
- *(CK_BBOOL *)(privTemplate[2].pValue) = token ? CK_TRUE : CK_FALSE;
- *(CK_BBOOL *)(privTemplate[3].pValue) = token ? CK_TRUE : CK_FALSE;
- *(CK_BBOOL *)(privTemplate[4].pValue) = sensitive ? CK_TRUE : CK_FALSE;
-
- /* Not everyone can handle zero padded key values, give
- * them the raw data as unsigned */
- for (ap=attrs; extra_count; ap++, extra_count--) {
- pk11_SignedToUnsigned(ap);
- }
-
- /* now Store the puppies */
- rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, privTemplate,
- count, token, &objectID);
- PORT_FreeArena(arena, PR_TRUE);
- if (rv != SECSuccess) {
- return NULL;
- }
-
- /* try loading the public key as a token object */
- if (pubKey) {
- PK11_ImportPublicKey(slot, pubKey, PR_TRUE);
- if (pubKey->pkcs11Slot) {
- PK11_FreeSlot(pubKey->pkcs11Slot);
- pubKey->pkcs11Slot = NULL;
- pubKey->pkcs11ID = CK_INVALID_HANDLE;
- }
- }
-
- /* build new key structure */
- return PK11_MakePrivKey(slot, privKey->keyType, (PRBool)!token,
- objectID, privKey->wincx);
+ return pk11_loadPrivKeyWithFlags(slot, privKey, pubKey, attrFlags);
}
/*
@@ -1110,7 +729,6 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
{ CKA_ENCRYPT, NULL, 0},
{ CKA_MODIFIABLE, NULL, 0},
};
-#ifdef NSS_ENABLE_ECC
CK_ATTRIBUTE ecPubTemplate[] = {
{ CKA_EC_PARAMS, NULL, 0 },
{ CKA_TOKEN, NULL, 0},
@@ -1122,7 +740,6 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
{ CKA_MODIFIABLE, NULL, 0},
};
SECKEYECParams * ecParams;
-#endif /* NSS_ENABLE_ECC */
/*CK_ULONG key_size = 0;*/
CK_ATTRIBUTE *pubTemplate;
@@ -1144,7 +761,6 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
CK_ATTRIBUTE *privattrs;
SECItem *pubKeyIndex;
CK_ATTRIBUTE setTemplate;
- SECStatus rv;
CK_MECHANISM_INFO mechanism_info;
CK_OBJECT_CLASS keyClass;
SECItem *cka_id;
@@ -1219,7 +835,12 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
/* set up the mechanism specific info */
switch (type) {
case CKM_RSA_PKCS_KEY_PAIR_GEN:
+ case CKM_RSA_X9_31_KEY_PAIR_GEN:
rsaParams = (PK11RSAGenParams *)param;
+ if (rsaParams->pe == 0) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return NULL;
+ }
modulusBits = rsaParams->keySizeInBits;
peCount = 0;
@@ -1266,7 +887,6 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
keyType = dhKey;
test_mech.mechanism = CKM_DH_PKCS_DERIVE;
break;
-#ifdef NSS_ENABLE_ECC
case CKM_EC_KEY_PAIR_GEN:
ecParams = (SECKEYECParams *)param;
attrs = ecPubTemplate;
@@ -1281,7 +901,6 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
*/
test_mech.mechanism = CKM_ECDH1_DERIVE;
break;
-#endif /* NSS_ENABLE_ECC */
default:
PORT_SetError( SEC_ERROR_BAD_KEY );
return NULL;
@@ -1305,7 +924,6 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
case CKM_DH_PKCS_DERIVE:
mechanism_info.flags = CKF_DERIVE;
break;
-#ifdef NSS_ENABLE_ECC
case CKM_ECDH1_DERIVE:
mechanism_info.flags = CKF_DERIVE;
break;
@@ -1313,7 +931,6 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
case CKM_ECDSA_SHA1:
mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
break;
-#endif /* NSS_ENABLE_ECC */
default:
break;
}
@@ -1355,12 +972,17 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
haslock = PK11_RWSessionHasLock(slot,session_handle);
restore = PR_TRUE;
} else {
- PK11_EnterSlotMonitor(slot); /* gross!! */
session_handle = slot->session;
+ if (session_handle != CK_INVALID_SESSION)
+ PK11_EnterSlotMonitor(slot);
restore = PR_FALSE;
haslock = PR_TRUE;
}
+ if (session_handle == CK_INVALID_SESSION) {
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return NULL;
+ }
privCount = privattrs - privTemplate;
pubCount = attrs - pubTemplate;
crv = PK11_GETTAB(slot)->C_GenerateKeyPair(session_handle, &mechanism,
@@ -1403,6 +1025,7 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
pubKeyIndex = NULL;
switch (type) {
case CKM_RSA_PKCS_KEY_PAIR_GEN:
+ case CKM_RSA_X9_31_KEY_PAIR_GEN:
pubKeyIndex = &(*pubKey)->u.rsa.modulus;
break;
case CKM_DSA_KEY_PAIR_GEN:
@@ -1411,11 +1034,9 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
case CKM_DH_PKCS_KEY_PAIR_GEN:
pubKeyIndex = &(*pubKey)->u.dh.publicValue;
break;
-#ifdef NSS_ENABLE_ECC
case CKM_EC_KEY_PAIR_GEN:
pubKeyIndex = &(*pubKey)->u.ec.publicValue;
break;
-#endif /* NSS_ENABLE_ECC */
}
PORT_Assert(pubKeyIndex != NULL);
@@ -1458,16 +1079,6 @@ PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
return NULL;
}
- /* Perform PKCS #11 pairwise consistency check. */
- rv = pk11_PairwiseConsistencyCheck( *pubKey, privKey, &test_mech, wincx );
- if( rv != SECSuccess ) {
- SECKEY_DestroyPublicKey( *pubKey );
- SECKEY_DestroyPrivateKey( privKey );
- *pubKey = NULL;
- privKey = NULL;
- return NULL; /* due to pairwise consistency check */
- }
-
return privKey;
}
@@ -1479,410 +1090,20 @@ PK11_GenerateKeyPair(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
void *param, SECKEYPublicKey **pubKey, PRBool token,
PRBool sensitive, void *wincx)
{
- /* we have to use these native types because when we call PKCS 11 modules
- * we have to make sure that we are using the correct sizes for all the
- * parameters. */
- CK_BBOOL ckfalse = CK_FALSE;
- CK_BBOOL cktrue = CK_TRUE;
- CK_ULONG modulusBits;
- CK_BYTE publicExponent[4];
- CK_ATTRIBUTE privTemplate[] = {
- { CKA_SENSITIVE, NULL, 0},
- { CKA_TOKEN, NULL, 0},
- { CKA_PRIVATE, NULL, 0},
- { CKA_DERIVE, NULL, 0},
- { CKA_UNWRAP, NULL, 0},
- { CKA_SIGN, NULL, 0},
- { CKA_DECRYPT, NULL, 0},
- };
- CK_ATTRIBUTE rsaPubTemplate[] = {
- { CKA_MODULUS_BITS, NULL, 0},
- { CKA_PUBLIC_EXPONENT, NULL, 0},
- { CKA_TOKEN, NULL, 0},
- { CKA_DERIVE, NULL, 0},
- { CKA_WRAP, NULL, 0},
- { CKA_VERIFY, NULL, 0},
- { CKA_VERIFY_RECOVER, NULL, 0},
- { CKA_ENCRYPT, NULL, 0},
- };
- CK_ATTRIBUTE dsaPubTemplate[] = {
- { CKA_PRIME, NULL, 0 },
- { CKA_SUBPRIME, NULL, 0 },
- { CKA_BASE, NULL, 0 },
- { CKA_TOKEN, NULL, 0},
- { CKA_DERIVE, NULL, 0},
- { CKA_WRAP, NULL, 0},
- { CKA_VERIFY, NULL, 0},
- { CKA_VERIFY_RECOVER, NULL, 0},
- { CKA_ENCRYPT, NULL, 0},
- };
- CK_ATTRIBUTE dhPubTemplate[] = {
- { CKA_PRIME, NULL, 0 },
- { CKA_BASE, NULL, 0 },
- { CKA_TOKEN, NULL, 0},
- { CKA_DERIVE, NULL, 0},
- { CKA_WRAP, NULL, 0},
- { CKA_VERIFY, NULL, 0},
- { CKA_VERIFY_RECOVER, NULL, 0},
- { CKA_ENCRYPT, NULL, 0},
- };
-#ifdef NSS_ENABLE_ECC
- CK_ATTRIBUTE ecPubTemplate[] = {
- { CKA_EC_PARAMS, NULL, 0 },
- { CKA_TOKEN, NULL, 0},
- { CKA_DERIVE, NULL, 0},
- { CKA_WRAP, NULL, 0},
- { CKA_VERIFY, NULL, 0},
- { CKA_VERIFY_RECOVER, NULL, 0},
- { CKA_ENCRYPT, NULL, 0},
- };
- int ecPubCount = sizeof(ecPubTemplate)/sizeof(ecPubTemplate[0]);
- SECKEYECParams * ecParams;
-#endif /* NSS_ENABLE_ECC */
-
- int dsaPubCount = sizeof(dsaPubTemplate)/sizeof(dsaPubTemplate[0]);
- /*CK_ULONG key_size = 0;*/
- CK_ATTRIBUTE *pubTemplate;
- int privCount = sizeof(privTemplate)/sizeof(privTemplate[0]);
- int rsaPubCount = sizeof(rsaPubTemplate)/sizeof(rsaPubTemplate[0]);
- int dhPubCount = sizeof(dhPubTemplate)/sizeof(dhPubTemplate[0]);
- int pubCount = 0;
- PK11RSAGenParams *rsaParams;
- SECKEYPQGParams *dsaParams;
- SECKEYDHParams * dhParams;
- CK_MECHANISM mechanism;
- CK_MECHANISM test_mech;
- CK_SESSION_HANDLE session_handle;
- CK_RV crv;
- CK_OBJECT_HANDLE privID,pubID;
- SECKEYPrivateKey *privKey;
- KeyType keyType;
- PRBool restore;
- int peCount,i;
- CK_ATTRIBUTE *attrs;
- CK_ATTRIBUTE *privattrs;
- SECItem *pubKeyIndex;
- CK_ATTRIBUTE setTemplate;
- SECStatus rv;
- CK_MECHANISM_INFO mechanism_info;
- CK_OBJECT_CLASS keyClass;
- SECItem *cka_id;
- PRBool haslock = PR_FALSE;
- PRBool pubIsToken = PR_FALSE;
-
- PORT_Assert(slot != NULL);
- if (slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE);
- return NULL;
- }
-
- /* if our slot really doesn't do this mechanism, Generate the key
- * in our internal token and write it out */
- if (!PK11_DoesMechanism(slot,type)) {
- PK11SlotInfo *int_slot = PK11_GetInternalSlot();
-
- /* don't loop forever looking for a slot */
- if (slot == int_slot) {
- PK11_FreeSlot(int_slot);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
-
- /* if there isn't a suitable slot, then we can't do the keygen */
- if (int_slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
- }
-
- /* generate the temporary key to load */
- privKey = PK11_GenerateKeyPair(int_slot,type, param, pubKey, PR_FALSE,
- PR_FALSE, wincx);
- PK11_FreeSlot(int_slot);
-
- /* if successful, load the temp key into the new token */
- if (privKey != NULL) {
- SECKEYPrivateKey *newPrivKey = pk11_loadPrivKey(slot,privKey,
- *pubKey,token,sensitive);
- SECKEY_DestroyPrivateKey(privKey);
- if (newPrivKey == NULL) {
- SECKEY_DestroyPublicKey(*pubKey);
- *pubKey = NULL;
- }
- return newPrivKey;
- }
- return NULL;
- }
-
-
- mechanism.mechanism = type;
- mechanism.pParameter = NULL;
- mechanism.ulParameterLen = 0;
- test_mech.pParameter = NULL;
- test_mech.ulParameterLen = 0;
-
- /* set up the private key template */
- privattrs = privTemplate;
- PK11_SETATTRS(privattrs, CKA_SENSITIVE, sensitive ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); privattrs++;
- PK11_SETATTRS(privattrs, CKA_TOKEN, token ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); privattrs++;
- PK11_SETATTRS(privattrs, CKA_PRIVATE, sensitive ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); privattrs++;
-
- /* set up the mechanism specific info */
- switch (type) {
- case CKM_RSA_PKCS_KEY_PAIR_GEN:
- rsaParams = (PK11RSAGenParams *)param;
- modulusBits = rsaParams->keySizeInBits;
- peCount = 0;
-
- /* convert pe to a PKCS #11 string */
- for (i=0; i < 4; i++) {
- if (peCount || (rsaParams->pe &
- ((unsigned long)0xff000000L >> (i*8)))) {
- publicExponent[peCount] =
- (CK_BYTE)((rsaParams->pe >> (3-i)*8) & 0xff);
- peCount++;
- }
- }
- PORT_Assert(peCount != 0);
- attrs = rsaPubTemplate;
- PK11_SETATTRS(attrs, CKA_MODULUS_BITS,
- &modulusBits, sizeof(modulusBits)); attrs++;
- PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT,
- publicExponent, peCount);attrs++;
- pubTemplate = rsaPubTemplate;
- pubCount = rsaPubCount;
- keyType = rsaKey;
- test_mech.mechanism = CKM_RSA_PKCS;
- break;
- case CKM_DSA_KEY_PAIR_GEN:
- dsaParams = (SECKEYPQGParams *)param;
- attrs = dsaPubTemplate;
- PK11_SETATTRS(attrs, CKA_PRIME, dsaParams->prime.data,
- dsaParams->prime.len); attrs++;
- PK11_SETATTRS(attrs, CKA_SUBPRIME, dsaParams->subPrime.data,
- dsaParams->subPrime.len); attrs++;
- PK11_SETATTRS(attrs, CKA_BASE, dsaParams->base.data,
- dsaParams->base.len); attrs++;
- pubTemplate = dsaPubTemplate;
- pubCount = dsaPubCount;
- keyType = dsaKey;
- test_mech.mechanism = CKM_DSA;
- break;
- case CKM_DH_PKCS_KEY_PAIR_GEN:
- dhParams = (SECKEYDHParams *)param;
- attrs = dhPubTemplate;
- PK11_SETATTRS(attrs, CKA_PRIME, dhParams->prime.data,
- dhParams->prime.len); attrs++;
- PK11_SETATTRS(attrs, CKA_BASE, dhParams->base.data,
- dhParams->base.len); attrs++;
- pubTemplate = dhPubTemplate;
- pubCount = dhPubCount;
- keyType = dhKey;
- test_mech.mechanism = CKM_DH_PKCS_DERIVE;
- break;
-#ifdef NSS_ENABLE_ECC
- case CKM_EC_KEY_PAIR_GEN:
- ecParams = (SECKEYECParams *)param;
- attrs = ecPubTemplate;
- PK11_SETATTRS(attrs, CKA_EC_PARAMS, ecParams->data,
- ecParams->len); attrs++;
- pubTemplate = ecPubTemplate;
- pubCount = ecPubCount;
- keyType = ecKey;
- /* XXX An EC key can be used for other mechanisms too such
- * as CKM_ECDSA and CKM_ECDSA_SHA1. How can we reflect
- * that in test_mech.mechanism so the CKA_SIGN, CKA_VERIFY
- * attributes are set correctly?
- */
- test_mech.mechanism = CKM_ECDH1_DERIVE;
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- PORT_SetError( SEC_ERROR_BAD_KEY );
- return NULL;
- }
-
- /* now query the slot to find out how "good" a key we can generate */
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
- test_mech.mechanism,&mechanism_info);
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- if ((crv != CKR_OK) || (mechanism_info.flags == 0)) {
- /* must be old module... guess what it should be... */
- switch (test_mech.mechanism) {
- case CKM_RSA_PKCS:
- mechanism_info.flags = (CKF_SIGN | CKF_DECRYPT |
- CKF_WRAP | CKF_VERIFY_RECOVER | CKF_ENCRYPT | CKF_WRAP);;
- break;
- case CKM_DSA:
- mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
- break;
- case CKM_DH_PKCS_DERIVE:
- mechanism_info.flags = CKF_DERIVE;
- break;
-#ifdef NSS_ENABLE_ECC
- case CKM_ECDH1_DERIVE:
- mechanism_info.flags = CKF_DERIVE;
- break;
- case CKM_ECDSA:
- case CKM_ECDSA_SHA1:
- mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- break;
- }
- }
- /* set the public key objects */
- PK11_SETATTRS(attrs, CKA_TOKEN, token ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); attrs++;
- PK11_SETATTRS(attrs, CKA_DERIVE,
- mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); attrs++;
- PK11_SETATTRS(attrs, CKA_WRAP,
- mechanism_info.flags & CKF_WRAP ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); attrs++;
- PK11_SETATTRS(attrs, CKA_VERIFY,
- mechanism_info.flags & CKF_VERIFY ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); attrs++;
- PK11_SETATTRS(attrs, CKA_VERIFY_RECOVER,
- mechanism_info.flags & CKF_VERIFY_RECOVER ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); attrs++;
- PK11_SETATTRS(attrs, CKA_ENCRYPT,
- mechanism_info.flags & CKF_ENCRYPT? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); attrs++;
- PK11_SETATTRS(privattrs, CKA_DERIVE,
- mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); privattrs++;
- PK11_SETATTRS(privattrs, CKA_UNWRAP,
- mechanism_info.flags & CKF_UNWRAP ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); privattrs++;
- PK11_SETATTRS(privattrs, CKA_SIGN,
- mechanism_info.flags & CKF_SIGN ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); privattrs++;
- PK11_SETATTRS(privattrs, CKA_DECRYPT,
- mechanism_info.flags & CKF_DECRYPT ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); privattrs++;
+ PK11AttrFlags attrFlags = 0;
if (token) {
- session_handle = PK11_GetRWSession(slot);
- haslock = PK11_RWSessionHasLock(slot,session_handle);
- restore = PR_TRUE;
+ attrFlags |= PK11_ATTR_TOKEN;
} else {
- PK11_EnterSlotMonitor(slot); /* gross!! */
- session_handle = slot->session;
- restore = PR_FALSE;
- haslock = PR_TRUE;
- }
-
- crv = PK11_GETTAB(slot)->C_GenerateKeyPair(session_handle, &mechanism,
- pubTemplate,pubCount,privTemplate,privCount,&pubID,&privID);
-
- if (crv != CKR_OK) {
- if (restore) {
- PK11_RestoreROSession(slot,session_handle);
- } else PK11_ExitSlotMonitor(slot);
- PORT_SetError( PK11_MapError(crv) );
- return NULL;
- }
- /* This locking code is dangerous and needs to be more thought
- * out... the real problem is that we're holding the mutex open this long
- */
- if (haslock) { PK11_ExitSlotMonitor(slot); }
-
- /* swap around the ID's for older PKCS #11 modules */
- keyClass = PK11_ReadULongAttribute(slot,pubID,CKA_CLASS);
- if (keyClass != CKO_PUBLIC_KEY) {
- CK_OBJECT_HANDLE tmp = pubID;
- pubID = privID;
- privID = tmp;
- }
-
- *pubKey = PK11_ExtractPublicKey(slot, keyType, pubID);
- if (*pubKey == NULL) {
- if (restore) {
- /* we may have to restore the mutex so it get's exited properly
- * in RestoreROSession */
- if (haslock) PK11_EnterSlotMonitor(slot);
- PK11_RestoreROSession(slot,session_handle);
- }
- PK11_DestroyObject(slot,pubID);
- PK11_DestroyObject(slot,privID);
- return NULL;
- }
-
- /* set the ID to the public key so we can find it again */
- pubKeyIndex = NULL;
- switch (type) {
- case CKM_RSA_PKCS_KEY_PAIR_GEN:
- pubKeyIndex = &(*pubKey)->u.rsa.modulus;
- break;
- case CKM_DSA_KEY_PAIR_GEN:
- pubKeyIndex = &(*pubKey)->u.dsa.publicValue;
- break;
- case CKM_DH_PKCS_KEY_PAIR_GEN:
- pubKeyIndex = &(*pubKey)->u.dh.publicValue;
- break;
-#ifdef NSS_ENABLE_ECC
- case CKM_EC_KEY_PAIR_GEN:
- pubKeyIndex = &(*pubKey)->u.ec.publicValue;
- break;
-#endif /* NSS_ENABLE_ECC */
- }
- PORT_Assert(pubKeyIndex != NULL);
-
- cka_id = PK11_MakeIDFromPubKey(pubKeyIndex);
- pubIsToken = (PRBool)PK11_HasAttributeSet(slot,pubID, CKA_TOKEN);
-
- PK11_SETATTRS(&setTemplate, CKA_ID, cka_id->data, cka_id->len);
-
- if (haslock) { PK11_EnterSlotMonitor(slot); }
- crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, privID,
- &setTemplate, 1);
-
- if (crv == CKR_OK && pubIsToken) {
- crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, pubID,
- &setTemplate, 1);
+ attrFlags |= PK11_ATTR_SESSION;
}
-
-
- if (restore) {
- PK11_RestoreROSession(slot,session_handle);
+ if (sensitive) {
+ attrFlags |= (PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE);
} else {
- PK11_ExitSlotMonitor(slot);
+ attrFlags |= (PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC);
}
- SECITEM_FreeItem(cka_id,PR_TRUE);
-
-
- if (crv != CKR_OK) {
- PK11_DestroyObject(slot,pubID);
- PK11_DestroyObject(slot,privID);
- PORT_SetError( PK11_MapError(crv) );
- *pubKey = NULL;
- return NULL;
- }
-
- privKey = PK11_MakePrivKey(slot,keyType,(PRBool)!token,privID,wincx);
- if (privKey == NULL) {
- SECKEY_DestroyPublicKey(*pubKey);
- PK11_DestroyObject(slot,privID);
- *pubKey = NULL;
- return NULL; /* due to pairwise consistency check */
- }
-
- /* Perform PKCS #11 pairwise consistency check. */
- rv = pk11_PairwiseConsistencyCheck( *pubKey, privKey, &test_mech, wincx );
- if( rv != SECSuccess ) {
- SECKEY_DestroyPublicKey( *pubKey );
- SECKEY_DestroyPrivateKey( privKey );
- *pubKey = NULL;
- privKey = NULL;
- return NULL;
- }
-
- return privKey;
+ return PK11_GenerateKeyPairWithFlags(slot, type, param, pubKey,
+ attrFlags, wincx);
}
/* build a public KEA key from the public value */
@@ -1941,9 +1162,7 @@ PK11_ImportEncryptedPrivateKeyInfo(PK11SlotInfo *slot,
CKA_UNWRAP, CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER };
CK_ATTRIBUTE_TYPE dsaUsage[] = { CKA_SIGN };
CK_ATTRIBUTE_TYPE dhUsage[] = { CKA_DERIVE };
-#ifdef NSS_ENABLE_ECC
CK_ATTRIBUTE_TYPE ecUsage[] = { CKA_SIGN, CKA_DERIVE };
-#endif /* NSS_ENABLE_ECC */
if((epki == NULL) || (pwitem == NULL))
return SECFailure;
@@ -1982,7 +1201,6 @@ PK11_ImportEncryptedPrivateKeyInfo(PK11SlotInfo *slot,
usage = dsaUsage;
usageCount = sizeof(dsaUsage)/sizeof(dsaUsage[0]);
break;
-#ifdef NSS_ENABLE_ECC
case ecKey:
key_type = CKK_EC;
switch (keyUsage & (KU_DIGITAL_SIGNATURE|KU_KEY_AGREEMENT)) {
@@ -2001,7 +1219,6 @@ PK11_ImportEncryptedPrivateKeyInfo(PK11SlotInfo *slot,
break;
}
break;
-#endif /* NSS_ENABLE_ECC */
}
try_faulty_3des:
@@ -2102,7 +1319,6 @@ pk11_private_key_encrypt_buffer_length(SECKEYPrivateKey *key)
{
CK_ATTRIBUTE rsaTemplate = { CKA_MODULUS, NULL, 0 };
CK_ATTRIBUTE dsaTemplate = { CKA_PRIME, NULL, 0 };
-#ifdef NSS_ENABLE_ECC
/* XXX We should normally choose an attribute such that
* factor times its size is enough to hold the private key.
* For EC keys, we have no choice but to use CKA_EC_PARAMS,
@@ -2111,7 +1327,6 @@ pk11_private_key_encrypt_buffer_length(SECKEYPrivateKey *key)
* is quite small so we bump up factor from 10 to 15.
*/
CK_ATTRIBUTE ecTemplate = { CKA_EC_PARAMS, NULL, 0 };
-#endif /* NSS_ENABLE_ECC */
CK_ATTRIBUTE_PTR pTemplate;
CK_RV crv;
int length;
@@ -2129,12 +1344,10 @@ pk11_private_key_encrypt_buffer_length(SECKEYPrivateKey *key)
case dhKey:
pTemplate = &dsaTemplate;
break;
-#ifdef NSS_ENABLE_ECC
case ecKey:
pTemplate = &ecTemplate;
factor = 15;
break;
-#endif /* NSS_ENABLE_ECC */
case fortezzaKey:
default:
pTemplate = NULL;
@@ -2447,6 +1660,46 @@ loser:
}
SECKEYPrivateKey*
+PK11_CopyTokenPrivKeyToSessionPrivKey(PK11SlotInfo *destSlot,
+ SECKEYPrivateKey *privKey)
+{
+ CK_RV crv;
+ CK_OBJECT_HANDLE newKeyID;
+
+ static const CK_BBOOL ckfalse = CK_FALSE;
+ static const CK_ATTRIBUTE template[1] = {
+ { CKA_TOKEN, (CK_BBOOL *)&ckfalse, sizeof ckfalse }
+ };
+
+ if (destSlot && destSlot != privKey->pkcs11Slot) {
+ SECKEYPrivateKey *newKey =
+ pk11_loadPrivKey(destSlot,
+ privKey,
+ NULL, /* pubKey */
+ PR_FALSE, /* token */
+ PR_FALSE);/* sensitive */
+ if (newKey)
+ return newKey;
+ }
+ destSlot = privKey->pkcs11Slot;
+ PK11_Authenticate(destSlot, PR_TRUE, privKey->wincx);
+ PK11_EnterSlotMonitor(destSlot);
+ crv = PK11_GETTAB(destSlot)->C_CopyObject( destSlot->session,
+ privKey->pkcs11ID,
+ (CK_ATTRIBUTE *)template,
+ 1, &newKeyID);
+ PK11_ExitSlotMonitor(destSlot);
+
+ if (crv != CKR_OK) {
+ PORT_SetError( PK11_MapError(crv) );
+ return NULL;
+ }
+
+ return PK11_MakePrivKey(destSlot, privKey->keyType, PR_TRUE /*isTemp*/,
+ newKeyID, privKey->wincx);
+}
+
+SECKEYPrivateKey*
PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey *privk, void* wincx)
{
PK11SlotInfo* slot = privk->pkcs11Slot;
@@ -2461,6 +1714,10 @@ PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey *privk, void* wincx)
PK11_Authenticate(slot, PR_TRUE, wincx);
rwsession = PK11_GetRWSession(slot);
+ if (rwsession == CK_INVALID_SESSION) {
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return NULL;
+ }
crv = PK11_GETTAB(slot)->C_CopyObject(rwsession, privk->pkcs11ID,
template, 1, &newKeyID);
PK11_RestoreROSession(slot, rwsession);
@@ -2473,6 +1730,7 @@ PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey *privk, void* wincx)
return PK11_MakePrivKey(slot, nullKey /*KeyType*/, PR_FALSE /*isTemp*/,
newKeyID, NULL /*wincx*/);
}
+
/*
* destroy a private key if there are no matching certs.
* this function also frees the privKey structure.
diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c
index aa8ad695f..08c0af2db 100644
--- a/security/nss/lib/pk11wrap/pk11cert.c
+++ b/security/nss/lib/pk11wrap/pk11cert.c
@@ -191,11 +191,9 @@ PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert,
pubKey->u.dh.publicValue.len);
break;
case ecKey:
-#ifdef NSS_ENABLE_ECC
PK11_SETATTRS(&theTemplate,CKA_EC_POINT,
pubKey->u.ec.publicValue.data,
pubKey->u.ec.publicValue.len);
-#endif /* NSS_ENABLE_ECC */
break;
case keaKey:
case fortezzaKey:
@@ -432,12 +430,8 @@ PK11_DeleteTokenCertAndKey(CERTCertificate *cert,void *wincx)
pubKey = pk11_FindPubKeyByAnyCert(cert, &slot, wincx);
if (privKey) {
-#ifdef NSS_CLASSIC
- PK11_DestroyTokenObject(cert->slot,cert->pkcs11ID);
-#else
/* For 3.4, utilize the generic cert delete function */
SEC_DeletePermCertificate(cert);
-#endif
PK11_DeleteTokenPrivateKey(privKey, PR_FALSE);
}
if ((pubKey != CK_INVALID_HANDLE) && (slot != NULL)) {
@@ -457,39 +451,6 @@ typedef struct pk11DoCertCallbackStr {
void *callbackArg;
} pk11DoCertCallback;
-#ifdef NSS_CLASSIC
-/*
- * callback to map object handles to certificate structures.
- */
-static SECStatus
-pk11_DoCerts(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID, void *arg)
-{
- CERTCertificate *cert;
- pk11DoCertCallback *certcb = (pk11DoCertCallback *) arg;
-
- cert = PK11_MakeCertFromHandle(slot, certID, NULL);
-
- if (cert == NULL) {
- return SECFailure;
- }
-
- if (certcb ) {
- if (certcb->callback) {
- (*certcb->callback)(slot, cert, certcb->callbackArg);
- }
- if (certcb->noslotcallback) {
- (*certcb->noslotcallback)(cert, certcb->callbackArg);
- }
- if (certcb->itemcallback) {
- (*certcb->itemcallback)(cert, NULL, certcb->callbackArg);
- }
- }
-
- CERT_DestroyCertificate(cert);
-
- return SECSuccess;
-}
-#endif
typedef struct pk11CertCallbackStr {
SECStatus(* callback)(CERTCertificate*,SECItem *,void *);
@@ -513,26 +474,8 @@ static SECStatus fake_der_cb(CERTCertificate *c, void *a)
*/
SECStatus
PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *),
- void *arg, void *wincx) {
-#ifdef NSS_CLASSIC
- pk11DoCertCallback caller;
- pk11TraverseSlot creater;
- CK_ATTRIBUTE theTemplate;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
-
- PK11_SETATTRS(&theTemplate, CKA_CLASS, &certClass, sizeof(certClass));
-
- caller.callback = NULL;
- caller.noslotcallback = NULL;
- caller.itemcallback = callback;
- caller.callbackArg = arg;
- creater.callback = pk11_DoCerts;
- creater.callbackArg = (void *) & caller;
- creater.findTemplate = &theTemplate;
- creater.templateCount = 1;
-
- return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, wincx);
-#else
+ void *arg, void *wincx)
+{
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
struct fake_der_cb_argstr fda;
struct nss3_cert_cbstr pk11cb;
@@ -546,7 +489,6 @@ PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *),
pk11cb.arg = &fda;
NSSTrustDomain_TraverseCertificates(defaultTD, convert_cert, &pk11cb);
return SECSuccess;
-#endif
}
static void
@@ -584,19 +526,6 @@ transfer_token_certs_to_collection(nssList *certList, NSSToken *token,
CERTCertificate *
PK11_FindCertFromNickname(char *nickname, void *wincx)
{
-#ifdef NSS_CLASSIC
- PK11SlotInfo *slot;
- int count=0;
- CK_OBJECT_HANDLE *certID = PK11_FindObjectsFromNickname(nickname,&slot,
- CKO_CERTIFICATE, &count, wincx);
- CERTCertificate *cert;
-
- if (certID == CK_INVALID_HANDLE) return NULL;
- cert = PK11_MakeCertFromHandle(slot,certID[0],NULL);
- PK11_FreeSlot(slot);
- PORT_Free(certID);
- return cert;
-#else
PRStatus status;
CERTCertificate *rvCert = NULL;
NSSCertificate *cert = NULL;
@@ -703,36 +632,11 @@ loser:
}
if (nickCopy) PORT_Free(nickCopy);
return NULL;
-#endif
}
CERTCertList *
-PK11_FindCertsFromNickname(char *nickname, void *wincx) {
-#ifdef NSS_CLASSIC
- PK11SlotInfo *slot;
- int i,count = 0;
- CK_OBJECT_HANDLE *certID = PK11_FindObjectsFromNickname(nickname,&slot,
- CKO_CERTIFICATE, &count, wincx);
- CERTCertList *certList = NULL;
-
- if (certID == NULL) return NULL;
-
- certList= CERT_NewCertList();
-
- for (i=0; i < count; i++) {
- CERTCertificate *cert = PK11_MakeCertFromHandle(slot,certID[i],NULL);
-
- if (cert) CERT_AddCertToListTail(certList,cert);
- }
-
- if (CERT_LIST_HEAD(certList) == NULL) {
- CERT_DestroyCertList(certList);
- certList = NULL;
- }
- PK11_FreeSlot(slot);
- PORT_Free(certID);
- return certList;
-#else
+PK11_FindCertsFromNickname(char *nickname, void *wincx)
+{
char *nickCopy;
char *delimit = NULL;
char *tokenName;
@@ -827,7 +731,6 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
nss_ZFreeIf(foundCerts);
}
return certList;
-#endif
}
/*
@@ -854,9 +757,7 @@ PK11_GetPubIndexKeyID(CERTCertificate *cert) {
newItem = SECITEM_DupItem(&pubk->u.dh.publicValue);
break;
case ecKey:
-#ifdef NSS_ENABLE_ECC
newItem = SECITEM_DupItem(&pubk->u.ec.publicValue);
-#endif /* NSS_ENABLE_ECC */
break;
case fortezzaKey:
default:
@@ -889,154 +790,6 @@ SECStatus
PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
CK_OBJECT_HANDLE key, char *nickname, PRBool includeTrust)
{
-#ifdef NSS_CLASSIC
- int len = 0;
- SECItem *keyID = pk11_mkcertKeyID(cert);
- CK_ATTRIBUTE keyAttrs[] = {
- { CKA_LABEL, NULL, 0},
- { CKA_SUBJECT, NULL, 0},
- };
- CK_OBJECT_CLASS certc = CKO_CERTIFICATE;
- CK_CERTIFICATE_TYPE certType = CKC_X_509;
- CK_OBJECT_HANDLE certID;
- CK_SESSION_HANDLE rwsession;
- CK_BBOOL cktrue = CK_TRUE;
- SECStatus rv = SECFailure;
- CK_ATTRIBUTE certAttrs[] = {
- { CKA_ID, NULL, 0 },
- { CKA_LABEL, NULL, 0},
- { CKA_CLASS, NULL, 0},
- { CKA_TOKEN, NULL, 0},
- { CKA_CERTIFICATE_TYPE, NULL, 0},
- { CKA_SUBJECT, NULL, 0},
- { CKA_ISSUER, NULL, 0},
- { CKA_SERIAL_NUMBER, NULL, 0},
- { CKA_VALUE, NULL, 0},
- { CKA_NETSCAPE_TRUST, NULL, 0},
- { CKA_NETSCAPE_EMAIL, NULL, 0},
- };
- int certCount = sizeof(certAttrs)/sizeof(certAttrs[0]), keyCount = 2;
- int realCount = 0;
- CK_ATTRIBUTE *attrs;
- CK_RV crv;
- SECCertUsage *certUsage = NULL;
- SECItem derSerial = { 0 };
- NSSToken *token;
-
- if (keyID == NULL) {
- PORT_SetError(SEC_ERROR_ADDING_CERT);
- return rv;
- }
-
- len = ((nickname) ? PORT_Strlen(nickname) : 0);
-
- attrs = certAttrs;
- PK11_SETATTRS(attrs,CKA_ID, keyID->data, keyID->len); attrs++;
- if (nickname) {
- PK11_SETATTRS(attrs,CKA_LABEL, nickname, len ); attrs++;
- }
- PK11_SETATTRS(attrs,CKA_CLASS, &certc, sizeof(certc) ); attrs++;
- PK11_SETATTRS(attrs,CKA_TOKEN, &cktrue, sizeof(cktrue) ); attrs++;
- PK11_SETATTRS(attrs,CKA_CERTIFICATE_TYPE, &certType,
- sizeof(certType)); attrs++;
- PK11_SETATTRS(attrs,CKA_SUBJECT, cert->derSubject.data,
- cert->derSubject.len ); attrs++;
- PK11_SETATTRS(attrs,CKA_ISSUER, cert->derIssuer.data,
- cert->derIssuer.len ); attrs++;
- if (PR_TRUE) {
- /* CERTCertificate stores serial numbers decoded. I need the DER
- * here. sigh.
- */
- CERT_SerialNumberFromDERCert(&cert->derCert, &derSerial);
- PK11_SETATTRS(attrs,CKA_SERIAL_NUMBER, derSerial.data, derSerial.len);
- attrs++;
- }
- PK11_SETATTRS(attrs,CKA_VALUE, cert->derCert.data,
- cert->derCert.len); attrs++;
- if (includeTrust && PK11_IsInternal(slot)) {
- certUsage = (SECCertUsage*)PORT_Alloc(sizeof(SECCertUsage));
- if(!certUsage) {
- SECITEM_FreeItem(keyID,PR_TRUE);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return rv;
- }
- *certUsage = certUsageUserCertImport;
- PK11_SETATTRS(attrs,CKA_NETSCAPE_TRUST, certUsage,
- sizeof(SECCertUsage));
- attrs++;
- if (cert->emailAddr && cert->emailAddr[0]) {
- PK11_SETATTRS(attrs,CKA_NETSCAPE_EMAIL, cert->emailAddr,
- PORT_Strlen(cert->emailAddr);
- attrs++;
- }
- }
- realCount = attrs - certAttrs;
- PORT_Assert(realCount <= certCount);
-
- attrs = keyAttrs;
- if(nickname) {
- PK11_SETATTRS(attrs,CKA_LABEL, nickname, len ); attrs++;
- }
- PK11_SETATTRS(attrs,CKA_SUBJECT, cert->derSubject.data,
- cert->derSubject.len );
-
- if(!nickname) {
- certCount--;
- keyCount--;
- }
-
- rwsession = PK11_GetRWSession(slot);
- if (key != CK_INVALID_HANDLE) {
- crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession,key,keyAttrs,
- keyCount);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- goto done;
- }
- }
-
- crv = PK11_GETTAB(slot)->
- C_CreateObject(rwsession,certAttrs,realCount,&certID);
- if (crv == CKR_OK) {
- rv = SECSuccess;
- } else {
- PORT_SetError( PK11_MapError(crv) );
- }
-
- if (!cert->nickname && nickname) {
- cert->nickname = PORT_ArenaStrdup(cert->arena, nickname);
- }
-
- cert->pkcs11ID = certID;
- cert->dbhandle = STAN_GetDefaultTrustDomain();
- if (cert->slot == NULL) {
- cert->slot = PK11_ReferenceSlot(slot);
- cert->series = slot->series;
- cert->ownSlot = PR_TRUE;
- if (cert->nssCertificate) {
- nssCryptokiInstance *instance;
- NSSCertificate *c = cert->nssCertificate;
- instance = nss_ZNEW(c->object.arena, nssCryptokiInstance);
- instance->token = slot->nssToken;
- instance->handle = cert->pkcs11ID;
- instance->isTokenObject = PR_TRUE;
- nssPKIObject_AddInstance(&c->object, instance);
- } else {
- cert->nssCertificate = STAN_GetNSSCertificate(cert);
- }
- }
- cert->trust = nssTrust_GetCERTCertTrustForCert(cert->nssCertificate, cert);
- token = PK11Slot_GetNSSToken(slot);
-
-done:
- if (derSerial.data) PORT_Free(derSerial.data);
- SECITEM_FreeItem(keyID,PR_TRUE);
- PK11_RestoreROSession(slot,rwsession);
- if(certUsage) {
- PORT_Free(certUsage);
- }
- return rv;
-#else
PRStatus status;
NSSCertificate *c;
nssCryptokiObject *keyobj, *certobj;
@@ -1126,7 +879,6 @@ loser:
SECITEM_FreeItem(keyID,PR_TRUE);
PORT_SetError(SEC_ERROR_ADDING_CERT);
return SECFailure;
-#endif
}
SECStatus
@@ -1704,36 +1456,6 @@ CERTCertificate *
PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN,
void *wincx)
{
-#ifdef NSS_CLASSIC
- CK_OBJECT_HANDLE certHandle;
- CERTCertificate *cert = NULL;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- CK_ATTRIBUTE searchTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_ISSUER, NULL, 0 },
- { CKA_SERIAL_NUMBER, NULL, 0}
- };
- int count = sizeof(searchTemplate)/sizeof(CK_ATTRIBUTE);
- CK_ATTRIBUTE *attrs = searchTemplate;
-
- PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); attrs++;
- PK11_SETATTRS(attrs, CKA_ISSUER, issuerSN->derIssuer.data,
- issuerSN->derIssuer.len); attrs++;
- PK11_SETATTRS(attrs, CKA_SERIAL_NUMBER, issuerSN->serialNumber.data,
- issuerSN->serialNumber.len);
-
- certHandle = pk11_FindCertObjectByTemplate
- (slotPtr,searchTemplate,count,wincx);
- if (certHandle == CK_INVALID_HANDLE) {
- return NULL;
- }
- cert = PK11_MakeCertFromHandle(*slotPtr,certHandle,NULL);
- if (cert == NULL) {
- PK11_FreeSlot(*slotPtr);
- return NULL;
- }
- return cert;
-#else
CERTCertificate *rvCert = NULL;
NSSCertificate *cert;
NSSDER issuer, serial;
@@ -1792,7 +1514,6 @@ PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN,
SECITEM_FreeItem(derSerial, PR_TRUE);
return rvCert;
-#endif
}
CK_OBJECT_HANDLE
@@ -1940,34 +1661,6 @@ SECStatus
PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
SECStatus(* callback)(CERTCertificate*, void *), void *arg)
{
-#ifdef NSS_CLASSIC
- pk11DoCertCallback caller;
- pk11TraverseSlot callarg;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 },
- };
- CK_ATTRIBUTE *attr = theTemplate;
- int templateSize = sizeof(theTemplate)/sizeof(theTemplate[0]);
-
- PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
- PK11_SETATTRS(attr,CKA_SUBJECT,cert->derSubject.data,cert->derSubject.len);
-
- if (slot == NULL) {
- return SECSuccess;
- }
- caller.noslotcallback = callback;
- caller.callback = NULL;
- caller.itemcallback = NULL;
- caller.callbackArg = arg;
- callarg.callback = pk11_DoCerts;
- callarg.callbackArg = (void *) & caller;
- callarg.findTemplate = theTemplate;
- callarg.templateCount = templateSize;
-
- return PK11_TraverseSlot(slot, &callarg);
-#else
PRStatus nssrv = PR_SUCCESS;
NSSToken *token;
NSSDER subject;
@@ -2020,46 +1713,12 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
nssCertificateArray_Destroy(certs);
}
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
-#endif
}
SECStatus
PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
SECStatus(* callback)(CERTCertificate*, void *), void *arg)
{
-#ifdef NSS_CLASSIC
- pk11DoCertCallback caller;
- pk11TraverseSlot callarg;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_LABEL, NULL, 0 },
- };
- CK_ATTRIBUTE *attr = theTemplate;
- int templateSize = sizeof(theTemplate)/sizeof(theTemplate[0]);
-
- if(!nickname) {
- return SECSuccess;
- }
-
- PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
- PK11_SETATTRS(attr,CKA_LABEL,nickname->data,nickname->len);
-
- if (slot == NULL) {
- return SECSuccess;
- }
-
- caller.noslotcallback = callback;
- caller.callback = NULL;
- caller.itemcallback = NULL;
- caller.callbackArg = arg;
- callarg.callback = pk11_DoCerts;
- callarg.callbackArg = (void *) & caller;
- callarg.findTemplate = theTemplate;
- callarg.templateCount = templateSize;
-
- return PK11_TraverseSlot(slot, &callarg);
-#else
struct nss3_cert_cbstr pk11cb;
PRStatus nssrv = PR_SUCCESS;
NSSToken *token;
@@ -2132,39 +1791,12 @@ loser:
nssList_Destroy(nameList);
}
return SECFailure;
-#endif
}
SECStatus
PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
SECStatus(* callback)(CERTCertificate*, void *), void *arg)
{
-#ifdef NSS_CLASSIC
- pk11DoCertCallback caller;
- pk11TraverseSlot callarg;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- };
- CK_ATTRIBUTE *attr = theTemplate;
- int templateSize = sizeof(theTemplate)/sizeof(theTemplate[0]);
-
- PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
-
- if (slot == NULL) {
- return SECSuccess;
- }
-
- caller.noslotcallback = callback;
- caller.callback = NULL;
- caller.itemcallback = NULL;
- caller.callbackArg = arg;
- callarg.callback = pk11_DoCerts;
- callarg.callbackArg = (void *) & caller;
- callarg.findTemplate = theTemplate;
- callarg.templateCount = templateSize;
- return PK11_TraverseSlot(slot, &callarg);
-#else
PRStatus nssrv;
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
NSSToken *tok;
@@ -2212,7 +1844,6 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
nssCertificateArray_Destroy(certs);
}
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
-#endif
}
/*
@@ -2645,22 +2276,6 @@ pk11ListCertCallback(NSSCertificate *c, void *arg)
CERTCertList *
PK11_ListCerts(PK11CertListType type, void *pwarg)
{
-#ifdef NSS_CLASSIC
- CERTCertList *certList = NULL;
- struct listCertsStr listCerts;
-
- certList= CERT_NewCertList();
- listCerts.type = type;
- listCerts.certList = certList;
-
- PK11_TraverseSlotCerts(pk11ListCertCallback,&listCerts,pwarg);
-
- if (CERT_LIST_HEAD(certList) == NULL) {
- CERT_DestroyCertList(certList);
- certList = NULL;
- }
- return certList;
-#else
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
CERTCertList *certList = NULL;
struct listCertsStr listCerts;
@@ -2673,7 +2288,6 @@ PK11_ListCerts(PK11CertListType type, void *pwarg)
NSSTrustDomain_TraverseCertificates(defaultTD, pk11ListCertCallback,
&listCerts);
return certList;
-#endif
}
SECItem *
diff --git a/security/nss/lib/pk11wrap/pk11err.c b/security/nss/lib/pk11wrap/pk11err.c
index 28559d8d8..a63475636 100644
--- a/security/nss/lib/pk11wrap/pk11err.c
+++ b/security/nss/lib/pk11wrap/pk11err.c
@@ -95,8 +95,8 @@ PK11_MapError(CK_RV rv) {
MAPERROR(CKR_OPERATION_ACTIVE, SEC_ERROR_LIBRARY_FAILURE)
MAPERROR(CKR_OPERATION_NOT_INITIALIZED,SEC_ERROR_LIBRARY_FAILURE )
MAPERROR(CKR_PIN_INCORRECT, SEC_ERROR_BAD_PASSWORD)
- MAPERROR(CKR_PIN_INVALID, SEC_ERROR_BAD_PASSWORD)
- MAPERROR(CKR_PIN_LEN_RANGE, SEC_ERROR_BAD_PASSWORD)
+ MAPERROR(CKR_PIN_INVALID, SEC_ERROR_INVALID_PASSWORD)
+ MAPERROR(CKR_PIN_LEN_RANGE, SEC_ERROR_INVALID_PASSWORD)
MAPERROR(CKR_SESSION_CLOSED, SEC_ERROR_LIBRARY_FAILURE)
MAPERROR(CKR_SESSION_COUNT, SEC_ERROR_NO_MEMORY) /* XXXX? */
MAPERROR(CKR_SESSION_HANDLE_INVALID, SEC_ERROR_BAD_DATA)
@@ -124,7 +124,7 @@ PK11_MapError(CK_RV rv) {
MAPERROR(CKR_VENDOR_DEFINED, SEC_ERROR_LIBRARY_FAILURE)
MAPERROR(CKR_NETSCAPE_CERTDB_FAILED, SEC_ERROR_BAD_DATABASE)
MAPERROR(CKR_NETSCAPE_KEYDB_FAILED, SEC_ERROR_BAD_DATABASE)
-
+ MAPERROR(CKR_CANT_LOCK, SEC_ERROR_INCOMPATIBLE_PKCS11)
#ifdef PK11_ERROR_USE_ARRAY
};
diff --git a/security/nss/lib/pk11wrap/pk11load.c b/security/nss/lib/pk11wrap/pk11load.c
index 6017361ae..d0d305eb4 100644
--- a/security/nss/lib/pk11wrap/pk11load.c
+++ b/security/nss/lib/pk11wrap/pk11load.c
@@ -45,6 +45,7 @@
#include "secmodi.h"
#include "secmodti.h"
#include "nssilock.h"
+#include "secerr.h"
extern void FC_GetFunctionList(void);
extern void NSC_GetFunctionList(void);
@@ -90,16 +91,53 @@ static const CK_C_INITIALIZE_ARGS secmodLockFunctions = {
,NULL
};
+static PRBool loadSingleThreadedModules = PR_TRUE;
+static PRBool enforceAlreadyInitializedError = PR_TRUE;
+static PRBool finalizeModules = PR_TRUE;
+
+/* set global options for NSS PKCS#11 module loader */
+SECStatus pk11_setGlobalOptions(PRBool noSingleThreadedModules,
+ PRBool allowAlreadyInitializedModules,
+ PRBool dontFinalizeModules)
+{
+ if (noSingleThreadedModules) {
+ loadSingleThreadedModules = PR_FALSE;
+ } else {
+ loadSingleThreadedModules = PR_TRUE;
+ }
+ if (allowAlreadyInitializedModules) {
+ enforceAlreadyInitializedError = PR_FALSE;
+ } else {
+ enforceAlreadyInitializedError = PR_TRUE;
+ }
+ if (dontFinalizeModules) {
+ finalizeModules = PR_FALSE;
+ } else {
+ finalizeModules = PR_TRUE;
+ }
+ return SECSuccess;
+}
+
+PRBool pk11_getFinalizeModulesOption(void)
+{
+ return finalizeModules;
+}
+
/*
* collect the steps we need to initialize a module in a single function
*/
SECStatus
-secmod_ModuleInit(SECMODModule *mod)
+secmod_ModuleInit(SECMODModule *mod, PRBool* alreadyLoaded)
{
CK_C_INITIALIZE_ARGS moduleArgs;
CK_VOID_PTR pInitArgs;
CK_RV crv;
+ if (!mod || !alreadyLoaded) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
if (mod->isThreadSafe == PR_FALSE) {
pInitArgs = NULL;
} else if (mod->libraryParams == NULL) {
@@ -110,6 +148,11 @@ secmod_ModuleInit(SECMODModule *mod)
pInitArgs = &moduleArgs;
}
crv = PK11_GETTAB(mod)->C_Initialize(pInitArgs);
+ if ((CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) &&
+ (!enforceAlreadyInitializedError)) {
+ *alreadyLoaded = PR_TRUE;
+ return SECSuccess;
+ }
if (crv != CKR_OK) {
if (pInitArgs == NULL ||
crv == CKR_NETSCAPE_CERTDB_FAILED ||
@@ -117,8 +160,17 @@ secmod_ModuleInit(SECMODModule *mod)
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
+ if (!loadSingleThreadedModules) {
+ PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
+ return SECFailure;
+ }
mod->isThreadSafe = PR_FALSE;
crv = PK11_GETTAB(mod)->C_Initialize(NULL);
+ if ((CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) &&
+ (!enforceAlreadyInitializedError)) {
+ *alreadyLoaded = PR_TRUE;
+ return SECSuccess;
+ }
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
@@ -180,6 +232,7 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) {
CK_INFO info;
CK_ULONG slotCount = 0;
SECStatus rv;
+ PRBool alreadyLoaded = PR_FALSE;
if (mod->loaded) return SECSuccess;
@@ -266,7 +319,7 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) {
mod->isThreadSafe = PR_TRUE;
/* Now we initialize the module */
- rv = secmod_ModuleInit(mod);
+ rv = secmod_ModuleInit(mod, &alreadyLoaded);
if (rv != SECSuccess) {
goto fail;
}
@@ -275,11 +328,16 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) {
if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK) goto fail2;
if (info.cryptokiVersion.major != 2) goto fail2;
/* all 2.0 are a priori *not* thread safe */
- if (info.cryptokiVersion.minor < 1) mod->isThreadSafe = PR_FALSE;
-
+ if (info.cryptokiVersion.minor < 1) {
+ if (!loadSingleThreadedModules) {
+ PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
+ goto fail2;
+ } else {
+ mod->isThreadSafe = PR_FALSE;
+ }
+ }
mod->cryptokiVersion = info.cryptokiVersion;
-
/* If we don't have a common name, get it from the PKCS 11 module */
if ((mod->commonName == NULL) || (mod->commonName[0] == 0)) {
mod->commonName = PK11_MakeString(mod->arena,NULL,
@@ -325,7 +383,9 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) {
mod->moduleID = nextModuleID++;
return SECSuccess;
fail2:
- PK11_GETTAB(mod)->C_Finalize(NULL);
+ if (enforceAlreadyInitializedError || (!alreadyLoaded)) {
+ PK11_GETTAB(mod)->C_Finalize(NULL);
+ }
fail:
mod->functionList = NULL;
if (library) PR_UnloadLibrary(library);
@@ -339,8 +399,9 @@ SECMOD_UnloadModule(SECMODModule *mod) {
if (!mod->loaded) {
return SECFailure;
}
-
- if (!mod->moduleDBOnly) PK11_GETTAB(mod)->C_Finalize(NULL);
+ if (finalizeModules) {
+ if (!mod->moduleDBOnly) PK11_GETTAB(mod)->C_Finalize(NULL);
+ }
mod->moduleID = 0;
mod->loaded = PR_FALSE;
diff --git a/security/nss/lib/pk11wrap/pk11mech.c b/security/nss/lib/pk11wrap/pk11mech.c
index 2b73ed3ba..1f8f2a372 100644
--- a/security/nss/lib/pk11wrap/pk11mech.c
+++ b/security/nss/lib/pk11wrap/pk11mech.c
@@ -353,6 +353,7 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len)
case CKM_SHA512_RSA_PKCS:
case CKM_KEY_WRAP_SET_OAEP:
case CKM_RSA_PKCS_KEY_PAIR_GEN:
+ case CKM_RSA_X9_31_KEY_PAIR_GEN:
return CKK_RSA;
case CKM_DSA:
case CKM_DSA_SHA1:
@@ -526,6 +527,8 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
case CKM_KEY_WRAP_SET_OAEP:
case CKM_RSA_PKCS_KEY_PAIR_GEN:
return CKM_RSA_PKCS_KEY_PAIR_GEN;
+ case CKM_RSA_X9_31_KEY_PAIR_GEN:
+ return CKM_RSA_X9_31_KEY_PAIR_GEN;
case CKM_DSA:
case CKM_DSA_SHA1:
case CKM_DSA_KEY_PAIR_GEN:
@@ -1738,7 +1741,7 @@ have_key_len:
/* Make a Key type to an appropriate signing/verification mechanism */
CK_MECHANISM_TYPE
-pk11_mapSignKeyType(KeyType keyType)
+PK11_MapSignKeyType(KeyType keyType)
{
switch (keyType) {
case rsaKey:
@@ -1746,10 +1749,8 @@ pk11_mapSignKeyType(KeyType keyType)
case fortezzaKey:
case dsaKey:
return CKM_DSA;
-#ifdef NSS_ENABLE_ECC
case ecKey:
return CKM_ECDSA;
-#endif /* NSS_ENABLE_ECC */
case dhKey:
default:
break;
diff --git a/security/nss/lib/pk11wrap/pk11nobj.c b/security/nss/lib/pk11wrap/pk11nobj.c
index 523e0dafe..db9aa6ba9 100644
--- a/security/nss/lib/pk11wrap/pk11nobj.c
+++ b/security/nss/lib/pk11wrap/pk11nobj.c
@@ -431,88 +431,6 @@ SECItem *
PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
SECItem *name, int type, char **url)
{
-#ifdef NSS_CLASSIC
- CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_SUBJECT, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
- { CKA_NETSCAPE_KRL, NULL, 0 },
- };
- CK_ATTRIBUTE crlData[] = {
- { CKA_VALUE, NULL, 0 },
- { CKA_NETSCAPE_URL, NULL, 0 },
- };
- /* if you change the array, change the variable below as well */
- int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
- CK_BBOOL ck_true = CK_TRUE;
- CK_BBOOL ck_false = CK_FALSE;
- CK_OBJECT_HANDLE crlh = CK_INVALID_HANDLE;
- CK_ATTRIBUTE *attrs = theTemplate;
- CK_RV crv;
- SECItem *derCrl = NULL;
-
- PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++;
- PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass)); attrs++;
- PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, (type == SEC_CRL_TYPE) ?
- &ck_false : &ck_true, sizeof (CK_BBOOL)); attrs++;
-
- if (*slot) {
- crlh = pk11_FindObjectByTemplate(*slot,theTemplate,tsize);
- } else {
- PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
- PR_FALSE,PR_TRUE,NULL);
- PK11SlotListElement *le;
-
- /* loop through all the fortezza tokens */
- for (le = list->head; le; le = le->next) {
- crlh = pk11_FindObjectByTemplate(le->slot,theTemplate,tsize);
- if (crlh != CK_INVALID_HANDLE) {
- *slot = PK11_ReferenceSlot(le->slot);
- break;
- }
- }
- PK11_FreeSlotList(list);
- }
-
- if (crlh == CK_INVALID_HANDLE) {
- PORT_SetError(SEC_ERROR_NO_KRL);
- return NULL;
- }
- crv = PK11_GetAttributes(NULL,*slot,crlh,crlData,2);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError (crv));
- goto loser;
- }
-
- derCrl = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if (derCrl == NULL) {
- goto loser;
- }
-
- /* why are we arbitrarily picking the first CRL ??? */
- derCrl->data = crlData[0].pValue;
- derCrl->len = crlData[0].ulValueLen;
-
- if (crlHandle) {
- *crlHandle = crlh;
- }
-
- if ((url) && crlData[1].ulValueLen != 0) {
- /* make sure it's a null terminated string */
- *url = PORT_ZAlloc (crlData[1].ulValueLen+1);
- if (*url) {
- PORT_Memcpy(*url,crlData[1].pValue,crlData[1].ulValueLen);
- }
- }
-
-
-loser:
- if (!derCrl) {
- if (crlData[0].pValue) PORT_Free(crlData[0].pValue);
- }
- if (crlData[1].pValue) PORT_Free(crlData[1].pValue);
- return derCrl;
-#else
NSSCRL **crls, **crlp, *crl;
NSSDER subject;
SECItem *rvItem;
@@ -581,61 +499,12 @@ loser:
*crlHandle = crl->object.instances[0]->handle;
nssCRL_Destroy(crl);
return rvItem;
-#endif
}
CK_OBJECT_HANDLE
PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
char *url, int type)
{
-#ifdef NSS_CLASSIC
- CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_SUBJECT, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
- { CKA_NETSCAPE_KRL, NULL, 0 },
- { CKA_NETSCAPE_URL, NULL, 0 },
- { CKA_VALUE, NULL, 0 },
- { CKA_TOKEN, NULL, 0 }
- };
- /* if you change the array, change the variable below as well */
- int tsize;
- CK_BBOOL ck_true = CK_TRUE;
- CK_BBOOL ck_false = CK_FALSE;
- CK_OBJECT_HANDLE crlh = CK_INVALID_HANDLE;
- CK_ATTRIBUTE *attrs = theTemplate;
- CK_SESSION_HANDLE rwsession;
- CK_RV crv;
-
- PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++;
- PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass)); attrs++;
- PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, (type == SEC_CRL_TYPE) ?
- &ck_false : &ck_true, sizeof (CK_BBOOL)); attrs++;
- if (url) {
- PK11_SETATTRS(attrs, CKA_NETSCAPE_URL, url, PORT_Strlen(url)+1); attrs++;
- }
- PK11_SETATTRS(attrs, CKA_VALUE,crl->data,crl->len); attrs++;
- PK11_SETATTRS(attrs, CKA_TOKEN, &ck_true,sizeof(CK_BBOOL)); attrs++;
-
- tsize = attrs - &theTemplate[0];
- PORT_Assert(tsize <= sizeof(theTemplate)/sizeof(theTemplate[0]));
-
- rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_READ_ONLY);
- return crlh;
- }
-
- crv = PK11_GETTAB(slot)->
- C_CreateObject(rwsession,theTemplate,tsize,&crlh);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- }
-
- PK11_RestoreROSession(slot,rwsession);
-
- return crlh;
-#else
NSSItem derCRL, derSubject;
NSSToken *token = PK11Slot_GetNSSToken(slot);
nssCryptokiObject *object;
@@ -655,7 +524,6 @@ PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
rvH = CK_INVALID_HANDLE;
}
return rvH;
-#endif
}
@@ -665,25 +533,6 @@ PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
SECStatus
SEC_DeletePermCRL(CERTSignedCrl *crl)
{
-#ifdef NSS_CLASSIC
- PK11SlotInfo *slot = crl->slot;
- CK_RV crv;
-
- if (slot == NULL) {
- /* shouldn't happen */
- PORT_SetError( SEC_ERROR_CRL_INVALID);
- return SECFailure;
- }
-
- crv = PK11_DestroyTokenObject(slot,crl->pkcs11ID);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
- crl->slot = NULL;
- PK11_FreeSlot(slot);
- return SECSuccess;
-#else
PRStatus status;
NSSToken *token;
nssCryptokiObject *object;
@@ -706,7 +555,6 @@ SEC_DeletePermCRL(CERTSignedCrl *crl)
nssCryptokiObject_Destroy(object);
return (status == PR_SUCCESS) ? SECSuccess : SECFailure;
-#endif
}
/*
diff --git a/security/nss/lib/pk11wrap/pk11obj.c b/security/nss/lib/pk11wrap/pk11obj.c
index 0af025539..65b47ef96 100644
--- a/security/nss/lib/pk11wrap/pk11obj.c
+++ b/security/nss/lib/pk11wrap/pk11obj.c
@@ -97,6 +97,10 @@ PK11_DestroyTokenObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object) {
rwsession = PK11_GetRWSession(slot);
+ if (rwsession == CK_INVALID_SESSION) {
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return SECFailure;
+ }
crv = PK11_GETTAB(slot)->C_DestroyObject(rwsession,object);
if (crv != CKR_OK) {
@@ -210,6 +214,9 @@ PK11_GetAttributes(PRArenaPool *arena,PK11SlotInfo *slot,
/* make pedantic happy... note that it's only used arena != NULL */
void *mark = NULL;
CK_RV crv;
+ PORT_Assert(slot->session != CK_INVALID_SESSION);
+ if (slot->session == CK_INVALID_SESSION)
+ return CKR_SESSION_HANDLE_INVALID;
/*
* first get all the lengths of the parameters.
@@ -319,6 +326,10 @@ PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
PK11_SETATTRS(&setTemplate, CKA_LABEL, (CK_CHAR *) nickname, len);
rwsession = PK11_GetRWSession(slot);
+ if (rwsession == CK_INVALID_SESSION) {
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return SECFailure;
+ }
crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, id,
&setTemplate, 1);
PK11_RestoreROSession(slot, rwsession);
@@ -389,7 +400,12 @@ PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
rwsession = PK11_GetRWSession(slot);
} else if (rwsession == CK_INVALID_SESSION) {
rwsession = slot->session;
- PK11_EnterSlotMonitor(slot);
+ if (rwsession != CK_INVALID_SESSION)
+ PK11_EnterSlotMonitor(slot);
+ }
+ if (rwsession == CK_INVALID_SESSION) {
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return SECFailure;
}
crv = PK11_GETTAB(slot)->C_CreateObject(rwsession, theTemplate,
count,objectID);
@@ -407,6 +423,7 @@ PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
}
+/* This function may add a maximum of 9 attributes. */
unsigned int
pk11_OpFlagsToAttributes(CK_FLAGS flags, CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue)
{
@@ -428,6 +445,7 @@ pk11_OpFlagsToAttributes(CK_FLAGS flags, CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue)
for (; flags && test <= CKF_DERIVE; test <<= 1, ++pType) {
if (test & flags) {
flags ^= test;
+ PR_ASSERT(*pType);
PK11_SETATTRS(attr, *pType, ckTrue, sizeof *ckTrue);
++attr;
}
@@ -498,7 +516,7 @@ pk11_backupGetSignLength(SECKEYPrivateKey *key)
unsigned char buf[20]; /* obviously to small */
CK_ULONG smallLen = sizeof(buf);
- mech.mechanism = pk11_mapSignKeyType(key->keyType);
+ mech.mechanism = PK11_MapSignKeyType(key->keyType);
session = pk11_GetNewSession(slot,&owner);
if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot);
@@ -532,11 +550,9 @@ int
PK11_SignatureLen(SECKEYPrivateKey *key)
{
int val;
-#ifdef NSS_ENABLE_ECC
CK_ATTRIBUTE theTemplate = { CKA_EC_PARAMS, NULL, 0 };
SECItem params = {siBuffer, NULL, 0};
int length;
-#endif /* NSS_ENABLE_ECC */
switch (key->keyType) {
case rsaKey:
@@ -549,7 +565,6 @@ PK11_SignatureLen(SECKEYPrivateKey *key)
case fortezzaKey:
case dsaKey:
return 40;
-#ifdef NSS_ENABLE_ECC
case ecKey:
if (PK11_GetAttributes(NULL, key->pkcs11Slot, key->pkcs11ID,
&theTemplate, 1) == CKR_OK) {
@@ -563,7 +578,6 @@ PK11_SignatureLen(SECKEYPrivateKey *key)
return length;
}
break;
-#endif /* NSS_ENABLE_ECC */
default:
break;
}
@@ -616,7 +630,7 @@ PK11_VerifyRecover(SECKEYPublicKey *key,
CK_ULONG len;
CK_RV crv;
- mech.mechanism = pk11_mapSignKeyType(key->keyType);
+ mech.mechanism = PK11_MapSignKeyType(key->keyType);
if (slot == NULL) {
slot = PK11_GetBestSlot(mech.mechanism,wincx);
@@ -673,7 +687,7 @@ PK11_Verify(SECKEYPublicKey *key, SECItem *sig, SECItem *hash, void *wincx)
CK_SESSION_HANDLE session;
CK_RV crv;
- mech.mechanism = pk11_mapSignKeyType(key->keyType);
+ mech.mechanism = PK11_MapSignKeyType(key->keyType);
if (slot == NULL) {
slot = PK11_GetBestSlot(mech.mechanism,wincx);
@@ -729,7 +743,7 @@ PK11_Sign(SECKEYPrivateKey *key, SECItem *sig, SECItem *hash)
CK_ULONG len;
CK_RV crv;
- mech.mechanism = pk11_mapSignKeyType(key->keyType);
+ mech.mechanism = PK11_MapSignKeyType(key->keyType);
if (SECKEY_HAS_ATTRIBUTE_SET(key,CKA_PRIVATE)) {
PK11_HandlePasswordCheck(slot, key->wincx);
@@ -967,11 +981,17 @@ PK11_UnwrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
if (newKey) {
if (perm) {
/* Get RW Session will either lock the monitor if necessary,
- * or return a thread safe session handle. */
+ * or return a thread safe session handle, or fail. */
rwsession = PK11_GetRWSession(slot);
} else {
rwsession = slot->session;
- PK11_EnterSlotMonitor(slot);
+ if (rwsession != CK_INVALID_SESSION)
+ PK11_EnterSlotMonitor(slot);
+ }
+ if (rwsession == CK_INVALID_SESSION) {
+ PK11_FreeSymKey(newKey);
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return NULL;
}
crv = PK11_GETTAB(slot)->C_UnwrapKey(rwsession, &mechanism,
newKey->objectID,
@@ -1148,7 +1168,7 @@ PK11_FindGenericObjects(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass)
CK_ATTRIBUTE template[1];
CK_ATTRIBUTE *attrs = template;
CK_OBJECT_HANDLE *objectIDs = NULL;
- PK11GenericObject *lastObj, *obj;
+ PK11GenericObject *lastObj = NULL, *obj;
PK11GenericObject *firstObj = NULL;
int i, count = 0;
diff --git a/security/nss/lib/pk11wrap/pk11pars.c b/security/nss/lib/pk11wrap/pk11pars.c
index 54ebb8227..8644cdccc 100644
--- a/security/nss/lib/pk11wrap/pk11pars.c
+++ b/security/nss/lib/pk11wrap/pk11pars.c
@@ -137,10 +137,10 @@ SECMOD_CreateModule(const char *library, const char *moduleName,
if (slotParams) PORT_Free(slotParams);
/* new field */
mod->trustOrder = secmod_argReadLong("trustOrder",nssc,
- SFTK_DEFAULT_TRUST_ORDER,NULL);
+ SECMOD_DEFAULT_TRUST_ORDER,NULL);
/* new field */
mod->cipherOrder = secmod_argReadLong("cipherOrder",nssc,
- SFTK_DEFAULT_CIPHER_ORDER,NULL);
+ SECMOD_DEFAULT_CIPHER_ORDER,NULL);
/* new field */
mod->isModuleDB = secmod_argHasFlag("flags","moduleDB",nssc);
mod->moduleDBOnly = secmod_argHasFlag("flags","moduleDBOnly",nssc);
diff --git a/security/nss/lib/pk11wrap/pk11pqg.c b/security/nss/lib/pk11wrap/pk11pqg.c
index dd5e5ef3c..62afc7756 100644
--- a/security/nss/lib/pk11wrap/pk11pqg.c
+++ b/security/nss/lib/pk11wrap/pk11pqg.c
@@ -79,12 +79,16 @@ PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes,
PRArenaPool *varena = NULL;
PQGParams *params = NULL;
PQGVerify *verify = NULL;
- CK_ULONG primeBits = j;
+ CK_ULONG primeBits = PQG_INDEX_TO_PBITS(j);
CK_ULONG seedBits = seedBytes*8;
*pParams = NULL;
*pVfy = NULL;
+ if (primeBits == (CK_ULONG)-1) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
+ }
PK11_SETATTRS(attrs, CKA_PRIME_BITS,&primeBits,sizeof(primeBits)); attrs++;
if (seedBits != 0) {
PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED_BITS,
diff --git a/security/nss/lib/pk11wrap/pk11priv.h b/security/nss/lib/pk11wrap/pk11priv.h
index 69845b5f5..6d0b012b0 100644
--- a/security/nss/lib/pk11wrap/pk11priv.h
+++ b/security/nss/lib/pk11wrap/pk11priv.h
@@ -213,6 +213,14 @@ SECStatus pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *),
SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer,
void *wincx);
+/* set global options for NSS PKCS#11 module loader */
+SECStatus pk11_setGlobalOptions(PRBool noSingleThreadedModules,
+ PRBool allowAlreadyInitializedModules,
+ PRBool dontFinalizeModules);
+
+/* return whether NSS is allowed to call C_Finalize */
+PRBool pk11_getFinalizeModulesOption(void);
+
SEC_END_PROTOS
#endif
diff --git a/security/nss/lib/pk11wrap/pk11pub.h b/security/nss/lib/pk11wrap/pk11pub.h
index 51cce7c62..8a933cc93 100644
--- a/security/nss/lib/pk11wrap/pk11pub.h
+++ b/security/nss/lib/pk11wrap/pk11pub.h
@@ -58,6 +58,7 @@ SEC_BEGIN_PROTOS
* Generic Slot Lists Management
************************************************************/
void PK11_FreeSlotList(PK11SlotList *list);
+SECStatus PK11_FreeSlotListElement(PK11SlotList *list, PK11SlotListElement *le);
PK11SlotListElement * PK11_GetFirstSafe(PK11SlotList *list);
PK11SlotListElement *PK11_GetNextSafe(PK11SlotList *list,
PK11SlotListElement *le, PRBool restart);
@@ -180,6 +181,57 @@ PK11SlotInfo *PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type, int count,
PK11SlotInfo *PK11_GetBestSlot(CK_MECHANISM_TYPE type, void *wincx);
CK_MECHANISM_TYPE PK11_GetBestWrapMechanism(PK11SlotInfo *slot);
int PK11_GetBestKeyLength(PK11SlotInfo *slot, CK_MECHANISM_TYPE type);
+/*
+ * Open a new database using the softoken. The caller is responsible for making
+ * sure the module spec is correct and usable. The caller should ask for one
+ * new database per call if the caller wants to get meaningful information
+ * about the new database.
+ *
+ * moduleSpec is the same data that you would pass to softoken at
+ * initialization time under the 'tokens' options. For example, if you were
+ * to specify tokens=<0x4=[configdir='./mybackup' tokenDescription='Backup']>
+ * You would specify "configdir='./mybackup' tokenDescription='Backup'" as your
+ * module spec here. The slot ID will be calculated for you by
+ * SECMOD_OpenUserDB().
+ *
+ * Typical parameters here are configdir, tokenDescription and flags.
+ *
+ * a Full list is below:
+ *
+ *
+ * configDir - The location of the databases for this token. If configDir is
+ * not specified, and noCertDB and noKeyDB is not specified, the load
+ * will fail.
+ * certPrefix - Cert prefix for this token.
+ * keyPrefix - Prefix for the key database for this token. (if not specified,
+ * certPrefix will be used).
+ * tokenDescription - The label value for this token returned in the
+ * CK_TOKEN_INFO structure with an internationalize string (UTF8).
+ * This value will be truncated at 32 bytes (no NULL, partial UTF8
+ * characters dropped). You should specify a user friendly name here
+ * as this is the value the token will be refered to in most
+ * application UI's. You should make sure tokenDescription is unique.
+ * slotDescription - The slotDescription value for this token returned
+ * in the CK_SLOT_INFO structure with an internationalize string
+ * (UTF8). This value will be truncated at 64 bytes (no NULL, partial
+ * UTF8 characters dropped). This name will not change after the
+ * database is closed. It should have some number to make this unique.
+ * minPWLen - minimum password length for this token.
+ * flags - comma separated list of flag values, parsed case-insensitive.
+ * Valid flags are:
+ * readOnly - Databases should be opened read only.
+ * noCertDB - Don't try to open a certificate database.
+ * noKeyDB - Don't try to open a key database.
+ * forceOpen - Don't fail to initialize the token if the
+ * databases could not be opened.
+ * passwordRequired - zero length passwords are not acceptable
+ * (valid only if there is a keyDB).
+ * optimizeSpace - allocate smaller hash tables and lock tables.
+ * When this flag is not specified, Softoken will allocate
+ * large tables to prevent lock contention.
+ */
+PK11SlotInfo *SECMOD_OpenUserDB(const char *moduleSpec);
+SECStatus SECMOD_CloseUserDB(PK11SlotInfo *slot);
/*********************************************************************
* Mechanism Mapping functions
@@ -201,12 +253,14 @@ SECOidTag PK11_FortezzaMapSig(SECOidTag algTag);
SECStatus PK11_ParamToAlgid(SECOidTag algtag, SECItem *param,
PRArenaPool *arena, SECAlgorithmID *algid);
SECStatus PK11_SeedRandom(PK11SlotInfo *,unsigned char *data,int len);
+SECStatus PK11_GenerateRandomOnSlot(PK11SlotInfo *,unsigned char *data,int len);
SECStatus PK11_RandomUpdate(void *data, size_t bytes);
SECStatus PK11_GenerateRandom(unsigned char *data,int len);
CK_RV PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism,
CK_MECHANISM_PTR pCryptoMechanism,
SECItem *pbe_pwd, PRBool bad3DES);
CK_MECHANISM_TYPE PK11_GetPadMechanism(CK_MECHANISM_TYPE);
+CK_MECHANISM_TYPE PK11_MapSignKeyType(KeyType keyType);
/**********************************************************************
* Symetric, Public, and Private Keys
@@ -245,6 +299,39 @@ PK11SymKey * PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname,
PK11SymKey *PK11_GetNextSymKey(PK11SymKey *symKey);
CK_KEY_TYPE PK11_GetSymKeyType(PK11SymKey *key);
+/*
+ * PK11_SetSymKeyUserData
+ * sets generic user data on keys (usually a pointer to a data structure)
+ * that can later be retrieved by PK11_GetSymKeyUserData().
+ * symKey - key where data will be set.
+ * data - data to be set.
+ * freefunc - function used to free the data.
+ * Setting user data on symKeys with existing user data already set will cause
+ * the existing user data to be freed before the new user data is set.
+ * Freeing user data is done by calling the user specified freefunc.
+ * If freefunc is NULL, the user data is assumed to be global or static an
+ * not freed. Passing NULL for user data to PK11_SetSymKeyUserData has the
+ * effect of freeing any existing user data, and clearing the user data
+ * pointer. If user data exists when the symKey is finally freed, that
+ * data will be freed with freefunc.
+ *
+ * Applications should only use this function on keys which the application
+ * has created directly, as there is only one user data value per key.
+ */
+void PK11_SetSymKeyUserData(PK11SymKey *symKey, void *data,
+ PK11FreeDataFunc freefunc);
+/* PK11_GetSymKeyUserData
+ * retrieves generic user data which was set on a key by
+ * PK11_SetSymKeyUserData.
+ * symKey - key with data to be fetched
+ *
+ * If no data exists, or the data has been cleared, PK11_GetSymKeyUserData
+ * will return NULL. Returned data is still owned and managed by the SymKey,
+ * the caller should not free the data.
+ *
+ */
+void *PK11_GetSymKeyUserData(PK11SymKey *symKey);
+
SECStatus PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
PK11SymKey *symKey, SECItem *wrappedKey);
SECStatus PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *params,
@@ -440,6 +527,8 @@ PK11SymKey *PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk,
void *wincx);
SECKEYPrivateKey *PK11_ConvertSessionPrivKeyToTokenPrivKey(
SECKEYPrivateKey *privk, void* wincx);
+SECKEYPrivateKey * PK11_CopyTokenPrivKeyToSessionPrivKey(PK11SlotInfo *destSlot,
+ SECKEYPrivateKey *privKey);
/**********************************************************************
* Certs
@@ -585,7 +674,7 @@ SECStatus PK11_UpdateSlotAttribute(PK11SlotInfo *, PK11DefaultArrayEntry *,
PK11GenericObject *PK11_FindGenericObjects(PK11SlotInfo *slot,
CK_OBJECT_CLASS objClass);
PK11GenericObject *PK11_GetNextGenericObject(PK11GenericObject *object);
-PK11GenericObject *PK11_GetPrevtGenericObject(PK11GenericObject *object);
+PK11GenericObject *PK11_GetPrevGenericObject(PK11GenericObject *object);
SECStatus PK11_UnlinkGenericObject(PK11GenericObject *object);
SECStatus PK11_LinkGenericObject(PK11GenericObject *list,
PK11GenericObject *object);
diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c
index 299702a48..ce5cbd811 100644
--- a/security/nss/lib/pk11wrap/pk11skey.c
+++ b/security/nss/lib/pk11wrap/pk11skey.c
@@ -69,45 +69,94 @@ pk11_ExitKeyMonitor(PK11SymKey *symKey) {
PK11_ExitSlotMonitor(symKey->slot);
}
-
+/*
+ * pk11_getKeyFromList returns a symKey that has a session (if needSession
+ * was specified), or explicitly does not have a session (if needSession
+ * was not specified).
+ */
static PK11SymKey *
-pk11_getKeyFromList(PK11SlotInfo *slot) {
+pk11_getKeyFromList(PK11SlotInfo *slot, PRBool needSession) {
PK11SymKey *symKey = NULL;
PZ_Lock(slot->freeListLock);
- if (slot->freeSymKeysHead) {
- symKey = slot->freeSymKeysHead;
- slot->freeSymKeysHead = symKey->next;
- slot->keyCount--;
+ /* own session list are symkeys with sessions that the symkey owns.
+ * 'most' symkeys will own their own session. */
+ if (needSession) {
+ if (slot->freeSymKeysWithSessionHead) {
+ symKey = slot->freeSymKeysWithSessionHead;
+ slot->freeSymKeysWithSessionHead = symKey->next;
+ slot->keyCount--;
+ }
+ }
+ /* if we don't need a symkey with its own session, or we couldn't find
+ * one on the owner list, get one from the non-owner free list. */
+ if (!symKey) {
+ if (slot->freeSymKeysHead) {
+ symKey = slot->freeSymKeysHead;
+ slot->freeSymKeysHead = symKey->next;
+ slot->keyCount--;
+ }
}
PZ_Unlock(slot->freeListLock);
if (symKey) {
symKey->next = NULL;
- if ((symKey->series != slot->series) || (!symKey->sessionOwner))
- symKey->session = pk11_GetNewSession(slot,&symKey->sessionOwner);
- return symKey;
+ if (!needSession) {
+ return symKey;
+ }
+ /* if we are getting an owner key, make sure we have a valid session.
+ * session could be invalid if the token has been removed or because
+ * we got it from the non-owner free list */
+ if ((symKey->series != slot->series) ||
+ (symKey->session == CK_INVALID_SESSION)) {
+ symKey->session = pk11_GetNewSession(slot, &symKey->sessionOwner);
+ }
+ PORT_Assert(symKey->session != CK_INVALID_SESSION);
+ if (symKey->session != CK_INVALID_SESSION)
+ return symKey;
+ PK11_FreeSymKey(symKey);
+ /* if we are here, we need a session, but couldn't get one, it's
+ * unlikely we pk11_GetNewSession will succeed if we call it a second
+ * time. */
+ return NULL;
}
symKey = PORT_New(PK11SymKey);
if (symKey == NULL) {
return NULL;
}
- symKey->session = pk11_GetNewSession(slot,&symKey->sessionOwner);
+
symKey->next = NULL;
+ if (needSession) {
+ symKey->session = pk11_GetNewSession(slot,&symKey->sessionOwner);
+ PORT_Assert(symKey->session != CK_INVALID_SESSION);
+ if (symKey->session == CK_INVALID_SESSION) {
+ PK11_FreeSymKey(symKey);
+ symKey = NULL;
+ }
+ } else {
+ symKey->session = CK_INVALID_SESSION;
+ }
return symKey;
}
+/* Caller MUST hold slot->freeListLock (or ref count == 0?) !! */
void
PK11_CleanKeyList(PK11SlotInfo *slot)
{
PK11SymKey *symKey = NULL;
+ while (slot->freeSymKeysWithSessionHead) {
+ symKey = slot->freeSymKeysWithSessionHead;
+ slot->freeSymKeysWithSessionHead = symKey->next;
+ pk11_CloseSession(slot, symKey->session, symKey->sessionOwner);
+ PORT_Free(symKey);
+ }
while (slot->freeSymKeysHead) {
symKey = slot->freeSymKeysHead;
slot->freeSymKeysHead = symKey->next;
- pk11_CloseSession(slot, symKey->session,symKey->sessionOwner);
+ pk11_CloseSession(slot, symKey->session, symKey->sessionOwner);
PORT_Free(symKey);
- };
+ }
return;
}
@@ -115,18 +164,29 @@ PK11_CleanKeyList(PK11SlotInfo *slot)
* create a symetric key:
* Slot is the slot to create the key in.
* type is the mechanism type
+ * owner is does this symKey structure own it's object handle (rare
+ * that this is false).
+ * needSession means the returned symKey will return with a valid session
+ * allocated already.
*/
static PK11SymKey *
-pk11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PRBool owner,
- void *wincx)
+pk11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
+ PRBool owner, PRBool needSession, void *wincx)
{
- PK11SymKey *symKey = pk11_getKeyFromList(slot);
-
+ PK11SymKey *symKey = pk11_getKeyFromList(slot, needSession);
if (symKey == NULL) {
return NULL;
}
+ /* if needSession was specified, make sure we have a valid session.
+ * callers which specify needSession as false should do their own
+ * check of the session before returning the symKey */
+ if (needSession && symKey->session == CK_INVALID_SESSION) {
+ PK11_FreeSymKey(symKey);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return NULL;
+ }
symKey->type = type;
symKey->data.type = siBuffer;
@@ -141,6 +201,8 @@ pk11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PRBool owner,
symKey->refCount = 1;
symKey->origin = PK11_OriginNULL;
symKey->parent = NULL;
+ symKey->freeFunc = NULL;
+ symKey->userData = NULL;
PK11_ReferenceSlot(slot);
return symKey;
}
@@ -168,11 +230,33 @@ PK11_FreeSymKey(PK11SymKey *symKey)
PORT_Memset(symKey->data.data, 0, symKey->data.len);
PORT_Free(symKey->data.data);
}
+ /* free any existing data */
+ if (symKey->userData && symKey->freeFunc) {
+ (*symKey->freeFunc)(symKey->userData);
+ }
slot = symKey->slot;
PZ_Lock(slot->freeListLock);
if (slot->keyCount < slot->maxKeyCount) {
- symKey->next = slot->freeSymKeysHead;
- slot->freeSymKeysHead = symKey;
+ /*
+ * freeSymkeysWithSessionHead contain a list of reusable
+ * SymKey structures with valid sessions.
+ * sessionOwner must be true.
+ * session must be valid.
+ * freeSymKeysHead contain a list of SymKey structures without
+ * valid session.
+ * session must be CK_INVALID_SESSION.
+ * though sessionOwner is false, callers should not depend on
+ * this fact.
+ */
+ if (symKey->sessionOwner) {
+ PORT_Assert (symKey->session != CK_INVALID_SESSION);
+ symKey->next = slot->freeSymKeysWithSessionHead;
+ slot->freeSymKeysWithSessionHead = symKey;
+ } else {
+ symKey->session = CK_INVALID_SESSION;
+ symKey->next = slot->freeSymKeysHead;
+ slot->freeSymKeysHead = symKey;
+ }
slot->keyCount++;
symKey->slot = NULL;
freeit = PR_FALSE;
@@ -239,6 +323,25 @@ PK11_SetSymKeyNickname(PK11SymKey *symKey, const char *nickname)
return PK11_SetObjectNickname(symKey->slot,symKey->objectID,nickname);
}
+void *
+PK11_GetSymKeyUserData(PK11SymKey *symKey)
+{
+ return symKey->userData;
+}
+
+void
+PK11_SetSymKeyUserData(PK11SymKey *symKey, void *userData,
+ PK11FreeDataFunc freeFunc)
+{
+ /* free any existing data */
+ if (symKey->userData && symKey->freeFunc) {
+ (*symKey->freeFunc)(symKey->userData);
+ }
+ symKey->userData = userData;
+ symKey->freeFunc = freeFunc;
+ return;
+}
+
/*
* turn key handle into an appropriate key object
*/
@@ -247,12 +350,13 @@ PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin,
CK_MECHANISM_TYPE type, CK_OBJECT_HANDLE keyID, PRBool owner, void *wincx)
{
PK11SymKey *symKey;
+ PRBool needSession = !(owner && parent);
if (keyID == CK_INVALID_HANDLE) {
return NULL;
}
- symKey = pk11_CreateSymKey(slot,type,owner,wincx);
+ symKey = pk11_CreateSymKey(slot, type, owner, needSession, wincx);
if (symKey == NULL) {
return NULL;
}
@@ -264,11 +368,19 @@ PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin,
/* This is only used by SSL. What we really want here is a session
* structure with a ref count so the session goes away only after all the
* keys do. */
- if (owner && parent) {
- pk11_CloseSession(symKey->slot, symKey->session,symKey->sessionOwner);
+ if (!needSession) {
symKey->sessionOwner = PR_FALSE;
symKey->session = parent->session;
symKey->parent = PK11_ReferenceSymKey(parent);
+ /* This is the only case where pk11_CreateSymKey does not explicitly
+ * check symKey->session. We need to assert here to make sure.
+ * the session isn't invalid. */
+ PORT_Assert(parent->session != CK_INVALID_SESSION);
+ if (parent->session == CK_INVALID_SESSION) {
+ PK11_FreeSymKey(symKey);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return NULL;
+ }
}
return symKey;
@@ -329,7 +441,7 @@ pk11_ImportSymKeyWithTempl(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
PK11SymKey * symKey;
SECStatus rv;
- symKey = pk11_CreateSymKey(slot,type,!isToken,wincx);
+ symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx);
if (symKey == NULL) {
return NULL;
}
@@ -828,11 +940,11 @@ PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
return NULL;
}
- symKey = pk11_CreateSymKey(bestSlot, type, !isToken, wincx);
+ symKey = pk11_CreateSymKey(bestSlot, type, !isToken, PR_TRUE, wincx);
PK11_FreeSlot(bestSlot);
} else {
- symKey = pk11_CreateSymKey(slot, type, !isToken, wincx);
+ symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx);
}
if (symKey == NULL) return NULL;
@@ -857,11 +969,18 @@ PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
/* Get session and perform locking */
if (isToken) {
PK11_Authenticate(symKey->slot,PR_TRUE,wincx);
- session = PK11_GetRWSession(symKey->slot); /* Should always be original slot */
+ /* Should always be original slot */
+ session = PK11_GetRWSession(symKey->slot);
symKey->owner = PR_FALSE;
} else {
session = symKey->session;
- pk11_EnterKeyMonitor(symKey);
+ if (session != CK_INVALID_SESSION)
+ pk11_EnterKeyMonitor(symKey);
+ }
+ if (session == CK_INVALID_SESSION) {
+ PK11_FreeSymKey(symKey);
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return NULL;
}
crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session,
@@ -897,108 +1016,25 @@ PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
int keySize, SECItem *keyid, PRBool isToken, void *wincx)
{
PK11SymKey *symKey;
- CK_ATTRIBUTE genTemplate[6];
- CK_ATTRIBUTE *attrs = genTemplate;
- int count = sizeof(genTemplate)/sizeof(genTemplate[0]);
- CK_SESSION_HANDLE session;
- CK_MECHANISM mechanism;
- CK_RV crv;
PRBool weird = PR_FALSE; /* hack for fortezza */
- CK_BBOOL cktrue = CK_TRUE;
- CK_ULONG ck_key_size; /* only used for variable-length keys */
+ CK_FLAGS opFlags = CKF_SIGN;
+ PK11AttrFlags attrFlags = 0;
if ((keySize == -1) && (type == CKM_SKIPJACK_CBC64)) {
weird = PR_TRUE;
keySize = 0;
}
- /* TNH: Isn't this redundant, since "handleKey" will set defaults? */
- PK11_SETATTRS(attrs, (!weird)
- ? CKA_ENCRYPT : CKA_DECRYPT, &cktrue, sizeof(CK_BBOOL)); attrs++;
-
- if (keySize != 0) {
- ck_key_size = keySize; /* Convert to PK11 type */
-
- PK11_SETATTRS(attrs, CKA_VALUE_LEN, &ck_key_size, sizeof(ck_key_size));
- attrs++;
- }
-
- /* Include key id value if provided */
- if (keyid) {
- PK11_SETATTRS(attrs, CKA_ID, keyid->data, keyid->len); attrs++;
- }
-
- if (isToken) {
- PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); attrs++;
- PK11_SETATTRS(attrs, CKA_PRIVATE, &cktrue, sizeof(cktrue)); attrs++;
- }
-
- PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(cktrue)); attrs++;
-
- count = attrs - genTemplate;
- PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE));
-
- /* find a slot to generate the key into */
- /* Only do slot management if this is not a token key */
- if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot,type))) {
- PK11SlotInfo *bestSlot;
-
- bestSlot = PK11_GetBestSlot(type,wincx);
- if (bestSlot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
- }
-
- symKey = pk11_CreateSymKey(bestSlot, type, !isToken, wincx);
-
- PK11_FreeSlot(bestSlot);
- } else {
- symKey = pk11_CreateSymKey(slot, type, !isToken, wincx);
- }
- if (symKey == NULL) return NULL;
-
- symKey->size = keySize;
- symKey->origin = (!weird) ? PK11_OriginGenerated : PK11_OriginFortezzaHack;
+ opFlags |= weird ? CKF_DECRYPT : CKF_ENCRYPT;
- /* Initialize the Key Gen Mechanism */
- mechanism.mechanism = PK11_GetKeyGenWithSize(type, keySize);
- if (mechanism.mechanism == CKM_FAKE_RANDOM) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
- }
-
- /* Set the parameters for the key gen if provided */
- mechanism.pParameter = NULL;
- mechanism.ulParameterLen = 0;
- if (param) {
- mechanism.pParameter = param->data;
- mechanism.ulParameterLen = param->len;
- }
-
- /* Get session and perform locking */
if (isToken) {
- PK11_Authenticate(symKey->slot,PR_TRUE,wincx);
- session = PK11_GetRWSession(symKey->slot); /* Should always be original slot */
- symKey->owner = PR_FALSE;
- } else {
- session = symKey->session;
- pk11_EnterKeyMonitor(symKey);
- }
-
- crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session,
- &mechanism, genTemplate, count, &symKey->objectID);
-
- /* Release lock and session */
- if (isToken) {
- PK11_RestoreROSession(symKey->slot, session);
- } else {
- pk11_ExitKeyMonitor(symKey);
+ attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE);
}
- if (crv != CKR_OK) {
- PK11_FreeSymKey(symKey);
- PORT_SetError( PK11_MapError(crv) );
- return NULL;
+ symKey = PK11_TokenKeyGenWithFlags(slot, type, param, keySize, keyid,
+ opFlags, attrFlags, wincx);
+ if (symKey && weird) {
+ PK11_SetFortezzaHack(symKey);
}
return symKey;
@@ -1033,6 +1069,10 @@ PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, void *wincx)
PK11_Authenticate(slot, PR_TRUE, wincx);
rwsession = PK11_GetRWSession(slot);
+ if (rwsession == CK_INVALID_SESSION) {
+ PORT_SetError(SEC_ERROR_BAD_DATA);
+ return NULL;
+ }
crv = PK11_GETTAB(slot)->C_CopyObject(rwsession, symk->objectID,
template, 1, &newKeyID);
PK11_RestoreROSession(slot, rwsession);
@@ -1297,7 +1337,7 @@ PK11_DeriveWithFlagsPerm( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
int keySize, CK_FLAGS flags, PRBool isPerm)
{
CK_BBOOL cktrue = CK_TRUE;
- CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS+1];
+ CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
CK_ATTRIBUTE *attrs;
unsigned int templateCount = 0;
@@ -1376,14 +1416,15 @@ pk11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
newBaseKey = pk11_CopyToSlot (newSlot, derive, CKA_DERIVE,
baseKey);
PK11_FreeSlot(newSlot);
- if (newBaseKey == NULL) return NULL;
+ if (newBaseKey == NULL)
+ return NULL;
baseKey = newBaseKey;
slot = baseKey->slot;
}
/* get our key Structure */
- symKey = pk11_CreateSymKey(slot,target,!isPerm,baseKey->cx);
+ symKey = pk11_CreateSymKey(slot, target, !isPerm, PR_TRUE, baseKey->cx);
if (symKey == NULL) {
return NULL;
}
@@ -1406,15 +1447,21 @@ pk11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
pk11_EnterKeyMonitor(symKey);
session = symKey->session;
}
- crv = PK11_GETTAB(slot)->C_DeriveKey(session, &mechanism,
- baseKey->objectID, keyTemplate, templateCount, &symKey->objectID);
- if (isPerm) {
- PK11_RestoreROSession(slot, session);
+ if (session == CK_INVALID_SESSION) {
+ if (!isPerm)
+ pk11_ExitKeyMonitor(symKey);
+ crv = CKR_SESSION_HANDLE_INVALID;
} else {
- pk11_ExitKeyMonitor(symKey);
+ crv = PK11_GETTAB(slot)->C_DeriveKey(session, &mechanism,
+ baseKey->objectID, keyTemplate, templateCount, &symKey->objectID);
+ if (isPerm) {
+ PK11_RestoreROSession(slot, session);
+ } else {
+ pk11_ExitKeyMonitor(symKey);
+ }
}
-
- if (newBaseKey) PK11_FreeSymKey(newBaseKey);
+ if (newBaseKey)
+ PK11_FreeSymKey(newBaseKey);
if (crv != CKR_OK) {
PK11_FreeSymKey(symKey);
return NULL;
@@ -1450,7 +1497,7 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
}
/* get our key Structure */
- symKey = pk11_CreateSymKey(slot,target,PR_TRUE,wincx);
+ symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx);
if (symKey == NULL) {
return NULL;
}
@@ -1540,7 +1587,6 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
PORT_SetError( PK11_MapError(crv) );
}
break;
-#ifdef NSS_ENABLE_ECC
case ecKey:
{
CK_BBOOL cktrue = CK_TRUE;
@@ -1594,10 +1640,6 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
if (crv == CKR_OK) return symKey;
PORT_SetError( PK11_MapError(crv) );
}
-#else
- case ecKey:
- break;
-#endif /* NSS_ENABLE_ECC */
}
PK11_FreeSymKey(symKey);
@@ -1613,13 +1655,11 @@ PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
{
PK11SlotInfo *slot = privKey->pkcs11Slot;
PK11SymKey *symKey;
-#ifdef NSS_ENABLE_ECC
CK_MECHANISM mechanism;
CK_RV crv;
-#endif
/* get our key Structure */
- symKey = pk11_CreateSymKey(slot,target,PR_TRUE,wincx);
+ symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx);
if (symKey == NULL) {
return NULL;
}
@@ -1636,7 +1676,6 @@ PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
PK11_FreeSymKey(symKey);
return PK11_PubDerive(privKey, pubKey, isSender, randomA, randomB,
derive, target, operation, keySize, wincx);
-#ifdef NSS_ENABLE_ECC
case ecKey:
{
CK_BBOOL cktrue = CK_TRUE;
@@ -1699,10 +1738,6 @@ PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
if (crv == CKR_OK) return symKey;
PORT_SetError( PK11_MapError(crv) );
}
-#else
- case ecKey:
- break;
-#endif /* NSS_ENABLE_ECC */
}
PK11_FreeSymKey(symKey);
@@ -1908,7 +1943,7 @@ pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
}
/* get our key Structure */
- symKey = pk11_CreateSymKey(slot,target,!isPerm,wincx);
+ symKey = pk11_CreateSymKey(slot, target, !isPerm, PR_TRUE, wincx);
if (symKey == NULL) {
if (param_free) SECITEM_FreeItem(param_free,PR_TRUE);
return NULL;
@@ -1923,11 +1958,16 @@ pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
pk11_EnterKeyMonitor(symKey);
rwsession = symKey->session;
}
- crv = PK11_GETTAB(slot)->C_UnwrapKey(rwsession,&mechanism,wrappingKey,
+ PORT_Assert(rwsession != CK_INVALID_SESSION);
+ if (rwsession == CK_INVALID_SESSION)
+ crv = CKR_SESSION_HANDLE_INVALID;
+ else
+ crv = PK11_GETTAB(slot)->C_UnwrapKey(rwsession,&mechanism,wrappingKey,
wrappedKey->data, wrappedKey->len, keyTemplate, templateCount,
&symKey->objectID);
if (isPerm) {
- PK11_RestoreROSession(slot, rwsession);
+ if (rwsession != CK_INVALID_SESSION)
+ PK11_RestoreROSession(slot, rwsession);
} else {
pk11_ExitKeyMonitor(symKey);
}
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
index 201959f18..a92fbf7df 100644
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -145,11 +145,16 @@ PK11_NewSlotList(void)
/*
* free a list element when all the references go away.
*/
-static void
-pk11_FreeListElement(PK11SlotList *list, PK11SlotListElement *le)
+SECStatus
+PK11_FreeSlotListElement(PK11SlotList *list, PK11SlotListElement *le)
{
PRBool freeit = PR_FALSE;
+ if (list == NULL || le == NULL) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
PZ_Lock(list->lock);
if (le->refCount-- == 1) {
freeit = PR_TRUE;
@@ -159,23 +164,34 @@ pk11_FreeListElement(PK11SlotList *list, PK11SlotListElement *le)
PK11_FreeSlot(le->slot);
PORT_Free(le);
}
+ return SECSuccess;
}
-/*
- * if we are freeing the list, we must be the only ones with a pointer
- * to the list.
- */
-void
-PK11_FreeSlotList(PK11SlotList *list)
+static void
+pk11_FreeSlotListStatic(PK11SlotList *list)
{
PK11SlotListElement *le, *next ;
if (list == NULL) return;
for (le = list->head ; le; le = next) {
next = le->next;
- pk11_FreeListElement(list,le);
+ PK11_FreeSlotListElement(list,le);
+ }
+ if (list->lock) {
+ PZ_DestroyLock(list->lock);
}
- PZ_DestroyLock(list->lock);
+ list->lock = NULL;
+ list->head = NULL;
+}
+
+/*
+ * if we are freeing the list, we must be the only ones with a pointer
+ * to the list.
+ */
+void
+PK11_FreeSlotList(PK11SlotList *list)
+{
+ pk11_FreeSlotListStatic(list);
PORT_Free(list);
}
@@ -213,7 +229,7 @@ PK11_DeleteSlotFromList(PK11SlotList *list,PK11SlotListElement *le)
if (le->next) le->next->prev = le->prev; else list->tail = le->prev;
le->next = le->prev = NULL;
PZ_Unlock(list->lock);
- pk11_FreeListElement(list,le);
+ PK11_FreeSlotListElement(list,le);
return SECSuccess;
}
@@ -259,7 +275,7 @@ PK11_GetNextRef(PK11SlotList *list, PK11SlotListElement *le, PRBool restart)
PK11SlotListElement *new_le;
new_le = le->next;
if (new_le) new_le->refCount++;
- pk11_FreeListElement(list,le);
+ PK11_FreeSlotListElement(list,le);
return new_le;
}
@@ -300,7 +316,7 @@ PK11_GetNextSafe(PK11SlotList *list, PK11SlotListElement *le, PRBool restart)
}
if (new_le) new_le->refCount++;
PZ_Unlock(list->lock);
- pk11_FreeListElement(list,le);
+ PK11_FreeSlotListElement(list,le);
return new_le;
}
@@ -348,6 +364,7 @@ PK11_NewSlotInfo(SECMODModule *mod)
PORT_Free(slot);
return slot;
}
+ slot->freeSymKeysWithSessionHead = NULL;
slot->freeSymKeysHead = NULL;
slot->keyCount = 0;
slot->maxKeyCount = 0;
@@ -650,36 +667,53 @@ CK_SESSION_HANDLE PK11_GetRWSession(PK11SlotInfo *slot)
{
CK_SESSION_HANDLE rwsession;
CK_RV crv;
+ PRBool haveMonitor = PR_FALSE;
- if (!slot->isThreadSafe || slot->defRWSession) PK11_EnterSlotMonitor(slot);
- if (slot->defRWSession) return slot->session;
+ if (!slot->isThreadSafe || slot->defRWSession) {
+ PK11_EnterSlotMonitor(slot);
+ haveMonitor = PR_TRUE;
+ }
+ if (slot->defRWSession) {
+ PORT_Assert(slot->session != CK_INVALID_SESSION);
+ if (slot->session != CK_INVALID_SESSION)
+ return slot->session;
+ }
crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID,
CKF_RW_SESSION|CKF_SERIAL_SESSION,
slot, pk11_notify,&rwsession);
- if (crv == CKR_SESSION_COUNT) {
- PK11_GETTAB(slot)->C_CloseSession(slot->session);
- slot->session = CK_INVALID_SESSION;
- crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID,
- CKF_RW_SESSION|CKF_SERIAL_SESSION,
- slot,pk11_notify,&rwsession);
- }
- if (crv != CKR_OK) {
+ PORT_Assert(rwsession != CK_INVALID_SESSION || crv != CKR_OK);
+ if (crv != CKR_OK || rwsession == CK_INVALID_SESSION) {
+ if (crv == CKR_OK)
+ crv = CKR_DEVICE_ERROR;
+ if (haveMonitor)
+ PK11_ExitSlotMonitor(slot);
PORT_SetError(PK11_MapError(crv));
- if (slot->session == CK_INVALID_SESSION) {
- PK11_GETTAB(slot)->C_OpenSession(slot->slotID,CKF_SERIAL_SESSION,
- slot,pk11_notify,&slot->session);
- }
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
return CK_INVALID_SESSION;
}
-
+ if (slot->defRWSession) { /* we have the monitor */
+ slot->session = rwsession;
+ }
return rwsession;
}
PRBool
-PK11_RWSessionHasLock(PK11SlotInfo *slot,CK_SESSION_HANDLE session_handle) {
- return (PRBool)(!slot->isThreadSafe || slot->defRWSession);
+PK11_RWSessionHasLock(PK11SlotInfo *slot,CK_SESSION_HANDLE session_handle)
+{
+ PRBool hasLock;
+ hasLock = (PRBool)(!slot->isThreadSafe ||
+ (slot->defRWSession && slot->session != CK_INVALID_SESSION));
+ return hasLock;
+}
+
+static PRBool
+pk11_RWSessionIsDefault(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession)
+{
+ PRBool isDefault;
+ isDefault = (PRBool)(slot->session == rwsession &&
+ slot->defRWSession &&
+ slot->session != CK_INVALID_SESSION);
+ return isDefault;
}
/*
@@ -690,16 +724,14 @@ PK11_RWSessionHasLock(PK11SlotInfo *slot,CK_SESSION_HANDLE session_handle) {
void
PK11_RestoreROSession(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession)
{
- if (slot->defRWSession) {
- PK11_ExitSlotMonitor(slot);
- return;
- }
- PK11_GETTAB(slot)->C_CloseSession(rwsession);
- if (slot->session == CK_INVALID_SESSION) {
- PK11_GETTAB(slot)->C_OpenSession(slot->slotID,CKF_SERIAL_SESSION,
- slot,pk11_notify,&slot->session);
+ PORT_Assert(rwsession != CK_INVALID_SESSION);
+ if (rwsession != CK_INVALID_SESSION) {
+ PRBool doExit = PK11_RWSessionHasLock(slot, rwsession);
+ if (!pk11_RWSessionIsDefault(slot, rwsession))
+ PK11_GETTAB(slot)->C_CloseSession(rwsession);
+ if (doExit)
+ PK11_ExitSlotMonitor(slot);
}
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
}
/************************************************************
@@ -709,75 +741,59 @@ PK11_RestoreROSession(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession)
/* Init the static built int slot list (should actually integrate
* with PK11_NewSlotList */
static void
-pk11_initSlotList(PK11SlotList *list)
+pk11_InitSlotListStatic(PK11SlotList *list)
{
list->lock = PZ_NewLock(nssILockList);
list->head = NULL;
}
-static void
-pk11_freeSlotList(PK11SlotList *list)
-{
- PK11SlotListElement *le, *next ;
- if (list == NULL) return;
-
- for (le = list->head ; le; le = next) {
- next = le->next;
- pk11_FreeListElement(list,le);
- }
- if (list->lock) {
- PZ_DestroyLock(list->lock);
- }
- list->lock = NULL;
- list->head = NULL;
-}
/* initialize the system slotlists */
SECStatus
PK11_InitSlotLists(void)
{
- pk11_initSlotList(&pk11_aesSlotList);
- pk11_initSlotList(&pk11_desSlotList);
- pk11_initSlotList(&pk11_rc4SlotList);
- pk11_initSlotList(&pk11_rc2SlotList);
- pk11_initSlotList(&pk11_rc5SlotList);
- pk11_initSlotList(&pk11_md5SlotList);
- pk11_initSlotList(&pk11_md2SlotList);
- pk11_initSlotList(&pk11_sha1SlotList);
- pk11_initSlotList(&pk11_rsaSlotList);
- pk11_initSlotList(&pk11_dsaSlotList);
- pk11_initSlotList(&pk11_dhSlotList);
- pk11_initSlotList(&pk11_ecSlotList);
- pk11_initSlotList(&pk11_ideaSlotList);
- pk11_initSlotList(&pk11_sslSlotList);
- pk11_initSlotList(&pk11_tlsSlotList);
- pk11_initSlotList(&pk11_randomSlotList);
- pk11_initSlotList(&pk11_sha256SlotList);
- pk11_initSlotList(&pk11_sha512SlotList);
+ pk11_InitSlotListStatic(&pk11_aesSlotList);
+ pk11_InitSlotListStatic(&pk11_desSlotList);
+ pk11_InitSlotListStatic(&pk11_rc4SlotList);
+ pk11_InitSlotListStatic(&pk11_rc2SlotList);
+ pk11_InitSlotListStatic(&pk11_rc5SlotList);
+ pk11_InitSlotListStatic(&pk11_md5SlotList);
+ pk11_InitSlotListStatic(&pk11_md2SlotList);
+ pk11_InitSlotListStatic(&pk11_sha1SlotList);
+ pk11_InitSlotListStatic(&pk11_rsaSlotList);
+ pk11_InitSlotListStatic(&pk11_dsaSlotList);
+ pk11_InitSlotListStatic(&pk11_dhSlotList);
+ pk11_InitSlotListStatic(&pk11_ecSlotList);
+ pk11_InitSlotListStatic(&pk11_ideaSlotList);
+ pk11_InitSlotListStatic(&pk11_sslSlotList);
+ pk11_InitSlotListStatic(&pk11_tlsSlotList);
+ pk11_InitSlotListStatic(&pk11_randomSlotList);
+ pk11_InitSlotListStatic(&pk11_sha256SlotList);
+ pk11_InitSlotListStatic(&pk11_sha512SlotList);
return SECSuccess;
}
void
PK11_DestroySlotLists(void)
{
- pk11_freeSlotList(&pk11_aesSlotList);
- pk11_freeSlotList(&pk11_desSlotList);
- pk11_freeSlotList(&pk11_rc4SlotList);
- pk11_freeSlotList(&pk11_rc2SlotList);
- pk11_freeSlotList(&pk11_rc5SlotList);
- pk11_freeSlotList(&pk11_md5SlotList);
- pk11_freeSlotList(&pk11_md2SlotList);
- pk11_freeSlotList(&pk11_sha1SlotList);
- pk11_freeSlotList(&pk11_rsaSlotList);
- pk11_freeSlotList(&pk11_dsaSlotList);
- pk11_freeSlotList(&pk11_dhSlotList);
- pk11_freeSlotList(&pk11_ecSlotList);
- pk11_freeSlotList(&pk11_ideaSlotList);
- pk11_freeSlotList(&pk11_sslSlotList);
- pk11_freeSlotList(&pk11_tlsSlotList);
- pk11_freeSlotList(&pk11_randomSlotList);
- pk11_freeSlotList(&pk11_sha256SlotList);
- pk11_freeSlotList(&pk11_sha512SlotList);
+ pk11_FreeSlotListStatic(&pk11_aesSlotList);
+ pk11_FreeSlotListStatic(&pk11_desSlotList);
+ pk11_FreeSlotListStatic(&pk11_rc4SlotList);
+ pk11_FreeSlotListStatic(&pk11_rc2SlotList);
+ pk11_FreeSlotListStatic(&pk11_rc5SlotList);
+ pk11_FreeSlotListStatic(&pk11_md5SlotList);
+ pk11_FreeSlotListStatic(&pk11_md2SlotList);
+ pk11_FreeSlotListStatic(&pk11_sha1SlotList);
+ pk11_FreeSlotListStatic(&pk11_rsaSlotList);
+ pk11_FreeSlotListStatic(&pk11_dsaSlotList);
+ pk11_FreeSlotListStatic(&pk11_dhSlotList);
+ pk11_FreeSlotListStatic(&pk11_ecSlotList);
+ pk11_FreeSlotListStatic(&pk11_ideaSlotList);
+ pk11_FreeSlotListStatic(&pk11_sslSlotList);
+ pk11_FreeSlotListStatic(&pk11_tlsSlotList);
+ pk11_FreeSlotListStatic(&pk11_randomSlotList);
+ pk11_FreeSlotListStatic(&pk11_sha256SlotList);
+ pk11_FreeSlotListStatic(&pk11_sha512SlotList);
return;
}
@@ -955,7 +971,7 @@ PK11_ClearSlotList(PK11SlotInfo *slot)
if (le) {
PK11_DeleteSlotFromList(slotList,le);
- pk11_FreeListElement(slotList,le);
+ PK11_FreeSlotListElement(slotList,le);
}
}
}
@@ -2065,7 +2081,7 @@ PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type, int mech_count, void *wincx)
}
slot = le->slot;
PK11_ReferenceSlot(slot);
- pk11_FreeListElement(list,le);
+ PK11_FreeSlotListElement(list,le);
if (freeit) { PK11_FreeSlotList(list); }
return slot;
}
@@ -2106,9 +2122,29 @@ PK11_SeedRandom(PK11SlotInfo *slot, unsigned char *data, int len) {
CK_RV crv;
PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_SeedRandom(slot->session,data, (CK_ULONG)len);
+ crv = PK11_GETTAB(slot)->C_SeedRandom(slot->session, data, (CK_ULONG)len);
PK11_ExitSlotMonitor(slot);
- return (crv != CKR_OK) ? SECFailure : SECSuccess;
+ if (crv != CKR_OK) {
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+
+SECStatus
+PK11_GenerateRandomOnSlot(PK11SlotInfo *slot, unsigned char *data, int len) {
+ CK_RV crv;
+
+ if (!slot->isInternal) PK11_EnterSlotMonitor(slot);
+ crv = PK11_GETTAB(slot)->C_GenerateRandom(slot->session,data,
+ (CK_ULONG)len);
+ if (!slot->isInternal) PK11_ExitSlotMonitor(slot);
+ if (crv != CKR_OK) {
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
+ }
+ return SECSuccess;
}
/* Attempts to update the Best Slot for "FAKE RANDOM" generation.
@@ -2147,17 +2183,14 @@ PK11_RandomUpdate(void *data, size_t bytes)
SECStatus
PK11_GenerateRandom(unsigned char *data,int len) {
PK11SlotInfo *slot;
- CK_RV crv;
+ SECStatus rv;
slot = PK11_GetBestSlot(CKM_FAKE_RANDOM,NULL);
if (slot == NULL) return SECFailure;
- if (!slot->isInternal) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GenerateRandom(slot->session,data,
- (CK_ULONG)len);
- if (!slot->isInternal) PK11_ExitSlotMonitor(slot);
+ rv = PK11_GenerateRandomOnSlot(slot, data, len);
PK11_FreeSlot(slot);
- return (crv != CKR_OK) ? SECFailure : SECSuccess;
+ return rv;
}
/*
diff --git a/security/nss/lib/pk11wrap/pk11util.c b/security/nss/lib/pk11wrap/pk11util.c
index 5c6998da8..e4edaf2e6 100644
--- a/security/nss/lib/pk11wrap/pk11util.c
+++ b/security/nss/lib/pk11wrap/pk11util.c
@@ -45,6 +45,7 @@
#include "pki3hack.h"
#include "secerr.h"
#include "dev.h"
+#include "pkcs11ni.h"
/* these are for displaying error messages */
@@ -859,9 +860,9 @@ SECMOD_UpdateSlotList(SECMODModule *mod)
{
CK_RV crv;
CK_ULONG count;
- int i, oldCount;
+ CK_ULONG i, oldCount;
PRBool freeRef = PR_FALSE;
- void *mark;
+ void *mark = NULL;
CK_ULONG *slotIDs = NULL;
PK11SlotInfo **newSlots = NULL;
PK11SlotInfo **oldSlots = NULL;
@@ -882,7 +883,7 @@ SECMOD_UpdateSlotList(SECMODModule *mod)
PZ_Unlock(mod->refLock);
return SECSuccess;
}
- if (count < mod->slotCount) {
+ if (count < (CK_ULONG)mod->slotCount) {
/* shouldn't happen with a properly functioning PKCS #11 module */
PORT_SetError( SEC_ERROR_INCOMPATIBLE_PKCS11 );
goto loser;
@@ -1060,13 +1061,15 @@ SECMOD_WaitForAnyTokenEvent(SECMODModule *mod, unsigned long flags,
CK_RV crv;
PK11SlotInfo *slot;
- if ((mod->cryptokiVersion.major == 2) &&
- (mod->cryptokiVersion.minor < 1)) {
- /* if the module is version 2.0,
- * C_WaitForSlotEvent() doesn't exist */
+ if (!pk11_getFinalizeModulesOption() ||
+ ((mod->cryptokiVersion.major == 2) &&
+ (mod->cryptokiVersion.minor < 1))) {
+ /* if we are sharing the module with other software in our
+ * address space, we can't reliably use C_WaitForSlotEvent(),
+ * and if the module is version 2.0, C_WaitForSlotEvent() doesn't
+ * exist */
return secmod_HandleWaitForSlotEvent(mod, flags, latency);
}
-
/* first the the PKCS #11 call */
PZ_Lock(mod->refLock);
if (mod->evControlMask & SECMOD_END_WAIT) {
@@ -1137,16 +1140,24 @@ SECMOD_CancelWait(SECMODModule *mod)
mod->evControlMask |= SECMOD_END_WAIT;
controlMask = mod->evControlMask;
if (controlMask & SECMOD_WAIT_PKCS11_EVENT) {
+ if (!pk11_getFinalizeModulesOption()) {
+ /* can't get here unless pk11_getFinalizeModulesOption is set */
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ rv = SECFailure;
+ goto loser;
+ }
/* NOTE: this call will drop all transient keys, in progress
* operations, and any authentication. This is the only documented
* way to get WaitForSlotEvent to return. Also note: for non-thread
* safe tokens, we need to hold the module lock, this is not yet at
- * system shutdown/starup time, so we need to protect these calls */
+ * system shutdown/startup time, so we need to protect these calls */
crv = PK11_GETTAB(mod)->C_Finalize(NULL);
/* ok, we slammed the module down, now we need to reinit it in case
* we intend to use it again */
if (CKR_OK == crv) {
- secmod_ModuleInit(mod);
+ PRBool alreadyLoaded;
+ secmod_ModuleInit(mod, &alreadyLoaded);
} else {
/* Finalized failed for some reason, notify the application
* so maybe it has a prayer of recovering... */
@@ -1158,6 +1169,7 @@ SECMOD_CancelWait(SECMODModule *mod)
/* Simulated events will eventually timeout
* and wake up in the loop */
}
+loser:
PZ_Unlock(mod->refLock);
return rv;
}
@@ -1185,3 +1197,244 @@ SECMOD_HasRemovableSlots(SECMODModule *mod)
SECMOD_ReleaseReadLock(moduleLock);
return ret;
}
+
+/*
+ * helper function to actually create and destroy user defined slots
+ */
+static SECStatus
+secmod_UserDBOp(CK_OBJECT_CLASS objClass, const char *sendSpec)
+{
+ PK11SlotInfo *slot = PK11_GetInternalSlot();
+ CK_OBJECT_HANDLE dummy;
+ CK_ATTRIBUTE template[2] ;
+ CK_ATTRIBUTE *attrs = template;
+ SECStatus rv;
+ CK_RV crv;
+
+ PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass)); attrs++;
+ PK11_SETATTRS(attrs, CKA_NETSCAPE_MODULE_SPEC , (unsigned char *)sendSpec,
+ strlen(sendSpec)+1); attrs++;
+
+ PORT_Assert(attrs-template <= 2);
+
+
+ PK11_EnterSlotMonitor(slot);
+ crv = PK11_CreateNewObject(slot, slot->session,
+ template, attrs-template, PR_FALSE, &dummy);
+ PK11_ExitSlotMonitor(slot);
+
+ if (crv != CKR_OK) {
+ PK11_FreeSlot(slot);
+ PORT_SetError(PK11_MapError(crv));
+ return SECFailure;
+ }
+ rv = SECMOD_UpdateSlotList(slot->module);
+ PK11_FreeSlot(slot);
+ return rv;
+}
+
+/*
+ * add escapes to protect quote characters...
+ */
+static char *
+nss_addEscape(const char *string, char quote)
+{
+ char *newString = 0;
+ int escapes = 0, size = 0;
+ const char *src;
+ char *dest;
+
+ for (src=string; *src ; src++) {
+ if ((*src == quote) || (*src == '\\')) escapes++;
+ size++;
+ }
+
+ newString = PORT_ZAlloc(escapes+size+1);
+ if (newString == NULL) {
+ return NULL;
+ }
+
+ for (src=string, dest=newString; *src; src++,dest++) {
+ if ((*src == '\\') || (*src == quote)) {
+ *dest++ = '\\';
+ }
+ *dest = *src;
+ }
+
+ return newString;
+}
+
+static char *
+nss_doubleEscape(const char *string)
+{
+ char *round1 = NULL;
+ char *retValue = NULL;
+ if (string == NULL) {
+ goto done;
+ }
+ round1 = nss_addEscape(string,'>');
+ if (round1) {
+ retValue = nss_addEscape(round1,']');
+ PORT_Free(round1);
+ }
+
+done:
+ if (retValue == NULL) {
+ retValue = PORT_Strdup("");
+ }
+ return retValue;
+}
+
+/*
+ * Open a new database using the softoken. The caller is responsible for making
+ * sure the module spec is correct and usable. The caller should ask for one
+ * new database per call if the caller wants to get meaningful information
+ * about the new database.
+ *
+ * moduleSpec is the same data that you would pass to softoken at
+ * initialization time under the 'tokens' options. For example, if you were
+ * to specify tokens=<0x4=[configdir='./mybackup' tokenDescription='Backup']>
+ * You would specify "configdir='./mybackup' tokenDescription='Backup'" as your
+ * module spec here. The slot ID will be calculated for you by
+ * SECMOD_OpenUserDB().
+ *
+ * Typical parameters here are configdir, tokenDescription and flags.
+ *
+ * a Full list is below:
+ *
+ *
+ * configDir - The location of the databases for this token. If configDir is
+ * not specified, and noCertDB and noKeyDB is not specified, the load
+ * will fail.
+ * certPrefix - Cert prefix for this token.
+ * keyPrefix - Prefix for the key database for this token. (if not specified,
+ * certPrefix will be used).
+ * tokenDescription - The label value for this token returned in the
+ * CK_TOKEN_INFO structure with an internationalize string (UTF8).
+ * This value will be truncated at 32 bytes (no NULL, partial UTF8
+ * characters dropped). You should specify a user friendly name here
+ * as this is the value the token will be refered to in most
+ * application UI's. You should make sure tokenDescription is unique.
+ * slotDescription - The slotDescription value for this token returned
+ * in the CK_SLOT_INFO structure with an internationalize string
+ * (UTF8). This value will be truncated at 64 bytes (no NULL, partial
+ * UTF8 characters dropped). This name will not change after the
+ * database is closed. It should have some number to make this unique.
+ * minPWLen - minimum password length for this token.
+ * flags - comma separated list of flag values, parsed case-insensitive.
+ * Valid flags are:
+ * readOnly - Databases should be opened read only.
+ * noCertDB - Don't try to open a certificate database.
+ * noKeyDB - Don't try to open a key database.
+ * forceOpen - Don't fail to initialize the token if the
+ * databases could not be opened.
+ * passwordRequired - zero length passwords are not acceptable
+ * (valid only if there is a keyDB).
+ * optimizeSpace - allocate smaller hash tables and lock tables.
+ * When this flag is not specified, Softoken will allocate
+ * large tables to prevent lock contention.
+ */
+PK11SlotInfo *
+SECMOD_OpenUserDB(const char *moduleSpec)
+{
+ CK_SLOT_ID slotID = 0;
+ char *escSpec;
+ char *sendSpec;
+ SECStatus rv;
+ SECMODModule *mod;
+ CK_SLOT_ID i, minSlotID, maxSlotID;
+ PRBool found = PR_FALSE;
+
+ if (moduleSpec == NULL) {
+ return NULL;
+ }
+
+ /* NOTE: unlike most PK11 function, this does not return a reference
+ * to the module */
+ mod = SECMOD_GetInternalModule();
+ if (!mod) {
+ /* shouldn't happen */
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return NULL;
+ }
+
+ /* look for a free slot id on the internal module */
+ if (mod->isFIPS) {
+ minSlotID = SFTK_MIN_FIPS_USER_SLOT_ID;
+ maxSlotID = SFTK_MAX_FIPS_USER_SLOT_ID;
+ } else {
+ minSlotID = SFTK_MIN_USER_SLOT_ID;
+ maxSlotID = SFTK_MAX_USER_SLOT_ID;
+ }
+ for (i=minSlotID; i < maxSlotID; i++) {
+ PK11SlotInfo *slot = SECMOD_LookupSlot(mod->moduleID, i);
+ if (slot) {
+ PRBool present = PK11_IsPresent(slot);
+ PK11_FreeSlot(slot);
+ if (present) {
+ continue;
+ }
+ /* not present means it's available */
+ }
+ /* it doesn't exist or isn't present, it's available */
+ slotID = i;
+ found = PR_TRUE;
+ break;
+ }
+
+ if (!found) {
+ /* this could happen if we try to open too many slots */
+ PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
+ return NULL;
+ }
+
+ /* we've found the slot, now build the moduleSpec */
+
+ escSpec = nss_doubleEscape(moduleSpec);
+ if (escSpec == NULL) {
+ return NULL;
+ }
+ sendSpec = PR_smprintf("tokens=[0x%x=<%s>]", slotID, escSpec);
+ PORT_Free(escSpec);
+
+ if (sendSpec == NULL) {
+ /* PR_smprintf does not set no memory error */
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
+ }
+ rv = secmod_UserDBOp(CKO_NETSCAPE_NEWSLOT, sendSpec);
+ PR_smprintf_free(sendSpec);
+ if (rv != SECSuccess) {
+ return NULL;
+ }
+
+ return SECMOD_FindSlotByID(mod, slotID);
+}
+
+/*
+ * close an already opened user database. NOTE: the database must be
+ * in the internal token, and must be one created with SECMOD_OpenUserDB().
+ * Once the database is closed, the slot will remain as an empty slot
+ * until it's used again with SECMOD_OpenUserDB().
+ */
+SECStatus
+SECMOD_CloseUserDB(PK11SlotInfo *slot)
+{
+ SECStatus rv;
+ char *sendSpec;
+
+ if (!slot->isInternal) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ sendSpec = PR_smprintf("tokens=[0x%x=<>]", slot->slotID);
+ if (sendSpec == NULL) {
+ /* PR_smprintf does not set no memory error */
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+ }
+ rv = secmod_UserDBOp(CKO_NETSCAPE_DELSLOT, sendSpec);
+ PR_smprintf_free(sendSpec);
+ return rv;
+}
diff --git a/security/nss/lib/pk11wrap/secmodi.h b/security/nss/lib/pk11wrap/secmodi.h
index 4514cdaf5..1e3a6aebd 100644
--- a/security/nss/lib/pk11wrap/secmodi.h
+++ b/security/nss/lib/pk11wrap/secmodi.h
@@ -59,7 +59,7 @@ void nss_DumpModuleLog(void);
extern int secmod_PrivateModuleCount;
extern void SECMOD_Init(void);
-SECStatus secmod_ModuleInit(SECMODModule *mod);
+SECStatus secmod_ModuleInit(SECMODModule *mod, PRBool* alreadyLoaded);
/* list managment */
extern SECStatus SECMOD_AddModuleToList(SECMODModule *newModule);
@@ -135,7 +135,6 @@ unsigned int pk11_AttrFlagsToAttributes(PK11AttrFlags attrFlags,
PRBool pk11_FindAttrInTemplate(CK_ATTRIBUTE *attr, unsigned int numAttrs,
CK_ATTRIBUTE_TYPE target);
-CK_MECHANISM_TYPE pk11_mapSignKeyType(KeyType keyType);
CK_MECHANISM_TYPE pk11_mapWrapKeyType(KeyType keyType);
PK11SymKey *pk11_KeyExchange(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags, PRBool isPerm,
diff --git a/security/nss/lib/pk11wrap/secmodt.h b/security/nss/lib/pk11wrap/secmodt.h
index cc63eddc7..a6f7b180f 100644
--- a/security/nss/lib/pk11wrap/secmodt.h
+++ b/security/nss/lib/pk11wrap/secmodt.h
@@ -66,6 +66,7 @@ typedef struct PK11RSAGenParamsStr PK11RSAGenParams;
typedef unsigned long SECMODModuleID;
typedef struct PK11DefaultArrayEntryStr PK11DefaultArrayEntry;
typedef struct PK11GenericObjectStr PK11GenericObject;
+typedef void (*PK11FreeDataFunc)(void *);
struct SECMODModuleStr {
PRArenaPool *arena;
diff --git a/security/nss/lib/pk11wrap/secmodti.h b/security/nss/lib/pk11wrap/secmodti.h
index a338e7b6d..328a07130 100644
--- a/security/nss/lib/pk11wrap/secmodti.h
+++ b/security/nss/lib/pk11wrap/secmodti.h
@@ -97,6 +97,7 @@ struct PK11SlotInfoStr {
* still in use */
PRInt32 refCount; /* to be in/decremented by atomic calls ONLY! */
PZLock *freeListLock;
+ PK11SymKey *freeSymKeysWithSessionHead;
PK11SymKey *freeSymKeysHead;
int keyCount;
int maxKeyCount;
@@ -153,19 +154,22 @@ struct PK11SymKeyStr {
CK_OBJECT_HANDLE objectID; /* object id of this key in the slot */
PK11SlotInfo *slot; /* Slot this key is loaded into */
void *cx; /* window context in case we need to loggin */
- PK11SymKey *next;
- PRBool owner;
- SECItem data; /* raw key data if available */
+ PK11SymKey *next;
+ PRBool owner;
+ SECItem data; /* raw key data if available */
CK_SESSION_HANDLE session;
- PRBool sessionOwner;
- PRInt32 refCount; /* number of references to this key */
- int size; /* key size in bytes */
- PK11Origin origin; /* where this key came from
- (see def in secmodt.h) */
- PK11SymKey *parent;
- uint16 series; /* break up the slot info into various groups of
- * inserted tokens so that keys and certs can be
- * invalidated */
+ PRBool sessionOwner;
+ PRInt32 refCount; /* number of references to this key */
+ int size; /* key size in bytes */
+ PK11Origin origin; /* where this key came from
+ * (see def in secmodt.h) */
+ PK11SymKey *parent; /* potential owner key of the session */
+ uint16 series; /* break up the slot info into various groups
+ * of inserted tokens so that keys and certs
+ * can be invalidated */
+ void *userData; /* random data the application can attach to
+ * this key */
+ PK11FreeDataFunc freeFunc; /* function to free the user data */
};
diff --git a/security/nss/lib/pkcs12/manifest.mn b/security/nss/lib/pkcs12/manifest.mn
index 7812674f2..af76ca2ed 100644
--- a/security/nss/lib/pkcs12/manifest.mn
+++ b/security/nss/lib/pkcs12/manifest.mn
@@ -59,8 +59,4 @@ CSRCS = \
REQUIRES = dbm
-ifdef NSS_ENABLE_ECC
-DEFINES += -DNSS_ENABLE_ECC
-endif
-
LIBRARY_NAME = pkcs12
diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c
index dd96e99bd..2d4d29cae 100644
--- a/security/nss/lib/pkcs12/p12d.c
+++ b/security/nss/lib/pkcs12/p12d.c
@@ -110,7 +110,6 @@ struct SEC_PKCS12DecoderContextStr {
/* state variables for decoding authenticated safes. */
SEC_PKCS7DecoderContext *currentASafeP7Dcx;
- SEC_PKCS5KeyAndPassword *currentASafeKeyPwd;
SEC_ASN1DecoderContext *aSafeDcx;
SEC_PKCS7DecoderContext *aSafeP7Dcx;
sec_PKCS12AuthenticatedSafe authSafe;
@@ -173,25 +172,43 @@ sec_pkcs12_proper_version(sec_PKCS12PFXItem *pfx)
static PK11SymKey *
sec_pkcs12_decoder_get_decrypt_key(void *arg, SECAlgorithmID *algid)
{
- SEC_PKCS5KeyAndPassword *keyPwd =
- (SEC_PKCS5KeyAndPassword *)arg;
+ SEC_PKCS12DecoderContext *p12dcx =
+ (SEC_PKCS12DecoderContext *) arg;
+ PK11SlotInfo *slot;
+ PK11SymKey *bulkKey;
- if(!keyPwd) {
+ if(!p12dcx) {
return NULL;
}
/* if no slot specified, use the internal key slot */
- if(!keyPwd->slot) {
- keyPwd->slot = PK11_GetInternalKeySlot();
+ if(p12dcx->slot) {
+ slot = PK11_ReferenceSlot(p12dcx->slot);
+ } else {
+ slot = PK11_GetInternalKeySlot();
+ }
+
+ bulkKey = PK11_PBEKeyGen(slot, algid, p12dcx->pwitem,
+ PR_FALSE, p12dcx->wincx);
+ /* some tokens can't generate PBE keys on their own, generate the
+ * key in the internal slot, and let the Import code deal with it,
+ * (if the slot can't generate PBEs, then we need to use the internal
+ * slot anyway to unwrap). */
+ if (!bulkKey && !PK11_IsInternal(slot)) {
+ PK11_FreeSlot(slot);
+ slot = PK11_GetInternalKeySlot();
+ bulkKey = PK11_PBEKeyGen(slot, algid, p12dcx->pwitem,
+ PR_FALSE, p12dcx->wincx);
}
+ PK11_FreeSlot(slot);
- /* retrieve the key */
- if(!keyPwd->key) {
- keyPwd->key = PK11_PBEKeyGen(keyPwd->slot, algid,
- keyPwd->pwitem, PR_FALSE, keyPwd->wincx);
+ /* set the password data on the key */
+ if (bulkKey) {
+ PK11_SetSymKeyUserData(bulkKey,p12dcx->pwitem, NULL);
}
- return (PK11SymKey *)keyPwd;
+
+ return bulkKey;
}
/* XXX this needs to be modified to handle enveloped data. most
@@ -778,25 +795,12 @@ sec_pkcs12_decoder_asafes_notify(void *arg, PRBool before, void *dest,
goto loser;
}
- /* set up password and encryption key information */
- p12dcx->currentASafeKeyPwd =
- (SEC_PKCS5KeyAndPassword*)PORT_ArenaZAlloc(p12dcx->arena,
- sizeof(SEC_PKCS5KeyAndPassword));
- if(!p12dcx->currentASafeKeyPwd) {
- p12dcx->errorValue = SEC_ERROR_NO_MEMORY;
- goto loser;
- }
- p12dcx->currentASafeKeyPwd->pwitem = p12dcx->pwitem;
- p12dcx->currentASafeKeyPwd->slot = p12dcx->slot;
- p12dcx->currentASafeKeyPwd->wincx = p12dcx->wincx;
-
/* initiate the PKCS7ContentInfo decode */
p12dcx->currentASafeP7Dcx = SEC_PKCS7DecoderStart(
sec_pkcs12_decoder_safe_contents_callback,
safeContentsCtx,
p12dcx->pwfn, p12dcx->pwfnarg,
- sec_pkcs12_decoder_get_decrypt_key,
- p12dcx->currentASafeKeyPwd,
+ sec_pkcs12_decoder_get_decrypt_key, p12dcx,
sec_pkcs12_decoder_decryption_allowed);
if(!p12dcx->currentASafeP7Dcx) {
p12dcx->errorValue = PORT_GetError();
@@ -818,9 +822,6 @@ sec_pkcs12_decoder_asafes_notify(void *arg, PRBool before, void *dest,
p12dcx->currentASafeP7Dcx = NULL;
}
p12dcx->currentASafeP7Dcx = NULL;
- if(p12dcx->currentASafeKeyPwd->key != NULL) {
- p12dcx->currentASafeKeyPwd->key = NULL;
- }
}
@@ -2793,11 +2794,9 @@ sec_pkcs12_get_public_value_and_type(sec_PKCS12SafeBag *certBag,
case rsaKey:
pubValue = SECITEM_DupItem(&pubKey->u.rsa.modulus);
break;
-#ifdef NSS_ENABLE_ECC
case ecKey:
pubValue = SECITEM_DupItem(&pubKey->u.ec.publicValue);
break;
-#endif /* NSS_ENABLE_ECC */
default:
pubValue = NULL;
}
diff --git a/security/nss/lib/pkcs12/p12e.c b/security/nss/lib/pkcs12/p12e.c
index 650fd175c..f0fbbcb2e 100644
--- a/security/nss/lib/pkcs12/p12e.c
+++ b/security/nss/lib/pkcs12/p12e.c
@@ -1901,10 +1901,9 @@ sec_pkcs12_encoder_asafe_process(sec_PKCS12EncoderContext *p12ecx)
{
SEC_PKCS7EncoderContext *innerP7ecx;
SEC_PKCS7ContentInfo *cinfo;
- void *arg = NULL;
+ PK11SymKey *bulkKey = NULL;
SEC_ASN1EncoderContext *innerA1ecx = NULL;
SECStatus rv = SECSuccess;
- SEC_PKCS5KeyAndPassword keyPwd;
if(p12ecx->currentSafe < p12ecx->p12exp->authSafe.safeCount) {
SEC_PKCS12SafeInfo *safeInfo;
@@ -1923,15 +1922,11 @@ sec_pkcs12_encoder_asafe_process(sec_PKCS12EncoderContext *p12ecx)
/* determine the safe type and set the appropriate argument */
switch(cinfoType) {
case SEC_OID_PKCS7_DATA:
- arg = NULL;
+ case SEC_OID_PKCS7_ENVELOPED_DATA:
break;
case SEC_OID_PKCS7_ENCRYPTED_DATA:
- keyPwd.pwitem = &safeInfo->pwitem;
- keyPwd.key = safeInfo->encryptionKey;
- arg = &keyPwd;
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- arg = NULL;
+ bulkKey = safeInfo->encryptionKey;
+ PK11_SetSymKeyUserData(bulkKey, &safeInfo->pwitem, NULL);
break;
default:
return SECFailure;
@@ -1941,7 +1936,7 @@ sec_pkcs12_encoder_asafe_process(sec_PKCS12EncoderContext *p12ecx)
/* start the PKCS7 encoder */
innerP7ecx = SEC_PKCS7EncoderStart(cinfo,
sec_P12P7OutputCB_CallA1Update,
- p12ecx->middleA1ecx, (PK11SymKey *)arg);
+ p12ecx->middleA1ecx, bulkKey);
if(!innerP7ecx) {
goto loser;
}
diff --git a/security/nss/lib/pkcs7/p7decode.c b/security/nss/lib/pkcs7/p7decode.c
index 36f4d6945..37a0c5b40 100644
--- a/security/nss/lib/pkcs7/p7decode.c
+++ b/security/nss/lib/pkcs7/p7decode.c
@@ -19,6 +19,7 @@
* the Initial Developer. 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
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -690,16 +691,6 @@ sec_pkcs7_decoder_start_decrypt (SEC_PKCS7DecoderContext *p7dcx, int depth,
decryptobj = sec_PKCS7CreateDecryptObject (bulkkey,
&(enccinfo->contentEncAlg));
- /*
- * For PKCS5 Encryption Algorithms, the bulkkey is actually a different
- * structure. Therefore, we need to set the bulkkey to the actual key
- * prior to freeing it.
- */
- if ( SEC_PKCS5IsAlgorithmPBEAlg(&(enccinfo->contentEncAlg)) && bulkkey ) {
- SEC_PKCS5KeyAndPassword *keyPwd = (SEC_PKCS5KeyAndPassword *)bulkkey;
- bulkkey = keyPwd->key;
- }
-
/*
* We are done with (this) bulkkey now.
*/
@@ -1674,6 +1665,7 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
algiddata = SECOID_FindOID (&(signerinfo->digestEncAlg.algorithm));
if (algiddata == NULL ||
((algiddata->offset != SEC_OID_PKCS1_RSA_ENCRYPTION) &&
+ (algiddata->offset != SEC_OID_ANSIX962_EC_PUBLIC_KEY) &&
(algiddata->offset != SEC_OID_ANSIX9_DSA_SIGNATURE))) {
PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
goto done;
@@ -1743,6 +1735,10 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
goto done;
}
+ /*
+ * XXX the 5th (algid) argument should be the signature algorithm.
+ * See sec_pkcs7_pick_sign_alg in p7encode.c.
+ */
goodsig = (PRBool)(VFY_VerifyData (encoded_attrs.data,
encoded_attrs.len,
publickey, &(signerinfo->encDigest),
@@ -1801,6 +1797,10 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
sig = &holder;
}
+ /*
+ * XXX the 4th (algid) argument should be the signature algorithm.
+ * See sec_pkcs7_pick_sign_alg in p7encode.c.
+ */
goodsig = (PRBool)(VFY_VerifyDigest (digest, publickey, sig,
SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg)),
cinfo->pwfn_arg)
diff --git a/security/nss/lib/pkcs7/p7encode.c b/security/nss/lib/pkcs7/p7encode.c
index 3188e0d21..2ef105598 100644
--- a/security/nss/lib/pkcs7/p7encode.c
+++ b/security/nss/lib/pkcs7/p7encode.c
@@ -19,6 +19,7 @@
* the Initial Developer. 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
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -869,6 +870,13 @@ sec_pkcs7_pick_sign_alg (SECOidTag hashalg, SECOidTag encalg)
default:
return SEC_OID_UNKNOWN;
}
+ case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
+ switch (hashalg) {
+ case SEC_OID_SHA1:
+ return SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
+ default:
+ return SEC_OID_UNKNOWN;
+ }
default:
break;
}
diff --git a/security/nss/lib/pkcs7/p7local.c b/security/nss/lib/pkcs7/p7local.c
index c75182282..b7f79b696 100644
--- a/security/nss/lib/pkcs7/p7local.c
+++ b/security/nss/lib/pkcs7/p7local.c
@@ -118,11 +118,12 @@ sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid)
if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
CK_MECHANISM pbeMech, cryptoMech;
SECItem *pbeParams, *pwitem;
- SEC_PKCS5KeyAndPassword *keyPwd;
- keyPwd = (SEC_PKCS5KeyAndPassword *)key;
- key = keyPwd->key;
- pwitem = keyPwd->pwitem;
+ pwitem = (SECItem *)PK11_GetSymKeyUserData(key);
+ if (!pwitem) {
+ PORT_Free(result);
+ return NULL;
+ }
pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);
pbeParams = PK11_ParamFromAlgid(algid);
@@ -211,25 +212,28 @@ sec_PKCS7CreateEncryptObject (PRArenaPool *poolp, PK11SymKey *key,
ciphercx = NULL;
if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
CK_MECHANISM pbeMech, cryptoMech;
- SECItem *pbeParams;
- SEC_PKCS5KeyAndPassword *keyPwd;
+ SECItem *pbeParams, *pwitem;
PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM));
PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM));
+ pwitem = (SECItem *)PK11_GetSymKeyUserData(key);
+ if (!pwitem) {
+ PORT_Free(result);
+ return NULL;
+ }
+
pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);
pbeParams = PK11_ParamFromAlgid(algid);
if(!pbeParams) {
PORT_Free(result);
return NULL;
}
- keyPwd = (SEC_PKCS5KeyAndPassword *)key;
- key = keyPwd->key;
pbeMech.pParameter = pbeParams->data;
pbeMech.ulParameterLen = pbeParams->len;
- if(PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech,
- keyPwd->pwitem, PR_FALSE) != CKR_OK) {
+ if(PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, pwitem,
+ PR_FALSE) != CKR_OK) {
PORT_Free(result);
SECITEM_ZfreeItem(pbeParams, PR_TRUE);
return NULL;
diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c
index f82b090da..3abca38c1 100644
--- a/security/nss/lib/pki/certificate.c
+++ b/security/nss/lib/pki/certificate.c
@@ -481,7 +481,7 @@ nssCertificate_BuildChain (
{
NSSCertificate **rvChain = NULL;
NSSUsage issuerUsage = *usage;
- nssPKIObjectCollection *collection;
+ nssPKIObjectCollection *collection = NULL;
PRUint32 rvCount = 0;
PRStatus st;
PRStatus ret = PR_SUCCESS;
@@ -767,6 +767,26 @@ NSSCertificate_IsPrivateKeyAvailable (
return isUser;
}
+/* sort the subject cert list from newest to oldest */
+PRIntn
+nssCertificate_SubjectListSort (
+ void *v1,
+ void *v2
+)
+{
+ NSSCertificate *c1 = (NSSCertificate *)v1;
+ NSSCertificate *c2 = (NSSCertificate *)v2;
+ nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1);
+ nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2);
+ if (!dc1) {
+ return dc2 ? 1 : 0;
+ } else if (!dc2) {
+ return -1;
+ } else {
+ return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
+ }
+}
+
NSS_IMPLEMENT PRBool
NSSUserCertificate_IsStillPresent (
NSSUserCertificate *uc,
@@ -860,83 +880,6 @@ NSSUserCertificate_DeriveSymmetricKey (
return NULL;
}
-NSS_IMPLEMENT void
-nssBestCertificate_SetArgs (
- nssBestCertificateCB *best,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policies
-)
-{
- if (timeOpt) {
- best->time = timeOpt;
- } else {
- NSSTime_Now(&best->sTime);
- best->time = &best->sTime;
- }
- best->usage = usage;
- best->policies = policies;
- best->cert = NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-nssBestCertificate_Callback (
- NSSCertificate *c,
- void *arg
-)
-{
- nssBestCertificateCB *best = (nssBestCertificateCB *)arg;
- nssDecodedCert *dc, *bestdc;
- dc = nssCertificate_GetDecoding(c);
- if (!best->cert) {
- /* usage */
- if (best->usage->anyUsage) {
- best->cert = nssCertificate_AddRef(c);
- } else {
-#ifdef NSS_3_4_CODE
- /* For this to work in NSS 3.4, we have to go out and fill in
- * all of the CERTCertificate fields. Why? Because the
- * matchUsage function calls CERT_IsCACert, which needs to know
- * what the trust values are for the cert.
- * Ignore the returned pointer, the refcount is in c anyway.
- */
- if (STAN_GetCERTCertificate(c) == NULL) {
- return PR_FAILURE;
- }
-#endif
- if (dc->matchUsage(dc, best->usage)) {
- best->cert = nssCertificate_AddRef(c);
- }
- }
- return PR_SUCCESS;
- }
- bestdc = nssCertificate_GetDecoding(best->cert);
- /* time */
- if (bestdc->isValidAtTime(bestdc, best->time)) {
- /* The current best cert is valid at time */
- if (!dc->isValidAtTime(dc, best->time)) {
- /* If the new cert isn't valid at time, it's not better */
- return PR_SUCCESS;
- }
- } else {
- /* The current best cert is not valid at time */
- if (dc->isValidAtTime(dc, best->time)) {
- /* If the new cert is valid at time, it's better */
- NSSCertificate_Destroy(best->cert);
- best->cert = nssCertificate_AddRef(c);
- return PR_SUCCESS;
- }
- }
- /* either they are both valid at time, or neither valid; take the newer */
- /* XXX later -- defer to policies */
- if (!bestdc->isNewerThan(bestdc, dc)) {
- NSSCertificate_Destroy(best->cert);
- best->cert = nssCertificate_AddRef(c);
- }
- /* policies */
- return PR_SUCCESS;
-}
-
NSS_IMPLEMENT nssSMIMEProfile *
nssSMIMEProfile_Create (
NSSCertificate *cert,
diff --git a/security/nss/lib/pki/pkim.h b/security/nss/lib/pki/pkim.h
index 3a28335d6..5fad8a13f 100644
--- a/security/nss/lib/pki/pkim.h
+++ b/security/nss/lib/pki/pkim.h
@@ -233,6 +233,13 @@ nssCertificate_GetDecoding
NSSCertificate *c
);
+extern PRIntn
+nssCertificate_SubjectListSort
+(
+ void *v1,
+ void *v2
+);
+
NSS_EXTERN nssDecodedCert *
nssDecodedCert_Create
(
diff --git a/security/nss/lib/pki/pkistore.c b/security/nss/lib/pki/pkistore.c
index d069846cf..ed35c9749 100644
--- a/security/nss/lib/pki/pkistore.c
+++ b/security/nss/lib/pki/pkistore.c
@@ -89,25 +89,6 @@ struct certificate_hash_entry_str
nssSMIMEProfile *profile;
};
-/* XXX This a common function that should be moved out, possibly an
- * nssSubjectCertificateList should be created?
- */
-/* sort the subject list from newest to oldest */
-static PRIntn subject_list_sort(void *v1, void *v2)
-{
- NSSCertificate *c1 = (NSSCertificate *)v1;
- NSSCertificate *c2 = (NSSCertificate *)v2;
- nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1);
- nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2);
- if (!dc1) {
- return dc2 ? 1 : 0;
- } else if (!dc2) {
- return -1;
- } else {
- return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
- }
-}
-
NSS_IMPLEMENT nssCertificateStore *
nssCertificateStore_Create (
NSSArena *arenaOpt
@@ -225,7 +206,7 @@ add_subject_entry (
if (!subjectList) {
return PR_FAILURE;
}
- nssList_SetSortFunction(subjectList, subject_list_sort);
+ nssList_SetSortFunction(subjectList, nssCertificate_SubjectListSort);
/* Add the cert entry to this list of subjects */
nssrv = nssList_Add(subjectList, cert);
if (nssrv != PR_SUCCESS) {
diff --git a/security/nss/lib/pki/pkitm.h b/security/nss/lib/pki/pkitm.h
index 04d701c45..7530809de 100644
--- a/security/nss/lib/pki/pkitm.h
+++ b/security/nss/lib/pki/pkitm.h
@@ -105,16 +105,6 @@ struct NSSUsageStr {
#endif
};
-typedef struct nssBestCertificateCBStr nssBestCertificateCB;
-
-struct nssBestCertificateCBStr {
- NSSCertificate *cert;
- NSSTime *time;
- NSSTime sTime; /* to avoid allocating when unnecessary */
- NSSUsage *usage;
- NSSPolicies *policies;
-};
-
typedef struct nssPKIObjectCollectionStr nssPKIObjectCollection;
typedef struct
diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c
index b85e88143..90727d011 100644
--- a/security/nss/lib/pki/tdcache.c
+++ b/security/nss/lib/pki/tdcache.c
@@ -150,22 +150,6 @@ new_cache_entry(NSSArena *arena, void *value, PRBool ownArena)
return ce;
}
-/* sort the subject list from newest to oldest */
-static PRIntn subject_list_sort(void *v1, void *v2)
-{
- NSSCertificate *c1 = (NSSCertificate *)v1;
- NSSCertificate *c2 = (NSSCertificate *)v2;
- nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1);
- nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2);
- if (!dc1) {
- return dc2 ? 1 : 0;
- } else if (!dc2) {
- return -1;
- } else {
- return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
- }
-}
-
/* this should not be exposed in a header, but is here to keep the above
* types/functions static
*/
@@ -598,7 +582,7 @@ add_subject_entry (
if (nickname) {
ce->nickname = nssUTF8_Duplicate(nickname, arena);
}
- nssList_SetSortFunction(list, subject_list_sort);
+ nssList_SetSortFunction(list, nssCertificate_SubjectListSort);
/* Add the cert entry to this list of subjects */
nssrv = nssList_AddUnique(list, cert);
if (nssrv != PR_SUCCESS) {
diff --git a/security/nss/lib/smime/cmscipher.c b/security/nss/lib/smime/cmscipher.c
index c4a37208f..00042937a 100644
--- a/security/nss/lib/smime/cmscipher.c
+++ b/security/nss/lib/smime/cmscipher.c
@@ -93,17 +93,14 @@ NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid)
/* set param and mechanism */
if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
CK_MECHANISM pbeMech, cryptoMech;
- SECItem *pbeParams;
- SEC_PKCS5KeyAndPassword *keyPwd;
+ SECItem *pbeParams, *pwitem;
PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM));
PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM));
- /* HACK ALERT!
- * in this case, key is not actually a PK11SymKey *, but a SEC_PKCS5KeyAndPassword *
- */
- keyPwd = (SEC_PKCS5KeyAndPassword *)key;
- key = keyPwd->key;
+ pwitem = PK11_GetSymKeyUserData(key);
+ if (!pwitem)
+ return NULL;
/* find correct PK11 mechanism and parameters to initialize pbeMech */
pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);
@@ -114,7 +111,7 @@ NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid)
pbeMech.ulParameterLen = pbeParams->len;
/* now map pbeMech to cryptoMech */
- if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, keyPwd->pwitem,
+ if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, pwitem,
PR_FALSE) != CKR_OK) {
SECITEM_ZfreeItem(pbeParams, PR_TRUE);
return NULL;
@@ -187,17 +184,14 @@ NSS_CMSCipherContext_StartEncrypt(PRArenaPool *poolp, PK11SymKey *key, SECAlgori
/* set param and mechanism */
if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
CK_MECHANISM pbeMech, cryptoMech;
- SECItem *pbeParams;
- SEC_PKCS5KeyAndPassword *keyPwd;
+ SECItem *pbeParams, *pwitem;
PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM));
PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM));
- /* HACK ALERT!
- * in this case, key is not actually a PK11SymKey *, but a SEC_PKCS5KeyAndPassword *
- */
- keyPwd = (SEC_PKCS5KeyAndPassword *)key;
- key = keyPwd->key;
+ pwitem = PK11_GetSymKeyUserData(key);
+ if (!pwitem)
+ return NULL;
/* find correct PK11 mechanism and parameters to initialize pbeMech */
pbeMech.mechanism = PK11_AlgtagToMechanism(algtag);
@@ -208,7 +202,7 @@ NSS_CMSCipherContext_StartEncrypt(PRArenaPool *poolp, PK11SymKey *key, SECAlgori
pbeMech.ulParameterLen = pbeParams->len;
/* now map pbeMech to cryptoMech */
- if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, keyPwd->pwitem,
+ if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, pwitem,
PR_FALSE) != CKR_OK) {
SECITEM_ZfreeItem(pbeParams, PR_TRUE);
return NULL;
diff --git a/security/nss/lib/smime/cmsencdata.c b/security/nss/lib/smime/cmsencdata.c
index fdf10c02b..0bcbb680a 100644
--- a/security/nss/lib/smime/cmsencdata.c
+++ b/security/nss/lib/smime/cmsencdata.c
@@ -245,16 +245,6 @@ NSS_CMSEncryptedData_Decode_BeforeData(NSSCMSEncryptedData *encd)
if (cinfo->ciphcx == NULL)
goto loser; /* error has been set by NSS_CMSCipherContext_StartDecrypt */
- /*
- * HACK ALERT!!
- * For PKCS5 Encryption Algorithms, the bulkkey is actually a different
- * structure. Therefore, we need to set the bulkkey to the actual key
- * prior to freeing it.
- */
- if (SEC_PKCS5IsAlgorithmPBEAlg(bulkalg)) {
- SEC_PKCS5KeyAndPassword *keyPwd = (SEC_PKCS5KeyAndPassword *)bulkkey;
- bulkkey = keyPwd->key;
- }
/* we are done with (this) bulkkey now. */
PK11_FreeSymKey(bulkkey);
diff --git a/security/nss/lib/smime/cmsenvdata.c b/security/nss/lib/smime/cmsenvdata.c
index 7b5aaf9c2..c575a995e 100644
--- a/security/nss/lib/smime/cmsenvdata.c
+++ b/security/nss/lib/smime/cmsenvdata.c
@@ -384,16 +384,6 @@ NSS_CMSEnvelopedData_Decode_BeforeData(NSSCMSEnvelopedData *envd)
if (cinfo->ciphcx == NULL)
goto loser; /* error has been set by NSS_CMSCipherContext_StartDecrypt */
- /*
- * HACK ALERT!!
- * For PKCS5 Encryption Algorithms, the bulkkey is actually a different
- * structure. Therefore, we need to set the bulkkey to the actual key
- * prior to freeing it.
- */
- if (SEC_PKCS5IsAlgorithmPBEAlg(bulkalg)) {
- SEC_PKCS5KeyAndPassword *keyPwd = (SEC_PKCS5KeyAndPassword *)bulkkey;
- bulkkey = keyPwd->key;
- }
rv = SECSuccess;
diff --git a/security/nss/lib/smime/cmsrecinfo.c b/security/nss/lib/smime/cmsrecinfo.c
index 6f0ed119d..07236adc1 100644
--- a/security/nss/lib/smime/cmsrecinfo.c
+++ b/security/nss/lib/smime/cmsrecinfo.c
@@ -63,8 +63,15 @@ nss_cmsrecipientinfo_usessubjectkeyid(NSSCMSRecipientInfo *ri)
return PR_FALSE;
}
-
-static SECOidData fakeContent = { 0 };
+/*
+ * NOTE: fakeContent marks CMSMessage structure which is only used as a carrier
+ * of pwfn_arg and arena pools. In an ideal world, NSSCMSMessage would not have
+ * been exported, and we would have added an ordinary enum to handle this
+ * check. Unfortunatly wo don't have that luxury so we are overloading the
+ * contentTypeTag field. NO code should every try to interpret this content tag
+ * as a real OID tag, or use any fields other than pwfn_arg or poolp of this
+ * CMSMessage for that matter */
+static const SECOidData fakeContent;
NSSCMSRecipientInfo *
nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type,
CERTCertificate *cert, SECKEYPublicKey *pubKey,
@@ -183,8 +190,8 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type,
case SEC_OID_MISSI_KEA_DSS_OLD:
case SEC_OID_MISSI_KEA_DSS:
case SEC_OID_MISSI_KEA:
- PORT_Assert(type != NSSCMSRecipientID_SubjectKeyID);
- if (type == NSSCMSRecipientID_SubjectKeyID) {
+ PORT_Assert(type == NSSCMSRecipientID_IssuerSN);
+ if (type != NSSCMSRecipientID_IssuerSN) {
rv = SECFailure;
break;
}
@@ -199,8 +206,8 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type,
}
break;
case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */
- PORT_Assert(type != NSSCMSRecipientID_SubjectKeyID);
- if (type == NSSCMSRecipientID_SubjectKeyID) {
+ PORT_Assert(type == NSSCMSRecipientID_IssuerSN);
+ if (type != NSSCMSRecipientID_IssuerSN) {
rv = SECFailure;
break;
}
diff --git a/security/nss/lib/smime/cmsreclist.c b/security/nss/lib/smime/cmsreclist.c
index 2402c3979..34e31d582 100644
--- a/security/nss/lib/smime/cmsreclist.c
+++ b/security/nss/lib/smime/cmsreclist.c
@@ -82,6 +82,9 @@ nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos, NSSCMSRecipien
rle->kind = RLSubjKeyID;
rle->id.subjectKeyID = ri->ri.keyTransRecipientInfo.recipientIdentifier.id.subjectKeyID;
break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return -1;
}
recipient_list[rlindex++] = rle;
} else {
diff --git a/security/nss/lib/smime/cmssiginfo.c b/security/nss/lib/smime/cmssiginfo.c
index a8549128c..675040b66 100644
--- a/security/nss/lib/smime/cmssiginfo.c
+++ b/security/nss/lib/smime/cmssiginfo.c
@@ -19,6 +19,7 @@
* the Initial Developer. 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
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -347,7 +348,9 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
CERTCertificate *cert;
NSSCMSVerificationStatus vs = NSSCMSVS_Unverified;
PLArenaPool *poolp;
- SECOidTag tag;
+ SECOidTag digestalgtag;
+ SECOidTag pubkAlgTag;
+ SECOidTag signAlgTag;
if (signerinfo == NULL)
return SECFailure;
@@ -366,6 +369,8 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
goto loser;
}
+ digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
+
/*
* XXX This may not be the right set of algorithms to check.
* I'd prefer to trust that just calling VFY_Verify{Data,Digest}
@@ -374,13 +379,14 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
* and we would Just Work. So this check should just be removed,
* but not until the VFY code is better at setting errors.
*/
- tag = SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg));
- switch (tag) {
+ pubkAlgTag = SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg));
+ switch (pubkAlgTag) {
case SEC_OID_PKCS1_RSA_ENCRYPTION:
case SEC_OID_ANSIX9_DSA_SIGNATURE:
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
+ case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
/* ok */
break;
case SEC_OID_UNKNOWN:
@@ -391,6 +397,8 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
goto loser;
}
+ signAlgTag = NSS_CMSUtil_MakeSignatureAlgorithm(digestalgtag, pubkAlgTag);
+
if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr)) {
if (contentType) {
/*
@@ -454,8 +462,7 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
}
vs = (VFY_VerifyData (encoded_attrs.data, encoded_attrs.len,
- publickey, &(signerinfo->encDigest),
- SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg)),
+ publickey, &(signerinfo->encDigest), signAlgTag,
signerinfo->cmsg->pwfn_arg) != SECSuccess)
? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
@@ -472,8 +479,7 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
goto loser;
vs = (!digest ||
- VFY_VerifyDigest(digest, publickey, sig,
- SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg)),
+ VFY_VerifyDigest(digest, publickey, sig, signAlgTag,
signerinfo->cmsg->pwfn_arg) != SECSuccess)
? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
}
diff --git a/security/nss/lib/smime/cmsutil.c b/security/nss/lib/smime/cmsutil.c
index fdb88f639..1765655bb 100644
--- a/security/nss/lib/smime/cmsutil.c
+++ b/security/nss/lib/smime/cmsutil.c
@@ -19,6 +19,7 @@
* the Initial Developer. 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
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -115,7 +116,7 @@ NSS_CMSUtil_DERCompare(void *a, void *b)
{
SECItem *der1 = (SECItem *)a;
SECItem *der2 = (SECItem *)b;
- int j;
+ unsigned int j;
/*
* Find the lowest (lexigraphically) encoding. One that is
@@ -255,6 +256,13 @@ NSS_CMSUtil_MakeSignatureAlgorithm(SECOidTag hashalg, SECOidTag encalg)
default:
return SEC_OID_UNKNOWN;
}
+ case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
+ switch (hashalg) {
+ case SEC_OID_SHA1:
+ return SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
+ default:
+ return SEC_OID_UNKNOWN;
+ }
default:
break;
}
diff --git a/security/nss/lib/smime/config.mk b/security/nss/lib/smime/config.mk
index d7f5c4519..236dd375b 100644
--- a/security/nss/lib/smime/config.mk
+++ b/security/nss/lib/smime/config.mk
@@ -50,6 +50,7 @@ ifdef NS_USE_GCC
EXTRA_SHARED_LIBS += \
-L$(DIST)/lib \
-lnss3 \
+ -L$(NSPR_LIB_DIR) \
-lplc4 \
-lplds4 \
-lnspr4 \
@@ -57,17 +58,18 @@ EXTRA_SHARED_LIBS += \
else # ! NS_USE_GCC
EXTRA_SHARED_LIBS += \
$(DIST)/lib/nss3.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)nspr4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
$(NULL)
endif # NS_USE_GCC
else
EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib/ \
+ -L$(DIST)/lib \
-lnss3 \
+ -L$(NSPR_LIB_DIR) \
-lplc4 \
-lplds4 \
-lnspr4 \
@@ -95,4 +97,3 @@ ifeq ($(OS_TARGET),SunOS)
# dependencies in the same directory where it resides.
MKSHLIB += -R '$$ORIGIN'
endif
-
diff --git a/security/nss/lib/softoken/cdbhdl.h b/security/nss/lib/softoken/cdbhdl.h
index a53aacea3..238a48669 100644
--- a/security/nss/lib/softoken/cdbhdl.h
+++ b/security/nss/lib/softoken/cdbhdl.h
@@ -45,6 +45,7 @@
#include "nspr.h"
#include "mcom_db.h"
#include "pcertt.h"
+#include "prtypes.h"
/*
* Handle structure for open certificate databases
@@ -53,8 +54,11 @@ struct NSSLOWCERTCertDBHandleStr {
DB *permCertDB;
PZMonitor *dbMon;
PRBool dbVerify;
+ PRInt32 ref; /* reference count */
};
+#define nsslowcert_reference(x) (PR_AtomicIncrement(&(x)->ref) , (x))
+
#ifdef DBM_USING_NSPR
#define NO_RDONLY PR_RDONLY
#define NO_RDWR PR_RDWR
diff --git a/security/nss/lib/softoken/config.mk b/security/nss/lib/softoken/config.mk
index eabf275dd..2e097c8a5 100644
--- a/security/nss/lib/softoken/config.mk
+++ b/security/nss/lib/softoken/config.mk
@@ -61,7 +61,7 @@ RESNAME = $(LIBRARY_NAME).rc
ifdef NS_USE_GCC
EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
+ -L$(NSPR_LIB_DIR) \
-lplc4 \
-lplds4 \
-lnspr4 \
@@ -69,9 +69,9 @@ EXTRA_SHARED_LIBS += \
else # ! NS_USE_GCC
EXTRA_SHARED_LIBS += \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)nspr4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
$(NULL)
endif # NS_USE_GCC
@@ -80,7 +80,7 @@ else
# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib/ \
+ -L$(NSPR_LIB_DIR) \
-lplc4 \
-lplds4 \
-lnspr4 \
@@ -96,3 +96,6 @@ endif
ifeq ($(OS_TARGET),WINCE)
DEFINES += -DDBM_USING_NSPR
endif
+
+# indicates dependency on freebl static lib
+$(SHARED_LIBRARY): $(CRYPTOLIB)
diff --git a/security/nss/lib/softoken/dbinit.c b/security/nss/lib/softoken/dbinit.c
index 110419dac..2b7f81a73 100644
--- a/security/nss/lib/softoken/dbinit.c
+++ b/security/nss/lib/softoken/dbinit.c
@@ -43,10 +43,12 @@
#include "prinit.h"
#include "prprf.h"
#include "prmem.h"
+#include "pratom.h"
#include "pcertt.h"
#include "lowkeyi.h"
#include "pcert.h"
#include "cdbhdl.h"
+#include "keydbi.h"
#include "pkcs11i.h"
static char *
@@ -164,6 +166,7 @@ sftk_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly,
if (certdb == NULL)
goto loser;
+ certdb->ref = 1;
/* fix when we get the DB in */
rv = nsslowcert_OpenCertDB(certdb, readOnly, appName, prefix,
sftk_certdb_name_cb, (void *)name, PR_FALSE);
@@ -254,20 +257,52 @@ loser:
return crv;
}
-
-void
-sftk_DBShutdown(NSSLOWCERTCertDBHandle *certHandle,
- NSSLOWKEYDBHandle *keyHandle)
+NSSLOWCERTCertDBHandle *
+sftk_getCertDB(SFTKSlot *slot)
{
+ NSSLOWCERTCertDBHandle *certHandle;
+
+ PZ_Lock(slot->slotLock);
+ certHandle = slot->certDB;
if (certHandle) {
- nsslowcert_ClosePermCertDB(certHandle);
- PORT_Free(certHandle);
+ PR_AtomicIncrement(&certHandle->ref);
}
+ PZ_Unlock(slot->slotLock);
+ return certHandle;
+}
+NSSLOWKEYDBHandle *
+sftk_getKeyDB(SFTKSlot *slot)
+{
+ NSSLOWKEYDBHandle *keyHandle;
+
+ PZ_Lock(slot->slotLock);
+ keyHandle = slot->keyDB;
if (keyHandle) {
- nsslowkey_CloseKeyDB(keyHandle);
+ PR_AtomicIncrement(&keyHandle->ref);
}
+ PZ_Unlock(slot->slotLock);
+ return keyHandle;
+}
+
+void
+sftk_freeCertDB(NSSLOWCERTCertDBHandle *certHandle)
+{
+ PRInt32 ref = PR_AtomicDecrement(&certHandle->ref);
+ if (ref == 0) {
+ nsslowcert_ClosePermCertDB(certHandle);
+ }
+}
+
+void
+sftk_freeKeyDB(NSSLOWKEYDBHandle *keyHandle)
+{
+ PRInt32 ref = PR_AtomicDecrement(&keyHandle->ref);
+ if (ref == 0) {
+ nsslowkey_CloseKeyDB(keyHandle);
+ }
}
+
static int rdbmapflags(int flags);
static rdbfunc sftk_rdbfunc = NULL;
diff --git a/security/nss/lib/softoken/fipstest.c b/security/nss/lib/softoken/fipstest.c
index 36e8f62d4..acee77676 100644
--- a/security/nss/lib/softoken/fipstest.c
+++ b/security/nss/lib/softoken/fipstest.c
@@ -68,16 +68,17 @@
#define FIPS_DES3_DECRYPT_LENGTH 8 /* 64-bits */
-/* FIPS preprocessor directives for MD2. */
-#define FIPS_MD2_HASH_MESSAGE_LENGTH 64 /* 512-bits */
+/* FIPS preprocessor directives for AES-ECB and AES-CBC. */
+#define FIPS_AES_BLOCK_SIZE 16 /* 128-bits */
+#define FIPS_AES_ENCRYPT_LENGTH 16 /* 128-bits */
+#define FIPS_AES_DECRYPT_LENGTH 16 /* 128-bits */
+#define FIPS_AES_128_KEY_SIZE 16 /* 128-bits */
+#define FIPS_AES_192_KEY_SIZE 24 /* 192-bits */
+#define FIPS_AES_256_KEY_SIZE 32 /* 256-bits */
-/* FIPS preprocessor directives for MD5. */
-#define FIPS_MD5_HASH_MESSAGE_LENGTH 64 /* 512-bits */
-
-
-/* FIPS preprocessor directives for SHA-1. */
-#define FIPS_SHA1_HASH_MESSAGE_LENGTH 64 /* 512-bits */
+/* FIPS preprocessor directives for message digests */
+#define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */
/* FIPS preprocessor directives for RSA. */
@@ -562,17 +563,186 @@ sftk_fips_DES3_PowerUpSelfTest( void )
}
+/* AES self-test for 128-bit, 192-bit, or 256-bit key sizes*/
static CK_RV
-sftk_fips_MD2_PowerUpSelfTest( void )
+sftk_fips_AES_PowerUpSelfTest( int aes_key_size )
{
- /* MD2 Known Hash Message (512-bits). */
- static const PRUint8 md2_known_hash_message[] = {
- "The test message for the MD2, MD5, and SHA-1 hashing algorithms." };
+ /* AES Known Key (up to 256-bits). */
+ static const PRUint8 aes_known_key[] =
+ { "AES-128 RIJNDAELLEADNJIR 821-SEA" };
+
+ /* AES-CBC Known Initialization Vector (128-bits). */
+ static const PRUint8 aes_cbc_known_initialization_vector[] =
+ { "SecurityytiruceS" };
+
+ /* AES Known Plaintext (128-bits). (blocksize is 128-bits) */
+ static const PRUint8 aes_known_plaintext[] = { "NetscapeepacsteN" };
+
+ /* AES Known Ciphertext (128-bit key). */
+ static const PRUint8 aes_ecb128_known_ciphertext[] = {
+ 0x3c,0xa5,0x96,0xf3,0x34,0x6a,0x96,0xc1,
+ 0x03,0x88,0x16,0x7b,0x20,0xbf,0x35,0x47 };
+
+ static const PRUint8 aes_cbc128_known_ciphertext[] = {
+ 0xcf,0x15,0x1d,0x4f,0x96,0xe4,0x4f,0x63,
+ 0x15,0x54,0x14,0x1d,0x4e,0xd8,0xd5,0xea };
+
+ /* AES Known Ciphertext (192-bit key). */
+ static const PRUint8 aes_ecb192_known_ciphertext[] = {
+ 0xa0,0x18,0x62,0xed,0x88,0x19,0xcb,0x62,
+ 0x88,0x1d,0x4d,0xfe,0x84,0x02,0x89,0x0e };
+
+ static const PRUint8 aes_cbc192_known_ciphertext[] = {
+ 0x83,0xf7,0xa4,0x76,0xd1,0x6f,0x07,0xbe,
+ 0x07,0xbc,0x43,0x2f,0x6d,0xad,0x29,0xe1 };
+
+ /* AES Known Ciphertext (256-bit key). */
+ static const PRUint8 aes_ecb256_known_ciphertext[] = {
+ 0xdb,0xa6,0x52,0x01,0x8a,0x70,0xae,0x66,
+ 0x3a,0x99,0xd8,0x95,0x7f,0xfb,0x01,0x67 };
+
+ static const PRUint8 aes_cbc256_known_ciphertext[] = {
+ 0x37,0xea,0x07,0x06,0x31,0x1c,0x59,0x27,
+ 0xc5,0xc5,0x68,0x71,0x6e,0x34,0x40,0x16 };
+
+ const PRUint8 *aes_ecb_known_ciphertext =
+ ( aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_ecb128_known_ciphertext :
+ ( aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_ecb192_known_ciphertext :
+ aes_ecb256_known_ciphertext;
+
+ const PRUint8 *aes_cbc_known_ciphertext =
+ ( aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_cbc128_known_ciphertext :
+ ( aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_cbc192_known_ciphertext :
+ aes_cbc256_known_ciphertext;
+
+ /* AES variables. */
+ PRUint8 aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH];
+ PRUint8 aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH];
+ AESContext * aes_context;
+ unsigned int aes_bytes_encrypted;
+ unsigned int aes_bytes_decrypted;
+ SECStatus aes_status;
+
+ /*check if aes_key_size is 128, 192, or 256 bits */
+ if ((aes_key_size != FIPS_AES_128_KEY_SIZE) &&
+ (aes_key_size != FIPS_AES_192_KEY_SIZE) &&
+ (aes_key_size != FIPS_AES_256_KEY_SIZE))
+ return( CKR_DEVICE_ERROR );
+
+ /******************************************************/
+ /* AES-ECB Single-Round Known Answer Encryption Test: */
+ /******************************************************/
+
+ aes_context = AES_CreateContext( aes_known_key, NULL, NSS_AES, PR_TRUE,
+ aes_key_size, FIPS_AES_BLOCK_SIZE );
+
+ if( aes_context == NULL )
+ return( CKR_HOST_MEMORY );
+
+ aes_status = AES_Encrypt( aes_context, aes_computed_ciphertext,
+ &aes_bytes_encrypted, FIPS_AES_ENCRYPT_LENGTH,
+ aes_known_plaintext,
+ FIPS_AES_DECRYPT_LENGTH );
+
+ AES_DestroyContext( aes_context, PR_TRUE );
+
+ if( ( aes_status != SECSuccess ) ||
+ ( aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH ) ||
+ ( PORT_Memcmp( aes_computed_ciphertext, aes_ecb_known_ciphertext,
+ FIPS_AES_ENCRYPT_LENGTH ) != 0 ) )
+ return( CKR_DEVICE_ERROR );
+
+
+ /******************************************************/
+ /* AES-ECB Single-Round Known Answer Decryption Test: */
+ /******************************************************/
+
+ aes_context = AES_CreateContext( aes_known_key, NULL, NSS_AES, PR_FALSE,
+ aes_key_size, FIPS_AES_BLOCK_SIZE );
+
+ if( aes_context == NULL )
+ return( CKR_HOST_MEMORY );
+
+ aes_status = AES_Decrypt( aes_context, aes_computed_plaintext,
+ &aes_bytes_decrypted, FIPS_AES_DECRYPT_LENGTH,
+ aes_ecb_known_ciphertext,
+ FIPS_AES_ENCRYPT_LENGTH );
+
+ AES_DestroyContext( aes_context, PR_TRUE );
+
+ if( ( aes_status != SECSuccess ) ||
+ ( aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH ) ||
+ ( PORT_Memcmp( aes_computed_plaintext, aes_known_plaintext,
+ FIPS_AES_DECRYPT_LENGTH ) != 0 ) )
+ return( CKR_DEVICE_ERROR );
+
+ /******************************************************/
+ /* AES-CBC Single-Round Known Answer Encryption Test. */
+ /******************************************************/
+
+ aes_context = AES_CreateContext( aes_known_key,
+ aes_cbc_known_initialization_vector,
+ NSS_AES_CBC, PR_TRUE, aes_key_size,
+ FIPS_AES_BLOCK_SIZE );
+
+ if( aes_context == NULL )
+ return( CKR_HOST_MEMORY );
+
+ aes_status = AES_Encrypt( aes_context, aes_computed_ciphertext,
+ &aes_bytes_encrypted, FIPS_AES_ENCRYPT_LENGTH,
+ aes_known_plaintext,
+ FIPS_AES_DECRYPT_LENGTH );
+
+ AES_DestroyContext( aes_context, PR_TRUE );
+
+ if( ( aes_status != SECSuccess ) ||
+ ( aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH ) ||
+ ( PORT_Memcmp( aes_computed_ciphertext, aes_cbc_known_ciphertext,
+ FIPS_AES_ENCRYPT_LENGTH ) != 0 ) )
+ return( CKR_DEVICE_ERROR );
+
+
+ /******************************************************/
+ /* AES-CBC Single-Round Known Answer Decryption Test. */
+ /******************************************************/
+
+ aes_context = AES_CreateContext( aes_known_key,
+ aes_cbc_known_initialization_vector,
+ NSS_AES_CBC, PR_FALSE, aes_key_size,
+ FIPS_AES_BLOCK_SIZE );
+
+ if( aes_context == NULL )
+ return( CKR_HOST_MEMORY );
+
+ aes_status = AES_Decrypt( aes_context, aes_computed_plaintext,
+ &aes_bytes_decrypted, FIPS_AES_DECRYPT_LENGTH,
+ aes_cbc_known_ciphertext,
+ FIPS_AES_ENCRYPT_LENGTH );
+
+ AES_DestroyContext( aes_context, PR_TRUE );
+
+ if( ( aes_status != SECSuccess ) ||
+ ( aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH ) ||
+ ( PORT_Memcmp( aes_computed_plaintext, aes_known_plaintext,
+ FIPS_AES_DECRYPT_LENGTH ) != 0 ) )
+ return( CKR_DEVICE_ERROR );
+
+ return( CKR_OK );
+}
+
+/* Known Hash Message (512-bits). Used for all hashes (incl. SHA-N [N>1]). */
+static const PRUint8 known_hash_message[] = {
+ "The test message for the MD2, MD5, and SHA-1 hashing algorithms." };
+
+
+static CK_RV
+sftk_fips_MD2_PowerUpSelfTest( void )
+{
/* MD2 Known Digest Message (128-bits). */
static const PRUint8 md2_known_digest[] = {
- 0x41,0x5a,0x12,0xb2,0x3f,0x28,0x97,0x17,
- 0x0c,0x71,0x4e,0xcc,0x40,0xc8,0x1d,0x1b};
+ 0x41,0x5a,0x12,0xb2,0x3f,0x28,0x97,0x17,
+ 0x0c,0x71,0x4e,0xcc,0x40,0xc8,0x1d,0x1b};
/* MD2 variables. */
MD2Context * md2_context;
@@ -591,13 +761,13 @@ sftk_fips_MD2_PowerUpSelfTest( void )
MD2_Begin( md2_context );
- MD2_Update( md2_context, md2_known_hash_message,
- FIPS_MD2_HASH_MESSAGE_LENGTH );
+ MD2_Update( md2_context, known_hash_message,
+ FIPS_KNOWN_HASH_MESSAGE_LENGTH );
MD2_End( md2_context, md2_computed_digest, &md2_bytes_hashed, MD2_LENGTH );
MD2_DestroyContext( md2_context , PR_TRUE );
-
+
if( ( md2_bytes_hashed != MD2_LENGTH ) ||
( PORT_Memcmp( md2_computed_digest, md2_known_digest,
MD2_LENGTH ) != 0 ) )
@@ -610,10 +780,6 @@ sftk_fips_MD2_PowerUpSelfTest( void )
static CK_RV
sftk_fips_MD5_PowerUpSelfTest( void )
{
- /* MD5 Known Hash Message (512-bits). */
- static const PRUint8 md5_known_hash_message[] = {
- "The test message for the MD2, MD5, and SHA-1 hashing algorithms." };
-
/* MD5 Known Digest Message (128-bits). */
static const PRUint8 md5_known_digest[] = {
0x25,0xc8,0xc0,0x10,0xc5,0x6e,0x68,0x28,
@@ -628,8 +794,8 @@ sftk_fips_MD5_PowerUpSelfTest( void )
/* MD5 Single-Round Known Answer Hashing Test. */
/***********************************************/
- md5_status = MD5_HashBuf( md5_computed_digest, md5_known_hash_message,
- FIPS_MD5_HASH_MESSAGE_LENGTH );
+ md5_status = MD5_HashBuf( md5_computed_digest, known_hash_message,
+ FIPS_KNOWN_HASH_MESSAGE_LENGTH );
if( ( md5_status != SECSuccess ) ||
( PORT_Memcmp( md5_computed_digest, md5_known_digest,
@@ -639,37 +805,244 @@ sftk_fips_MD5_PowerUpSelfTest( void )
return( CKR_OK );
}
+/****************************************************/
+/* Single Round HMAC SHA-X test */
+/****************************************************/
+static SECStatus
+sftk_fips_HMAC(unsigned char *hmac_computed,
+ const PRUint8 *secret_key,
+ unsigned int secret_key_length,
+ const PRUint8 *message,
+ unsigned int message_length,
+ HASH_HashType hashAlg )
+{
+ SECStatus hmac_status = SECFailure;
+ HMACContext *cx = NULL;
+ SECHashObject *hashObj = NULL;
+ unsigned int bytes_hashed = 0;
+
+ hashObj = (SECHashObject *) HASH_GetRawHashObject(hashAlg);
+
+ if (!hashObj)
+ return( SECFailure );
+
+ cx = HMAC_Create(hashObj, secret_key,
+ secret_key_length,
+ PR_TRUE); /* PR_TRUE for in FIPS mode */
+
+ if (cx == NULL)
+ return( SECFailure );
+
+ HMAC_Begin(cx);
+ HMAC_Update(cx, message, message_length);
+ hmac_status = HMAC_Finish(cx, hmac_computed, &bytes_hashed,
+ hashObj->length);
+
+ HMAC_Destroy(cx, PR_TRUE);
+
+ return( hmac_status );
+}
static CK_RV
-sftk_fips_SHA1_PowerUpSelfTest( void )
+sftk_fips_HMAC_PowerUpSelfTest( void )
{
- /* SHA-1 Known Hash Message (512-bits). */
- static const PRUint8 sha1_known_hash_message[] = {
- "The test message for the MD2, MD5, and SHA-1 hashing algorithms." };
+ static const PRUint8 HMAC_known_secret_key[] = {
+ "Firefox and ThunderBird are awesome!"};
+
+ static const PRUint8 HMAC_known_secret_key_length
+ = sizeof HMAC_known_secret_key;
+
+ /* known SHA1 hmac (20 bytes) */
+ static const PRUint8 known_SHA1_hmac[] = {
+ 0xd5, 0x85, 0xf6, 0x5b, 0x39, 0xfa, 0xb9, 0x05,
+ 0x3b, 0x57, 0x1d, 0x61, 0xe7, 0xb8, 0x84, 0x1e,
+ 0x5d, 0x0e, 0x1e, 0x11};
+
+ /* known SHA256 hmac (32 bytes) */
+ static const PRUint8 known_SHA256_hmac[] = {
+ 0x05, 0x75, 0x9a, 0x9e, 0x70, 0x5e, 0xe7, 0x44,
+ 0xe2, 0x46, 0x4b, 0x92, 0x22, 0x14, 0x22, 0xe0,
+ 0x1b, 0x92, 0x8a, 0x0c, 0xfe, 0xf5, 0x49, 0xe9,
+ 0xa7, 0x1b, 0x56, 0x7d, 0x1d, 0x29, 0x40, 0x48};
+
+ /* known SHA384 hmac (48 bytes) */
+ static const PRUint8 known_SHA384_hmac[] = {
+ 0xcd, 0x56, 0x14, 0xec, 0x05, 0x53, 0x06, 0x2b,
+ 0x7e, 0x9c, 0x8a, 0x18, 0x5e, 0xea, 0xf3, 0x91,
+ 0x33, 0xfb, 0x64, 0xf6, 0xe3, 0x9f, 0x89, 0x0b,
+ 0xaf, 0xbe, 0x83, 0x4d, 0x3f, 0x3c, 0x43, 0x4d,
+ 0x4a, 0x0c, 0x56, 0x98, 0xf8, 0xca, 0xb4, 0xaa,
+ 0x9a, 0xf4, 0x0a, 0xaf, 0x4f, 0x69, 0xca, 0x87};
+
+ /* known SHA512 hmac (64 bytes) */
+ static const PRUint8 known_SHA512_hmac[] = {
+ 0xf6, 0x0e, 0x97, 0x12, 0x00, 0x67, 0x6e, 0xb9,
+ 0x0c, 0xb2, 0x63, 0xf0, 0x60, 0xac, 0x75, 0x62,
+ 0x70, 0x95, 0x2a, 0x52, 0x22, 0xee, 0xdd, 0xd2,
+ 0x71, 0xb1, 0xe8, 0x26, 0x33, 0xd3, 0x13, 0x27,
+ 0xcb, 0xff, 0x44, 0xef, 0x87, 0x97, 0x16, 0xfb,
+ 0xd3, 0x0b, 0x48, 0xbe, 0x12, 0x4e, 0xda, 0xb1,
+ 0x89, 0x90, 0xfb, 0x06, 0x0c, 0xbe, 0xe5, 0xc4,
+ 0xff, 0x24, 0x37, 0x3d, 0xc7, 0xe4, 0xe4, 0x37};
+
+ SECStatus hmac_status;
+ PRUint8 hmac_computed[HASH_LENGTH_MAX];
+
+ /***************************************************/
+ /* HMAC SHA-1 Single-Round Known Answer HMAC Test. */
+ /***************************************************/
+
+ hmac_status = sftk_fips_HMAC(hmac_computed,
+ HMAC_known_secret_key,
+ HMAC_known_secret_key_length,
+ known_hash_message,
+ FIPS_KNOWN_HASH_MESSAGE_LENGTH,
+ HASH_AlgSHA1);
+
+ if( ( hmac_status != SECSuccess ) ||
+ ( PORT_Memcmp( hmac_computed, known_SHA1_hmac,
+ SHA1_LENGTH ) != 0 ) )
+ return( CKR_DEVICE_ERROR );
+
+ /***************************************************/
+ /* HMAC SHA-256 Single-Round Known Answer Test. */
+ /***************************************************/
+
+ hmac_status = sftk_fips_HMAC(hmac_computed,
+ HMAC_known_secret_key,
+ HMAC_known_secret_key_length,
+ known_hash_message,
+ FIPS_KNOWN_HASH_MESSAGE_LENGTH,
+ HASH_AlgSHA256);
+
+ if( ( hmac_status != SECSuccess ) ||
+ ( PORT_Memcmp( hmac_computed, known_SHA256_hmac,
+ SHA256_LENGTH ) != 0 ) )
+ return( CKR_DEVICE_ERROR );
+
+ /***************************************************/
+ /* HMAC SHA-384 Single-Round Known Answer Test. */
+ /***************************************************/
+ hmac_status = sftk_fips_HMAC(hmac_computed,
+ HMAC_known_secret_key,
+ HMAC_known_secret_key_length,
+ known_hash_message,
+ FIPS_KNOWN_HASH_MESSAGE_LENGTH,
+ HASH_AlgSHA384);
+
+ if( ( hmac_status != SECSuccess ) ||
+ ( PORT_Memcmp( hmac_computed, known_SHA384_hmac,
+ SHA384_LENGTH ) != 0 ) )
+ return( CKR_DEVICE_ERROR );
+
+ /***************************************************/
+ /* HMAC SHA-512 Single-Round Known Answer Test. */
+ /***************************************************/
+
+ hmac_status = sftk_fips_HMAC(hmac_computed,
+ HMAC_known_secret_key,
+ HMAC_known_secret_key_length,
+ known_hash_message,
+ FIPS_KNOWN_HASH_MESSAGE_LENGTH,
+ HASH_AlgSHA512);
+
+ if( ( hmac_status != SECSuccess ) ||
+ ( PORT_Memcmp( hmac_computed, known_SHA512_hmac,
+ SHA512_LENGTH ) != 0 ) )
+ return( CKR_DEVICE_ERROR );
+
+ return( CKR_OK );
+}
+
+static CK_RV
+sftk_fips_SHA_PowerUpSelfTest( void )
+{
/* SHA-1 Known Digest Message (160-bits). */
static const PRUint8 sha1_known_digest[] = {
0x0a,0x6d,0x07,0xba,0x1e,0xbd,0x8a,0x1b,
0x72,0xf6,0xc7,0x22,0xf1,0x27,0x9f,0xf0,
0xe0,0x68,0x47,0x7a};
- /* SHA-1 variables. */
- PRUint8 sha1_computed_digest[SHA1_LENGTH];
- SECStatus sha1_status;
-
+ /* SHA-256 Known Digest Message (256-bits). */
+ static const PRUint8 sha256_known_digest[] = {
+ 0x38,0xa9,0xc1,0xf0,0x35,0xf6,0x5d,0x61,
+ 0x11,0xd4,0x0b,0xdc,0xce,0x35,0x14,0x8d,
+ 0xf2,0xdd,0xaf,0xaf,0xcf,0xb7,0x87,0xe9,
+ 0x96,0xa5,0xd2,0x83,0x62,0x46,0x56,0x79};
+
+ /* SHA-384 Known Digest Message (384-bits). */
+ static const PRUint8 sha384_known_digest[] = {
+ 0x11,0xfe,0x1c,0x00,0x89,0x48,0xde,0xb3,
+ 0x99,0xee,0x1c,0x18,0xb4,0x10,0xfb,0xfe,
+ 0xe3,0xa8,0x2c,0xf3,0x04,0xb0,0x2f,0xc8,
+ 0xa3,0xc4,0x5e,0xea,0x7e,0x60,0x48,0x7b,
+ 0xce,0x2c,0x62,0xf7,0xbc,0xa7,0xe8,0xa3,
+ 0xcf,0x24,0xce,0x9c,0xe2,0x8b,0x09,0x72};
+
+ /* SHA-512 Known Digest Message (512-bits). */
+ static const PRUint8 sha512_known_digest[] = {
+ 0xc8,0xb3,0x27,0xf9,0x0b,0x24,0xc8,0xbf,
+ 0x4c,0xba,0x33,0x54,0xf2,0x31,0xbf,0xdb,
+ 0xab,0xfd,0xb3,0x15,0xd7,0xfa,0x48,0x99,
+ 0x07,0x60,0x0f,0x57,0x41,0x1a,0xdd,0x28,
+ 0x12,0x55,0x25,0xac,0xba,0x3a,0x99,0x12,
+ 0x2c,0x7a,0x8f,0x75,0x3a,0xe1,0x06,0x6f,
+ 0x30,0x31,0xc9,0x33,0xc6,0x1b,0x90,0x1a,
+ 0x6c,0x98,0x9a,0x87,0xd0,0xb2,0xf8,0x07};
+
+ /* SHA-X variables. */
+ PRUint8 sha_computed_digest[HASH_LENGTH_MAX];
+ SECStatus sha_status;
/*************************************************/
/* SHA-1 Single-Round Known Answer Hashing Test. */
/*************************************************/
- sha1_status = SHA1_HashBuf( sha1_computed_digest, sha1_known_hash_message,
- FIPS_SHA1_HASH_MESSAGE_LENGTH );
-
- if( ( sha1_status != SECSuccess ) ||
- ( PORT_Memcmp( sha1_computed_digest, sha1_known_digest,
+ sha_status = SHA1_HashBuf( sha_computed_digest, known_hash_message,
+ FIPS_KNOWN_HASH_MESSAGE_LENGTH );
+
+ if( ( sha_status != SECSuccess ) ||
+ ( PORT_Memcmp( sha_computed_digest, sha1_known_digest,
SHA1_LENGTH ) != 0 ) )
return( CKR_DEVICE_ERROR );
+ /***************************************************/
+ /* SHA-256 Single-Round Known Answer Hashing Test. */
+ /***************************************************/
+
+ sha_status = SHA256_HashBuf( sha_computed_digest, known_hash_message,
+ FIPS_KNOWN_HASH_MESSAGE_LENGTH );
+
+ if( ( sha_status != SECSuccess ) ||
+ ( PORT_Memcmp( sha_computed_digest, sha256_known_digest,
+ SHA256_LENGTH ) != 0 ) )
+ return( CKR_DEVICE_ERROR );
+
+ /***************************************************/
+ /* SHA-384 Single-Round Known Answer Hashing Test. */
+ /***************************************************/
+
+ sha_status = SHA384_HashBuf( sha_computed_digest, known_hash_message,
+ FIPS_KNOWN_HASH_MESSAGE_LENGTH );
+
+ if( ( sha_status != SECSuccess ) ||
+ ( PORT_Memcmp( sha_computed_digest, sha384_known_digest,
+ SHA384_LENGTH ) != 0 ) )
+ return( CKR_DEVICE_ERROR );
+
+ /***************************************************/
+ /* SHA-512 Single-Round Known Answer Hashing Test. */
+ /***************************************************/
+
+ sha_status = SHA512_HashBuf( sha_computed_digest, known_hash_message,
+ FIPS_KNOWN_HASH_MESSAGE_LENGTH );
+
+ if( ( sha_status != SECSuccess ) ||
+ ( PORT_Memcmp( sha_computed_digest, sha512_known_digest,
+ SHA512_LENGTH ) != 0 ) )
+ return( CKR_DEVICE_ERROR );
+
return( CKR_OK );
}
@@ -872,7 +1245,8 @@ sftk_fips_RSA_PowerUpSelfTest( void )
/* Perform RSA signature with the RSA private key. */
rsa_status = RSA_Sign( rsa_private_key, rsa_computed_signature,
&rsa_bytes_signed,
- FIPS_RSA_SIGNATURE_LENGTH, (unsigned char *)rsa_known_message,
+ FIPS_RSA_SIGNATURE_LENGTH,
+ (unsigned char *)rsa_known_message,
FIPS_RSA_MESSAGE_LENGTH );
if( ( rsa_status != SECSuccess ) ||
@@ -1059,6 +1433,24 @@ sftk_fipsPowerUpSelfTest( void )
if( rv != CKR_OK )
return rv;
+
+ /* AES Power-Up SelfTest(s) for 128-bit key. */
+ rv = sftk_fips_AES_PowerUpSelfTest(FIPS_AES_128_KEY_SIZE);
+
+ if( rv != CKR_OK )
+ return rv;
+
+ /* AES Power-Up SelfTest(s) for 192-bit key. */
+ rv = sftk_fips_AES_PowerUpSelfTest(FIPS_AES_192_KEY_SIZE);
+
+ if( rv != CKR_OK )
+ return rv;
+
+ /* AES Power-Up SelfTest(s) for 256-bit key. */
+ rv = sftk_fips_AES_PowerUpSelfTest(FIPS_AES_256_KEY_SIZE);
+
+ if( rv != CKR_OK )
+ return rv;
/* MD2 Power-Up SelfTest(s). */
rv = sftk_fips_MD2_PowerUpSelfTest();
@@ -1072,9 +1464,15 @@ sftk_fipsPowerUpSelfTest( void )
if( rv != CKR_OK )
return rv;
- /* SHA-1 Power-Up SelfTest(s). */
- rv = sftk_fips_SHA1_PowerUpSelfTest();
+ /* SHA-X Power-Up SelfTest(s). */
+ rv = sftk_fips_SHA_PowerUpSelfTest();
+
+ if( rv != CKR_OK )
+ return rv;
+ /* HMAC SHA-X Power-Up SelfTest(s). */
+ rv = sftk_fips_HMAC_PowerUpSelfTest();
+
if( rv != CKR_OK )
return rv;
diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c
index af0e957be..9ef144cb8 100644
--- a/security/nss/lib/softoken/fipstokn.c
+++ b/security/nss/lib/softoken/fipstokn.c
@@ -56,6 +56,8 @@
#include "pkcs11.h"
#include "pkcs11i.h"
+#include <ctype.h>
+
/*
* ******************** Password Utilities *******************************
@@ -63,7 +65,101 @@
static PRBool isLoggedIn = PR_FALSE;
static PRBool fatalError = PR_FALSE;
-/* Fips required checks before any useful crypto graphic services */
+/*
+ * This function returns
+ * - CKR_PIN_INVALID if the password/PIN is not a legal UTF8 string
+ * - CKR_PIN_LEN_RANGE if the password/PIN is too short or does not
+ * consist of characters from three or more character classes.
+ * - CKR_OK otherwise
+ *
+ * The minimum password/PIN length is FIPS_MIN_PIN Unicode characters.
+ * We define five character classes: digits (0-9), ASCII lowercase letters,
+ * ASCII uppercase letters, ASCII non-alphanumeric characters (such as
+ * space and punctuation marks), and non-ASCII characters. If an ASCII
+ * uppercase letter is the first character of the password/PIN, the
+ * uppercase letter is not counted toward its character class. Similarly,
+ * if a digit is the last character of the password/PIN, the digit is not
+ * counted toward its character class.
+ *
+ * Although NSC_SetPIN and NSC_InitPIN already do the maximum and minimum
+ * password/PIN length checks, they check the length in bytes as opposed
+ * to characters. To meet the minimum password/PIN guessing probability
+ * requirements in FIPS 140-2, we need to check the length in characters.
+ */
+static CK_RV sftk_newPinCheck(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
+ unsigned int i;
+ int nchar = 0; /* number of characters */
+ int ntrail = 0; /* number of trailing bytes to follow */
+ int ndigit = 0; /* number of decimal digits */
+ int nlower = 0; /* number of ASCII lowercase letters */
+ int nupper = 0; /* number of ASCII uppercase letters */
+ int nnonalnum = 0; /* number of ASCII non-alphanumeric characters */
+ int nnonascii = 0; /* number of non-ASCII characters */
+ int nclass; /* number of character classes */
+
+ for (i = 0; i < ulPinLen; i++) {
+ unsigned int byte = pPin[i];
+
+ if (ntrail) {
+ if ((byte & 0xc0) != 0x80) {
+ /* illegal */
+ nchar = -1;
+ break;
+ }
+ if (--ntrail == 0) {
+ nchar++;
+ nnonascii++;
+ }
+ continue;
+ }
+ if ((byte & 0x80) == 0x00) {
+ /* single-byte (ASCII) character */
+ nchar++;
+ if (isdigit(byte)) {
+ if (i < ulPinLen - 1) {
+ ndigit++;
+ }
+ } else if (islower(byte)) {
+ nlower++;
+ } else if (isupper(byte)) {
+ if (i > 0) {
+ nupper++;
+ }
+ } else {
+ nnonalnum++;
+ }
+ } else if ((byte & 0xe0) == 0xc0) {
+ /* leading byte of two-byte character */
+ ntrail = 1;
+ } else if ((byte & 0xf0) == 0xe0) {
+ /* leading byte of three-byte character */
+ ntrail = 2;
+ } else if ((byte & 0xf8) == 0xf0) {
+ /* leading byte of four-byte character */
+ ntrail = 3;
+ } else {
+ /* illegal */
+ nchar = -1;
+ break;
+ }
+ }
+ if (nchar == -1) {
+ /* illegal UTF8 string */
+ return CKR_PIN_INVALID;
+ }
+ if (nchar < FIPS_MIN_PIN) {
+ return CKR_PIN_LEN_RANGE;
+ }
+ nclass = (ndigit != 0) + (nlower != 0) + (nupper != 0) +
+ (nnonalnum != 0) + (nnonascii != 0);
+ if (nclass < 3) {
+ return CKR_PIN_LEN_RANGE;
+ }
+ return CKR_OK;
+}
+
+
+/* FIPS required checks before any useful cryptographic services */
static CK_RV sftk_fipsCheck(void) {
if (isLoggedIn != PR_TRUE)
return CKR_USER_NOT_LOGGED_IN;
@@ -273,13 +369,16 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
/* FC_InitToken initializes a token. */
CK_RV FC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
CK_ULONG usPinLen,CK_CHAR_PTR pLabel) {
- return CKR_HOST_MEMORY; /*is this the right function for not implemented*/
+ return NSC_InitToken(slotID,pPin,usPinLen,pLabel);
}
/* FC_InitPIN initializes the normal user's PIN. */
CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession,
CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
+ CK_RV rv;
+ SFTK_FIPSFATALCHECK();
+ if ((rv = sftk_newPinCheck(pPin,ulPinLen)) != CKR_OK) return rv;
return NSC_InitPIN(hSession,pPin,ulPinLen);
}
@@ -290,6 +389,7 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) {
CK_RV rv;
if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
+ if ((rv = sftk_newPinCheck(pNewPin,usNewLen)) != CKR_OK) return rv;
return NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen);
}
@@ -455,7 +555,7 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_FindObjectsInit(CK_SESSION_HANDLE hSession,
CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) {
/* let publically readable object be found */
- int i;
+ unsigned int i;
CK_RV rv;
PRBool needLogin = PR_FALSE;
@@ -780,6 +880,7 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey,
CK_OBJECT_HANDLE_PTR phPrivateKey) {
CK_BBOOL *boolptr;
+ CK_RV crv;
SFTK_FIPSCHECK();
@@ -792,9 +893,14 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
return CKR_ATTRIBUTE_VALUE_INVALID;
}
}
- return NSC_GenerateKeyPair (hSession,pMechanism,pPublicKeyTemplate,
+ crv = NSC_GenerateKeyPair (hSession,pMechanism,pPublicKeyTemplate,
usPublicKeyAttributeCount,pPrivateKeyTemplate,
usPrivateKeyAttributeCount,phPublicKey,phPrivateKey);
+ if (crv == CKR_GENERAL_ERROR) {
+ /* pairwise consistency check failed. */
+ fatalError = PR_TRUE;
+ }
+ return crv;
}
diff --git a/security/nss/lib/softoken/keydb.c b/security/nss/lib/softoken/keydb.c
index 8ab56ec5b..2f685a5a6 100644
--- a/security/nss/lib/softoken/keydb.c
+++ b/security/nss/lib/softoken/keydb.c
@@ -161,20 +161,21 @@ free_dbt(DBT *dbt)
return;
}
-static int keydb_Get(DB *db, DBT *key, DBT *data, unsigned int flags);
-static int keydb_Put(DB *db, DBT *key, DBT *data, unsigned int flags);
-static int keydb_Sync(DB *db, unsigned int flags);
-static int keydb_Del(DB *db, DBT *key, unsigned int flags);
-static int keydb_Seq(DB *db, DBT *key, DBT *data, unsigned int flags);
-static void keydb_Close(DB *db);
-
-static PZLock *kdbLock = NULL;
+static int keydb_Get(NSSLOWKEYDBHandle *db, DBT *key, DBT *data,
+ unsigned int flags);
+static int keydb_Put(NSSLOWKEYDBHandle *db, DBT *key, DBT *data,
+ unsigned int flags);
+static int keydb_Sync(NSSLOWKEYDBHandle *db, unsigned int flags);
+static int keydb_Del(NSSLOWKEYDBHandle *db, DBT *key, unsigned int flags);
+static int keydb_Seq(NSSLOWKEYDBHandle *db, DBT *key, DBT *data,
+ unsigned int flags);
+static void keydb_Close(NSSLOWKEYDBHandle *db);
static void
keydb_InitLocks(NSSLOWKEYDBHandle *handle)
{
- if (kdbLock == NULL) {
- nss_InitLock(&kdbLock, nssILockKeyDB);
+ if (handle->lock == NULL) {
+ nss_InitLock(&handle->lock, nssILockKeyDB);
}
return;
@@ -183,9 +184,9 @@ keydb_InitLocks(NSSLOWKEYDBHandle *handle)
static void
keydb_DestroyLocks(NSSLOWKEYDBHandle *handle)
{
- if (kdbLock != NULL) {
- PZ_DestroyLock(kdbLock);
- kdbLock = NULL;
+ if (handle->lock != NULL) {
+ PZ_DestroyLock(handle->lock);
+ handle->lock = NULL;
}
return;
@@ -348,7 +349,7 @@ get_dbkey(NSSLOWKEYDBHandle *handle, DBT *index)
int ret;
/* get it from the database */
- ret = keydb_Get(handle->db, index, &entry, 0);
+ ret = keydb_Get(handle, index, &entry, 0);
if ( ret ) {
PORT_SetError(SEC_ERROR_BAD_DATABASE);
return NULL;
@@ -374,9 +375,9 @@ put_dbkey(NSSLOWKEYDBHandle *handle, DBT *index, NSSLOWKEYDBKey *dbkey, PRBool u
/* put it in the database */
if ( update ) {
- status = keydb_Put(handle->db, index, keydata, 0);
+ status = keydb_Put(handle, index, keydata, 0);
} else {
- status = keydb_Put(handle->db, index, keydata, R_NOOVERWRITE);
+ status = keydb_Put(handle, index, keydata, R_NOOVERWRITE);
}
if ( status ) {
@@ -384,7 +385,7 @@ put_dbkey(NSSLOWKEYDBHandle *handle, DBT *index, NSSLOWKEYDBKey *dbkey, PRBool u
}
/* sync the database */
- status = keydb_Sync(handle->db, 0);
+ status = keydb_Sync(handle, 0);
if ( status ) {
goto loser;
}
@@ -414,7 +415,7 @@ nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle,
return(SECFailure);
}
- ret = keydb_Seq(handle->db, &key, &data, R_FIRST);
+ ret = keydb_Seq(handle, &key, &data, R_FIRST);
if ( ret ) {
return(SECFailure);
}
@@ -441,7 +442,7 @@ nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle,
return(status);
}
}
- } while ( keydb_Seq(handle->db, &key, &data, R_NEXT) == 0 );
+ } while ( keydb_Seq(handle, &key, &data, R_NEXT) == 0 );
return(SECSuccess);
}
@@ -521,7 +522,7 @@ GetKeyDBGlobalSalt(NSSLOWKEYDBHandle *handle)
saltKey.data = SALT_STRING;
saltKey.size = sizeof(SALT_STRING) - 1;
- ret = keydb_Get(handle->db, &saltKey, &saltData, 0);
+ ret = keydb_Get(handle, &saltKey, &saltData, 0);
if ( ret ) {
return(NULL);
}
@@ -543,7 +544,7 @@ StoreKeyDBGlobalSalt(NSSLOWKEYDBHandle *handle)
saltData.size = handle->global_salt->len;
/* put global salt into the database now */
- status = keydb_Put(handle->db, &saltKey, &saltData, 0);
+ status = keydb_Put(handle, &saltKey, &saltData, 0);
if ( status ) {
return(SECFailure);
}
@@ -566,7 +567,7 @@ makeGlobalVersion(NSSLOWKEYDBHandle *handle)
versionKey.size = sizeof(VERSION_STRING)-1;
/* put version string into the database now */
- status = keydb_Put(handle->db, &versionKey, &versionData, 0);
+ status = keydb_Put(handle, &versionKey, &versionData, 0);
if ( status ) {
return(SECFailure);
}
@@ -592,7 +593,7 @@ makeGlobalSalt(NSSLOWKEYDBHandle *handle)
RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf));
/* put global salt into the database now */
- status = keydb_Put(handle->db, &saltKey, &saltData, 0);
+ status = keydb_Put(handle, &saltKey, &saltData, 0);
if ( status ) {
return(SECFailure);
}
@@ -623,7 +624,7 @@ encodePWCheckEntry(PLArenaPool *arena, SECItem *entry, SECOidTag alg,
SECItem *encCheck);
static unsigned char
-nsslowkey_version(DB *db)
+nsslowkey_version(NSSLOWKEYDBHandle *handle)
{
DBT versionKey;
DBT versionData;
@@ -631,8 +632,12 @@ nsslowkey_version(DB *db)
versionKey.data = VERSION_STRING;
versionKey.size = sizeof(VERSION_STRING)-1;
+ if (handle->db == NULL) {
+ return 255;
+ }
+
/* lookup version string in database */
- ret = keydb_Get( db, &versionKey, &versionData, 0 );
+ ret = keydb_Get( handle, &versionKey, &versionData, 0 );
/* error accessing the database */
if ( ret < 0 ) {
@@ -646,14 +651,14 @@ nsslowkey_version(DB *db)
}
static PRBool
-seckey_HasAServerKey(DB *db)
+seckey_HasAServerKey(NSSLOWKEYDBHandle *handle)
{
DBT key;
DBT data;
int ret;
PRBool found = PR_FALSE;
- ret = keydb_Seq(db, &key, &data, R_FIRST);
+ ret = keydb_Seq(handle, &key, &data, R_FIRST);
if ( ret ) {
return PR_FALSE;
}
@@ -690,10 +695,14 @@ seckey_HasAServerKey(DB *db)
}
}
- } while ( keydb_Seq(db, &key, &data, R_NEXT) == 0 );
+ } while ( keydb_Seq(handle, &key, &data, R_NEXT) == 0 );
return found;
}
+
+/* forward declare local create function */
+static NSSLOWKEYDBHandle * nsslowkey_NewHandle(DB *dbHandle);
+
/*
* currently updates key database from v2 to v3
*/
@@ -710,18 +719,29 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
unsigned char version;
SECItem *rc4key = NULL;
NSSLOWKEYDBKey *dbkey = NULL;
+ NSSLOWKEYDBHandle *update = NULL;
SECItem *oldSalt = NULL;
int ret;
SECItem checkitem;
if ( handle->updatedb == NULL ) {
- return(SECSuccess);
+ return SECSuccess;
+ }
+
+ /* create a full DB Handle for our update so we
+ * can use the correct locks for the db primatives */
+ update = nsslowkey_NewHandle(handle->updatedb);
+ if ( update == NULL) {
+ return SECSuccess;
}
+ /* update has now inherited the database handle */
+ handle->updatedb = NULL;
+
/*
* check the version record
*/
- version = nsslowkey_version(handle->updatedb);
+ version = nsslowkey_version(update);
if (version != 2) {
goto done;
}
@@ -729,7 +749,7 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
saltKey.data = SALT_STRING;
saltKey.size = sizeof(SALT_STRING) - 1;
- ret = keydb_Get(handle->updatedb, &saltKey, &saltData, 0);
+ ret = keydb_Get(update, &saltKey, &saltData, 0);
if ( ret ) {
/* no salt in old db, so it is corrupted */
goto done;
@@ -747,8 +767,7 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
checkKey.data = KEYDB_PW_CHECK_STRING;
checkKey.size = KEYDB_PW_CHECK_LEN;
- ret = keydb_Get(handle->updatedb, &checkKey,
- &checkData, 0 );
+ ret = keydb_Get(update, &checkKey, &checkData, 0 );
if (ret) {
/*
* if we have a key, but no KEYDB_PW_CHECK_STRING, then this must
@@ -756,7 +775,7 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
* with it. Put a fake entry in so we can identify this db when we do
* get the password for it.
*/
- if (seckey_HasAServerKey(handle->updatedb)) {
+ if (seckey_HasAServerKey(update)) {
DBT fcheckKey;
DBT fcheckData;
@@ -768,11 +787,11 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
fcheckData.data = "1";
fcheckData.size = 1;
/* put global salt into the new database now */
- ret = keydb_Put( handle->db, &saltKey, &saltData, 0);
+ ret = keydb_Put( handle, &saltKey, &saltData, 0);
if ( ret ) {
goto done;
}
- ret = keydb_Put( handle->db, &fcheckKey, &fcheckData, 0);
+ ret = keydb_Put( handle, &fcheckKey, &fcheckData, 0);
if ( ret ) {
goto done;
}
@@ -781,7 +800,7 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
}
} else {
/* put global salt into the new database now */
- ret = keydb_Put( handle->db, &saltKey, &saltData, 0);
+ ret = keydb_Put( handle, &saltKey, &saltData, 0);
if ( ret ) {
goto done;
}
@@ -811,7 +830,7 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
/* now traverse the database */
- ret = keydb_Seq(handle->updatedb, &key, &data, R_FIRST);
+ ret = keydb_Seq(update, &key, &data, R_FIRST);
if ( ret ) {
goto done;
}
@@ -857,17 +876,15 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
sec_destroy_dbkey(dbkey);
}
- } while ( keydb_Seq(handle->updatedb, &key, &data,
- R_NEXT) == 0 );
+ } while ( keydb_Seq(update, &key, &data, R_NEXT) == 0 );
dbkey = NULL;
done:
/* sync the database */
- ret = keydb_Sync(handle->db, 0);
+ ret = keydb_Sync(handle, 0);
- keydb_Close(handle->updatedb);
- handle->updatedb = NULL;
+ nsslowkey_CloseKeyDB(update);
if ( rc4key ) {
SECITEM_FreeItem(rc4key, PR_TRUE);
@@ -913,7 +930,7 @@ openNewDB(const char *appName, const char *prefix, const char *dbname,
/* force a transactional read, which will verify that one and only one
* process attempts the update. */
- if (nsslowkey_version(handle->db) == NSSLOWKEY_DB_FILE_VERSION) {
+ if (nsslowkey_version(handle) == NSSLOWKEY_DB_FILE_VERSION) {
/* someone else has already updated the database for us */
db_FinishTransaction(handle->db, PR_FALSE);
db_InitComplete(handle->db);
@@ -925,20 +942,35 @@ openNewDB(const char *appName, const char *prefix, const char *dbname,
* local database we can update from.
*/
if (appName) {
+ NSSLOWKEYDBHandle *updateHandle = nsslowkey_NewHandle(updatedb);
updatedb = dbopen( dbname, NO_RDONLY, 0600, DB_HASH, 0 );
- if (updatedb) {
- handle->version = nsslowkey_version(updatedb);
- if (handle->version != NSSLOWKEY_DB_FILE_VERSION) {
- keydb_Close(updatedb);
- } else {
- db_Copy(handle->db, updatedb);
- keydb_Close(updatedb);
- db_FinishTransaction(handle->db,PR_FALSE);
- db_InitComplete(handle->db);
- return SECSuccess;
- }
+ if (!updatedb) {
+ goto noupdate;
}
+
+ /* nsslowkey_version needs a full handle because it calls
+ * the kdb_Get() function, which needs to lock.
+ */
+ updateHandle = nsslowkey_NewHandle(updatedb);
+ if (!updateHandle) {
+ updatedb->close(updatedb);
+ goto noupdate;
+ }
+
+ handle->version = nsslowkey_version(updateHandle);
+ if (handle->version != NSSLOWKEY_DB_FILE_VERSION) {
+ nsslowkey_CloseKeyDB(updateHandle);
+ goto noupdate;
+ }
+
+ /* copy the new DB from the old one */
+ db_Copy(handle->db, updatedb);
+ nsslowkey_CloseKeyDB(updateHandle);
+ db_FinishTransaction(handle->db,PR_FALSE);
+ db_InitComplete(handle->db);
+ return SECSuccess;
}
+noupdate:
/* update the version number */
rv = makeGlobalVersion(handle);
@@ -978,7 +1010,7 @@ openNewDB(const char *appName, const char *prefix, const char *dbname,
}
/* sync the database */
- ret = keydb_Sync(handle->db, 0);
+ ret = keydb_Sync(handle, 0);
if ( ret ) {
rv = SECFailure;
goto loser;
@@ -994,7 +1026,7 @@ loser:
static DB *
openOldDB(const char *appName, const char *prefix, const char *dbname,
- PRBool openflags, int *version) {
+ PRBool openflags) {
DB *db = NULL;
if (appName) {
@@ -1003,54 +1035,79 @@ openOldDB(const char *appName, const char *prefix, const char *dbname,
db = dbopen( dbname, openflags, 0600, DB_HASH, 0 );
}
- /* check for correct version number */
- if (db != NULL) {
- *version = nsslowkey_version(db);
- if (*version != NSSLOWKEY_DB_FILE_VERSION ) {
- /* bogus version number record, reset the database */
- keydb_Close( db );
- db = NULL;
+ return db;
+}
+
+/* check for correct version number */
+static PRBool
+verifyVersion(NSSLOWKEYDBHandle *handle)
+{
+ int version = nsslowkey_version(handle);
+
+ handle->version = version;
+ if (version != NSSLOWKEY_DB_FILE_VERSION ) {
+ if (handle->db) {
+ keydb_Close(handle);
+ handle->db = NULL;
}
}
- return db;
+ return handle->db != NULL;
}
-NSSLOWKEYDBHandle *
-nsslowkey_OpenKeyDB(PRBool readOnly, const char *appName, const char *prefix,
- NSSLOWKEYDBNameFunc namecb, void *cbarg)
+static NSSLOWKEYDBHandle *
+nsslowkey_NewHandle(DB *dbHandle)
{
NSSLOWKEYDBHandle *handle;
- SECStatus rv;
- int openflags;
- char *dbname = NULL;
-
handle = (NSSLOWKEYDBHandle *)PORT_ZAlloc (sizeof(NSSLOWKEYDBHandle));
if (handle == NULL) {
PORT_SetError (SEC_ERROR_NO_MEMORY);
return NULL;
}
+ handle->appname = NULL;
+ handle->dbname = NULL;
+ handle->global_salt = NULL;
+ handle->updatedb = NULL;
+ handle->db = dbHandle;
+ handle->ref = 1;
+
+ keydb_InitLocks(handle);
+ return handle;
+}
+
+NSSLOWKEYDBHandle *
+nsslowkey_OpenKeyDB(PRBool readOnly, const char *appName, const char *prefix,
+ NSSLOWKEYDBNameFunc namecb, void *cbarg)
+{
+ NSSLOWKEYDBHandle *handle = NULL;
+ SECStatus rv;
+ int openflags;
+ char *dbname = NULL;
+
+
+ handle = nsslowkey_NewHandle(NULL);
+
openflags = readOnly ? NO_RDONLY : NO_RDWR;
+
dbname = (*namecb)(cbarg, NSSLOWKEY_DB_FILE_VERSION);
if ( dbname == NULL ) {
goto loser;
}
-
handle->appname = appName ? PORT_Strdup(appName) : NULL ;
handle->dbname = (appName == NULL) ? PORT_Strdup(dbname) :
(prefix ? PORT_Strdup(prefix) : NULL);
handle->readOnly = readOnly;
- keydb_InitLocks(handle);
- handle->db = openOldDB(appName, prefix, dbname, openflags,
- &handle->version);
- if (handle->version == 255) {
- goto loser;
+ handle->db = openOldDB(appName, prefix, dbname, openflags);
+ if (handle->db) {
+ verifyVersion(handle);
+ if (handle->version == 255) {
+ goto loser;
+ }
}
-
/* if first open fails, try to create a new DB */
if ( handle->db == NULL ) {
@@ -1063,8 +1120,8 @@ nsslowkey_OpenKeyDB(PRBool readOnly, const char *appName, const char *prefix,
* The multiprocess code blocked the second one, then had it retry to
* see if it can just open the database normally */
if (rv == SECWouldBlock) {
- handle->db = openOldDB(appName,prefix,dbname,
- openflags, &handle->version);
+ handle->db = openOldDB(appName,prefix,dbname, openflags);
+ verifyVersion(handle);
if (handle->db == NULL) {
goto loser;
}
@@ -1083,14 +1140,7 @@ loser:
if ( dbname )
PORT_Free( dbname );
PORT_SetError(SEC_ERROR_BAD_DATABASE);
-
- if ( handle->db ) {
- keydb_Close(handle->db);
- }
- if ( handle->updatedb ) {
- keydb_Close(handle->updatedb);
- }
- PORT_Free(handle);
+ nsslowkey_CloseKeyDB(handle);
return NULL;
}
@@ -1102,8 +1152,11 @@ nsslowkey_CloseKeyDB(NSSLOWKEYDBHandle *handle)
{
if (handle != NULL) {
if (handle->db != NULL) {
- keydb_Close(handle->db);
+ keydb_Close(handle);
}
+ if (handle->updatedb) {
+ handle->updatedb->close(handle->updatedb);
+ }
if (handle->dbname) PORT_Free(handle->dbname);
if (handle->appname) PORT_Free(handle->appname);
if (handle->global_salt) {
@@ -1143,14 +1196,14 @@ nsslowkey_DeleteKey(NSSLOWKEYDBHandle *handle, SECItem *pubkey)
namekey.size = pubkey->len;
/* delete it from the database */
- ret = keydb_Del(handle->db, &namekey, 0);
+ ret = keydb_Del(handle, &namekey, 0);
if ( ret ) {
PORT_SetError(SEC_ERROR_BAD_DATABASE);
return(SECFailure);
}
/* sync the database */
- ret = keydb_Sync(handle->db, 0);
+ ret = keydb_Sync(handle, 0);
if ( ret ) {
PORT_SetError(SEC_ERROR_BAD_DATABASE);
return(SECFailure);
@@ -1195,7 +1248,7 @@ nsslowkey_KeyForIDExists(NSSLOWKEYDBHandle *handle, SECItem *id)
namekey.data = (char *)id->data;
namekey.size = id->len;
- status = keydb_Get(handle->db, &namekey, &dummy, 0);
+ status = keydb_Get(handle, &namekey, &dummy, 0);
if ( status ) {
return PR_FALSE;
}
@@ -1253,7 +1306,7 @@ nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cer
namekey.size = sizeof(buf);
}
- status = keydb_Get(handle->db, &namekey, &dummy, 0);
+ status = keydb_Get(handle, &namekey, &dummy, 0);
/* some databases have the key stored as a signed value */
if (status) {
unsigned char *buf = (unsigned char *)PORT_Alloc(namekey.size+1);
@@ -1262,7 +1315,7 @@ nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cer
buf[0] = 0;
namekey.data = buf;
namekey.size ++;
- status = keydb_Get(handle->db, &namekey, &dummy, 0);
+ status = keydb_Get(handle, &namekey, &dummy, 0);
PORT_Free(buf);
}
}
@@ -1290,12 +1343,12 @@ nsslowkey_HasKeyDBPassword(NSSLOWKEYDBHandle *handle)
checkkey.data = KEYDB_PW_CHECK_STRING;
checkkey.size = KEYDB_PW_CHECK_LEN;
- ret = keydb_Get(handle->db, &checkkey, &checkdata, 0 );
+ ret = keydb_Get(handle, &checkkey, &checkdata, 0 );
if ( ret ) {
/* see if this was an updated DB first */
checkkey.data = KEYDB_FAKE_PW_CHECK_STRING;
checkkey.size = KEYDB_FAKE_PW_CHECK_LEN;
- ret = keydb_Get(handle->db, &checkkey, &checkdata, 0 );
+ ret = keydb_Get(handle, &checkkey, &checkdata, 0 );
if ( ret ) {
return(SECFailure);
}
@@ -2423,7 +2476,7 @@ nsslowkey_CheckKeyDBPassword(NSSLOWKEYDBHandle *handle, SECItem *pwitem)
if ( dbkey == NULL ) {
checkkey.data = KEYDB_FAKE_PW_CHECK_STRING;
checkkey.size = KEYDB_FAKE_PW_CHECK_LEN;
- ret = keydb_Get(handle->db, &checkkey, &checkdata, 0 );
+ ret = keydb_Get(handle, &checkkey, &checkdata, 0 );
if (ret) {
goto loser;
}
@@ -2568,7 +2621,7 @@ ChangeKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
}
/* delete the old record */
- ret = keydb_Del(handle->db, &node->key, 0);
+ ret = keydb_Del(handle, &node->key, 0);
if ( ret ) {
PORT_SetError(SEC_ERROR_BAD_DATABASE);
rv = SECFailure;
@@ -2685,7 +2738,7 @@ nsslowkey_ResetKeyDB(NSSLOWKEYDBHandle *handle)
return SECFailure;
}
- keydb_Close(handle->db);
+ keydb_Close(handle);
if (handle->appname) {
handle->db=
rdbopen(handle->appname, handle->dbname, "key", NO_CREATE, NULL);
@@ -2717,17 +2770,19 @@ nsslowkey_ResetKeyDB(NSSLOWKEYDBHandle *handle)
done:
/* sync the database */
- ret = keydb_Sync(handle->db, 0);
+ ret = keydb_Sync(handle, 0);
db_InitComplete(handle->db);
return (errors == 0 ? SECSuccess : SECFailure);
}
static int
-keydb_Get(DB *db, DBT *key, DBT *data, unsigned int flags)
+keydb_Get(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags)
{
PRStatus prstat;
int ret;
+ PRLock *kdbLock = kdb->lock;
+ DB *db = kdb->db;
PORT_Assert(kdbLock != NULL);
PZ_Lock(kdbLock);
@@ -2740,10 +2795,12 @@ keydb_Get(DB *db, DBT *key, DBT *data, unsigned int flags)
}
static int
-keydb_Put(DB *db, DBT *key, DBT *data, unsigned int flags)
+keydb_Put(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags)
{
PRStatus prstat;
int ret = 0;
+ PRLock *kdbLock = kdb->lock;
+ DB *db = kdb->db;
PORT_Assert(kdbLock != NULL);
PZ_Lock(kdbLock);
@@ -2756,10 +2813,12 @@ keydb_Put(DB *db, DBT *key, DBT *data, unsigned int flags)
}
static int
-keydb_Sync(DB *db, unsigned int flags)
+keydb_Sync(NSSLOWKEYDBHandle *kdb, unsigned int flags)
{
PRStatus prstat;
int ret;
+ PRLock *kdbLock = kdb->lock;
+ DB *db = kdb->db;
PORT_Assert(kdbLock != NULL);
PZ_Lock(kdbLock);
@@ -2772,10 +2831,12 @@ keydb_Sync(DB *db, unsigned int flags)
}
static int
-keydb_Del(DB *db, DBT *key, unsigned int flags)
+keydb_Del(NSSLOWKEYDBHandle *kdb, DBT *key, unsigned int flags)
{
PRStatus prstat;
int ret;
+ PRLock *kdbLock = kdb->lock;
+ DB *db = kdb->db;
PORT_Assert(kdbLock != NULL);
PZ_Lock(kdbLock);
@@ -2788,10 +2849,12 @@ keydb_Del(DB *db, DBT *key, unsigned int flags)
}
static int
-keydb_Seq(DB *db, DBT *key, DBT *data, unsigned int flags)
+keydb_Seq(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags)
{
PRStatus prstat;
int ret;
+ PRLock *kdbLock = kdb->lock;
+ DB *db = kdb->db;
PORT_Assert(kdbLock != NULL);
PZ_Lock(kdbLock);
@@ -2804,9 +2867,11 @@ keydb_Seq(DB *db, DBT *key, DBT *data, unsigned int flags)
}
static void
-keydb_Close(DB *db)
+keydb_Close(NSSLOWKEYDBHandle *kdb)
{
PRStatus prstat;
+ PRLock *kdbLock = kdb->lock;
+ DB *db = kdb->db;
PORT_Assert(kdbLock != NULL);
PZ_Lock(kdbLock);
diff --git a/security/nss/lib/softoken/keydbi.h b/security/nss/lib/softoken/keydbi.h
index 1c9c2699a..f7f427266 100644
--- a/security/nss/lib/softoken/keydbi.h
+++ b/security/nss/lib/softoken/keydbi.h
@@ -56,6 +56,8 @@ struct NSSLOWKEYDBHandleStr {
char *appname; /* multiaccess app name */
char *dbname; /* name of the openned DB */
PRBool readOnly; /* is the DB read only */
+ PRLock *lock;
+ PRInt32 ref; /* reference count */
};
/*
diff --git a/security/nss/lib/softoken/lowcert.c b/security/nss/lib/softoken/lowcert.c
index 01659aba2..cb048307d 100644
--- a/security/nss/lib/softoken/lowcert.c
+++ b/security/nss/lib/softoken/lowcert.c
@@ -50,6 +50,7 @@
#include "pcert.h"
#include "secasn1.h"
#include "secoid.h"
+#include "secerr.h"
#ifdef NSS_ENABLE_ECC
extern SECStatus EC_FillParams(PRArenaPool *arena,
@@ -362,21 +363,41 @@ nsslowcert_IsNewer(NSSLOWCERTCertificate *certa, NSSLOWCERTCertificate *certb)
#define SOFT_DEFAULT_CHUNKSIZE 2048
-
static SECStatus
-nsslowcert_KeyFromIssuerAndSN(PRArenaPool *arena, SECItem *issuer, SECItem *sn,
- SECItem *key)
+nsslowcert_KeyFromIssuerAndSN(PRArenaPool *arena,
+ SECItem *issuer, SECItem *sn, SECItem *key)
{
unsigned int len = sn->len + issuer->len;
-
- if (arena) {
- key->data = (unsigned char*)PORT_ArenaAlloc(arena, len);
- } else {
- if (len > key->len) {
- key->data = (unsigned char*)PORT_ArenaAlloc(arena, len);
- }
+ if (!arena) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto loser;
}
+ key->data = (unsigned char*)PORT_ArenaAlloc(arena, len);
+ if ( !key->data ) {
+ goto loser;
+ }
+
+ key->len = len;
+ /* copy the serialNumber */
+ PORT_Memcpy(key->data, sn->data, sn->len);
+
+ /* copy the issuer */
+ PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);
+
+ return(SECSuccess);
+
+loser:
+ return(SECFailure);
+}
+
+static SECStatus
+nsslowcert_KeyFromIssuerAndSNStatic(unsigned char *space,
+ int spaceLen, SECItem *issuer, SECItem *sn, SECItem *key)
+{
+ unsigned int len = sn->len + issuer->len;
+
+ key->data = pkcs11_allocStaticData(len, space, spaceLen);
if ( !key->data ) {
goto loser;
}
@@ -428,12 +449,12 @@ nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, char *nickname)
cert->subjectKeyID.len = 0;
cert->dbEntry = NULL;
cert ->trust = NULL;
+ cert ->dbhandle = NULL;
/* generate and save the database key for the cert */
- cert->certKey.data = cert->certKeySpace;
- cert->certKey.len = sizeof(cert->certKeySpace);
- rv = nsslowcert_KeyFromIssuerAndSN(NULL, &cert->derIssuer,
- &cert->serialNumber, &cert->certKey);
+ rv = nsslowcert_KeyFromIssuerAndSNStatic(cert->certKeySpace,
+ sizeof(cert->certKeySpace), &cert->derIssuer,
+ &cert->serialNumber, &cert->certKey);
if ( rv ) {
goto loser;
}
diff --git a/security/nss/lib/softoken/lowpbe.c b/security/nss/lib/softoken/lowpbe.c
index 02ba3dfdb..81a0cb06b 100644
--- a/security/nss/lib/softoken/lowpbe.c
+++ b/security/nss/lib/softoken/lowpbe.c
@@ -249,7 +249,7 @@ nsspkcs5_PFXPBE(const SECHashObject *hashObj, NSSPKCS5PBEParameter *pbe_param,
loser:
if (state != NULL)
PORT_ZFree(state, state_len);
- HMAC_Destroy(cx);
+ HMAC_Destroy(cx, PR_TRUE);
if(rv != SECSuccess) {
SECITEM_ZfreeItem(ret_bits, PR_TRUE);
@@ -363,7 +363,7 @@ nsspkcs5_PBKFD2_F(const SECHashObject *hashobj, SECItem *pwitem, SECItem *salt,
}
loser:
if (cx) {
- HMAC_DestroyContext(cx);
+ HMAC_DestroyContext(cx, PR_TRUE);
}
if (last) {
PORT_ZFree(last,reaLastLength);
@@ -587,7 +587,7 @@ nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
iv->len = pbe_param->ivLen;
}
- hashObj = &SECRawHashObjects[pbe_param->hashType];
+ hashObj = HASH_GetRawHashObject(pbe_param->hashType);
switch (pbe_param->pbeType) {
case NSSPKCS5_PBKDF1:
hash = nsspkcs5_PBKDF1Extended(hashObj,pbe_param,pwitem,faulty3DES);
diff --git a/security/nss/lib/softoken/manifest.mn b/security/nss/lib/softoken/manifest.mn
index 57f2b273b..52d1f75cd 100644
--- a/security/nss/lib/softoken/manifest.mn
+++ b/security/nss/lib/softoken/manifest.mn
@@ -58,10 +58,10 @@ EXPORTS = \
PRIVATE_EXPORTS = \
pk11pars.h \
+ pkcs11ni.h \
$(NULL)
CSRCS = \
- alghmac.c \
dbinit.c \
dbmshim.c \
ecdecode.c \
@@ -77,7 +77,6 @@ CSRCS = \
pkcs11.c \
pkcs11c.c \
pkcs11u.c \
- rawhash.c \
rsawrapr.c \
softkver.c \
tlsprf.c \
diff --git a/security/nss/lib/softoken/pcert.h b/security/nss/lib/softoken/pcert.h
index 15b268433..a808373d8 100644
--- a/security/nss/lib/softoken/pcert.h
+++ b/security/nss/lib/softoken/pcert.h
@@ -237,6 +237,9 @@ void
pkcs11_freeStaticData(unsigned char *data, unsigned char *space);
unsigned char *
+pkcs11_allocStaticData(int datalen, unsigned char *space, int spaceLen);
+
+unsigned char *
pkcs11_copyStaticData(unsigned char *data, int datalen, unsigned char *space,
int spaceLen);
NSSLOWCERTCertificate *
diff --git a/security/nss/lib/softoken/pcertdb.c b/security/nss/lib/softoken/pcertdb.c
index 80faa7d84..4a7706378 100644
--- a/security/nss/lib/softoken/pcertdb.c
+++ b/security/nss/lib/softoken/pcertdb.c
@@ -60,6 +60,7 @@
#include "plhash.h"
#include "cdbhdl.h"
+#include "pkcs11i.h"
/* forward declaration */
NSSLOWCERTCertificate *
@@ -389,16 +390,24 @@ pkcs11_freeStaticData (unsigned char *data, unsigned char *space)
}
unsigned char *
-pkcs11_copyStaticData(unsigned char *data, int len,
- unsigned char *space, int spaceLen)
+pkcs11_allocStaticData(int len, unsigned char *space, int spaceLen)
{
- unsigned char *copy = NULL;
+ unsigned char *data = NULL;
if (len <= spaceLen) {
- copy = space;
+ data = space;
} else {
- copy = (unsigned char *) PORT_Alloc(len);
+ data = (unsigned char *) PORT_Alloc(len);
}
+
+ return data;
+}
+
+unsigned char *
+pkcs11_copyStaticData(unsigned char *data, int len,
+ unsigned char *space, int spaceLen)
+{
+ unsigned char *copy = pkcs11_allocStaticData(len, space, spaceLen);
if (copy) {
PORT_Memcpy(copy,data,len);
}
@@ -3386,12 +3395,15 @@ AddCertToPermDB(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTCertificate *cert,
state = 2;
- cert->dbhandle = handle;
+ /* "Change" handles if necessary */
+ if (cert->dbhandle) {
+ sftk_freeCertDB(cert->dbhandle);
+ }
+ cert->dbhandle = nsslowcert_reference(handle);
/* add to or create new subject entry */
if ( subjectEntry ) {
/* REWRITE BASED ON SUBJECT ENTRY */
- cert->dbhandle = handle;
rv = AddPermSubjectNode(subjectEntry, cert, nickname);
if ( rv != SECSuccess ) {
goto loser;
@@ -3513,6 +3525,9 @@ UpdateV7DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
case certDBEntryTypeSubject:
case certDBEntryTypeContentVersion:
case certDBEntryTypeNickname:
+ /* smime profiles need entries created after the certs have
+ * been imported, loop over them in a second run */
+ case certDBEntryTypeSMimeProfile:
break;
case certDBEntryTypeCert:
@@ -3560,22 +3575,45 @@ UpdateV7DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
crlEntry.common.arena = NULL;
break;
- case certDBEntryTypeSMimeProfile:
- smimeEntry.common.version = (unsigned int)dataBuf[0];
- smimeEntry.common.type = entryType;
- smimeEntry.common.flags = (unsigned int)dataBuf[2];
- smimeEntry.common.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- rv = DecodeDBSMimeEntry(&smimeEntry,&dbEntry,(char *)dbKey.data);
- /* decode entry */
+ default:
+ break;
+ }
+ } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 );
+
+ /* now loop again updating just the SMimeProfile. */
+ ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
+
+ if ( ret ) {
+ return(SECFailure);
+ }
+
+ do {
+ unsigned char *dataBuf = (unsigned char *)data.data;
+ unsigned char *keyBuf = (unsigned char *)key.data;
+ dbEntry.data = &dataBuf[SEC_DB_ENTRY_HEADER_LEN];
+ dbEntry.len = data.size - SEC_DB_ENTRY_HEADER_LEN;
+ entryType = (certDBEntryType) keyBuf[0];
+ if (entryType != certDBEntryTypeSMimeProfile) {
+ continue;
+ }
+ dbKey.data = &keyBuf[SEC_DB_KEY_HEADER_LEN];
+ dbKey.len = key.size - SEC_DB_KEY_HEADER_LEN;
+ if ((dbEntry.len <= 0) || (dbKey.len <= 0)) {
+ continue;
+ }
+ smimeEntry.common.version = (unsigned int)dataBuf[0];
+ smimeEntry.common.type = entryType;
+ smimeEntry.common.flags = (unsigned int)dataBuf[2];
+ smimeEntry.common.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ /* decode entry */
+ rv = DecodeDBSMimeEntry(&smimeEntry,&dbEntry,(char *)dbKey.data);
+ if (rv == SECSuccess) {
nsslowcert_UpdateSMimeProfile(handle, smimeEntry.emailAddr,
&smimeEntry.subjectName, &smimeEntry.smimeOptions,
&smimeEntry.optionsDate);
- PORT_FreeArena(smimeEntry.common.arena, PR_FALSE);
- smimeEntry.common.arena = NULL;
- break;
- default:
- break;
}
+ PORT_FreeArena(smimeEntry.common.arena, PR_FALSE);
+ smimeEntry.common.arena = NULL;
} while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 );
(* updatedb->close)(updatedb);
@@ -4029,17 +4067,6 @@ openNewCertDB(const char *appName, const char *prefix, const char *certdbname,
}
/* Verify version number; */
-
- if (appName) {
- updatedb = dbsopen(certdbname, NO_RDONLY, 0600, DB_HASH, 0);
- if (updatedb) {
- rv = UpdateV8DB(handle, updatedb);
- db_FinishTransaction(handle->permCertDB,PR_FALSE);
- db_InitComplete(handle->permCertDB);
- return(rv);
- }
- }
-
versionEntry = NewDBVersionEntry(0);
if ( versionEntry == NULL ) {
rv = SECFailure;
@@ -4056,7 +4083,10 @@ openNewCertDB(const char *appName, const char *prefix, const char *certdbname,
/* rv must already be Success here because of previous if statement */
/* try to upgrade old db here */
- if ((updatedb = nsslowcert_openolddb(namecb,cbarg,7)) != NULL) {
+ if (appName &&
+ (updatedb = dbsopen(certdbname, NO_RDONLY, 0600, DB_HASH, 0)) != NULL) {
+ rv = UpdateV8DB(handle, updatedb);
+ } else if ((updatedb = nsslowcert_openolddb(namecb,cbarg,7)) != NULL) {
rv = UpdateV7DB(handle, updatedb);
} else if ((updatedb = nsslowcert_openolddb(namecb,cbarg,6)) != NULL) {
rv = UpdateV6DB(handle, updatedb);
@@ -4295,7 +4325,7 @@ DecodeACert(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry)
goto loser;
}
- cert->dbhandle = handle;
+ cert->dbhandle = nsslowcert_reference(handle);
cert->dbEntry = entry;
cert->trust = &entry->trust;
@@ -4349,7 +4379,7 @@ DecodeTrustEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry,
if (trust == NULL) {
return trust;
}
- trust->dbhandle = handle;
+ trust->dbhandle = nsslowcert_reference(handle);
trust->dbEntry = entry;
trust->dbKey.data = pkcs11_copyStaticData(dbKey->data,dbKey->len,
trust->dbKeySpace, sizeof(trust->dbKeySpace));
@@ -4983,6 +5013,9 @@ DestroyCertificate(NSSLOWCERTCertificate *cert, PRBool lockdb)
*/
if ( lockdb && handle ) {
nsslowcert_LockDB(handle);
+ /* keep a reference until we unlock, so handle won't disappear
+ * before we are through with it */
+ nsslowcert_reference(handle);
}
nsslowcert_LockCertRefCount(cert);
@@ -5016,11 +5049,15 @@ DestroyCertificate(NSSLOWCERTCertificate *cert, PRBool lockdb)
certListHead = cert;
}
nsslowcert_UnlockFreeList();
+ if (handle) {
+ sftk_freeCertDB(handle);
+ }
cert = NULL;
}
if ( lockdb && handle ) {
nsslowcert_UnlockDB(handle);
+ sftk_freeCertDB(handle);
}
}
diff --git a/security/nss/lib/softoken/pk11db.c b/security/nss/lib/softoken/pk11db.c
index 391803329..c60e87780 100644
--- a/security/nss/lib/softoken/pk11db.c
+++ b/security/nss/lib/softoken/pk11db.c
@@ -120,9 +120,9 @@ secmod_parseTokens(char *tokenParams, sftk_parameters *parsed)
tokenIndex += next;
tokens[i].slotID = secmod_argDecodeNumber(name);
- tokens[i].readOnly = PR_TRUE;
- tokens[i].noCertDB = PR_TRUE;
- tokens[i].noKeyDB = PR_TRUE;
+ tokens[i].readOnly = PR_FALSE;
+ tokens[i].noCertDB = PR_FALSE;
+ tokens[i].noKeyDB = PR_FALSE;
if (!secmod_argIsBlank(*tokenIndex)) {
char *args = secmod_argFetchValue(tokenIndex,&next);
tokenIndex += next;
@@ -167,8 +167,8 @@ secmod_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
SECMOD_HANDLE_STRING_ARG(index,slotdes,"cryptoSlotDescription=",;)
SECMOD_HANDLE_STRING_ARG(index,pslotdes,"dbSlotDescription=",;)
SECMOD_HANDLE_STRING_ARG(index,fslotdes,"FIPSSlotDescription=",;)
- SECMOD_HANDLE_STRING_ARG(index,minPW,"FIPSTokenDescription=",;)
- SECMOD_HANDLE_STRING_ARG(index,tmp,"minPWLen=",;)
+ SECMOD_HANDLE_STRING_ARG(index,fpslotdes,"FIPSTokenDescription=",;)
+ SECMOD_HANDLE_STRING_ARG(index,minPW,"minPWLen=",;)
SECMOD_HANDLE_STRING_ARG(index,tmp,"flags=",
if(tmp) { secmod_parseFlags(param,parsed); PORT_Free(tmp); })
@@ -445,10 +445,10 @@ secmod_EncodeData(DBT *data, char * module)
encoded->isCritical = (unsigned char)
(secmod_argHasFlag("flags","critical",nss) ? 1 : 0);
- order = secmod_argReadLong("trustOrder", nss, SFTK_DEFAULT_TRUST_ORDER,
+ order = secmod_argReadLong("trustOrder", nss, SECMOD_DEFAULT_TRUST_ORDER,
NULL);
SECMOD_PUTLONG(encoded->trustOrder,order);
- order = secmod_argReadLong("cipherOrder", nss, SFTK_DEFAULT_CIPHER_ORDER,
+ order = secmod_argReadLong("cipherOrder", nss, SECMOD_DEFAULT_CIPHER_ORDER,
NULL);
SECMOD_PUTLONG(encoded->cipherOrder,order);
@@ -551,8 +551,8 @@ secmod_DecodeData(char *defParams, DBT *data, PRBool *retInternal)
unsigned long slotID;
unsigned long defaultFlags;
unsigned long timeout;
- unsigned long trustOrder =SFTK_DEFAULT_TRUST_ORDER;
- unsigned long cipherOrder =SFTK_DEFAULT_CIPHER_ORDER;
+ unsigned long trustOrder =SECMOD_DEFAULT_TRUST_ORDER;
+ unsigned long cipherOrder =SECMOD_DEFAULT_CIPHER_ORDER;
unsigned short len;
unsigned short namesOffset = 0; /* start of the names block */
unsigned long namesRunningOffset; /* offset to name we are
diff --git a/security/nss/lib/softoken/pk11pars.h b/security/nss/lib/softoken/pk11pars.h
index 6e01b7ffb..ebb1d1b2b 100644
--- a/security/nss/lib/softoken/pk11pars.h
+++ b/security/nss/lib/softoken/pk11pars.h
@@ -64,8 +64,8 @@ struct secmodargSlotFlagTable {
unsigned long value;
};
-#define SFTK_DEFAULT_CIPHER_ORDER 0
-#define SFTK_DEFAULT_TRUST_ORDER 50
+#define SECMOD_DEFAULT_CIPHER_ORDER 0
+#define SECMOD_DEFAULT_TRUST_ORDER 50
#define SECMOD_ARG_ENTRY(arg,flag) \
@@ -194,14 +194,21 @@ secmod_argFetchValue(char *string, int *pcount)
char *end = secmod_argFindEnd(string);
char *retString, *copyString;
PRBool lastEscape = PR_FALSE;
+ int len;
- *pcount = (end - string)+1;
+ len = end - string;
+ if (len == 0) {
+ *pcount = 0;
+ return NULL;
+ }
- if (*pcount == 0) return NULL;
+ copyString = retString = (char *)PORT_Alloc(len+1);
- copyString = retString = (char *)PORT_Alloc(*pcount);
+ if (*end) len++;
+ *pcount = len;
if (retString == NULL) return NULL;
+
if (secmod_argIsQuote(*string)) string++;
for (; string < end; string++) {
if (secmod_argIsEscape(*string) && !lastEscape) {
@@ -815,9 +822,9 @@ secmod_mkNSS(char **slotStrings, int slotCount, PRBool internal, PRBool isFIPS,
ciphers = secmod_mkCipherFlags(ssl0, ssl1);
trustOrderPair=secmod_formatIntPair("trustOrder",trustOrder,
- SFTK_DEFAULT_TRUST_ORDER);
+ SECMOD_DEFAULT_TRUST_ORDER);
cipherOrderPair=secmod_formatIntPair("cipherOrder",cipherOrder,
- SFTK_DEFAULT_CIPHER_ORDER);
+ SECMOD_DEFAULT_CIPHER_ORDER);
slotPair=secmod_formatPair("slotParams",slotParams,'{'); /* } */
if (slotParams) PORT_Free(slotParams);
cipherPair=secmod_formatPair("ciphers",ciphers,'\'');
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index f9090a925..10a7bcfb7 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -55,6 +55,7 @@
#include "secitem.h"
#include "pkcs11.h"
#include "pkcs11i.h"
+#include "pkcs11p.h"
#include "softoken.h"
#include "lowkeyi.h"
#include "blapi.h"
@@ -81,6 +82,12 @@ static char manufacturerID_space[33];
static char *libraryDescription = "NSS Internal Crypto Services ";
static char libraryDescription_space[33];
+/*
+ * In FIPS mode, we disallow login attempts for 1 second after a login
+ * failure so that there are at most 60 login attempts per minute.
+ */
+static PRIntervalTime loginWaitTime;
+
#define __PASTE(x,y) x##y
/*
@@ -267,7 +274,7 @@ static const struct mechanismList mechanisms[] = {
{CKM_RSA_PKCS_KEY_PAIR_GEN,{RSA_MIN_MODULUS_BITS,CK_MAX,
CKF_GENERATE_KEY_PAIR},PR_TRUE},
{CKM_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_DUZ_IT_ALL}, PR_TRUE},
+ CKF_DUZ_IT_ALL}, PR_TRUE},
#ifdef SFTK_RSA9796_SUPPORTED
{CKM_RSA_9796, {RSA_MIN_MODULUS_BITS,CK_MAX,
CKF_DUZ_IT_ALL}, PR_TRUE},
@@ -523,7 +530,7 @@ sftk_configure(const char *man, const char *libdes)
/*
* see if the key DB password is enabled
*/
-PRBool
+static PRBool
sftk_hasNullPassword(NSSLOWKEYDBHandle *keydb,SECItem **pwitem)
{
PRBool pwenabled;
@@ -659,8 +666,10 @@ sftk_handleCertObject(SFTKSession *session,SFTKObject *object)
char *email = NULL;
SECStatus rv;
PRBool inDB = PR_TRUE;
+ NSSLOWCERTCertDBHandle *certHandle = sftk_getCertDB(slot);
+ NSSLOWKEYDBHandle *keyHandle = NULL;
- if (slot->certDB == NULL) {
+ if (certHandle == NULL) {
return CKR_TOKEN_WRITE_PROTECTED;
}
@@ -674,25 +683,31 @@ sftk_handleCertObject(SFTKSession *session,SFTKObject *object)
label = sftk_getString(object,CKA_LABEL);
- cert = nsslowcert_FindCertByDERCert(slot->certDB, &derCert);
- if (cert == NULL) {
+ cert = nsslowcert_FindCertByDERCert(certHandle, &derCert);
+ if (cert == NULL) {
cert = nsslowcert_DecodeDERCertificate(&derCert, label);
inDB = PR_FALSE;
}
if (cert == NULL) {
if (label) PORT_Free(label);
sftk_FreeAttribute(attribute);
+ sftk_freeCertDB(certHandle);
return CKR_ATTRIBUTE_VALUE_INVALID;
}
- if (slot->keyDB && nsslowkey_KeyForCertExists(slot->keyDB,cert)) {
- trust = &userTrust;
+ keyHandle = sftk_getKeyDB(slot);
+ if (keyHandle) {
+ if (nsslowkey_KeyForCertExists(keyHandle,cert)) {
+ trust = &userTrust;
+ }
+ sftk_freeKeyDB(keyHandle);
}
+
if (!inDB) {
if (!trust) trust = &defTrust;
- rv = nsslowcert_AddPermCert(slot->certDB, cert, label, trust);
+ rv = nsslowcert_AddPermCert(certHandle, cert, label, trust);
} else {
- rv = trust ? nsslowcert_ChangeCertTrust(slot->certDB,cert,trust) :
+ rv = trust ? nsslowcert_ChangeCertTrust(certHandle,cert,trust) :
SECSuccess;
}
@@ -700,6 +715,7 @@ sftk_handleCertObject(SFTKSession *session,SFTKObject *object)
sftk_FreeAttribute(attribute);
if (rv != SECSuccess) {
+ sftk_freeCertDB(certHandle);
nsslowcert_DestroyCertificate(cert);
return CKR_DEVICE_ERROR;
}
@@ -711,15 +727,16 @@ sftk_handleCertObject(SFTKSession *session,SFTKObject *object)
if (email) {
certDBEntrySMime *entry;
- entry = nsslowcert_ReadDBSMimeEntry(slot->certDB,email);
+ entry = nsslowcert_ReadDBSMimeEntry(certHandle,email);
if (!entry) {
- nsslowcert_SaveSMimeProfile(slot->certDB, email,
+ nsslowcert_SaveSMimeProfile(certHandle, email,
&cert->derSubject, NULL, NULL);
} else {
nsslowcert_DestroyDBEntry((certDBEntry *)entry);
}
PORT_Free(email);
}
+ sftk_freeCertDB(certHandle);
object->handle=sftk_mkHandle(slot,&cert->certKey,SFTK_TOKEN_TYPE_CERT);
nsslowcert_DestroyCertificate(cert);
}
@@ -792,11 +809,12 @@ sftk_handleTrustObject(SFTKSession *session,SFTKObject *object)
CK_BBOOL stepUp;
NSSLOWCERTCertTrust dbTrust = { 0 };
SECStatus rv;
+ NSSLOWCERTCertDBHandle *certHandle = sftk_getCertDB(slot);
-
- if (slot->certDB == NULL) {
+ if (certHandle == NULL) {
return CKR_TOKEN_WRITE_PROTECTED;
}
+
issuer = sftk_FindAttribute(object,CKA_ISSUER);
PORT_Assert(issuer);
issuerSN.derIssuer.data = (unsigned char *)issuer->attrib.pValue;
@@ -807,11 +825,12 @@ sftk_handleTrustObject(SFTKSession *session,SFTKObject *object)
issuerSN.serialNumber.data = (unsigned char *)serial->attrib.pValue;
issuerSN.serialNumber.len = serial->attrib.ulValueLen ;
- cert = nsslowcert_FindCertByIssuerAndSN(slot->certDB,&issuerSN);
+ cert = nsslowcert_FindCertByIssuerAndSN(certHandle,&issuerSN);
sftk_FreeAttribute(serial);
sftk_FreeAttribute(issuer);
if (cert == NULL) {
+ sftk_freeCertDB(certHandle);
return CKR_ATTRIBUTE_VALUE_INVALID;
}
@@ -873,9 +892,10 @@ sftk_handleTrustObject(SFTKSession *session,SFTKObject *object)
dbTrust.sslFlags |= CERTDB_GOVT_APPROVED_CA;
}
- rv = nsslowcert_ChangeCertTrust(slot->certDB,cert,&dbTrust);
+ rv = nsslowcert_ChangeCertTrust(certHandle,cert,&dbTrust);
object->handle=sftk_mkHandle(slot,&cert->certKey,SFTK_TOKEN_TYPE_TRUST);
nsslowcert_DestroyCertificate(cert);
+ sftk_freeCertDB(certHandle);
if (rv != SECSuccess) {
return CKR_DEVICE_ERROR;
}
@@ -912,9 +932,12 @@ sftk_handleSMimeObject(SFTKSession *session,SFTKObject *object)
char *email = NULL;
SFTKAttribute *subject,*profile,*time;
SECStatus rv;
+ NSSLOWCERTCertDBHandle *certHandle;
PORT_Assert(slot);
- if (slot->certDB == NULL) {
+ certHandle = sftk_getCertDB(slot);
+
+ if (certHandle == NULL) {
return CKR_TOKEN_WRITE_PROTECTED;
}
@@ -947,9 +970,9 @@ sftk_handleSMimeObject(SFTKSession *session,SFTKObject *object)
email = sftk_getString(object,CKA_NETSCAPE_EMAIL);
/* Store CRL by SUBJECT */
- rv = nsslowcert_SaveSMimeProfile(slot->certDB, email, &derSubj,
+ rv = nsslowcert_SaveSMimeProfile(certHandle, email, &derSubj,
pRawProfile,pRawTime);
-
+ sftk_freeCertDB(certHandle);
sftk_FreeAttribute(subject);
if (profile) sftk_FreeAttribute(profile);
if (time) sftk_FreeAttribute(time);
@@ -994,9 +1017,12 @@ sftk_handleCrlObject(SFTKSession *session,SFTKObject *object)
char *url = NULL;
SFTKAttribute *subject,*crl;
SECStatus rv;
+ NSSLOWCERTCertDBHandle *certHandle;
PORT_Assert(slot);
- if (slot->certDB == NULL) {
+ certHandle = sftk_getCertDB(slot);
+
+ if (certHandle == NULL) {
return CKR_TOKEN_WRITE_PROTECTED;
}
@@ -1017,7 +1043,8 @@ sftk_handleCrlObject(SFTKSession *session,SFTKObject *object)
isKRL = sftk_isTrue(object,CKA_NETSCAPE_KRL);
/* Store CRL by SUBJECT */
- rv = nsslowcert_AddCrl(slot->certDB, &derCrl, &derSubj, url, isKRL);
+ rv = nsslowcert_AddCrl(certHandle, &derCrl, &derSubj, url, isKRL);
+ sftk_freeCertDB(certHandle);
if (url) {
PORT_Free(url);
@@ -1156,16 +1183,18 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
SFTKSlot *slot = session->slot;
NSSLOWKEYPrivateKey *priv;
SECItem pubKey;
+ NSSLOWKEYDBHandle *keyHandle = NULL;
crv = sftk_Attribute2SSecItem(NULL,&pubKey,object,pubKeyAttr);
if (crv != CKR_OK) return crv;
PORT_Assert(pubKey.data);
- if (slot->keyDB == NULL) {
+ keyHandle = sftk_getKeyDB(slot);
+ if (keyHandle == NULL) {
PORT_Free(pubKey.data);
return CKR_TOKEN_WRITE_PROTECTED;
}
- if (slot->keyDB->version != 3) {
+ if (keyHandle->version != 3) {
unsigned char buf[SHA1_LENGTH];
SHA1_HashBuf(buf,pubKey.data,pubKey.len);
PORT_Memcpy(pubKey.data,buf,sizeof(buf));
@@ -1173,11 +1202,11 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
}
/* make sure the associated private key already exists */
/* only works if we are logged in */
- priv = nsslowkey_FindKeyByPublicKey(slot->keyDB, &pubKey,
- slot->password);
+ priv = nsslowkey_FindKeyByPublicKey(keyHandle, &pubKey, slot->password);
+ sftk_freeKeyDB(keyHandle);
if (priv == NULL) {
PORT_Free(pubKey.data);
- return CKR_ATTRIBUTE_VALUE_INVALID;
+ return crv;
}
nsslowkey_DestroyPrivateKey(priv);
@@ -1315,9 +1344,11 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
NSSLOWKEYPrivateKey *privKey;
char *label;
SECStatus rv = SECSuccess;
+ CK_RV crv = CKR_DEVICE_ERROR;
SECItem pubKey;
+ NSSLOWKEYDBHandle *keyHandle = sftk_getKeyDB(slot);
- if (slot->keyDB == NULL) {
+ if (keyHandle == NULL) {
return CKR_TOKEN_WRITE_PROTECTED;
}
@@ -1327,11 +1358,11 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
crv = sftk_Attribute2SSecItem(NULL,&pubKey,object,CKA_NETSCAPE_DB);
if (crv != CKR_OK) {
- if (label) PORT_Free(label);
- nsslowkey_DestroyPrivateKey(privKey);
- return CKR_TEMPLATE_INCOMPLETE;
+ crv = CKR_TEMPLATE_INCOMPLETE;
+ rv = SECFailure;
+ goto fail;
}
- if (slot->keyDB->version != 3) {
+ if (keyHandle->version != 3) {
unsigned char buf[SHA1_LENGTH];
SHA1_HashBuf(buf,pubKey.data,pubKey.len);
PORT_Memcpy(pubKey.data,buf,sizeof(buf));
@@ -1344,28 +1375,24 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE
goto fail;
}
}
- rv = nsslowkey_StoreKeyByPublicKey(object->slot->keyDB,
- privKey, &pubKey, label, object->slot->password);
+ rv = nsslowkey_StoreKeyByPublicKey(keyHandle, privKey, &pubKey,
+ label, slot->password);
fail:
+ sftk_freeKeyDB(keyHandle);
if (label) PORT_Free(label);
object->handle = sftk_mkHandle(slot,&pubKey,SFTK_TOKEN_TYPE_PRIV);
if (pubKey.data) PORT_Free(pubKey.data);
nsslowkey_DestroyPrivateKey(privKey);
- if (rv != SECSuccess) return CKR_DEVICE_ERROR;
+ if (rv != SECSuccess) return crv;
} else {
object->objectInfo = sftk_mkPrivKey(object,key_type,&crv);
if (object->objectInfo == NULL) return crv;
object->infoFree = (SFTKFree) nsslowkey_DestroyPrivateKey;
/* now NULL out the sensitive attributes */
- if (sftk_isTrue(object,CKA_SENSITIVE)) {
- sftk_nullAttribute(object,CKA_PRIVATE_EXPONENT);
- sftk_nullAttribute(object,CKA_PRIME_1);
- sftk_nullAttribute(object,CKA_PRIME_2);
- sftk_nullAttribute(object,CKA_EXPONENT_1);
- sftk_nullAttribute(object,CKA_EXPONENT_2);
- sftk_nullAttribute(object,CKA_COEFFICIENT);
- }
+ /* remove nulled out attributes for session objects. these only
+ * applied to rsa private keys anyway (other private keys did not
+ * get their attributes NULL'ed out */
}
return CKR_OK;
}
@@ -1521,7 +1548,8 @@ sftk_handleSecretKeyObject(SFTKSession *session,SFTKObject *object,
CK_KEY_TYPE key_type, PRBool isFIPS)
{
CK_RV crv;
- NSSLOWKEYPrivateKey *privKey = NULL;
+ NSSLOWKEYPrivateKey *privKey = NULL;
+ NSSLOWKEYDBHandle *keyHandle = NULL;
SECItem pubKey;
char *label = NULL;
@@ -1535,8 +1563,9 @@ sftk_handleSecretKeyObject(SFTKSession *session,SFTKObject *object,
if (sftk_isTrue(object,CKA_TOKEN)) {
SFTKSlot *slot = session->slot;
SECStatus rv = SECSuccess;
+ keyHandle = sftk_getKeyDB(slot);
- if (slot->keyDB == NULL) {
+ if (keyHandle == NULL) {
return CKR_TOKEN_WRITE_PROTECTED;
}
@@ -1552,21 +1581,20 @@ sftk_handleSecretKeyObject(SFTKSession *session,SFTKObject *object,
PORT_Free(pubKey.data);
pubKey.data = NULL;
}
- crv = sftk_GenerateSecretCKA_ID(slot->keyDB, &pubKey, label);
+ crv = sftk_GenerateSecretCKA_ID(keyHandle, &pubKey, label);
if (crv != CKR_OK) goto loser;
crv = sftk_forceAttribute(object, CKA_ID, pubKey.data, pubKey.len);
if (crv != CKR_OK) goto loser;
}
- privKey=sftk_mkSecretKeyRep(object);
+ privKey = sftk_mkSecretKeyRep(object);
if (privKey == NULL) {
crv = CKR_HOST_MEMORY;
goto loser;
}
- PORT_Assert(slot->keyDB);
- rv = nsslowkey_StoreKeyByPublicKey(slot->keyDB,
+ rv = nsslowkey_StoreKeyByPublicKey(keyHandle,
privKey, &pubKey, label, slot->password);
if (rv != SECSuccess) {
crv = CKR_DEVICE_ERROR;
@@ -1577,6 +1605,7 @@ sftk_handleSecretKeyObject(SFTKSession *session,SFTKObject *object,
}
loser:
+ if (keyHandle) sftk_freeKeyDB(keyHandle);
if (label) PORT_Free(label);
if (privKey) nsslowkey_DestroyPrivateKey(privKey);
if (pubKey.data) PORT_Free(pubKey.data);
@@ -2094,10 +2123,8 @@ sftk_GetPrivKey(SFTKObject *object,CK_KEY_TYPE key_type, CK_RV *crvp)
SFTKTokenObject *to = sftk_narrowToTokenObject(object);
PORT_Assert(to);
- PORT_Assert(object->slot->keyDB);
- priv = nsslowkey_FindKeyByPublicKey(object->slot->keyDB, &to->dbKey,
- object->slot->password);
- *crvp = priv ? CKR_OK : CKR_DEVICE_ERROR;
+ priv = sftk_FindKeyByPublicKey(object->slot, &to->dbKey);
+ *crvp = (priv == NULL) ? CKR_DEVICE_ERROR : CKR_OK;
} else {
priv = sftk_mkPrivKey(object, key_type, crvp);
}
@@ -2346,7 +2373,7 @@ static PLHashTable *nscSlotHashTable[2] = {NULL, NULL};
static int
sftk_GetModuleIndex(CK_SLOT_ID slotID)
{
- if ((slotID == FIPS_SLOT_ID) || (slotID > 100)) {
+ if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) {
return NSC_FIPS_MODULE;
}
return NSC_NON_FIPS_MODULE;
@@ -2354,12 +2381,18 @@ sftk_GetModuleIndex(CK_SLOT_ID slotID)
/* look up a slot structure from the ID (used to be a macro when we only
* had two slots) */
+/* if all is true, return the slot even if it has been 'unloaded' */
+/* if all is false, only return the slots which are present */
SFTKSlot *
-sftk_SlotFromID(CK_SLOT_ID slotID)
+sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all)
{
+ SFTKSlot *slot;
int index = sftk_GetModuleIndex(slotID);
- return (SFTKSlot *)PL_HashTableLookupConst(nscSlotHashTable[index],
+ slot = (SFTKSlot *)PL_HashTableLookupConst(nscSlotHashTable[index],
(void *)slotID);
+ /* cleared slots shouldn't 'show up' */
+ if (slot && !all && !slot->present) slot = NULL;
+ return slot;
}
SFTKSlot *
@@ -2372,7 +2405,7 @@ sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle)
return NULL;
}
- return sftk_SlotFromID(nscSlotList[moduleIndex][slotIDIndex]);
+ return sftk_SlotFromID(nscSlotList[moduleIndex][slotIDIndex], PR_FALSE);
}
static CK_RV
@@ -2427,13 +2460,19 @@ sftk_RegisterSlot(SFTKSlot *slot, int moduleIndex)
return CKR_OK;
}
+typedef struct sftk_DBsStr {
+ NSSLOWCERTCertDBHandle *certHandle;
+ NSSLOWKEYDBHandle *keyHandle;
+} sftkDBs;
+
static SECStatus
sftk_set_user(NSSLOWCERTCertificate *cert, SECItem *dummy, void *arg)
{
- SFTKSlot *slot = (SFTKSlot *)arg;
+ sftkDBs *param = (sftkDBs *)arg;
NSSLOWCERTCertTrust trust = *cert->trust;
- if (nsslowkey_KeyForCertExists(slot->keyDB,cert)) {
+ if (param->keyHandle &&
+ nsslowkey_KeyForCertExists(param->keyHandle,cert)) {
trust.sslFlags |= CERTDB_USER;
trust.emailFlags |= CERTDB_USER;
trust.objectSigningFlags |= CERTDB_USER;
@@ -2444,26 +2483,120 @@ sftk_set_user(NSSLOWCERTCertificate *cert, SECItem *dummy, void *arg)
}
if (PORT_Memcmp(&trust,cert->trust, sizeof (trust)) != 0) {
- nsslowcert_ChangeCertTrust(slot->certDB,cert, &trust);
+ nsslowcert_ChangeCertTrust(param->certHandle, cert, &trust);
}
/* should check for email address and make sure we have an s/mime profile */
return SECSuccess;
}
+/*
+ * this function fixes up old databases that may not have the CERTDB_USER
+ * flags set correctly. it expects the owner already has references to
+ * the cert and key handles.
+ */
static void
-sftk_DBVerify(SFTKSlot *slot)
+sftk_DBVerify(NSSLOWCERTCertDBHandle *certHandle, NSSLOWKEYDBHandle *keyHandle)
{
/* walk through all the certs and check to see if there are any
* user certs, and make sure there are s/mime profiles for all certs with
* email addresses */
- nsslowcert_TraversePermCerts(slot->certDB,sftk_set_user,slot);
+ sftkDBs param;
+ param.certHandle = certHandle;
+ param.keyHandle = keyHandle;
+
+ nsslowcert_TraversePermCerts(certHandle, sftk_set_user, &param);
return;
}
-/* forward static declaration. */
-static CK_RV sftk_DestroySlotData(SFTKSlot *slot);
+
+/*
+ * ths function has all the common initialization that happens whenever we
+ * create a new slot or repurpose an old slot (only valid for slotID's 4
+ * and greater).
+ *
+ * things that are not reinitialized are:
+ * slotID (can't change)
+ * slotDescription (can't change once defined)
+ * the locks and hash tables (difficult to change in running code, and
+ * unnecessary. hash tables and list are cleared on shutdown, but they
+ * are cleared in a 'friendly' way).
+ * session and object ID counters -- so any old sessions and objects in the
+ * application will get properly notified that the world has changed.
+ *
+ * things that are reinitialized:
+ * database (otherwise what would the point be;).
+ * state variables related to databases.
+ * session count stat info.
+ * tokenDescription.
+ *
+ * NOTE: slotID's 4 and greater show up as removable devices.
+ *
+ */
+CK_RV
+SFTK_SlotReInit(SFTKSlot *slot,
+ char *configdir,sftk_token_parameters *params, int moduleIndex)
+{
+ PRBool needLogin = !params->noKeyDB;
+ CK_RV crv;
+
+ slot->hasTokens = PR_FALSE;
+ slot->sessionIDConflict = 0;
+ slot->sessionCount = 0;
+ slot->rwSessionCount = 0;
+ slot->needLogin = PR_FALSE;
+ slot->isLoggedIn = PR_FALSE;
+ slot->ssoLoggedIn = PR_FALSE;
+ slot->DB_loaded = PR_FALSE;
+ slot->certDB = NULL;
+ slot->keyDB = NULL;
+ slot->minimumPinLen = 0;
+ slot->readOnly = params->readOnly;
+ sftk_setStringName(params->tokdes ? params->tokdes :
+ sftk_getDefTokName(slot->slotID), slot->tokDescription,
+ sizeof(slot->tokDescription));
+
+ if ((!params->noCertDB) || (!params->noKeyDB)) {
+ NSSLOWCERTCertDBHandle * certHandle = NULL;
+ NSSLOWKEYDBHandle *keyHandle = NULL;
+ crv = sftk_DBInit(params->configdir ? params->configdir : configdir,
+ params->certPrefix, params->keyPrefix, params->readOnly,
+ params->noCertDB, params->noKeyDB, params->forceOpen,
+ &certHandle, &keyHandle);
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+
+ if (nsslowcert_needDBVerify(certHandle)) {
+ sftk_DBVerify(certHandle, keyHandle);
+ }
+ slot->certDB = certHandle;
+ slot->keyDB = keyHandle;
+ }
+ if (needLogin) {
+ /* if the data base is initialized with a null password,remember that */
+ slot->needLogin =
+ (PRBool)!sftk_hasNullPassword(slot->keyDB,&slot->password);
+ if ((params->minPW >= 0) && (params->minPW <= SFTK_MAX_PIN)) {
+ slot->minimumPinLen = params->minPW;
+ }
+ if ((slot->minimumPinLen == 0) && (params->pwRequired)) {
+ slot->minimumPinLen = 1;
+ }
+ if ((moduleIndex == NSC_FIPS_MODULE) &&
+ (slot->minimumPinLen < FIPS_MIN_PIN)) {
+ slot->minimumPinLen = FIPS_MIN_PIN;
+ }
+ }
+
+ slot->present = PR_TRUE;
+ return CKR_OK;
+
+loser:
+ SFTK_ShutdownSlot(slot);
+ return crv;
+}
/*
* initialize one of the slot structures. figure out which by the ID
@@ -2473,9 +2606,15 @@ SFTK_SlotInit(char *configdir,sftk_token_parameters *params, int moduleIndex)
{
unsigned int i;
CK_SLOT_ID slotID = params->slotID;
- SFTKSlot *slot = PORT_ZNew(SFTKSlot);
- PRBool needLogin = !params->noKeyDB;
- CK_RV crv;
+ SFTKSlot *slot;
+ CK_RV crv = CKR_HOST_MEMORY;
+
+ /*
+ * first we initialize everything that is 'permanent' with this slot.
+ * that is everything we aren't going to shutdown if we close this slot
+ * and open it up again with different databases */
+
+ slot = PORT_ZNew(SFTKSlot);
if (slot == NULL) {
return CKR_HOST_MEMORY;
@@ -2507,6 +2646,9 @@ SFTK_SlotInit(char *configdir,sftk_token_parameters *params, int moduleIndex)
slot->objectLock = PZ_NewLock(nssILockObject);
if (slot->objectLock == NULL)
goto mem_loser;
+ slot->pwCheckLock = PR_NewLock();
+ if (slot->pwCheckLock == NULL)
+ goto mem_loser;
slot->head = PORT_ZNewArray(SFTKSession *, slot->sessHashSize);
if (slot->head == NULL)
goto mem_loser;
@@ -2518,53 +2660,18 @@ SFTK_SlotInit(char *configdir,sftk_token_parameters *params, int moduleIndex)
if (slot->tokenHashTable == NULL)
goto mem_loser;
- slot->password = NULL;
- slot->hasTokens = PR_FALSE;
slot->sessionIDCount = 0;
- slot->sessionIDConflict = 0;
- slot->sessionCount = 0;
- slot->rwSessionCount = 0;
slot->tokenIDCount = 1;
- slot->needLogin = PR_FALSE;
- slot->isLoggedIn = PR_FALSE;
- slot->ssoLoggedIn = PR_FALSE;
- slot->DB_loaded = PR_FALSE;
slot->slotID = slotID;
- slot->certDB = NULL;
- slot->keyDB = NULL;
- slot->minimumPinLen = 0;
- slot->readOnly = params->readOnly;
- sftk_setStringName(params->tokdes ? params->tokdes :
- sftk_getDefTokName(slotID), slot->tokDescription,
- sizeof(slot->tokDescription));
sftk_setStringName(params->slotdes ? params->slotdes :
- sftk_getDefSlotName(slotID), slot->slotDescription,
+ sftk_getDefSlotName(slotID), slot->slotDescription,
sizeof(slot->slotDescription));
- if ((!params->noCertDB) || (!params->noKeyDB)) {
- crv = sftk_DBInit(params->configdir ? params->configdir : configdir,
- params->certPrefix, params->keyPrefix, params->readOnly,
- params->noCertDB, params->noKeyDB, params->forceOpen,
- &slot->certDB, &slot->keyDB);
- if (crv != CKR_OK) {
- goto loser;
- }
-
- if (nsslowcert_needDBVerify(slot->certDB)) {
- sftk_DBVerify(slot);
- }
- }
- if (needLogin) {
- /* if the data base is initialized with a null password,remember that */
- slot->needLogin =
- (PRBool)!sftk_hasNullPassword(slot->keyDB,&slot->password);
- if (params->minPW <= SFTK_MAX_PIN) {
- slot->minimumPinLen = params->minPW;
- }
- if ((slot->minimumPinLen == 0) && (params->pwRequired) &&
- (slot->minimumPinLen <= SFTK_MAX_PIN)) {
- slot->minimumPinLen = 1;
- }
+ /* call the reinit code to set everything that changes between token
+ * init calls */
+ crv = SFTK_SlotReInit(slot, configdir, params, moduleIndex);
+ if (crv != CKR_OK) {
+ goto loser;
}
crv = sftk_RegisterSlot(slot, moduleIndex);
if (crv != CKR_OK) {
@@ -2575,77 +2682,167 @@ SFTK_SlotInit(char *configdir,sftk_token_parameters *params, int moduleIndex)
mem_loser:
crv = CKR_HOST_MEMORY;
loser:
- sftk_DestroySlotData(slot);
+ SFTK_DestroySlotData(slot);
return crv;
}
-static PRIntn
-sftk_freeHashItem(PLHashEntry* entry, PRIntn index, void *arg)
+
+static CK_RV sft_CloseAllSession(SFTKSlot *slot)
{
- SECItem *item = (SECItem *)entry->value;
+ SECItem *pw = NULL;
+ SFTKSession *session;
+ unsigned int i;
+ /* first log out the card */
+ PZ_Lock(slot->slotLock);
+ pw = slot->password;
+ slot->isLoggedIn = PR_FALSE;
+ slot->password = NULL;
+ PZ_Unlock(slot->slotLock);
+ if (pw) SECITEM_ZfreeItem(pw, PR_TRUE);
- SECITEM_FreeItem(item, PR_TRUE);
- return HT_ENUMERATE_NEXT;
+ /* now close all the current sessions */
+ /* NOTE: If you try to open new sessions before NSC_CloseAllSessions
+ * completes, some of those new sessions may or may not be closed by
+ * NSC_CloseAllSessions... but any session running when this code starts
+ * will guarrenteed be close, and no session will be partially closed */
+ for (i=0; i < slot->sessHashSize; i++) {
+ PZLock *lock = SFTK_SESSION_LOCK(slot,i);
+ do {
+ PZ_Lock(lock);
+ session = slot->head[i];
+ /* hand deque */
+ /* this duplicates function of NSC_close session functions, but
+ * because we know that we are freeing all the sessions, we can
+ * do more efficient processing */
+ if (session) {
+ slot->head[i] = session->next;
+ if (session->next) session->next->prev = NULL;
+ session->next = session->prev = NULL;
+ PZ_Unlock(lock);
+ PZ_Lock(slot->slotLock);
+ --slot->sessionCount;
+ PZ_Unlock(slot->slotLock);
+ if (session->info.flags & CKF_RW_SESSION) {
+ PR_AtomicDecrement(&slot->rwSessionCount);
+ }
+ } else {
+ PZ_Unlock(lock);
+ }
+ if (session) sftk_FreeSession(session);
+ } while (session != NULL);
+ }
+ return CKR_OK;
}
/*
- * initialize one of the slot structures. figure out which by the ID
+ * shut down the databases.
+ * we get the slot lock (which also protects slot->certDB and slot->keyDB)
+ * and clear the values so the new users will not find the databases.
+ * once things are clear, we can release our references to the databases.
+ * The databases will close when the last reference is released.
+ *
+ * We use reference counts so that we don't crash if someone shuts down
+ * a token that another thread is actively using.
*/
-static CK_RV
-sftk_DestroySlotData(SFTKSlot *slot)
+static void
+sftk_DBShutdown(SFTKSlot *slot)
{
- unsigned int i;
-
- if (slot->slotLock) {
- PZ_DestroyLock(slot->slotLock);
- slot->slotLock = NULL;
- }
- if (slot->sessionLock) {
- for (i=0; i < slot->numSessionLocks; i++) {
- if (slot->sessionLock[i]) {
- PZ_DestroyLock(slot->sessionLock[i]);
- slot->sessionLock[i] = NULL;
- }
- }
+ NSSLOWCERTCertDBHandle *certHandle;
+ NSSLOWKEYDBHandle *keyHandle;
+ PZ_Lock(slot->slotLock);
+ certHandle = slot->certDB;
+ slot->certDB = NULL;
+ keyHandle = slot->keyDB;
+ slot->keyDB = NULL;
+ PZ_Unlock(slot->slotLock);
+ if (certHandle) {
+ sftk_freeCertDB(certHandle);
}
- if (slot->objectLock) {
- PZ_DestroyLock(slot->objectLock);
- slot->objectLock = NULL;
+ if (keyHandle) {
+ sftk_freeKeyDB(keyHandle);
}
- if (slot->sessionLock) {
- PORT_Free(slot->sessionLock);
- slot->sessionLock = NULL;
+}
+
+CK_RV
+SFTK_ShutdownSlot(SFTKSlot *slot)
+{
+ /* make sure no new PK11 calls work except C_GetSlotInfo */
+ slot->present = PR_FALSE;
+
+ /* close all outstanding sessions
+ * the sessHashSize variable guarentees we have all the session
+ * mechanism set up */
+ if (slot->head) {
+ sft_CloseAllSession(slot);
+ }
+
+ /* clear all objects.. session objects are cleared as a result of
+ * closing all the sessions. We just need to clear the token object
+ * cache. slot->tokenHashTable guarentees we have the token
+ * infrastructure set up. */
+ if (slot->tokenHashTable) {
+ SFTK_ClearTokenKeyHashTable(slot);
}
+ /* clear the slot description for the next guy */
+ PORT_Memset(slot->tokDescription, 0, sizeof(slot->tokDescription));
+
+ /* now shut down the databases. */
+ sftk_DBShutdown(slot);
+ return CKR_OK;
+}
+
+/*
+ * initialize one of the slot structures. figure out which by the ID
+ */
+CK_RV
+SFTK_DestroySlotData(SFTKSlot *slot)
+{
+ unsigned int i;
+
+ SFTK_ShutdownSlot(slot);
+
if (slot->tokenHashTable) {
- PL_HashTableEnumerateEntries(slot->tokenHashTable,
- sftk_freeHashItem,NULL);
PL_HashTableDestroy(slot->tokenHashTable);
slot->tokenHashTable = NULL;
}
if (slot->tokObjects) {
- for(i=0; i < slot->tokObjHashSize; i++) {
- SFTKObject *object = slot->tokObjects[i];
- slot->tokObjects[i] = NULL;
- if (object) sftk_FreeObject(object);
- }
PORT_Free(slot->tokObjects);
slot->tokObjects = NULL;
}
slot->tokObjHashSize = 0;
+
if (slot->head) {
- for(i=0; i < slot->sessHashSize; i++) {
- SFTKSession *session = slot->head[i];
- slot->head[i] = NULL;
- if (session) sftk_FreeSession(session);
- }
PORT_Free(slot->head);
slot->head = NULL;
}
slot->sessHashSize = 0;
- sftk_DBShutdown(slot->certDB,slot->keyDB);
+ /* OK everything has been disassembled, now we can finally get rid
+ * of the locks */
+ if (slot->slotLock) {
+ PZ_DestroyLock(slot->slotLock);
+ slot->slotLock = NULL;
+ }
+ if (slot->sessionLock) {
+ for (i=0; i < slot->numSessionLocks; i++) {
+ if (slot->sessionLock[i]) {
+ PZ_DestroyLock(slot->sessionLock[i]);
+ slot->sessionLock[i] = NULL;
+ }
+ }
+ PORT_Free(slot->sessionLock);
+ slot->sessionLock = NULL;
+ }
+ if (slot->objectLock) {
+ PZ_DestroyLock(slot->objectLock);
+ slot->objectLock = NULL;
+ }
+ if (slot->pwCheckLock) {
+ PR_DestroyLock(slot->pwCheckLock);
+ slot->pwCheckLock = NULL;
+ }
PORT_Free(slot);
return CKR_OK;
}
@@ -2718,7 +2915,7 @@ static void nscFreeAllSlots(int moduleIndex)
PL_HashTableLookup(tmpSlotHashTable, (void *)slotID);
PORT_Assert(slot);
if (!slot) continue;
- sftk_DestroySlotData(slot);
+ SFTK_DestroySlotData(slot);
PL_HashTableRemove(tmpSlotHashTable, (void *)slotID);
}
PORT_Free(tmpSlotList);
@@ -2738,9 +2935,7 @@ sftk_closePeer(PRBool isFIPS)
if (slot == NULL) {
return;
}
- sftk_DBShutdown(slot->certDB,slot->keyDB);
- slot->certDB = NULL;
- slot->keyDB = NULL;
+ sftk_DBShutdown(slot);
return;
}
@@ -2764,6 +2959,8 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */
return crv;
}
+
+ loginWaitTime = PR_SecondsToInterval(1);
}
rv = secoid_Init();
@@ -2789,6 +2986,24 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
/* initialize the key and cert db's */
nsslowkey_SetDefaultKeyDBAlg
(SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC);
+ if (init_args && (!(init_args->flags & CKF_OS_LOCKING_OK))) {
+ if (init_args->CreateMutex && init_args->DestroyMutex &&
+ init_args->LockMutex && init_args->UnlockMutex) {
+ /* softoken always uses NSPR (ie. OS locking), and doesn't know how
+ * to use the lock functions provided by the application.
+ */
+ crv = CKR_CANT_LOCK;
+ return crv;
+ }
+ if (init_args->CreateMutex || init_args->DestroyMutex ||
+ init_args->LockMutex || init_args->UnlockMutex) {
+ /* only some of the lock functions were provided by the
+ * application. This is invalid per PKCS#11 spec.
+ */
+ crv = CKR_ARGUMENTS_BAD;
+ return crv;
+ }
+ }
crv = CKR_ARGUMENTS_BAD;
if ((init_args && init_args->LibraryParameters)) {
sftk_parameters paramStrings;
@@ -2810,8 +3025,8 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
}
for (i=0; i < paramStrings.token_count; i++) {
- crv =
- SFTK_SlotInit(paramStrings.configdir, &paramStrings.tokens[i],
+ crv = SFTK_SlotInit(paramStrings.configdir,
+ &paramStrings.tokens[i],
moduleIndex);
if (crv != CKR_OK) {
nscFreeAllSlots(moduleIndex);
@@ -2910,7 +3125,7 @@ CK_RV NSC_GetInfo(CK_INFO_PTR pInfo)
c = __nss_softokn_rcsid[0] + __nss_softokn_sccsid[0];
pInfo->cryptokiVersion.major = 2;
- pInfo->cryptokiVersion.minor = 11;
+ pInfo->cryptokiVersion.minor = 20;
PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
pInfo->libraryVersion.major = NSS_VMAJOR;
pInfo->libraryVersion.minor = NSS_VMINOR;
@@ -2943,7 +3158,7 @@ CK_RV NSC_GetSlotList(CK_BBOOL tokenPresent,
/* NSC_GetSlotInfo obtains information about a particular slot in the system. */
CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
{
- SFTKSlot *slot = sftk_SlotFromID(slotID);
+ SFTKSlot *slot = sftk_SlotFromID(slotID, PR_TRUE);
if (slot == NULL) return CKR_SLOT_ID_INVALID;
pInfo->firmwareVersion.major = 0;
@@ -2951,7 +3166,11 @@ CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
PORT_Memcpy(pInfo->slotDescription,slot->slotDescription,64);
- pInfo->flags = CKF_TOKEN_PRESENT;
+ pInfo->flags = (slot->present) ? CKF_TOKEN_PRESENT : 0;
+ /* all user defined slots are defined as removable */
+ if (slotID >= SFTK_MIN_USER_SLOT_ID) {
+ pInfo->flags |= CKF_REMOVABLE_DEVICE;
+ }
/* ok we really should read it out of the keydb file. */
/* pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION; */
pInfo->hardwareVersion.major = NSS_VMAJOR;
@@ -2965,11 +3184,12 @@ CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
* been changed underneath us.
*/
static PRBool
-sftk_checkNeedLogin(SFTKSlot *slot)
+sftk_checkNeedLogin(SFTKSlot *slot, NSSLOWKEYDBHandle *keyHandle)
{
if (slot->password) {
- if (nsslowkey_CheckKeyDBPassword(slot->keyDB,slot->password)
- == SECSuccess) {
+ SECStatus rv;
+ rv = nsslowkey_CheckKeyDBPassword(keyHandle,slot->password);
+ if ( rv == SECSuccess) {
return slot->needLogin;
} else {
SECITEM_FreeItem(slot->password, PR_TRUE);
@@ -2978,7 +3198,7 @@ sftk_checkNeedLogin(SFTKSlot *slot)
}
}
slot->needLogin =
- (PRBool)!sftk_hasNullPassword(slot->keyDB,&slot->password);
+ (PRBool)!sftk_hasNullPassword(keyHandle,&slot->password);
return (slot->needLogin);
}
@@ -2986,7 +3206,7 @@ sftk_checkNeedLogin(SFTKSlot *slot)
* the system. */
CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
{
- SFTKSlot *slot = sftk_SlotFromID(slotID);
+ SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE);
NSSLOWKEYDBHandle *handle;
if (slot == NULL) return CKR_SLOT_ID_INVALID;
@@ -3001,7 +3221,7 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
pInfo->firmwareVersion.major = 0;
pInfo->firmwareVersion.minor = 0;
PORT_Memcpy(pInfo->label,slot->tokDescription,32);
- handle = slot->keyDB;
+ handle = sftk_getKeyDB(slot);
if (handle == NULL) {
pInfo->flags= CKF_RNG | CKF_WRITE_PROTECTED | CKF_THREAD_SAFE;
pInfo->ulMaxPinLen = 0;
@@ -3024,23 +3244,21 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
*/
if (nsslowkey_HasKeyDBPassword(handle) == SECFailure) {
pInfo->flags = CKF_THREAD_SAFE | CKF_LOGIN_REQUIRED;
- } else if (!sftk_checkNeedLogin(slot)) {
+ } else if (!sftk_checkNeedLogin(slot,handle)) {
pInfo->flags = CKF_THREAD_SAFE | CKF_USER_PIN_INITIALIZED;
} else {
pInfo->flags = CKF_THREAD_SAFE |
CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED;
}
pInfo->ulMaxPinLen = SFTK_MAX_PIN;
- pInfo->ulMinPinLen = 0;
- if (slot->minimumPinLen > 0) {
- pInfo->ulMinPinLen = (CK_ULONG)slot->minimumPinLen;
- }
+ pInfo->ulMinPinLen = (CK_ULONG)slot->minimumPinLen;
pInfo->ulTotalPublicMemory = 1;
pInfo->ulFreePublicMemory = 1;
pInfo->ulTotalPrivateMemory = 1;
pInfo->ulFreePrivateMemory = 1;
pInfo->hardwareVersion.major = CERT_DB_FILE_VERSION;
pInfo->hardwareVersion.minor = handle->version;
+ sftk_freeKeyDB(handle);
}
return CKR_OK;
}
@@ -3155,7 +3373,7 @@ sftk_TurnOffUser(NSSLOWCERTCertificate *cert, SECItem *k, void *arg)
/* NSC_InitToken initializes a token. */
CK_RV NSC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
CK_ULONG ulPinLen,CK_CHAR_PTR pLabel) {
- SFTKSlot *slot = sftk_SlotFromID(slotID);
+ SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE);
NSSLOWKEYDBHandle *handle;
NSSLOWCERTCertDBHandle *certHandle;
SECStatus rv;
@@ -3194,19 +3412,23 @@ CK_RV NSC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
PZ_Unlock(slot->objectLock);
/* then clear out the key database */
- handle = slot->keyDB;
+ handle = sftk_getKeyDB(slot);
if (handle == NULL) {
return CKR_TOKEN_WRITE_PROTECTED;
}
- /* what to do on an error here? */
rv = nsslowkey_ResetKeyDB(handle);
+ sftk_freeKeyDB(handle);
+ if (rv != SECSuccess) {
+ return CKR_DEVICE_ERROR;
+ }
/* finally mark all the user certs as non-user certs */
- certHandle = slot->certDB;
+ certHandle = sftk_getCertDB(slot);
if (certHandle == NULL) return CKR_OK;
nsslowcert_TraversePermCerts(certHandle,sftk_TurnOffUser, NULL);
+ sftk_freeCertDB(certHandle);
return CKR_OK; /*is this the right function for not implemented*/
}
@@ -3216,49 +3438,53 @@ CK_RV NSC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
{
- SFTKSession *sp;
+ SFTKSession *sp = NULL;
SFTKSlot *slot;
- NSSLOWKEYDBHandle *handle;
+ NSSLOWKEYDBHandle *handle = NULL;
SECItem *newPin;
char newPinStr[SFTK_MAX_PIN+1];
SECStatus rv;
+ CK_RV crv = CKR_SESSION_HANDLE_INVALID;
sp = sftk_SessionFromHandle(hSession);
if (sp == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
+ goto loser;
}
slot = sftk_SlotFromSession(sp);
if (slot == NULL) {
- sftk_FreeSession(sp);
- return CKR_SESSION_HANDLE_INVALID;;
+ goto loser;
}
- handle = slot->keyDB;
+ handle = sftk_getKeyDB(slot);
if (handle == NULL) {
- sftk_FreeSession(sp);
- return CKR_PIN_LEN_RANGE;
+ crv = CKR_PIN_LEN_RANGE;
+ goto loser;
}
if (sp->info.state != CKS_RW_SO_FUNCTIONS) {
- sftk_FreeSession(sp);
- return CKR_USER_NOT_LOGGED_IN;
+ crv = CKR_USER_NOT_LOGGED_IN;
+ goto loser;
}
sftk_FreeSession(sp);
+ sp = NULL;
/* make sure the pins aren't too long */
if (ulPinLen > SFTK_MAX_PIN) {
- return CKR_PIN_LEN_RANGE;
+ crv = CKR_PIN_LEN_RANGE;
+ goto loser;
}
if (ulPinLen < (CK_ULONG)slot->minimumPinLen) {
- return CKR_PIN_LEN_RANGE;
+ crv = CKR_PIN_LEN_RANGE;
+ goto loser;
}
if (nsslowkey_HasKeyDBPassword(handle) != SECFailure) {
- return CKR_DEVICE_ERROR;
+ crv = CKR_DEVICE_ERROR;
+ goto loser;
}
/* convert to null terminated string */
@@ -3271,6 +3497,8 @@ CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
/* change the data base */
rv = nsslowkey_SetKeyDBPassword(handle,newPin);
+ sftk_freeKeyDB(handle);
+ handle = NULL;
/* Now update our local copy of the pin */
if (rv == SECSuccess) {
@@ -3282,7 +3510,16 @@ CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
return CKR_OK;
}
SECITEM_ZfreeItem(newPin, PR_TRUE);
- return CKR_PIN_INCORRECT;
+ crv = CKR_PIN_INCORRECT;
+
+loser:
+ if (sp) {
+ sftk_FreeSession(sp);
+ }
+ if (handle) {
+ sftk_freeKeyDB(handle);
+ }
+ return crv;
}
@@ -3291,45 +3528,48 @@ CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen)
{
- SFTKSession *sp;
+ SFTKSession *sp = NULL;
SFTKSlot *slot;
- NSSLOWKEYDBHandle *handle;
+ NSSLOWKEYDBHandle *handle = NULL;
SECItem *newPin;
SECItem *oldPin;
char newPinStr[SFTK_MAX_PIN+1],oldPinStr[SFTK_MAX_PIN+1];
SECStatus rv;
+ CK_RV crv = CKR_SESSION_HANDLE_INVALID;
sp = sftk_SessionFromHandle(hSession);
if (sp == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
+ goto loser;
}
slot = sftk_SlotFromSession(sp);
if (!slot) {
- sftk_FreeSession(sp);
- return CKR_SESSION_HANDLE_INVALID;;
+ goto loser;
}
- handle = slot->keyDB;
+ handle = sftk_getKeyDB(slot);
if (handle == NULL) {
sftk_FreeSession(sp);
return CKR_PIN_LEN_RANGE;
}
if (slot->needLogin && sp->info.state != CKS_RW_USER_FUNCTIONS) {
- sftk_FreeSession(sp);
- return CKR_USER_NOT_LOGGED_IN;
+ crv = CKR_USER_NOT_LOGGED_IN;
+ goto loser;
}
sftk_FreeSession(sp);
+ sp = NULL;
/* make sure the pins aren't too long */
if ((ulNewLen > SFTK_MAX_PIN) || (ulOldLen > SFTK_MAX_PIN)) {
- return CKR_PIN_LEN_RANGE;
+ crv = CKR_PIN_LEN_RANGE;
+ goto loser;
}
if (ulNewLen < (CK_ULONG)slot->minimumPinLen) {
- return CKR_PIN_LEN_RANGE;
+ crv = CKR_PIN_LEN_RANGE;
+ goto loser;
}
@@ -3345,8 +3585,15 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
PORT_Memset(newPinStr,0,sizeof(newPinStr));
PORT_Memset(oldPinStr,0,sizeof(oldPinStr));
- /* change the data base */
+ /* change the data base password */
+ PR_Lock(slot->pwCheckLock);
rv = nsslowkey_ChangeKeyDBPassword(handle,oldPin,newPin);
+ sftk_freeKeyDB(handle);
+ handle = NULL;
+ if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) {
+ PR_Sleep(loginWaitTime);
+ }
+ PR_Unlock(slot->pwCheckLock);
/* Now update our local copy of the pin */
SECITEM_ZfreeItem(oldPin, PR_TRUE);
@@ -3359,7 +3606,15 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
return CKR_OK;
}
SECITEM_ZfreeItem(newPin, PR_TRUE);
- return CKR_PIN_INCORRECT;
+ crv = CKR_PIN_INCORRECT;
+loser:
+ if (sp) {
+ sftk_FreeSession(sp);
+ }
+ if (handle) {
+ sftk_freeKeyDB(handle);
+ }
+ return crv;
}
/* NSC_OpenSession opens a session between an application and a token. */
@@ -3371,7 +3626,7 @@ CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
SFTKSession *session;
SFTKSession *sameID;
- slot = sftk_SlotFromID(slotID);
+ slot = sftk_SlotFromID(slotID, PR_FALSE);
if (slot == NULL) return CKR_SLOT_ID_INVALID;
/* new session (we only have serial sessions) */
@@ -3462,56 +3717,15 @@ CK_RV NSC_CloseSession(CK_SESSION_HANDLE hSession)
CK_RV NSC_CloseAllSessions (CK_SLOT_ID slotID)
{
SFTKSlot *slot;
- SECItem *pw = NULL;
- SFTKSession *session;
- unsigned int i;
- slot = sftk_SlotFromID(slotID);
+ slot = sftk_SlotFromID(slotID, PR_FALSE);
if (slot == NULL) return CKR_SLOT_ID_INVALID;
- /* first log out the card */
- PZ_Lock(slot->slotLock);
- pw = slot->password;
- slot->isLoggedIn = PR_FALSE;
- slot->password = NULL;
- PZ_Unlock(slot->slotLock);
- if (pw) SECITEM_ZfreeItem(pw, PR_TRUE);
-
- /* now close all the current sessions */
- /* NOTE: If you try to open new sessions before NSC_CloseAllSessions
- * completes, some of those new sessions may or may not be closed by
- * NSC_CloseAllSessions... but any session running when this code starts
- * will guarrenteed be close, and no session will be partially closed */
- for (i=0; i < slot->sessHashSize; i++) {
- PZLock *lock = SFTK_SESSION_LOCK(slot,i);
- do {
- PZ_Lock(lock);
- session = slot->head[i];
- /* hand deque */
- /* this duplicates function of NSC_close session functions, but
- * because we know that we are freeing all the sessions, we can
- * do more efficient processing */
- if (session) {
- slot->head[i] = session->next;
- if (session->next) session->next->prev = NULL;
- session->next = session->prev = NULL;
- PZ_Unlock(lock);
- PZ_Lock(slot->slotLock);
- --slot->sessionCount;
- PZ_Unlock(slot->slotLock);
- if (session->info.flags & CKF_RW_SESSION) {
- PR_AtomicDecrement(&slot->rwSessionCount);
- }
- } else {
- PZ_Unlock(lock);
- }
- if (session) sftk_FreeSession(session);
- } while (session != NULL);
- }
- return CKR_OK;
+ return sft_CloseAllSession(slot);
}
+
/* NSC_GetSessionInfo obtains information about the session. */
CK_RV NSC_GetSessionInfo(CK_SESSION_HANDLE hSession,
CK_SESSION_INFO_PTR pInfo)
@@ -3534,6 +3748,8 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
SFTKSession *session;
NSSLOWKEYDBHandle *handle;
CK_FLAGS sessionFlags;
+ SECStatus rv;
+ CK_RV crv;
SECItem *pin;
char pinStr[SFTK_MAX_PIN+1];
@@ -3543,14 +3759,17 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
/* make sure the session is valid */
session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
+ if (session == NULL) {
+ return CKR_SESSION_HANDLE_INVALID;
+ }
sessionFlags = session->info.flags;
sftk_FreeSession(session);
session = NULL;
/* can't log into the Netscape Slot */
- if (slot->slotID == NETSCAPE_SLOT_ID)
+ if (slot->slotID == NETSCAPE_SLOT_ID) {
return CKR_USER_TYPE_INVALID;
+ }
if (slot->isLoggedIn) return CKR_USER_ALREADY_LOGGED_IN;
slot->ssoLoggedIn = PR_FALSE;
@@ -3561,7 +3780,7 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
PORT_Memcpy(pinStr,pPin,ulPinLen);
pinStr[ulPinLen] = 0;
- handle = slot->keyDB;
+ handle = sftk_getKeyDB(slot);
if (handle == NULL) {
return CKR_USER_TYPE_INVALID;
}
@@ -3571,7 +3790,8 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
* password if and only if we haven't initialized the KEY DB yet.
* We only allow this on a RW session.
*/
- if (nsslowkey_HasKeyDBPassword(handle) == SECFailure) {
+ rv = nsslowkey_HasKeyDBPassword(handle);
+ if (rv == SECFailure) {
/* allow SSO's to log in only if there is not password on the
* key database */
if (((userType == CKU_SO) && (sessionFlags & CKF_RW_SESSION))
@@ -3588,22 +3808,39 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
PZ_Unlock(slot->slotLock);
sftk_update_all_states(slot);
SECITEM_ZfreeItem(pw,PR_TRUE);
- return CKR_OK;
+ crv = CKR_OK;
+ goto done;
}
- return CKR_PIN_INCORRECT;
+ crv = CKR_PIN_INCORRECT;
+ goto done;
}
- return CKR_USER_TYPE_INVALID;
+ crv = CKR_USER_TYPE_INVALID;
+ goto done;
}
/* don't allow the SSO to log in if the user is already initialized */
- if (userType != CKU_USER) { return CKR_USER_TYPE_INVALID; }
+ if (userType != CKU_USER) {
+ crv = CKR_USER_TYPE_INVALID;
+ goto done;
+ }
/* build the hashed pins which we pass around */
pin = nsslowkey_HashPassword(pinStr,handle->global_salt);
- if (pin == NULL) return CKR_HOST_MEMORY;
+ if (pin == NULL) {
+ crv = CKR_HOST_MEMORY;
+ goto done;
+ }
- if (nsslowkey_CheckKeyDBPassword(handle,pin) == SECSuccess) {
+ PR_Lock(slot->pwCheckLock);
+ rv = nsslowkey_CheckKeyDBPassword(handle,pin);
+ sftk_freeKeyDB(handle);
+ handle = NULL;
+ if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) {
+ PR_Sleep(loginWaitTime);
+ }
+ PR_Unlock(slot->pwCheckLock);
+ if (rv == SECSuccess) {
SECItem *tmp;
PZ_Lock(slot->slotLock);
tmp = slot->password;
@@ -3618,7 +3855,12 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
}
SECITEM_ZfreeItem(pin, PR_TRUE);
- return CKR_PIN_INCORRECT;
+ crv = CKR_PIN_INCORRECT;
+done:
+ if (handle) {
+ sftk_freeKeyDB(handle);
+ }
+ return crv;
}
/* NSC_Logout logs a user out from a token. */
@@ -3647,6 +3889,98 @@ CK_RV NSC_Logout(CK_SESSION_HANDLE hSession)
return CKR_OK;
}
+/*
+ * Create a new slot on the fly. The slot that is passed in is the
+ * slot the request came from. Only the crypto or FIPS slots can
+ * be used. The resulting slot will live in the same module as
+ * the slot the request was passed to. object is the creation object
+ * that specifies the module spec for the new slot.
+ */
+static CK_RV sftk_CreateNewSlot(SFTKSlot *slot, CK_OBJECT_CLASS class,
+ SFTKObject *object)
+{
+ CK_SLOT_ID idMin, idMax;
+ PRBool isFIPS = PR_FALSE;
+ unsigned long moduleIndex;
+ SFTKAttribute *attribute;
+ sftk_parameters paramStrings;
+ char *paramString;
+ CK_SLOT_ID slotID = 0;
+ SFTKSlot *newSlot = NULL;
+ CK_RV crv = CKR_OK;
+
+ /* only the crypto or FIPS slots can create new slot objects */
+ if (slot->slotID == NETSCAPE_SLOT_ID) {
+ idMin = SFTK_MIN_USER_SLOT_ID;
+ idMax = SFTK_MAX_USER_SLOT_ID;
+ moduleIndex = NSC_NON_FIPS_MODULE;
+ isFIPS = PR_FALSE;
+ } else if (slot->slotID == FIPS_SLOT_ID) {
+ idMin = SFTK_MIN_FIPS_USER_SLOT_ID;
+ idMax = SFTK_MAX_FIPS_USER_SLOT_ID;
+ moduleIndex = NSC_FIPS_MODULE;
+ isFIPS = PR_TRUE;
+ } else {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ attribute = sftk_FindAttribute(object,CKA_NETSCAPE_MODULE_SPEC);
+ if (attribute == NULL) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ paramString = (unsigned char *)attribute->attrib.pValue;
+ crv = secmod_parseParameters(paramString, &paramStrings, isFIPS);
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+
+ /* enforce only one at a time */
+ if (paramStrings.token_count != 1) {
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto loser;
+ }
+
+ slotID = paramStrings.tokens[0].slotID;
+
+ /* stay within the valid ID space */
+ if ((slotID < idMin) || (slotID > idMax)) {
+ crv = CKR_ATTRIBUTE_VALUE_INVALID;
+ goto loser;
+ }
+
+ /* unload any existing slot at this id */
+ newSlot = sftk_SlotFromID(slotID, PR_TRUE);
+ if (newSlot && newSlot->present) {
+ crv = SFTK_ShutdownSlot(newSlot);
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+ }
+
+ /* if we were just planning on deleting the slot, then do so now */
+ if (class == CKO_NETSCAPE_DELSLOT) {
+ /* sort of a unconventional use of this error code, be we are
+ * overusing CKR_ATTRIBUTE_VALUE_INVALID, and it does apply */
+ crv = newSlot ? CKR_OK : CKR_SLOT_ID_INVALID;
+ goto loser; /* really exit */
+ }
+
+ if (newSlot) {
+ crv = SFTK_SlotReInit(newSlot, paramStrings.configdir,
+ &paramStrings.tokens[0], moduleIndex);
+ } else {
+ crv = SFTK_SlotInit(paramStrings.configdir,
+ &paramStrings.tokens[0], moduleIndex);
+ }
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+loser:
+ secmod_freeParams(&paramStrings);
+ sftk_FreeAttribute(attribute);
+
+ return crv;
+}
+
/* NSC_CreateObject creates a new object. */
CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession,
@@ -3656,9 +3990,11 @@ CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession,
SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
SFTKSession *session;
SFTKObject *object;
+ CK_OBJECT_CLASS class;
CK_RV crv;
int i;
+ *phObject = CK_INVALID_HANDLE;
/*
* now lets create an object to hang the attributes off of
@@ -3677,6 +4013,9 @@ CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession,
sftk_FreeObject(object);
return crv;
}
+ if ((pTemplate[i].type == CKA_CLASS) && pTemplate[i].pValue) {
+ class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
+ }
}
/* get the session */
@@ -3687,10 +4026,19 @@ CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession,
}
/*
+ * handle pseudo objects (CKO_NEWSLOT)
+ */
+ if ((class == CKO_NETSCAPE_NEWSLOT) || (class == CKO_NETSCAPE_DELSLOT)) {
+ crv = sftk_CreateNewSlot(slot, class, object);
+ goto done;
+ }
+
+ /*
* handle the base object stuff
*/
crv = sftk_handleObject(object,session);
*phObject = object->handle;
+done:
sftk_FreeSession(session);
sftk_FreeObject(object);
@@ -3698,6 +4046,7 @@ CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession,
}
+
/* NSC_CopyObject copies an object, creating a new object for the copy. */
CK_RV NSC_CopyObject(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
@@ -3983,7 +4332,7 @@ sftk_searchCrls(SFTKSlot *slot, SECItem *derSubject, PRBool isKrl,
{
NSSLOWCERTCertDBHandle *certHandle = NULL;
- certHandle = slot->certDB;
+ certHandle = sftk_getCertDB(slot);
if (certHandle == NULL) {
return;
}
@@ -4009,6 +4358,7 @@ sftk_searchCrls(SFTKSlot *slot, SECItem *derSubject, PRBool isKrl,
nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeKeyRevocation,
sftk_crl_collect, (void *)&crlData);
}
+ sftk_freeCertDB(certHandle);
}
/*
@@ -4016,6 +4366,7 @@ sftk_searchCrls(SFTKSlot *slot, SECItem *derSubject, PRBool isKrl,
*/
typedef struct sftkKeyDataStr {
SFTKSlot *slot;
+ NSSLOWKEYDBHandle *keyHandle;
SFTKSearchResults *searchHandles;
SECItem *id;
CK_ATTRIBUTE *template;
@@ -4041,7 +4392,7 @@ sftk_key_collect(DBT *key, DBT *data, void *arg)
tmpDBKey.len = key->size;
tmpDBKey.type = siBuffer;
- PORT_Assert(slot->keyDB);
+ PORT_Assert(keyData->keyHandle);
if (!keyData->strict && keyData->id) {
SECItem result;
PRBool haveMatch= PR_FALSE;
@@ -4051,7 +4402,7 @@ sftk_key_collect(DBT *key, DBT *data, void *arg)
if (keyData->id->len == 0) {
/* Make sure this isn't a NSC_KEY */
- privKey = nsslowkey_FindKeyByPublicKey(keyData->slot->keyDB,
+ privKey = nsslowkey_FindKeyByPublicKey(keyData->keyHandle,
&tmpDBKey, keyData->slot->password);
if (privKey) {
haveMatch = isSecretKey(privKey) ?
@@ -4094,7 +4445,7 @@ sftk_key_collect(DBT *key, DBT *data, void *arg)
return SECSuccess;
}
- privKey = nsslowkey_FindKeyByPublicKey(keyData->slot->keyDB, &tmpDBKey,
+ privKey = nsslowkey_FindKeyByPublicKey(keyData->keyHandle, &tmpDBKey,
keyData->slot->password);
if ( privKey == NULL ) {
goto loser;
@@ -4139,7 +4490,7 @@ sftk_searchKeys(SFTKSlot *slot, SECItem *key_id, PRBool isLoggedIn,
sftkKeyData keyData;
PRBool found = PR_FALSE;
- keyHandle = slot->keyDB;
+ keyHandle = sftk_getKeyDB(slot);
if (keyHandle == NULL) {
return;
}
@@ -4166,19 +4517,20 @@ sftk_searchKeys(SFTKSlot *slot, SECItem *key_id, PRBool isLoggedIn,
}
/* don't do the traversal if we have an up to date db */
if (keyHandle->version != 3) {
- return;
+ goto loser;
}
/* don't do the traversal if it can't possibly be the correct id */
/* all soft token id's are SHA1_HASH_LEN's */
if (key_id->len != SHA1_LENGTH) {
- return;
+ goto loser;
}
if (found) {
/* if we already found some keys, don't do the traversal */
- return;
+ goto loser;
}
}
keyData.slot = slot;
+ keyData.keyHandle = keyHandle;
keyData.searchHandles = search;
keyData.id = key_id;
keyData.template = pTemplate;
@@ -4188,6 +4540,9 @@ sftk_searchKeys(SFTKSlot *slot, SECItem *key_id, PRBool isLoggedIn,
keyData.strict = mustStrict ? mustStrict : NSC_STRICT;
nsslowkey_TraverseKeys(keyHandle, sftk_key_collect, &keyData);
+loser:
+ sftk_freeKeyDB(keyHandle);
+
}
/*
@@ -4301,7 +4656,7 @@ sftk_searchCertsAndTrust(SFTKSlot *slot, SECItem *derCert, SECItem *name,
sftkCertData certData;
int i;
- certHandle = slot->certDB;
+ certHandle = sftk_getCertDB(slot);
if (certHandle == NULL) return;
certData.slot = slot;
@@ -4387,10 +4742,11 @@ sftk_searchCertsAndTrust(SFTKSlot *slot, SECItem *derCert, SECItem *name,
} else {
/* we aren't filtering the certs, we are working on all, so turn
* on the strict filters. */
- certData.strict = PR_TRUE;
+ certData.strict = PR_TRUE;
sftk_CertSetupData(&certData,NSC_CERT_BLOCK_SIZE);
nsslowcert_TraversePermCerts(certHandle, sftk_cert_collect2, &certData);
}
+ sftk_freeCertDB(certHandle);
/*
* build the handles
@@ -4421,13 +4777,14 @@ sftk_searchSMime(SFTKSlot *slot, SECItem *email, SFTKSearchResults *handles,
NSSLOWCERTCertDBHandle *certHandle = NULL;
certDBEntrySMime *entry;
- certHandle = slot->certDB;
+ certHandle = sftk_getCertDB(slot);
if (certHandle == NULL) return;
if (email->data != NULL) {
char *tmp_name = (char*)PORT_Alloc(email->len+1);
if (tmp_name == NULL) {
+ sftk_freeCertDB(certHandle);
return;
}
PORT_Memcpy(tmp_name,email->data,email->len);
@@ -4446,6 +4803,7 @@ sftk_searchSMime(SFTKSlot *slot, SECItem *email, SFTKSearchResults *handles,
}
PORT_Free(tmp_name);
}
+ sftk_freeCertDB(certHandle);
return;
}
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
index 97315fcbb..56eb1814c 100644
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -122,12 +122,6 @@ sftk_FreePrivKey(NSSLOWKEYPrivateKey *key, PRBool freeit)
}
static void
-sftk_HMAC_Destroy(HMACContext *context, PRBool freeit)
-{
- HMAC_Destroy(context);
-}
-
-static void
sftk_Space(void *data, PRBool freeit)
{
PORT_Free(data);
@@ -1266,7 +1260,7 @@ sftk_doHMACInit(SFTKSessionContext *context,HASH_HashType hash,
SFTKAttribute *keyval;
HMACContext *HMACcontext;
CK_ULONG *intpointer;
- const SECHashObject *hashObj = &SECRawHashObjects[hash];
+ const SECHashObject *hashObj = HASH_GetRawHashObject(hash);
PRBool isFIPS = (key->slot->slotID == FIPS_SLOT_ID);
/* required by FIPS 198 Section 4 */
@@ -1292,7 +1286,7 @@ sftk_doHMACInit(SFTKSessionContext *context,HASH_HashType hash,
context->hashUpdate = (SFTKHash) HMAC_Update;
context->end = (SFTKEnd) HMAC_Finish;
- context->hashdestroy = (SFTKDestroy) sftk_HMAC_Destroy;
+ context->hashdestroy = (SFTKDestroy) HMAC_Destroy;
intpointer = (CK_ULONG *) PORT_Alloc(sizeof(CK_ULONG));
if (intpointer == NULL) {
return CKR_HOST_MEMORY;
@@ -1608,17 +1602,16 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
unsigned int *sigLen, unsigned int maxSigLen,
void *dataBuf, unsigned int dataLen)
{
- SECItem signature = { 0 }, digest;
+ SECItem signature, digest;
SECStatus rv;
NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
- (void)SECITEM_AllocItem(NULL, &signature, maxSigLen);
+ signature.data = (unsigned char *)sigBuf;
+ signature.len = maxSigLen;
digest.data = (unsigned char *)dataBuf;
digest.len = dataLen;
rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest);
*sigLen = signature.len;
- PORT_Memcpy(sigBuf, signature.data, signature.len);
- SECITEM_FreeItem(&signature, PR_FALSE);
return rv;
}
@@ -1642,17 +1635,16 @@ nsc_ECDSASignStub(void *ctx, void *sigBuf,
unsigned int *sigLen, unsigned int maxSigLen,
void *dataBuf, unsigned int dataLen)
{
- SECItem signature = { 0 }, digest;
+ SECItem signature, digest;
SECStatus rv;
NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
- (void)SECITEM_AllocItem(NULL, &signature, maxSigLen);
+ signature.data = (unsigned char *)sigBuf;
+ signature.len = maxSigLen;
digest.data = (unsigned char *)dataBuf;
digest.len = dataLen;
rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest);
*sigLen = signature.len;
- PORT_Memcpy(sigBuf, signature.data, signature.len);
- SECITEM_FreeItem(&signature, PR_FALSE);
return rv;
}
#endif /* NSS_ENABLE_ECC */
@@ -2502,6 +2494,7 @@ nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key)
CK_ULONG counter;
unsigned int seedBits = 0;
unsigned int primeBits;
+ unsigned int j;
CK_RV crv = CKR_OK;
PQGParams *params = NULL;
PQGVerify *vfy = NULL;
@@ -2513,6 +2506,10 @@ nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key)
}
primeBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue;
sftk_FreeAttribute(attribute);
+ j = PQG_PBITS_TO_INDEX(primeBits);
+ if (j == (unsigned int)-1) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
attribute = sftk_FindAttribute(key, CKA_NETSCAPE_PQG_SEED_BITS);
if (attribute != NULL) {
@@ -2524,9 +2521,9 @@ nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key)
sftk_DeleteAttributeType(key,CKA_NETSCAPE_PQG_SEED_BITS);
if (seedBits == 0) {
- rv = PQG_ParamGen(primeBits, &params, &vfy);
+ rv = PQG_ParamGen(j, &params, &vfy);
} else {
- rv = PQG_ParamGenSeedLen(primeBits,seedBits/8, &params, &vfy);
+ rv = PQG_ParamGenSeedLen(j,seedBits/8, &params, &vfy);
}
if (rv != SECSuccess) {
@@ -2931,6 +2928,287 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
return crv;
}
+#define PAIRWISE_DIGEST_LENGTH SHA1_LENGTH /* 160-bits */
+#define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */
+
+/*
+ * FIPS 140-2 pairwise consistency check utilized to validate key pair.
+ *
+ * This function returns
+ * CKR_OK if pairwise consistency check passed
+ * CKR_GENERAL_ERROR if pairwise consistency check failed
+ * other error codes if paiswise consistency check could not be
+ * performed, for example, CKR_HOST_MEMORY.
+ */
+static CK_RV
+sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
+ SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType)
+{
+ /*
+ * Key type Mechanism type
+ * --------------------------------
+ * For encrypt/decrypt: CKK_RSA => CKM_RSA_PKCS
+ * others => CKM_INVALID_MECHANISM
+ *
+ * For sign/verify: CKK_RSA => CKM_RSA_PKCS
+ * CKK_DSA => CKM_DSA
+ * CKK_EC => CKM_ECDSA
+ * others => CKM_INVALID_MECHANISM
+ *
+ * None of these mechanisms has a parameter.
+ */
+ CK_MECHANISM mech = {0, NULL, 0};
+
+ CK_ULONG modulusLen;
+ PRBool isEncryptable = PR_FALSE;
+ PRBool canSignVerify = PR_FALSE;
+ PRBool isDerivable = PR_FALSE;
+ CK_RV crv;
+
+ /* Variables used for Encrypt/Decrypt functions. */
+ unsigned char *known_message = (unsigned char *)"Known Crypto Message";
+ unsigned char plaintext[PAIRWISE_MESSAGE_LENGTH];
+ CK_ULONG bytes_decrypted;
+ unsigned char *ciphertext;
+ unsigned char *text_compared;
+ CK_ULONG bytes_encrypted;
+ CK_ULONG bytes_compared;
+
+ /* Variables used for Signature/Verification functions. */
+ /* always uses SHA-1 digest */
+ unsigned char *known_digest = (unsigned char *)"Mozilla Rules World!";
+ unsigned char *signature;
+ CK_ULONG signature_length;
+
+ if (keyType == CKK_RSA) {
+ SFTKAttribute *attribute;
+
+ /* Get modulus length of private key. */
+ attribute = sftk_FindAttribute(privateKey, CKA_MODULUS);
+ if (attribute == NULL) {
+ return CKR_DEVICE_ERROR;
+ }
+ modulusLen = attribute->attrib.ulValueLen;
+ if (*(unsigned char *)attribute->attrib.pValue == 0) {
+ modulusLen--;
+ }
+ sftk_FreeAttribute(attribute);
+ }
+
+ /**************************************************/
+ /* Pairwise Consistency Check of Encrypt/Decrypt. */
+ /**************************************************/
+
+ isEncryptable = sftk_isTrue(privateKey, CKA_DECRYPT);
+
+ /*
+ * If the decryption attribute is set, attempt to encrypt
+ * with the public key and decrypt with the private key.
+ */
+ if (isEncryptable) {
+ if (keyType != CKK_RSA) {
+ return CKR_DEVICE_ERROR;
+ }
+ bytes_encrypted = modulusLen;
+ mech.mechanism = CKM_RSA_PKCS;
+
+ /* Allocate space for ciphertext. */
+ ciphertext = (unsigned char *) PORT_ZAlloc(bytes_encrypted);
+ if (ciphertext == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+
+ /* Prepare for encryption using the public key. */
+ crv = NSC_EncryptInit(hSession, &mech, publicKey->handle);
+ if (crv != CKR_OK) {
+ PORT_Free(ciphertext);
+ return crv;
+ }
+
+ /* Encrypt using the public key. */
+ crv = NSC_Encrypt(hSession,
+ known_message,
+ PAIRWISE_MESSAGE_LENGTH,
+ ciphertext,
+ &bytes_encrypted);
+ if (crv != CKR_OK) {
+ PORT_Free(ciphertext);
+ return crv;
+ }
+
+ /* Always use the smaller of these two values . . . */
+ bytes_compared = PR_MIN(bytes_encrypted, PAIRWISE_MESSAGE_LENGTH);
+
+ /*
+ * If there was a failure, the plaintext
+ * goes at the end, therefore . . .
+ */
+ text_compared = ciphertext + bytes_encrypted - bytes_compared;
+
+ /*
+ * Check to ensure that ciphertext does
+ * NOT EQUAL known input message text
+ * per FIPS PUB 140-2 directive.
+ */
+ if (PORT_Memcmp(text_compared, known_message,
+ bytes_compared) == 0) {
+ /* Set error to Invalid PRIVATE Key. */
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
+ PORT_Free(ciphertext);
+ return CKR_GENERAL_ERROR;
+ }
+
+ /* Prepare for decryption using the private key. */
+ crv = NSC_DecryptInit(hSession, &mech, privateKey->handle);
+ if (crv != CKR_OK) {
+ PORT_Free(ciphertext);
+ return crv;
+ }
+
+ memset(plaintext, 0, PAIRWISE_MESSAGE_LENGTH);
+
+ /*
+ * Initialize bytes decrypted to be the
+ * expected PAIRWISE_MESSAGE_LENGTH.
+ */
+ bytes_decrypted = PAIRWISE_MESSAGE_LENGTH;
+
+ /*
+ * Decrypt using the private key.
+ * NOTE: No need to reset the
+ * value of bytes_encrypted.
+ */
+ crv = NSC_Decrypt(hSession,
+ ciphertext,
+ bytes_encrypted,
+ plaintext,
+ &bytes_decrypted);
+
+ /* Finished with ciphertext; free it. */
+ PORT_Free(ciphertext);
+
+ if (crv != CKR_OK) {
+ return crv;
+ }
+
+ /*
+ * Check to ensure that the output plaintext
+ * does EQUAL known input message text.
+ */
+ if ((bytes_decrypted != PAIRWISE_MESSAGE_LENGTH) ||
+ (PORT_Memcmp(plaintext, known_message,
+ PAIRWISE_MESSAGE_LENGTH) != 0)) {
+ /* Set error to Bad PUBLIC Key. */
+ PORT_SetError(SEC_ERROR_BAD_KEY);
+ return CKR_GENERAL_ERROR;
+ }
+ }
+
+ /**********************************************/
+ /* Pairwise Consistency Check of Sign/Verify. */
+ /**********************************************/
+
+ canSignVerify = sftk_isTrue(privateKey, CKA_SIGN);
+
+ if (canSignVerify) {
+ /* Determine length of signature. */
+ switch (keyType) {
+ case CKK_RSA:
+ signature_length = modulusLen;
+ mech.mechanism = CKM_RSA_PKCS;
+ break;
+ case CKK_DSA:
+ signature_length = DSA_SIGNATURE_LEN;
+ mech.mechanism = CKM_DSA;
+ break;
+#ifdef NSS_ENABLE_ECC
+ case CKK_EC:
+ signature_length = MAX_ECKEY_LEN * 2;
+ mech.mechanism = CKM_ECDSA;
+ break;
+#endif
+ default:
+ return CKR_DEVICE_ERROR;
+ }
+
+ /* Allocate space for signature data. */
+ signature = (unsigned char *) PORT_ZAlloc(signature_length);
+ if (signature == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+
+ /* Sign the known hash using the private key. */
+ crv = NSC_SignInit(hSession, &mech, privateKey->handle);
+ if (crv != CKR_OK) {
+ PORT_Free(signature);
+ return crv;
+ }
+
+ crv = NSC_Sign(hSession,
+ known_digest,
+ PAIRWISE_DIGEST_LENGTH,
+ signature,
+ &signature_length);
+ if (crv != CKR_OK) {
+ PORT_Free(signature);
+ return crv;
+ }
+
+ /* Verify the known hash using the public key. */
+ crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
+ if (crv != CKR_OK) {
+ PORT_Free(signature);
+ return crv;
+ }
+
+ crv = NSC_Verify(hSession,
+ known_digest,
+ PAIRWISE_DIGEST_LENGTH,
+ signature,
+ signature_length);
+
+ /* Free signature data. */
+ PORT_Free(signature);
+
+ if ((crv == CKR_SIGNATURE_LEN_RANGE) ||
+ (crv == CKR_SIGNATURE_INVALID)) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (crv != CKR_OK) {
+ return crv;
+ }
+ }
+
+ /**********************************************/
+ /* Pairwise Consistency Check for Derivation */
+ /**********************************************/
+
+ isDerivable = sftk_isTrue(privateKey, CKA_DERIVE);
+
+ if (isDerivable) {
+ /*
+ * We are not doing consistency check for Diffie-Hellman Key -
+ * otherwise it would be here
+ * This is also true for Elliptic Curve Diffie-Hellman keys
+ * NOTE: EC keys are currently subjected to pairwise
+ * consistency check for signing/verification.
+ */
+ /*
+ * FIPS 140-2 had the following pairwise consistency test for
+ * public and private keys used for key agreement:
+ * If the keys are used to perform key agreement, then the
+ * cryptographic module shall create a second, compatible
+ * key pair. The cryptographic module shall perform both
+ * sides of the key agreement algorithm and shall compare
+ * the resulting shared values. If the shared values are
+ * not equal, the test shall fail.
+ * This test was removed in Change Notice 3.
+ */
+
+ }
+
+ return CKR_OK;
+}
/* NSC_GenerateKeyPair generates a public-key/private-key pair,
* creating new key objects. */
@@ -3408,6 +3686,18 @@ ecgn_done:
sftk_forceAttribute(publicKey,CKA_NEVER_EXTRACTABLE,
&cktrue,sizeof(CK_BBOOL));
}
+
+ /* Perform FIPS 140-2 pairwise consistency check. */
+ crv = sftk_PairwiseConsistencyCheck(hSession,
+ publicKey, privateKey, key_type);
+ if (crv != CKR_OK) {
+ NSC_DestroyObject(hSession,publicKey->handle);
+ sftk_FreeObject(publicKey);
+ NSC_DestroyObject(hSession,privateKey->handle);
+ sftk_FreeObject(privateKey);
+ return crv;
+ }
+
*phPrivateKey = privateKey->handle;
*phPublicKey = publicKey->handle;
sftk_FreeObject(publicKey);
@@ -3429,7 +3719,6 @@ static SECItem *sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp)
#ifdef NSS_ENABLE_ECC
SECItem *fordebug;
int savelen;
- int i;
#endif
if(!key) {
@@ -4415,7 +4704,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
- status = sftk_PRF(&pms, "master secret", &crsr, &master, isFIPS);
+ status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS);
if (status != SECSuccess) {
crv = CKR_FUNCTION_FAILED;
break;
@@ -4546,7 +4835,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
ssl3_keys->RandomInfo.pClientRandom,
SSL3_RANDOM_LENGTH);
- status = sftk_PRF(&master, "key expansion", &srcr, &keyblk,
+ status = TLS_PRF(&master, "key expansion", &srcr, &keyblk,
isFIPS);
if (status != SECSuccess) {
goto key_and_mac_derive_fail;
@@ -4753,7 +5042,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
i += effKeySize;
keyblk.data = key_block2;
keyblk.len = sizeof key_block2;
- status = sftk_PRF(&secret, "client write key", &crsr, &keyblk,
+ status = TLS_PRF(&secret, "client write key", &crsr, &keyblk,
isFIPS);
if (status != SECSuccess) {
goto key_and_mac_derive_fail;
@@ -4775,7 +5064,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
i += effKeySize;
keyblk.data = key_block2;
keyblk.len = sizeof key_block2;
- status = sftk_PRF(&secret, "server write key", &crsr, &keyblk,
+ status = TLS_PRF(&secret, "server write key", &crsr, &keyblk,
isFIPS);
if (status != SECSuccess) {
goto key_and_mac_derive_fail;
@@ -4797,7 +5086,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
secret.len = 0;
keyblk.data = &key_block[i];
keyblk.len = 2 * IVSize;
- status = sftk_PRF(&secret, "IV block", &crsr, &keyblk,
+ status = TLS_PRF(&secret, "IV block", &crsr, &keyblk,
isFIPS);
if (status != SECSuccess) {
goto key_and_mac_derive_fail;
diff --git a/security/nss/lib/softoken/pkcs11f.h b/security/nss/lib/softoken/pkcs11f.h
index 4ade31aac..a6bc91f46 100644
--- a/security/nss/lib/softoken/pkcs11f.h
+++ b/security/nss/lib/softoken/pkcs11f.h
@@ -14,7 +14,7 @@
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
+ * RSA Security INC.
* Portions created by the Initial Developer are Copyright (C) 1994-2000
* the Initial Developer. All Rights Reserved.
*
@@ -152,10 +152,10 @@ CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
/* C_InitToken initializes a token. */
CK_PKCS11_FUNCTION_INFO(C_InitToken)
#ifdef CK_NEED_ARG_LIST
-(
/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
+(
CK_SLOT_ID slotID, /* ID of the token's slot */
- CK_CHAR_PTR pPin, /* the SO's initial PIN */
+ CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
CK_ULONG ulPinLen, /* length in bytes of the PIN */
CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
);
@@ -167,7 +167,7 @@ CK_PKCS11_FUNCTION_INFO(C_InitPIN)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_CHAR_PTR pPin, /* the normal user's PIN */
+ CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
CK_ULONG ulPinLen /* length in bytes of the PIN */
);
#endif
@@ -178,9 +178,9 @@ CK_PKCS11_FUNCTION_INFO(C_SetPIN)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_CHAR_PTR pOldPin, /* the old PIN */
+ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
CK_ULONG ulOldLen, /* length of the old PIN */
- CK_CHAR_PTR pNewPin, /* the new PIN */
+ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
CK_ULONG ulNewLen /* length of the new PIN */
);
#endif
@@ -264,7 +264,7 @@ CK_PKCS11_FUNCTION_INFO(C_Login)
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_USER_TYPE userType, /* the user type */
- CK_CHAR_PTR pPin, /* the user's PIN */
+ CK_UTF8CHAR_PTR pPin, /* the user's PIN */
CK_ULONG ulPinLen /* the length of the PIN */
);
#endif
diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h
index de7f0f80c..0eaf5bf37 100644
--- a/security/nss/lib/softoken/pkcs11i.h
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -321,40 +321,60 @@ struct SFTKSessionStr {
* as well as the reference count of session objects in that bucket
* (head[]->refCount), objectLock protects all elements of the token
* object hash table (tokObjects[], tokenIDCount, and tokenHashTable),
- * and slotLock protects the remaining protected elements:
- * password, isLoggedIn, ssoLoggedIn, and sessionCount
+ * slotLock protects the remaining protected elements:
+ * password, isLoggedIn, ssoLoggedIn, and sessionCount,
+ * and pwCheckLock serializes the key database password checks in
+ * NSC_SetPIN and NSC_Login.
+ *
+ * Each of the fields below has the following lifetime as commented
+ * next to the fields:
+ * invariant - This value is set when the slot is first created and
+ * never changed until it is destroyed.
+ * per load - This value is set when the slot is first created, or
+ * when the slot is used to open another directory. Between open and close
+ * this field does not change.
+ * variable - This value changes through the normal process of slot operation.
+ * - reset. The value of this variable is cleared during an open/close
+ * cycles.
+ * - preserved. The value of this variable is preserved over open/close
+ * cycles.
*/
struct SFTKSlotStr {
- CK_SLOT_ID slotID;
- PZLock *slotLock;
- PZLock **sessionLock;
- unsigned int numSessionLocks;
- unsigned long sessionLockMask;
- PZLock *objectLock;
- SECItem *password;
- PRBool hasTokens;
- PRBool isLoggedIn;
- PRBool ssoLoggedIn;
- PRBool needLogin;
- PRBool DB_loaded;
- PRBool readOnly;
- PRBool optimizeSpace;
- NSSLOWCERTCertDBHandle *certDB;
- NSSLOWKEYDBHandle *keyDB;
- int minimumPinLen;
- PRInt32 sessionIDCount; /* atomically incremented */
- int sessionIDConflict; /* not protected by a lock */
- int sessionCount;
- PRInt32 rwSessionCount; /* set by atomic operations */
- int tokenIDCount;
- int index;
- PLHashTable *tokenHashTable;
- SFTKObject **tokObjects;
- unsigned int tokObjHashSize;
- SFTKSession **head;
- unsigned int sessHashSize;
- char tokDescription[33];
- char slotDescription[64];
+ CK_SLOT_ID slotID; /* invariant */
+ PZLock *slotLock; /* invariant */
+ PZLock **sessionLock; /* invariant */
+ unsigned int numSessionLocks; /* invariant */
+ unsigned long sessionLockMask; /* invariant */
+ PZLock *objectLock; /* invariant */
+ PRLock *pwCheckLock; /* invariant */
+ SECItem *password; /* variable - reset */
+ PRBool present; /* variable -set */
+ PRBool hasTokens; /* per load */
+ PRBool isLoggedIn; /* variable - reset */
+ PRBool ssoLoggedIn; /* variable - reset */
+ PRBool needLogin; /* per load */
+ PRBool DB_loaded; /* per load */
+ PRBool readOnly; /* per load */
+ PRBool optimizeSpace; /* invariant */
+ NSSLOWCERTCertDBHandle *certDB; /* per load */
+ NSSLOWKEYDBHandle *keyDB; /* per load */
+ int minimumPinLen; /* per load */
+ PRInt32 sessionIDCount; /* atomically incremented */
+ /* (preserved) */
+ int sessionIDConflict; /* not protected by a lock */
+ /* (preserved) */
+ int sessionCount; /* variable - reset */
+ PRInt32 rwSessionCount; /* set by atomic operations */
+ /* (reset) */
+ int tokenIDCount; /* variable - perserved */
+ int index; /* invariant */
+ PLHashTable *tokenHashTable; /* invariant */
+ SFTKObject **tokObjects; /* variable - reset */
+ unsigned int tokObjHashSize; /* invariant */
+ SFTKSession **head; /* variable -reset */
+ unsigned int sessHashSize; /* invariant */
+ char tokDescription[33]; /* per load */
+ char slotDescription[64]; /* invariant */
};
/*
@@ -404,8 +424,10 @@ struct SFTKSSLMACInfoStr {
#define SFTK_TOKEN_TYPE_CERT 0x70000000L
#define SFTK_TOKEN_KRL_HANDLE (SFTK_TOKEN_MAGIC|SFTK_TOKEN_TYPE_CRL|1)
-/* how big a password/pin we can deal with */
+/* how big (in bytes) a password/pin we can deal with */
#define SFTK_MAX_PIN 255
+/* minimum password/pin length (in Unicode characters) in FIPS mode */
+#define FIPS_MIN_PIN 7
/* slot ID's */
#define NETSCAPE_SLOT_ID 1
@@ -533,14 +555,21 @@ typedef struct sftk_parametersStr {
SEC_BEGIN_PROTOS
+/* shared functions between PKCS11.c and SFTKFIPS.c */
extern int nsf_init;
extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS);
extern CK_RV nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS);
extern CK_RV nsc_CommonGetSlotList(CK_BBOOL tokPresent,
CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount, int moduleIndex);
-/* shared functions between PKCS11.c and SFTKFIPS.c */
-extern CK_RV SFTK_SlotInit(char *configdir,sftk_token_parameters *params,
- int moduleIndex);
+
+/* slot initialization, reinit, shutdown and destruction */
+extern CK_RV SFTK_SlotInit(char *configdir,
+ sftk_token_parameters *params, int moduleIndex);
+extern CK_RV SFTK_SlotReInit(SFTKSlot *slot, char *configdir,
+ sftk_token_parameters *params, int moduleIndex);
+extern CK_RV SFTK_DestroySlotData(SFTKSlot *slot);
+extern CK_RV SFTK_ShutdownSlot(SFTKSlot *slot);
+
/* internal utility functions used by pkcs11.c */
extern SFTKAttribute *sftk_FindAttribute(SFTKObject *object,
@@ -586,6 +615,9 @@ extern SFTKObject *sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle,
SFTKSession *session);
extern void sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object);
extern void sftk_AddObject(SFTKSession *session, SFTKObject *object);
+/* clear out all the existing object ID to database key mappings.
+ * used to reinit a token */
+extern CK_RV SFTK_ClearTokenKeyHashTable(SFTKSlot *slot);
extern CK_RV sftk_searchObjectList(SFTKSearchResults *search,
SFTKObject **head, unsigned int size,
@@ -597,7 +629,7 @@ extern void sftk_FreeObjectList(SFTKObjectListElement *objectList);
extern void sftk_FreeSearch(SFTKSearchResults *search);
extern CK_RV sftk_handleObject(SFTKObject *object, SFTKSession *session);
-extern SFTKSlot *sftk_SlotFromID(CK_SLOT_ID slotID);
+extern SFTKSlot *sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all);
extern SFTKSlot *sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle);
extern SFTKSession *sftk_SessionFromHandle(CK_SESSION_HANDLE handle);
extern void sftk_FreeSession(SFTKSession *session);
@@ -653,9 +685,14 @@ CK_RV sftk_DBInit(const char *configdir, const char *certPrefix,
const char *keyPrefix, PRBool readOnly, PRBool noCertDB,
PRBool noKeyDB, PRBool forceOpen,
NSSLOWCERTCertDBHandle **certDB, NSSLOWKEYDBHandle **keyDB);
+NSSLOWCERTCertDBHandle *sftk_getCertDB(SFTKSlot *slot);
+NSSLOWKEYDBHandle *sftk_getKeyDB(SFTKSlot *slot);
+void sftk_freeCertDB(NSSLOWCERTCertDBHandle *certHandle);
+void sftk_freeKeyDB(NSSLOWKEYDBHandle *keyHandle);
-void sftk_DBShutdown(NSSLOWCERTCertDBHandle *certHandle,
- NSSLOWKEYDBHandle *keyHandle);
+/* helper function which calls nsslowkey_FindKeyByPublicKey after safely
+ * acquiring a reference to the keydb from the slot */
+NSSLOWKEYPrivateKey *sftk_FindKeyByPublicKey(SFTKSlot *slot, SECItem *dbKey);
const char *sftk_EvaluateConfigDir(const char *configdir, char **domain);
@@ -683,10 +720,6 @@ SFTKTokenObject *sftk_convertSessionToToken(SFTKObject *so);
* implement TLS Pseudo Random Function (PRF)
*/
-extern SECStatus
-sftk_PRF(const SECItem *secret, const char *label, SECItem *seed,
- SECItem *result, PRBool isFIPS);
-
extern CK_RV
sftk_TLSPRFInit(SFTKSessionContext *context,
SFTKObject * key,
diff --git a/security/nss/lib/softoken/pkcs11n.h b/security/nss/lib/softoken/pkcs11n.h
index 31137c4d2..b1dce6c12 100644
--- a/security/nss/lib/softoken/pkcs11n.h
+++ b/security/nss/lib/softoken/pkcs11n.h
@@ -73,6 +73,8 @@ static const char CKT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
#define CKO_NETSCAPE_SMIME (CKO_NETSCAPE + 2)
#define CKO_NETSCAPE_TRUST (CKO_NETSCAPE + 3)
#define CKO_NETSCAPE_BUILTIN_ROOT_LIST (CKO_NETSCAPE + 4)
+#define CKO_NETSCAPE_NEWSLOT (CKO_NETSCAPE + 5)
+#define CKO_NETSCAPE_DELSLOT (CKO_NETSCAPE + 6)
/*
* Netscape-defined key types
@@ -106,6 +108,7 @@ static const char CKT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
#define CKA_NETSCAPE_PQG_SEED (CKA_NETSCAPE + 21)
#define CKA_NETSCAPE_PQG_H (CKA_NETSCAPE + 22)
#define CKA_NETSCAPE_PQG_SEED_BITS (CKA_NETSCAPE + 23)
+#define CKA_NETSCAPE_MODULE_SPEC (CKA_NETSCAPE + 24)
/*
* Trust attributes:
@@ -233,4 +236,11 @@ typedef CK_ULONG CK_TRUST;
typedef char ** (PR_CALLBACK *SECMODModuleDBFunc)(unsigned long function,
char *parameters, void *moduleSpec);
+/* softoken slot ID's */
+#define SFTK_MIN_USER_SLOT_ID 4
+#define SFTK_MAX_USER_SLOT_ID 100
+#define SFTK_MIN_FIPS_USER_SLOT_ID 101
+#define SFTK_MAX_FIPS_USER_SLOT_ID 127
+
+
#endif /* _PKCS11N_H_ */
diff --git a/security/nss/lib/softoken/pkcs11ni.h b/security/nss/lib/softoken/pkcs11ni.h
new file mode 100644
index 000000000..9e584a9f0
--- /dev/null
+++ b/security/nss/lib/softoken/pkcs11ni.h
@@ -0,0 +1,52 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Red Hat, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _PKCS11NI_H_
+#define _PKCS11NI_H_
+
+/*
+ * pkcs11ni.h
+ *
+ * This file contains softoken private exports for NSS
+ */
+
+/* softoken slot ID's */
+#define SFTK_MIN_USER_SLOT_ID 4
+#define SFTK_MAX_USER_SLOT_ID 100
+#define SFTK_MIN_FIPS_USER_SLOT_ID 101
+#define SFTK_MAX_FIPS_USER_SLOT_ID 127
+
+
+#endif /* _PKCS11NI_H_ */
diff --git a/security/nss/lib/softoken/pkcs11t.h b/security/nss/lib/softoken/pkcs11t.h
index f3761f6b5..771f65ab2 100644
--- a/security/nss/lib/softoken/pkcs11t.h
+++ b/security/nss/lib/softoken/pkcs11t.h
@@ -14,7 +14,7 @@
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
+ * RSA Security, Inc.
* Portions created by the Initial Developer are Copyright (C) 1994-2000
* the Initial Developer. All Rights Reserved.
*
@@ -34,27 +34,27 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
-/*
- * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
- * is granted provided that it is identified as "RSA Security In.c Public-Key
- * Cryptography Standards (PKCS)" in all material mentioning or referencing
- * this document.
- */
-/* See top of pkcs11.h for information about the macros that
- * must be defined and the structure-packing conventions that
- * must be set before including this file.
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki)" in all material mentioning or referencing this software.
+
+ * License is also granted to make and use derivative works provided that
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
+ * referencing the derived work.
+
+ * RSA Security Inc. makes no representations concerning either the
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
*/
+
#ifndef _PKCS11T_H_
#define _PKCS11T_H_ 1
-#ifndef CK_FALSE
-#define CK_FALSE 0
-#endif
-
-#ifndef CK_TRUE
-#define CK_TRUE (!CK_FALSE)
-#endif
+#define CK_TRUE 1
+#define CK_FALSE 0
#include "prtypes.h"
@@ -64,7 +64,7 @@
#define CK_DECLARE_FUNCTION(rv,func) PR_EXTERN(rv) func
#define CK_DECLARE_FUNCTION_POINTER(rv,func) rv (PR_CALLBACK * func)
-#define CK_INVALID_SESSION 0
+#define CK_INVALID_SESSION 0
/* an unsigned 8-bit value */
typedef unsigned char CK_BYTE;
@@ -72,7 +72,7 @@ typedef unsigned char CK_BYTE;
/* an unsigned 8-bit character */
typedef CK_BYTE CK_CHAR;
-/* an unsigned 8-bit character */
+/* an 8-bit UTF-8 character */
typedef CK_BYTE CK_UTF8CHAR;
/* a BYTE-sized Boolean flag */
@@ -121,8 +121,8 @@ typedef CK_VERSION CK_PTR CK_VERSION_PTR;
typedef struct CK_INFO {
- /* manufacturerID and libraryDecription have been changed from
- * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ /* manufacturerID and libraryDecription have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
CK_VERSION cryptokiVersion; /* PKCS #11 interface ver */
CK_UTF8CHAR manufacturerID[32]; /* blank padded */
CK_FLAGS flags; /* must be zero */
@@ -150,8 +150,8 @@ typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
/* CK_SLOT_INFO provides information about a slot */
typedef struct CK_SLOT_INFO {
- /* slotDescription and manufacturerID have been changed from
- * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ /* slotDescription and manufacturerID have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
CK_UTF8CHAR slotDescription[64]; /* blank padded */
CK_UTF8CHAR manufacturerID[32]; /* blank padded */
CK_FLAGS flags;
@@ -173,8 +173,8 @@ typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
/* CK_TOKEN_INFO provides information about a token */
typedef struct CK_TOKEN_INFO {
- /* label, manufacturerID, and model have been changed from
- * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ /* label, manufacturerID, and model have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
CK_UTF8CHAR label[32]; /* blank padded */
CK_UTF8CHAR manufacturerID[32]; /* blank padded */
CK_UTF8CHAR model[16]; /* blank padded */
@@ -203,7 +203,7 @@ typedef struct CK_TOKEN_INFO {
} CK_TOKEN_INFO;
/* The flags parameter is defined as follows:
- * Bit Flag Mask Meaning
+ * Bit Flag Mask Meaning
*/
#define CKF_RNG 0x00000001 /* has random #
* generator */
@@ -239,20 +239,20 @@ typedef struct CK_TOKEN_INFO {
#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
- * token has been initialized using C_InitializeToken or an
+ * token has been initialized using C_InitializeToken or an
* equivalent mechanism outside the scope of PKCS #11.
- * Calling C_InitializeToken when this flag is set will cause
+ * Calling C_InitializeToken when this flag is set will cause
* the token to be reinitialized. */
#define CKF_TOKEN_INITIALIZED 0x00000400
-/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
- * true, the token supports secondary authentication for
- * private key objects. */
-/* DEPRICATED in v2.11 */
+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
+ * true, the token supports secondary authentication for
+ * private key objects. This flag is deprecated in v2.11 and
+ onwards. */
#define CKF_SECONDARY_AUTHENTICATION 0x00000800
-/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
- * incorrect user login PIN has been entered at least once
+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect user login PIN has been entered at least once
* since the last successful authentication. */
#define CKF_USER_PIN_COUNT_LOW 0x00010000
@@ -260,18 +260,19 @@ typedef struct CK_TOKEN_INFO {
* supplying an incorrect user PIN will it to become locked. */
#define CKF_USER_PIN_FINAL_TRY 0x00020000
-/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
- * user PIN has been locked. User login to the token is not
+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
+ * user PIN has been locked. User login to the token is not
* possible. */
#define CKF_USER_PIN_LOCKED 0x00040000
-/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
- * the user PIN value is the default value set by token
- * initialization or manufacturing. */
+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the user PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card. */
#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000
-/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
- * incorrect SO login PIN has been entered at least once since
+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect SO login PIN has been entered at least once since
* the last successful authentication. */
#define CKF_SO_PIN_COUNT_LOW 0x00100000
@@ -279,14 +280,15 @@ typedef struct CK_TOKEN_INFO {
* supplying an incorrect SO PIN will it to become locked. */
#define CKF_SO_PIN_FINAL_TRY 0x00200000
-/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
* PIN has been locked. SO login to the token is not possible.
*/
#define CKF_SO_PIN_LOCKED 0x00400000
-/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
- * the SO PIN value is the default value set by token
- * initialization or manufacturing. */
+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the SO PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card. */
#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000
typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
@@ -296,7 +298,7 @@ typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
* identifies a session */
typedef CK_ULONG CK_SESSION_HANDLE;
-typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
/* CK_USER_TYPE enumerates the types of PKCS #11 users */
@@ -307,7 +309,8 @@ typedef CK_ULONG CK_USER_TYPE;
#define CKU_SO 0
/* Normal user */
#define CKU_USER 1
-
+/* Context specific (added in v2.20) */
+#define CKU_CONTEXT_SPECIFIC 2
/* CK_STATE enumerates the session states */
/* CK_STATE has been changed from an enum to a CK_ULONG for
@@ -357,6 +360,7 @@ typedef CK_ULONG CK_OBJECT_CLASS;
/* The following classes of objects are defined: */
/* CKO_HW_FEATURE is new for v2.10 */
/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
+/* CKO_MECHANISM is new for v2.20 */
#define CKO_DATA 0x00000000
#define CKO_CERTIFICATE 0x00000001
#define CKO_PUBLIC_KEY 0x00000002
@@ -364,7 +368,7 @@ typedef CK_ULONG CK_OBJECT_CLASS;
#define CKO_SECRET_KEY 0x00000004
#define CKO_HW_FEATURE 0x00000005
#define CKO_DOMAIN_PARAMETERS 0x00000006
-#define CKO_KG_PARAMETERS 0x00000006
+#define CKO_MECHANISM 0x00000007
#define CKO_VENDOR_DEFINED 0x80000000
typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
@@ -373,10 +377,12 @@ typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
* value that identifies the hardware feature type of an object
* with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
typedef CK_ULONG CK_HW_FEATURE_TYPE;
-
+
/* The following hardware feature types are defined */
+/* CKH_USER_INTERFACE is new for v2.20 */
#define CKH_MONOTONIC_COUNTER 0x00000001
#define CKH_CLOCK 0x00000002
+#define CKH_USER_INTERFACE 0x00000003
#define CKH_VENDOR_DEFINED 0x80000000
/* CK_KEY_TYPE is a value that identifies a key type */
@@ -389,10 +395,10 @@ typedef CK_ULONG CK_KEY_TYPE;
#define CKK_DH 0x00000002
/* CKK_ECDSA and CKK_KEA are new for v2.0 */
-/* CKK_X9_42_DH is new for v2.11 */
-#define CKK_ECDSA 0x00000003 /* deprecated in v2.11 */
+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
+#define CKK_ECDSA 0x00000003
#define CKK_EC 0x00000003
-#define CKK_X9_42_DH 0x00000004
+#define CKK_X9_42_DH 0x00000004
#define CKK_KEA 0x00000005
#define CKK_GENERIC_SECRET 0x00000010
@@ -405,7 +411,8 @@ typedef CK_ULONG CK_KEY_TYPE;
/* all these key types are new for v2.0 */
#define CKK_CAST 0x00000016
#define CKK_CAST3 0x00000017
-#define CKK_CAST5 0x00000018 /* deprecated in v2.11 */
+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
+#define CKK_CAST5 0x00000018
#define CKK_CAST128 0x00000018
#define CKK_RC5 0x00000019
#define CKK_IDEA 0x0000001A
@@ -413,12 +420,13 @@ typedef CK_ULONG CK_KEY_TYPE;
#define CKK_BATON 0x0000001C
#define CKK_JUNIPER 0x0000001D
#define CKK_CDMF 0x0000001E
-
-/* all these key types are new for v2.11 */
#define CKK_AES 0x0000001F
+/* BlowFish and TwoFish are new for v2.20 */
+#define CKK_BLOWFISH 0x00000020
+#define CKK_TWOFISH 0x00000021
+
#define CKK_VENDOR_DEFINED 0x80000000
-#define CKK_INVALID_KEY_TYPE 0xffffffff
/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
@@ -429,8 +437,10 @@ typedef CK_ULONG CK_CERTIFICATE_TYPE;
/* The following certificate types are defined: */
/* CKC_X_509_ATTR_CERT is new for v2.10 */
+/* CKC_WTLS is new for v2.20 */
#define CKC_X_509 0x00000000
#define CKC_X_509_ATTR_CERT 0x00000001
+#define CKC_WTLS 0x00000002
#define CKC_VENDOR_DEFINED 0x80000000
@@ -440,6 +450,10 @@ typedef CK_ULONG CK_CERTIFICATE_TYPE;
* v2.0 */
typedef CK_ULONG CK_ATTRIBUTE_TYPE;
+/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
+ consists of an array of values. */
+#define CKF_ARRAY_ATTRIBUTE 0x40000000
+
/* The following attribute types are defined: */
#define CKA_CLASS 0x00000000
#define CKA_TOKEN 0x00000001
@@ -455,14 +469,24 @@ typedef CK_ULONG CK_ATTRIBUTE_TYPE;
#define CKA_ISSUER 0x00000081
#define CKA_SERIAL_NUMBER 0x00000082
-/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
* for v2.10 */
#define CKA_AC_ISSUER 0x00000083
#define CKA_OWNER 0x00000084
#define CKA_ATTR_TYPES 0x00000085
+
/* CKA_TRUSTED is new for v2.11 */
#define CKA_TRUSTED 0x00000086
+/* CKA_CERTIFICATE_CATEGORY ...
+ * CKA_CHECK_VALUE are new for v2.20 */
+#define CKA_CERTIFICATE_CATEGORY 0x00000087
+#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088
+#define CKA_URL 0x00000089
+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008A
+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008B
+#define CKA_CHECK_VALUE 0x00000090
+
#define CKA_KEY_TYPE 0x00000100
#define CKA_SUBJECT 0x00000101
#define CKA_ID 0x00000102
@@ -490,9 +514,13 @@ typedef CK_ULONG CK_ATTRIBUTE_TYPE;
#define CKA_PRIME 0x00000130
#define CKA_SUBPRIME 0x00000131
#define CKA_BASE 0x00000132
+
/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
#define CKA_PRIME_BITS 0x00000133
-#define CKA_SUB_PRIME_BITS 0x00000134
+#define CKA_SUBPRIME_BITS 0x00000134
+#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS
+/* (To retain backwards-compatibility) */
+
#define CKA_VALUE_BITS 0x00000160
#define CKA_VALUE_LEN 0x00000161
@@ -503,22 +531,55 @@ typedef CK_ULONG CK_ATTRIBUTE_TYPE;
#define CKA_LOCAL 0x00000163
#define CKA_NEVER_EXTRACTABLE 0x00000164
#define CKA_ALWAYS_SENSITIVE 0x00000165
+
/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
#define CKA_KEY_GEN_MECHANISM 0x00000166
+
#define CKA_MODIFIABLE 0x00000170
-#define CKA_ECDSA_PARAMS 0x00000180 /* depricated v2.11 */
+
+/* CKA_ECDSA_PARAMS is deprecated in v2.11,
+ * CKA_EC_PARAMS is preferred. */
+#define CKA_ECDSA_PARAMS 0x00000180
#define CKA_EC_PARAMS 0x00000180
+
#define CKA_EC_POINT 0x00000181
-/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
- * CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
+ * are new for v2.10. Deprecated in v2.11 and onwards. */
+#define CKA_SECONDARY_AUTH 0x00000200
+#define CKA_AUTH_PIN_FLAGS 0x00000201
+
+/* CKA_ALWAYS_AUTHENTICATE ...
+ * CKA_UNWRAP_TEMPLATE are new for v2.20 */
+#define CKA_ALWAYS_AUTHENTICATE 0x00000202
+
+#define CKA_WRAP_WITH_TRUSTED 0x00000210
+#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211)
+#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212)
+
+/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
* are new for v2.10 */
-#define CKA_SECONDARY_AUTH 0x00000200 /* depricated v2.11 */
-#define CKA_AUTH_PIN_FLAGS 0x00000201 /* depricated v2.11 */
#define CKA_HW_FEATURE_TYPE 0x00000300
#define CKA_RESET_ON_INIT 0x00000301
#define CKA_HAS_RESET 0x00000302
+/* The following attributes are new for v2.20 */
+#define CKA_PIXEL_X 0x00000400
+#define CKA_PIXEL_Y 0x00000401
+#define CKA_RESOLUTION 0x00000402
+#define CKA_CHAR_ROWS 0x00000403
+#define CKA_CHAR_COLUMNS 0x00000404
+#define CKA_COLOR 0x00000405
+#define CKA_BITS_PER_PIXEL 0x00000406
+#define CKA_CHAR_SETS 0x00000480
+#define CKA_ENCODING_METHODS 0x00000481
+#define CKA_MIME_TYPES 0x00000482
+#define CKA_MECHANISM_TYPE 0x00000500
+#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501
+#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502
+#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503
+#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600)
+
#define CKA_VENDOR_DEFINED 0x80000000
@@ -561,17 +622,19 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_MD5_RSA_PKCS 0x00000005
#define CKM_SHA1_RSA_PKCS 0x00000006
-/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS & CKM_RSA_OAEP
- * are new for 2.10 */
+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
+ * CKM_RSA_PKCS_OAEP are new for v2.10 */
#define CKM_RIPEMD128_RSA_PKCS 0x00000007
#define CKM_RIPEMD160_RSA_PKCS 0x00000008
#define CKM_RSA_PKCS_OAEP 0x00000009
-/* CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31 & CKM_RSA_X9_31_KEY_PAIR_GEN
- * are new for 2.11 */
+/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
+ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A
#define CKM_RSA_X9_31 0x0000000B
#define CKM_SHA1_RSA_X9_31 0x0000000C
+#define CKM_RSA_PKCS_PSS 0x0000000D
+#define CKM_SHA1_RSA_PKCS_PSS 0x0000000E
#define CKM_DSA_KEY_PAIR_GEN 0x00000010
#define CKM_DSA 0x00000011
@@ -579,17 +642,21 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
#define CKM_DH_PKCS_DERIVE 0x00000021
-/* CKM_X9_42_DH_PKCS_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
- * CKM_X9_42_DH_HYBRID_DERIVE, & CKM_X9_42_MQV_DERIVE
- * are new for v2.11 */
-#define CKM_X9_42_DH_PKCS_KEY_PAIR_GEN 0x00000030
+/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
+ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
+ * v2.11 */
+#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030
#define CKM_X9_42_DH_DERIVE 0x00000031
#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032
#define CKM_X9_42_MQV_DERIVE 0x00000033
-#define CKM_SHA256_RSA_PKCS 0x00000040 /* v2.20 */
-#define CKM_SHA384_RSA_PKCS 0x00000041 /* v2.20 */
-#define CKM_SHA512_RSA_PKCS 0x00000042 /* v2.20 */
+/* CKM_SHA256/384/512 are new for v2.20 */
+#define CKM_SHA256_RSA_PKCS 0x00000040
+#define CKM_SHA384_RSA_PKCS 0x00000041
+#define CKM_SHA512_RSA_PKCS 0x00000042
+#define CKM_SHA256_RSA_PKCS_PSS 0x00000043
+#define CKM_SHA384_RSA_PKCS_PSS 0x00000044
+#define CKM_SHA512_RSA_PKCS_PSS 0x00000045
#define CKM_RC2_KEY_GEN 0x00000100
#define CKM_RC2_ECB 0x00000101
@@ -629,6 +696,12 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_CDMF_MAC_GENERAL 0x00000144
#define CKM_CDMF_CBC_PAD 0x00000145
+/* the following four DES mechanisms are new for v2.20 */
+#define CKM_DES_OFB64 0x00000150
+#define CKM_DES_OFB8 0x00000151
+#define CKM_DES_CFB64 0x00000152
+#define CKM_DES_CFB8 0x00000153
+
#define CKM_MD2 0x00000200
/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
@@ -647,7 +720,7 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_SHA_1_HMAC 0x00000221
#define CKM_SHA_1_HMAC_GENERAL 0x00000222
-/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
* CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
* and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
#define CKM_RIPEMD128 0x00000230
@@ -657,17 +730,16 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_RIPEMD160_HMAC 0x00000241
#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242
-#define CKM_SHA256 0x00000250 /* v2.20 */
-#define CKM_SHA256_HMAC 0x00000251 /* v2.20 */
-#define CKM_SHA256_HMAC_GENERAL 0x00000252 /* v2.20 */
-
-#define CKM_SHA384 0x00000260 /* v2.20 */
-#define CKM_SHA384_HMAC 0x00000261 /* v2.20 */
-#define CKM_SHA384_HMAC_GENERAL 0x00000262 /* v2.20 */
-
-#define CKM_SHA512 0x00000270 /* v2.20 */
-#define CKM_SHA512_HMAC 0x00000271 /* v2.20 */
-#define CKM_SHA512_HMAC_GENERAL 0x00000272 /* v2.20 */
+/* CKM_SHA256/384/512 are new for v2.20 */
+#define CKM_SHA256 0x00000250
+#define CKM_SHA256_HMAC 0x00000251
+#define CKM_SHA256_HMAC_GENERAL 0x00000252
+#define CKM_SHA384 0x00000260
+#define CKM_SHA384_HMAC 0x00000261
+#define CKM_SHA384_HMAC_GENERAL 0x00000262
+#define CKM_SHA512 0x00000270
+#define CKM_SHA512_HMAC 0x00000271
+#define CKM_SHA512_HMAC_GENERAL 0x00000272
/* All of the following mechanisms are new for v2.0 */
/* Note that CAST128 and CAST5 are the same algorithm */
@@ -718,23 +790,27 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
- * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE,
- * CKM_TLS_MASTER_KEY_DERIVE_DH, & CKM_SSL3_MASTER_KEY_DERIVE_DH
- * are new for v2.11. */
+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
+ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373
#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374
#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375
#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376
#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377
+/* CKM_TLS_PRF is new for v2.20 */
+#define CKM_TLS_PRF 0x00000378
+
#define CKM_SSL3_MD5_MAC 0x00000380
#define CKM_SSL3_SHA1_MAC 0x00000381
#define CKM_MD5_KEY_DERIVATION 0x00000390
#define CKM_MD2_KEY_DERIVATION 0x00000391
#define CKM_SHA1_KEY_DERIVATION 0x00000392
-#define CKM_SHA256_KEY_DERIVATION 0x00000393 /* v2.20 */
-#define CKM_SHA384_KEY_DERIVATION 0x00000394 /* v2.20 */
-#define CKM_SHA512_KEY_DERIVATION 0x00000395 /* v2.20 */
+
+/* CKM_SHA256/384/512 are new for v2.20 */
+#define CKM_SHA256_KEY_DERIVATION 0x00000393
+#define CKM_SHA384_KEY_DERIVATION 0x00000394
+#define CKM_SHA512_KEY_DERIVATION 0x00000395
#define CKM_PBE_MD2_DES_CBC 0x000003A0
#define CKM_PBE_MD5_DES_CBC 0x000003A1
@@ -755,9 +831,21 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_PKCS5_PBKD2 0x000003B0
#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
+
+/* WTLS mechanisms are new for v2.20 */
+#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0
+#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1
+#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2
+#define CKM_WTLS_PRF 0x000003D3
+#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4
+#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5
+
#define CKM_KEY_WRAP_LYNKS 0x00000400
#define CKM_KEY_WRAP_SET_OAEP 0x00000401
+/* CKM_CMS_SIG is new for v2.20 */
+#define CKM_CMS_SIG 0x00000500
+
/* Fortezza mechanisms */
#define CKM_SKIPJACK_KEY_GEN 0x00001000
#define CKM_SKIPJACK_ECB64 0x00001001
@@ -780,12 +868,17 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_BATON_COUNTER 0x00001034
#define CKM_BATON_SHUFFLE 0x00001035
#define CKM_BATON_WRAP 0x00001036
-#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040 /* depricated in v2.11 */
+
+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
+ * CKM_EC_KEY_PAIR_GEN is preferred */
+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
#define CKM_EC_KEY_PAIR_GEN 0x00001040
+
#define CKM_ECDSA 0x00001041
#define CKM_ECDSA_SHA1 0x00001042
-/* ECDH1 is new for 2.11 */
+/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
+ * are new for v2.11 */
#define CKM_ECDH1_DERIVE 0x00001050
#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051
#define CKM_ECMQV_DERIVE 0x00001052
@@ -798,7 +891,10 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_JUNIPER_WRAP 0x00001065
#define CKM_FASTHASH 0x00001070
-/* AES is new for 2.11 */
+/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
+ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
+ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
+ * new for v2.11 */
#define CKM_AES_KEY_GEN 0x00001080
#define CKM_AES_ECB 0x00001081
#define CKM_AES_CBC 0x00001082
@@ -806,11 +902,24 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_AES_MAC_GENERAL 0x00001084
#define CKM_AES_CBC_PAD 0x00001085
-/* CKM_DSA_PARAMETER_GEN, CKM_DH_PKCS_PARAMETER_GEN,
- * and CKM_DH_X9_42_PARAMETER_GEN are new for 2.11 */
+/* BlowFish and TwoFish are new for v2.20 */
+#define CKM_BLOWFISH_KEY_GEN 0x00001090
+#define CKM_BLOWFISH_CBC 0x00001091
+#define CKM_TWOFISH_KEY_GEN 0x00001092
+#define CKM_TWOFISH_CBC 0x00001093
+
+
+/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
+#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100
+#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101
+#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102
+#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103
+#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104
+#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105
+
#define CKM_DSA_PARAMETER_GEN 0x00002000
#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
-#define CKM_DH_X9_42_PARAMETER_GEN 0x00002002
+#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002
#define CKM_VENDOR_DEFINED 0x80000000
@@ -848,8 +957,6 @@ typedef struct CK_MECHANISM_INFO {
* CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
* and CKF_DERIVE are new for v2.0. They specify whether or not
* a mechanism can be used for a particular task */
-/* The flags CKF_EC_FP, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
- * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11 */
#define CKF_ENCRYPT 0x00000100
#define CKF_DECRYPT 0x00000200
#define CKF_DIGEST 0x00000400
@@ -862,14 +969,19 @@ typedef struct CK_MECHANISM_INFO {
#define CKF_WRAP 0x00020000
#define CKF_UNWRAP 0x00040000
#define CKF_DERIVE 0x00080000
-#define CKF_EC_FP 0x00100000
+
+/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
+ * describe a token's EC capabilities not available in mechanism
+ * information. */
+#define CKF_EC_F_P 0x00100000
#define CKF_EC_F_2M 0x00200000
#define CKF_EC_ECPARAMETERS 0x00400000
#define CKF_EC_NAMEDCURVE 0x00800000
#define CKF_EC_UNCOMPRESS 0x01000000
#define CKF_EC_COMPRESS 0x02000000
-#define CKF_EXTENSION 0x80000000 /* FALSE for 2.01 */
+#define CKF_EXTENSION 0x80000000 /* FALSE for this version */
typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
@@ -933,9 +1045,6 @@ typedef CK_ULONG CK_RV;
#define CKR_KEY_NOT_WRAPPABLE 0x00000069
#define CKR_KEY_UNEXTRACTABLE 0x0000006A
-/* CKR_KEY_PARAMS_INVALID is new for v2.11 */
-#define CKR_KEY_PARAMS_INVALID 0x0000006B
-
#define CKR_MECHANISM_INVALID 0x00000070
#define CKR_MECHANISM_PARAM_INVALID 0x00000071
@@ -991,10 +1100,10 @@ typedef CK_ULONG CK_RV;
#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
-/* New for v2.0 */
+/* These are new to v2.0 */
#define CKR_RANDOM_NO_RNG 0x00000121
-/* New for v2.11 */
+/* These are new to v2.11 */
#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
/* These are new to v2.0 */
@@ -1009,6 +1118,9 @@ typedef CK_ULONG CK_RV;
#define CKR_MUTEX_BAD 0x000001A0
#define CKR_MUTEX_NOT_LOCKED 0x000001A1
+/* This is new to v2.20 */
+#define CKR_FUNCTION_REJECTED 0x00000200
+
#define CKR_VENDOR_DEFINED 0x80000000
@@ -1066,7 +1178,17 @@ typedef struct CK_C_INITIALIZE_ARGS {
CK_LOCKMUTEX LockMutex;
CK_UNLOCKMUTEX UnlockMutex;
CK_FLAGS flags;
+ /* The official PKCS #11 spec does not have a 'LibraryParameters' field, but
+ * a reserved field. NSS needs a way to pass instance-specific information
+ * to the library (like where to find its config files, etc). This
+ * information is usually provided by the installer and passed uninterpreted
+ * by NSS to the library, though NSS does know the specifics of the softoken
+ * version of this parameter. Most compliant PKCS#11 modules expect this
+ * parameter to be NULL, and will return CKR_ARGUMENTS_BAD from
+ * C_Initialize if Library parameters is supplied. */
CK_CHAR_PTR *LibraryParameters;
+ /* This field is only present if the LibraryParameters is not NULL. It must
+ * be NULL in all cases */
CK_VOID_PTR pReserved;
} CK_C_INITIALIZE_ARGS;
@@ -1084,21 +1206,26 @@ typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
#define CKF_DONT_BLOCK 1
-/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
- * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message
- * Generation Function (MGF) applied to a message block when
- * formatting a message block for the PKCS #1 OAEP encryption
+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
+ * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message
+ * Generation Function (MGF) applied to a message block when
+ * formatting a message block for the PKCS #1 OAEP encryption
* scheme. */
-typedef CK_ULONG CK_RSA_PKCS_OAEP_MGF_TYPE;
+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
-typedef CK_RSA_PKCS_OAEP_MGF_TYPE CK_PTR CK_RSA_PKCS_OAEP_MGF_TYPE_PTR;
+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
/* The following MGFs are defined */
+/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
+ * are new for v2.20 */
#define CKG_MGF1_SHA1 0x00000001
+#define CKG_MGF1_SHA256 0x00000002
+#define CKG_MGF1_SHA384 0x00000003
+#define CKG_MGF1_SHA512 0x00000004
-/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
* CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
- * of the encoding parameter when formatting a message block
+ * of the encoding parameter when formatting a message block
* for the PKCS #1 OAEP encryption scheme. */
typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
@@ -1108,18 +1235,141 @@ typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
#define CKZ_DATA_SPECIFIED 0x00000001
/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
- * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
* CKM_RSA_PKCS_OAEP mechanism. */
typedef struct CK_RSA_PKCS_OAEP_PARAMS {
- CK_MECHANISM_TYPE hashAlg;
- CK_RSA_PKCS_OAEP_MGF_TYPE mgf;
- CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
- CK_VOID_PTR pSourceData;
- CK_ULONG ulSourceDataLen;
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_MGF_TYPE mgf;
+ CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
+ CK_VOID_PTR pSourceData;
+ CK_ULONG ulSourceDataLen;
} CK_RSA_PKCS_OAEP_PARAMS;
typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
+/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
+ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_PSS mechanism(s). */
+typedef struct CK_RSA_PKCS_PSS_PARAMS {
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_MGF_TYPE mgf;
+ CK_ULONG sLen;
+} CK_RSA_PKCS_PSS_PARAMS;
+
+typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
+
+/* CK_EC_KDF_TYPE is new for v2.11. */
+typedef CK_ULONG CK_EC_KDF_TYPE;
+
+/* The following EC Key Derivation Functions are defined */
+#define CKD_NULL 0x00000001
+#define CKD_SHA1_KDF 0x00000002
+
+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
+ * where each party contributes one key pair.
+ */
+typedef struct CK_ECDH1_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_ECDH1_DERIVE_PARAMS;
+
+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
+
+
+/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
+ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
+typedef struct CK_ECDH2_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+} CK_ECDH2_DERIVE_PARAMS;
+
+typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
+
+typedef struct CK_ECMQV_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+ CK_OBJECT_HANDLE publicKey;
+} CK_ECMQV_DERIVE_PARAMS;
+
+typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
+
+/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
+typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
+typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
+
+/* The following X9.42 DH key derivation functions are defined
+ (besides CKD_NULL already defined : */
+#define CKD_SHA1_KDF_ASN1 0x00000003
+#define CKD_SHA1_KDF_CONCATENATE 0x00000004
+
+/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
+ * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
+ * contributes one key pair */
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_X9_42_DH1_DERIVE_PARAMS;
+
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
+
+/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
+ * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
+ * mechanisms, where each party contributes two key pairs */
+typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+} CK_X9_42_DH2_DERIVE_PARAMS;
+
+typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
+
+typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+ CK_OBJECT_HANDLE publicKey;
+} CK_X9_42_MQV_DERIVE_PARAMS;
+
+typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
+
/* CK_KEA_DERIVE_PARAMS provides the parameters to the
* CKM_KEA_DERIVE mechanism */
/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
@@ -1213,6 +1463,22 @@ typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
+/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
+typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[8];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[16];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
* CKM_SKIPJACK_PRIVATE_WRAP mechanism */
@@ -1260,12 +1526,12 @@ typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
typedef struct CK_PBE_PARAMS {
- CK_CHAR_PTR pInitVector;
- CK_CHAR_PTR pPassword;
- CK_ULONG ulPasswordLen;
- CK_CHAR_PTR pSalt;
- CK_ULONG ulSaltLen;
- CK_ULONG ulIteration;
+ CK_BYTE_PTR pInitVector;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG ulPasswordLen;
+ CK_BYTE_PTR pSalt;
+ CK_ULONG ulSaltLen;
+ CK_ULONG ulIteration;
} CK_PBE_PARAMS;
typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
@@ -1324,6 +1590,83 @@ typedef struct CK_SSL3_KEY_MAT_PARAMS {
typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
+/* CK_TLS_PRF_PARAMS is new for version 2.20 */
+typedef struct CK_TLS_PRF_PARAMS {
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+ CK_BYTE_PTR pLabel;
+ CK_ULONG ulLabelLen;
+ CK_BYTE_PTR pOutput;
+ CK_ULONG_PTR pulOutputLen;
+} CK_TLS_PRF_PARAMS;
+
+typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
+
+/* WTLS is new for version 2.20 */
+typedef struct CK_WTLS_RANDOM_DATA {
+ CK_BYTE_PTR pClientRandom;
+ CK_ULONG ulClientRandomLen;
+ CK_BYTE_PTR pServerRandom;
+ CK_ULONG ulServerRandomLen;
+} CK_WTLS_RANDOM_DATA;
+
+typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
+
+typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_WTLS_RANDOM_DATA RandomInfo;
+ CK_BYTE_PTR pVersion;
+} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
+
+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+typedef struct CK_WTLS_PRF_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+ CK_BYTE_PTR pLabel;
+ CK_ULONG ulLabelLen;
+ CK_BYTE_PTR pOutput;
+ CK_ULONG_PTR pulOutputLen;
+} CK_WTLS_PRF_PARAMS;
+
+typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
+
+typedef struct CK_WTLS_KEY_MAT_OUT {
+ CK_OBJECT_HANDLE hMacSecret;
+ CK_OBJECT_HANDLE hKey;
+ CK_BYTE_PTR pIV;
+} CK_WTLS_KEY_MAT_OUT;
+
+typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
+
+typedef struct CK_WTLS_KEY_MAT_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_ULONG ulSequenceNumber;
+ CK_BBOOL bIsExport;
+ CK_WTLS_RANDOM_DATA RandomInfo;
+ CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_WTLS_KEY_MAT_PARAMS;
+
+typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
+
+/* CMS is new for version 2.20 */
+typedef struct CK_CMS_SIG_PARAMS {
+ CK_OBJECT_HANDLE certificateHandle;
+ CK_MECHANISM_PTR pSigningMechanism;
+ CK_MECHANISM_PTR pDigestMechanism;
+ CK_UTF8CHAR_PTR pContentType;
+ CK_BYTE_PTR pRequestedAttributes;
+ CK_ULONG ulRequestedAttributesLen;
+ CK_BYTE_PTR pRequiredAttributes;
+ CK_ULONG ulRequiredAttributesLen;
+} CK_CMS_SIG_PARAMS;
+
+typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
typedef struct CK_KEY_DERIVATION_STRING_DATA {
CK_BYTE_PTR pData;
@@ -1344,8 +1687,8 @@ typedef CK_ULONG CK_EXTRACT_PARAMS;
typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
- * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
- * indicate the Pseudo-Random Function (PRF) used to generate
+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
+ * indicate the Pseudo-Random Function (PRF) used to generate
* key bits using PKCS #5 PBKDF2. */
typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
@@ -1355,9 +1698,9 @@ typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_
#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
-/* CK_PKCS5_PBKD2_SALT_SOURCE_TYPE is new for v2.10.
- * CK_PKCS5_PBKD2_SALT_SOURCE_TYPE is used to indicate the
- * source of the salt value when deriving a key using PKCS #5
+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
+ * source of the salt value when deriving a key using PKCS #5
* PBKDF2. */
typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
@@ -1367,40 +1710,35 @@ typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE
#define CKZ_SALT_SPECIFIED 0x00000001
/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
- * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
* parameters to the CKM_PKCS5_PBKD2 mechanism. */
typedef struct CK_PKCS5_PBKD2_PARAMS {
- CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
- CK_VOID_PTR pSaltSourceData;
- CK_ULONG ulSaltSourceDataLen;
- CK_ULONG iterations;
- CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
- CK_VOID_PTR pPrfData;
- CK_ULONG ulPrfDataLen;
+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
+ CK_VOID_PTR pSaltSourceData;
+ CK_ULONG ulSaltSourceDataLen;
+ CK_ULONG iterations;
+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+ CK_VOID_PTR pPrfData;
+ CK_ULONG ulPrfDataLen;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG_PTR ulPasswordLen;
} CK_PKCS5_PBKD2_PARAMS;
-
+
typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
-/* CK_ECDH1_DERIVE_PARAMS is defined in Section 12.4.4 of
- * PKCS#11v2.11. This structure provides parameters for
- * the CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE key
- * derivation mechanisms.
- */
-typedef CK_ULONG CK_EC_KDF_TYPE;
-#define CKD_NULL 0x00000001
-#define CKD_SHA1_KDF 0x00000002
-
-typedef struct CK_ECDH1_DERIVE_PARAMS {
- CK_EC_KDF_TYPE kdf;
- CK_ULONG ulSharedDataLen;
- CK_BYTE_PTR pSharedData;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
-} CK_ECDH1_DERIVE_PARAMS;
+/* NSS Specific defines */
-typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
+/* defines that have been deprecated in 2.20, but maintained in our
+ * header file for backward compatibility */
+#define CKO_KG_PARAMETERS CKO_DOMAIN_PARAMETERS
+#define CKF_EC_FP CKF_EC_F_P
+/* new in v2.11 deprecated by 2.20 */
+#define CKR_KEY_PARAMS_INVALID 0x0000006B
+
+/* stuff that for historic reasons is in this header file but should have
+ * been in pkcs11n.h */
+#define CKK_INVALID_KEY_TYPE 0xffffffff
-/* Netscape Specific defines */
#include "pkcs11n.h"
/* undo packing */
diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c
index 8555f2bf3..8e68587ce 100644
--- a/security/nss/lib/softoken/pkcs11u.c
+++ b/security/nss/lib/softoken/pkcs11u.c
@@ -193,6 +193,10 @@ sftk_FreeAttribute(SFTKAttribute *attribute)
#define SFTK_DEF_ATTRIBUTE(value,len) \
{ NULL, NULL, PR_FALSE, PR_FALSE, 0, { 0, value, len } }
+#define SFTK_CLONE_ATTR(type, staticAttr) \
+ sftk_NewTokenAttribute( type, staticAttr.attrib.pValue, \
+ staticAttr.attrib.ulValueLen, PR_FALSE)
+
CK_BBOOL sftk_staticTrueValue = CK_TRUE;
CK_BBOOL sftk_staticFalseValue = CK_FALSE;
static const SFTKAttribute sftk_StaticTrueAttr =
@@ -236,10 +240,51 @@ static const SFTKAttribute sftk_StaticMustVerifyAttr =
SFTK_DEF_ATTRIBUTE(&sftk_staticMustVerifyValue,
sizeof(sftk_staticMustVerifyValue));
+/*
+ * helper functions which get the database and call the underlying
+ * low level database function.
+ */
+static char *
+sftk_FindKeyNicknameByPublicKey(SFTKSlot *slot, SECItem *dbKey)
+{
+ NSSLOWKEYDBHandle *keyHandle;
+ char * label;
+
+ keyHandle = sftk_getKeyDB(slot);
+ if (!keyHandle) {
+ return NULL;
+ }
+
+ label = nsslowkey_FindKeyNicknameByPublicKey(keyHandle, dbKey,
+ slot->password);
+ sftk_freeKeyDB(keyHandle);
+ return label;
+}
+
+
+NSSLOWKEYPrivateKey *
+sftk_FindKeyByPublicKey(SFTKSlot *slot, SECItem *dbKey)
+{
+ NSSLOWKEYPrivateKey *privKey;
+ NSSLOWKEYDBHandle *keyHandle;
+
+ keyHandle = sftk_getKeyDB(slot);
+ if (keyHandle == NULL) {
+ return NULL;
+ }
+ privKey = nsslowkey_FindKeyByPublicKey(keyHandle, dbKey, slot->password);
+ sftk_freeKeyDB(keyHandle);
+ if (privKey == NULL) {
+ return NULL;
+ }
+ return privKey;
+}
+
static certDBEntrySMime *
sftk_getSMime(SFTKTokenObject *object)
{
certDBEntrySMime *entry;
+ NSSLOWCERTCertDBHandle *certHandle;
if (object->obj.objclass != CKO_NETSCAPE_SMIME) {
return NULL;
@@ -248,10 +293,14 @@ sftk_getSMime(SFTKTokenObject *object)
return (certDBEntrySMime *)object->obj.objectInfo;
}
- entry = nsslowcert_ReadDBSMimeEntry(object->obj.slot->certDB,
- (char *)object->dbKey.data);
+ certHandle = sftk_getCertDB(object->obj.slot);
+ if (!certHandle) {
+ return NULL;
+ }
+ entry = nsslowcert_ReadDBSMimeEntry(certHandle, (char *)object->dbKey.data);
object->obj.objectInfo = (void *)entry;
object->obj.infoFree = (SFTKFree) nsslowcert_DestroyDBEntry;
+ sftk_freeCertDB(certHandle);
return entry;
}
@@ -260,6 +309,7 @@ sftk_getCrl(SFTKTokenObject *object)
{
certDBEntryRevocation *crl;
PRBool isKrl;
+ NSSLOWCERTCertDBHandle *certHandle;
if (object->obj.objclass != CKO_NETSCAPE_CRL) {
return NULL;
@@ -269,15 +319,20 @@ sftk_getCrl(SFTKTokenObject *object)
}
isKrl = (PRBool) (object->obj.handle == SFTK_TOKEN_KRL_HANDLE);
- crl = nsslowcert_FindCrlByKey(object->obj.slot->certDB,
- &object->dbKey, isKrl);
+ certHandle = sftk_getCertDB(object->obj.slot);
+ if (!certHandle) {
+ return NULL;
+ }
+
+ crl = nsslowcert_FindCrlByKey(certHandle, &object->dbKey, isKrl);
object->obj.objectInfo = (void *)crl;
object->obj.infoFree = (SFTKFree) nsslowcert_DestroyDBEntry;
+ sftk_freeCertDB(certHandle);
return crl;
}
static NSSLOWCERTCertificate *
-sftk_getCert(SFTKTokenObject *object)
+sftk_getCert(SFTKTokenObject *object, NSSLOWCERTCertDBHandle *certHandle)
{
NSSLOWCERTCertificate *cert;
CK_OBJECT_CLASS objClass = object->obj.objclass;
@@ -288,7 +343,7 @@ sftk_getCert(SFTKTokenObject *object)
if (objClass == CKO_CERTIFICATE && object->obj.objectInfo) {
return (NSSLOWCERTCertificate *)object->obj.objectInfo;
}
- cert = nsslowcert_FindCertByKey(object->obj.slot->certDB,&object->dbKey);
+ cert = nsslowcert_FindCertByKey(certHandle, &object->dbKey);
if (objClass == CKO_CERTIFICATE) {
object->obj.objectInfo = (void *)cert;
object->obj.infoFree = (SFTKFree) nsslowcert_DestroyCertificate ;
@@ -300,6 +355,7 @@ static NSSLOWCERTTrust *
sftk_getTrust(SFTKTokenObject *object)
{
NSSLOWCERTTrust *trust;
+ NSSLOWCERTCertDBHandle *certHandle;
if (object->obj.objclass != CKO_NETSCAPE_TRUST) {
return NULL;
@@ -307,9 +363,14 @@ sftk_getTrust(SFTKTokenObject *object)
if (object->obj.objectInfo) {
return (NSSLOWCERTTrust *)object->obj.objectInfo;
}
- trust = nsslowcert_FindTrustByKey(object->obj.slot->certDB,&object->dbKey);
+ certHandle = sftk_getCertDB(object->obj.slot);
+ if (!certHandle) {
+ return NULL;
+ }
+ trust = nsslowcert_FindTrustByKey(certHandle, &object->dbKey);
object->obj.objectInfo = (void *)trust;
object->obj.infoFree = (SFTKFree) nsslowcert_DestroyTrust ;
+ sftk_freeCertDB(certHandle);
return trust;
}
@@ -325,8 +386,7 @@ sftk_GetPublicKey(SFTKTokenObject *object)
if (object->obj.objectInfo) {
return (NSSLOWKEYPublicKey *)object->obj.objectInfo;
}
- privKey = nsslowkey_FindKeyByPublicKey(object->obj.slot->keyDB,
- &object->dbKey, object->obj.slot->password);
+ privKey = sftk_FindKeyByPublicKey(object->obj.slot, &object->dbKey);
if (privKey == NULL) {
return NULL;
}
@@ -337,8 +397,16 @@ sftk_GetPublicKey(SFTKTokenObject *object)
return pubKey;
}
+/*
+ * we need two versions of sftk_GetPrivateKey. One version that takes the
+ * DB handle so we can pass the handle we have already acquired in,
+ * rather than going through the 'getKeyDB' code again,
+ * which may fail the second time and another which just aquires
+ * the key handle from the slot (where we don't already have a key handle.
+ * This version does the former.
+ */
static NSSLOWKEYPrivateKey *
-sftk_GetPrivateKey(SFTKTokenObject *object)
+sftk_GetPrivateKeyWithDB(SFTKTokenObject *object, NSSLOWKEYDBHandle *keyHandle)
{
NSSLOWKEYPrivateKey *privKey;
@@ -349,8 +417,8 @@ sftk_GetPrivateKey(SFTKTokenObject *object)
if (object->obj.objectInfo) {
return (NSSLOWKEYPrivateKey *)object->obj.objectInfo;
}
- privKey = nsslowkey_FindKeyByPublicKey(object->obj.slot->keyDB,
- &object->dbKey, object->obj.slot->password);
+ privKey = nsslowkey_FindKeyByPublicKey(keyHandle, &object->dbKey,
+ object->obj.slot->password);
if (privKey == NULL) {
return NULL;
}
@@ -359,6 +427,22 @@ sftk_GetPrivateKey(SFTKTokenObject *object)
return privKey;
}
+/* this version does the latter */
+static NSSLOWKEYPrivateKey *
+sftk_GetPrivateKey(SFTKTokenObject *object)
+{
+ NSSLOWKEYDBHandle *keyHandle;
+ NSSLOWKEYPrivateKey *privKey;
+
+ keyHandle = sftk_getKeyDB(object->obj.slot);
+ if (!keyHandle) {
+ return NULL;
+ }
+ privKey = sftk_GetPrivateKeyWithDB(object, keyHandle);
+ sftk_freeKeyDB(keyHandle);
+ return privKey;
+}
+
/* sftk_GetPubItem returns data associated with the public key.
* one only needs to free the public key. This comment is here
* because this sematic would be non-obvious otherwise. All callers
@@ -407,12 +491,12 @@ sftk_FindRSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len);
return sftk_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
case CKA_DERIVE:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_ENCRYPT:
case CKA_VERIFY:
case CKA_VERIFY_RECOVER:
case CKA_WRAP:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_MODULUS:
return sftk_NewTokenAttributeSigned(type,key->u.rsa.modulus.data,
key->u.rsa.modulus.len, PR_FALSE);
@@ -442,9 +526,9 @@ sftk_FindDSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
case CKA_ENCRYPT:
case CKA_VERIFY_RECOVER:
case CKA_WRAP:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_VERIFY:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_VALUE:
return sftk_NewTokenAttributeSigned(type,key->u.dsa.publicValue.data,
key->u.dsa.publicValue.len, PR_FALSE);
@@ -477,12 +561,12 @@ sftk_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len);
return sftk_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
case CKA_DERIVE:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_ENCRYPT:
case CKA_VERIFY:
case CKA_VERIFY_RECOVER:
case CKA_WRAP:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_VALUE:
return sftk_NewTokenAttributeSigned(type,key->u.dh.publicValue.data,
key->u.dh.publicValue.len, PR_FALSE);
@@ -514,11 +598,11 @@ sftk_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
return sftk_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
case CKA_DERIVE:
case CKA_VERIFY:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_ENCRYPT:
case CKA_VERIFY_RECOVER:
case CKA_WRAP:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_EC_PARAMS:
/* XXX Why is the last arg PR_FALSE? */
return sftk_NewTokenAttributeSigned(type,
@@ -536,10 +620,11 @@ sftk_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
}
#endif /* NSS_ENABLE_ECC */
+
static SFTKAttribute *
sftk_FindPublicKeyAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
{
- NSSLOWKEYPublicKey *key;
+ NSSLOWKEYPublicKey *key;
SFTKAttribute *att = NULL;
char *label;
@@ -548,15 +633,15 @@ sftk_FindPublicKeyAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
case CKA_SENSITIVE:
case CKA_ALWAYS_SENSITIVE:
case CKA_NEVER_EXTRACTABLE:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_MODIFIABLE:
case CKA_EXTRACTABLE:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_LABEL:
- label = nsslowkey_FindKeyNicknameByPublicKey(object->obj.slot->keyDB,
- &object->dbKey, object->obj.slot->password);
+ label = sftk_FindKeyNicknameByPublicKey(object->obj.slot,
+ &object->dbKey);
if (label == NULL) {
- return (SFTKAttribute *)&sftk_StaticOneAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticOneAttr);
}
att = sftk_NewTokenAttribute(type,label,PORT_Strlen(label), PR_TRUE);
PORT_Free(label);
@@ -591,7 +676,7 @@ sftk_FindPublicKeyAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
static SFTKAttribute *
sftk_FindSecretKeyAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
{
- NSSLOWKEYPrivateKey *key;
+ NSSLOWKEYPrivateKey *key;
char *label;
unsigned char *keyString;
SFTKAttribute *att;
@@ -613,14 +698,14 @@ sftk_FindSecretKeyAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
case CKA_WRAP:
case CKA_UNWRAP:
case CKA_MODIFIABLE:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_NEVER_EXTRACTABLE:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_LABEL:
- label = nsslowkey_FindKeyNicknameByPublicKey(object->obj.slot->keyDB,
- &object->dbKey, object->obj.slot->password);
+ label = sftk_FindKeyNicknameByPublicKey(object->obj.slot,
+ &object->dbKey);
if (label == NULL) {
- return (SFTKAttribute *)&sftk_StaticNullAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticNullAttr);
}
att = sftk_NewTokenAttribute(type,label,PORT_Strlen(label), PR_TRUE);
PORT_Free(label);
@@ -723,7 +808,7 @@ sftk_FindSecretKeyAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
static SFTKAttribute *
sftk_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key,
- CK_ATTRIBUTE_TYPE type)
+ CK_ATTRIBUTE_TYPE type)
{
unsigned char hash[SHA1_LENGTH];
CK_KEY_TYPE keyType = CKK_RSA;
@@ -735,12 +820,12 @@ sftk_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key,
SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len);
return sftk_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
case CKA_DERIVE:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_DECRYPT:
case CKA_SIGN:
case CKA_SIGN_RECOVER:
case CKA_UNWRAP:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_MODULUS:
return sftk_NewTokenAttributeSigned(type,key->u.rsa.modulus.data,
key->u.rsa.modulus.len, PR_FALSE);
@@ -748,12 +833,24 @@ sftk_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key,
return sftk_NewTokenAttributeSigned(type,key->u.rsa.publicExponent.data,
key->u.rsa.publicExponent.len, PR_FALSE);
case CKA_PRIVATE_EXPONENT:
+ return sftk_NewTokenAttributeSigned(type,
+ key->u.rsa.privateExponent.data,
+ key->u.rsa.privateExponent.len, PR_FALSE);
case CKA_PRIME_1:
+ return sftk_NewTokenAttributeSigned(type, key->u.rsa.prime1.data,
+ key->u.rsa.prime1.len, PR_FALSE);
case CKA_PRIME_2:
+ return sftk_NewTokenAttributeSigned(type, key->u.rsa.prime2.data,
+ key->u.rsa.prime2.len, PR_FALSE);
case CKA_EXPONENT_1:
+ return sftk_NewTokenAttributeSigned(type, key->u.rsa.exponent1.data,
+ key->u.rsa.exponent1.len, PR_FALSE);
case CKA_EXPONENT_2:
+ return sftk_NewTokenAttributeSigned(type, key->u.rsa.exponent2.data,
+ key->u.rsa.exponent2.len, PR_FALSE);
case CKA_COEFFICIENT:
- return (SFTKAttribute *) &sftk_StaticNullAttr;
+ return sftk_NewTokenAttributeSigned(type, key->u.rsa.coefficient.data,
+ key->u.rsa.coefficient.len, PR_FALSE);
default:
break;
}
@@ -772,17 +869,18 @@ sftk_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key,
return sftk_NewTokenAttribute(type,&keyType,sizeof(keyType), PR_TRUE);
case CKA_ID:
SHA1_HashBuf(hash,key->u.dsa.publicValue.data,
- key->u.dsa.publicValue.len);
+ key->u.dsa.publicValue.len);
return sftk_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
case CKA_DERIVE:
case CKA_DECRYPT:
case CKA_SIGN_RECOVER:
case CKA_UNWRAP:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_SIGN:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_VALUE:
- return (SFTKAttribute *) &sftk_StaticNullAttr;
+ return sftk_NewTokenAttributeSigned(type, key->u.dsa.privateValue.data,
+ key->u.dsa.privateValue.len, PR_FALSE);
case CKA_PRIME:
return sftk_NewTokenAttributeSigned(type,key->u.dsa.params.prime.data,
key->u.dsa.params.prime.len, PR_FALSE);
@@ -812,14 +910,15 @@ sftk_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type)
SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len);
return sftk_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
case CKA_DERIVE:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_DECRYPT:
case CKA_SIGN:
case CKA_SIGN_RECOVER:
case CKA_UNWRAP:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_VALUE:
- return (SFTKAttribute *) &sftk_StaticNullAttr;
+ return sftk_NewTokenAttributeSigned(type,key->u.dh.privateValue.data,
+ key->u.dh.privateValue.len, PR_FALSE);
case CKA_PRIME:
return sftk_NewTokenAttributeSigned(type,key->u.dh.prime.data,
key->u.dh.prime.len, PR_FALSE);
@@ -847,13 +946,14 @@ sftk_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type)
return sftk_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
case CKA_DERIVE:
case CKA_SIGN:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_DECRYPT:
case CKA_SIGN_RECOVER:
case CKA_UNWRAP:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_VALUE:
- return (SFTKAttribute *) &sftk_StaticNullAttr;
+ return sftk_NewTokenAttributeSigned(type, key->u.ec.privateValue.data,
+ key->u.ec.privateValue.len, PR_FALSE);
case CKA_EC_PARAMS:
/* XXX Why is the last arg PR_FALSE? */
return sftk_NewTokenAttributeSigned(type,
@@ -870,7 +970,7 @@ sftk_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type)
static SFTKAttribute *
sftk_FindPrivateKeyAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
{
- NSSLOWKEYPrivateKey *key;
+ NSSLOWKEYPrivateKey *key;
char *label;
SFTKAttribute *att;
@@ -880,16 +980,16 @@ sftk_FindPrivateKeyAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
case CKA_ALWAYS_SENSITIVE:
case CKA_EXTRACTABLE:
case CKA_MODIFIABLE:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_NEVER_EXTRACTABLE:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_SUBJECT:
- return (SFTKAttribute *)&sftk_StaticNullAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticNullAttr);
case CKA_LABEL:
- label = nsslowkey_FindKeyNicknameByPublicKey(object->obj.slot->keyDB,
- &object->dbKey, object->obj.slot->password);
+ label = sftk_FindKeyNicknameByPublicKey(object->obj.slot,
+ &object->dbKey);
if (label == NULL) {
- return (SFTKAttribute *)&sftk_StaticNullAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticNullAttr);
}
att = sftk_NewTokenAttribute(type,label,PORT_Strlen(label), PR_TRUE);
PORT_Free(label);
@@ -926,7 +1026,7 @@ sftk_FindSMIMEAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
switch (type) {
case CKA_PRIVATE:
case CKA_MODIFIABLE:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_NETSCAPE_EMAIL:
return sftk_NewTokenAttribute(type,object->dbKey.data,
object->dbKey.len-1, PR_FALSE);
@@ -966,9 +1066,9 @@ sftk_FindTrustAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
switch (type) {
case CKA_PRIVATE:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_MODIFIABLE:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_CERT_SHA1_HASH:
case CKA_CERT_MD5_HASH:
case CKA_TRUST_CLIENT_AUTH:
@@ -1005,29 +1105,29 @@ sftk_FindTrustAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
trustFlags = trust->trust->objectSigningFlags;
trust:
if (trustFlags & CERTDB_TRUSTED_CA ) {
- return (SFTKAttribute *)&sftk_StaticTrustedDelegatorAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrustedDelegatorAttr);
}
if (trustFlags & CERTDB_TRUSTED) {
- return (SFTKAttribute *)&sftk_StaticTrustedAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrustedAttr);
}
if (trustFlags & CERTDB_NOT_TRUSTED) {
- return (SFTKAttribute *)&sftk_StaticUnTrustedAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticUnTrustedAttr);
}
if (trustFlags & CERTDB_TRUSTED_UNKNOWN) {
- return (SFTKAttribute *)&sftk_StaticTrustUnknownAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrustUnknownAttr);
}
if (trustFlags & CERTDB_VALID_CA) {
- return (SFTKAttribute *)&sftk_StaticValidDelegatorAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticValidDelegatorAttr);
}
if (trustFlags & CERTDB_VALID_PEER) {
- return (SFTKAttribute *)&sftk_StaticValidPeerAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticValidPeerAttr);
}
- return (SFTKAttribute *)&sftk_StaticMustVerifyAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticMustVerifyAttr);
case CKA_TRUST_STEP_UP_APPROVED:
if (trust->trust->sslFlags & CERTDB_GOVT_APPROVED_CA) {
- return (SFTKAttribute *)&sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
} else {
- return (SFTKAttribute *)&sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
}
default:
break;
@@ -1065,10 +1165,11 @@ sftk_FindCrlAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
switch (type) {
case CKA_PRIVATE:
case CKA_MODIFIABLE:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_NETSCAPE_KRL:
- return (SFTKAttribute *) ((object->obj.handle == SFTK_TOKEN_KRL_HANDLE)
- ? &sftk_StaticTrueAttr : &sftk_StaticFalseAttr);
+ return ((object->obj.handle == SFTK_TOKEN_KRL_HANDLE)
+ ? SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr)
+ : SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr));
case CKA_SUBJECT:
return sftk_NewTokenAttribute(type,object->dbKey.data,
object->dbKey.len, PR_FALSE);
@@ -1086,7 +1187,7 @@ sftk_FindCrlAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
switch (type) {
case CKA_NETSCAPE_URL:
if (crl->url == NULL) {
- return (SFTKAttribute *) &sftk_StaticNullAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticNullAttr);
}
return sftk_NewTokenAttribute(type, crl->url,
PORT_Strlen(crl->url)+1, PR_TRUE);
@@ -1102,19 +1203,20 @@ sftk_FindCrlAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
static SFTKAttribute *
sftk_FindCertAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
{
- NSSLOWCERTCertificate *cert;
- NSSLOWKEYPublicKey *pubKey;
+ NSSLOWCERTCertificate *cert;
+ NSSLOWCERTCertDBHandle *certHandle;
+ NSSLOWKEYPublicKey *pubKey;
unsigned char hash[SHA1_LENGTH];
SECItem *item;
switch (type) {
case CKA_PRIVATE:
- return (SFTKAttribute *) &sftk_StaticFalseAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticFalseAttr);
case CKA_MODIFIABLE:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_CERTIFICATE_TYPE:
/* hardcoding X.509 into here */
- return (SFTKAttribute *)&sftk_StaticX509Attr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticX509Attr);
case CKA_VALUE:
case CKA_ID:
case CKA_LABEL:
@@ -1126,7 +1228,14 @@ sftk_FindCertAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
default:
return NULL;
}
- cert = sftk_getCert(object);
+
+ certHandle = sftk_getCertDB(object->obj.slot);
+ if (certHandle == NULL) {
+ return NULL;
+ }
+
+ cert = sftk_getCert(object, certHandle);
+ sftk_freeCertDB(certHandle);
if (cert == NULL) {
return NULL;
}
@@ -1138,7 +1247,7 @@ sftk_FindCertAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
if (((cert->trust->sslFlags & CERTDB_USER) == 0) &&
((cert->trust->emailFlags & CERTDB_USER) == 0) &&
((cert->trust->objectSigningFlags & CERTDB_USER) == 0)) {
- return (SFTKAttribute *) &sftk_StaticNullAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticNullAttr);
}
pubKey = nsslowcert_ExtractPublicKey(cert);
if (pubKey == NULL) break;
@@ -1152,9 +1261,10 @@ sftk_FindCertAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
nsslowkey_DestroyPublicKey(pubKey);
return sftk_NewTokenAttribute(type, hash, SHA1_LENGTH, PR_TRUE);
case CKA_LABEL:
- return cert->nickname ? sftk_NewTokenAttribute(type, cert->nickname,
- PORT_Strlen(cert->nickname), PR_FALSE) :
- (SFTKAttribute *) &sftk_StaticNullAttr;
+ return cert->nickname
+ ? sftk_NewTokenAttribute(type, cert->nickname,
+ PORT_Strlen(cert->nickname), PR_FALSE)
+ : SFTK_CLONE_ATTR(type,sftk_StaticNullAttr);
case CKA_SUBJECT:
return sftk_NewTokenAttribute(type,cert->derSubject.data,
cert->derSubject.len, PR_FALSE);
@@ -1168,7 +1278,7 @@ sftk_FindCertAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
return (cert->emailAddr && cert->emailAddr[0])
? sftk_NewTokenAttribute(type, cert->emailAddr,
PORT_Strlen(cert->emailAddr), PR_FALSE)
- : (SFTKAttribute *) &sftk_StaticNullAttr;
+ : SFTK_CLONE_ATTR(type,sftk_StaticNullAttr);
default:
break;
}
@@ -1184,7 +1294,7 @@ sftk_FindTokenAttribute(SFTKTokenObject *object,CK_ATTRIBUTE_TYPE type)
return sftk_NewTokenAttribute(type,&object->obj.objclass,
sizeof(object->obj.objclass),PR_FALSE);
case CKA_TOKEN:
- return (SFTKAttribute *) &sftk_StaticTrueAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticTrueAttr);
case CKA_LABEL:
if ( (object->obj.objclass == CKO_CERTIFICATE)
|| (object->obj.objclass == CKO_PRIVATE_KEY)
@@ -1192,7 +1302,7 @@ sftk_FindTokenAttribute(SFTKTokenObject *object,CK_ATTRIBUTE_TYPE type)
|| (object->obj.objclass == CKO_SECRET_KEY)) {
break;
}
- return (SFTKAttribute *) &sftk_StaticNullAttr;
+ return SFTK_CLONE_ATTR(type,sftk_StaticNullAttr);
default:
break;
}
@@ -1247,7 +1357,8 @@ unsigned int
sftk_GetLengthInBits(unsigned char *buf, unsigned int bufLen)
{
unsigned int size = bufLen * 8;
- int i;
+ unsigned int i;
+
/* Get the real length in bytes */
for (i=0; i < bufLen; i++) {
unsigned char c = *buf++;
@@ -1279,7 +1390,7 @@ sftk_ConstrainAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
int minLength, int maxLength, int minMultiple)
{
SFTKAttribute *attribute;
- unsigned int size;
+ int size;
unsigned char *ptr;
attribute = sftk_FindAttribute(object, type);
@@ -1441,9 +1552,11 @@ static CK_RV
sftk_SetCertAttribute(SFTKTokenObject *to, CK_ATTRIBUTE_TYPE type,
void *value, unsigned int len)
{
- NSSLOWCERTCertificate *cert;
+ NSSLOWCERTCertificate *cert;
+ NSSLOWCERTCertDBHandle *certHandle;
char *nickname = NULL;
SECStatus rv;
+ CK_RV crv;
/* we can't change the EMAIL values, but let the
* upper layers feel better about the fact we tried to set these */
@@ -1451,17 +1564,21 @@ sftk_SetCertAttribute(SFTKTokenObject *to, CK_ATTRIBUTE_TYPE type,
return CKR_OK;
}
- if (to->obj.slot->certDB == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ certHandle = sftk_getCertDB(to->obj.slot);
+ if (certHandle == NULL) {
+ crv = CKR_TOKEN_WRITE_PROTECTED;
+ goto done;
}
if ((type != CKA_LABEL) && (type != CKA_ID)) {
- return CKR_ATTRIBUTE_READ_ONLY;
+ crv = CKR_ATTRIBUTE_READ_ONLY;
+ goto done;
}
- cert = sftk_getCert(to);
+ cert = sftk_getCert(to, certHandle);
if (cert == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
+ crv = CKR_OBJECT_HANDLE_INVALID;
+ goto done;
}
/* if the app is trying to set CKA_ID, it's probably because it just
@@ -1472,33 +1589,45 @@ sftk_SetCertAttribute(SFTKTokenObject *to, CK_ATTRIBUTE_TYPE type,
((cert->trust->emailFlags & CERTDB_USER) == 0) &&
((cert->trust->objectSigningFlags & CERTDB_USER) == 0)) {
SFTKSlot *slot = to->obj.slot;
-
- if (slot->keyDB && nsslowkey_KeyForCertExists(slot->keyDB,cert)) {
- NSSLOWCERTCertTrust trust = *cert->trust;
- trust.sslFlags |= CERTDB_USER;
- trust.emailFlags |= CERTDB_USER;
- trust.objectSigningFlags |= CERTDB_USER;
- nsslowcert_ChangeCertTrust(slot->certDB,cert,&trust);
+ NSSLOWKEYDBHandle *keyHandle;
+
+ keyHandle = sftk_getKeyDB(slot);
+ if (keyHandle) {
+ if (nsslowkey_KeyForCertExists(keyHandle, cert)) {
+ NSSLOWCERTCertTrust trust = *cert->trust;
+ trust.sslFlags |= CERTDB_USER;
+ trust.emailFlags |= CERTDB_USER;
+ trust.objectSigningFlags |= CERTDB_USER;
+ nsslowcert_ChangeCertTrust(certHandle,cert,&trust);
+ }
+ sftk_freeKeyDB(keyHandle);
}
}
- return CKR_OK;
+ crv = CKR_OK;
+ goto done;
}
/* must be CKA_LABEL */
if (value != NULL) {
nickname = PORT_ZAlloc(len+1);
if (nickname == NULL) {
- return CKR_HOST_MEMORY;
+ crv = CKR_HOST_MEMORY;
+ goto done;
}
PORT_Memcpy(nickname,value,len);
nickname[len] = 0;
}
- rv = nsslowcert_AddPermNickname(to->obj.slot->certDB, cert, nickname);
- if (nickname) PORT_Free(nickname);
- if (rv != SECSuccess) {
- return CKR_DEVICE_ERROR;
+ rv = nsslowcert_AddPermNickname(certHandle, cert, nickname);
+ crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
+
+done:
+ if (nickname) {
+ PORT_Free(nickname);
}
- return CKR_OK;
+ if (certHandle) {
+ sftk_freeCertDB(certHandle);
+ }
+ return crv;
}
static CK_RV
@@ -1506,8 +1635,10 @@ sftk_SetPrivateKeyAttribute(SFTKTokenObject *to, CK_ATTRIBUTE_TYPE type,
void *value, unsigned int len)
{
NSSLOWKEYPrivateKey *privKey;
+ NSSLOWKEYDBHandle *keyHandle;
char *nickname = NULL;
SECStatus rv;
+ CK_RV crv;
/* we can't change the ID and we don't store the subject, but let the
* upper layers feel better about the fact we tried to set these */
@@ -1515,32 +1646,41 @@ sftk_SetPrivateKeyAttribute(SFTKTokenObject *to, CK_ATTRIBUTE_TYPE type,
return CKR_OK;
}
- if (to->obj.slot->keyDB == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ keyHandle = sftk_getKeyDB(to->obj.slot);
+ if (keyHandle == NULL) {
+ crv = CKR_TOKEN_WRITE_PROTECTED;
+ goto done;
}
if (type != CKA_LABEL) {
- return CKR_ATTRIBUTE_READ_ONLY;
+ crv = CKR_ATTRIBUTE_READ_ONLY;
+ goto done;
}
- privKey = sftk_GetPrivateKey(to);
+ privKey = sftk_GetPrivateKeyWithDB(to, keyHandle);
if (privKey == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
+ crv = CKR_OBJECT_HANDLE_INVALID;
+ goto done;
}
if (value != NULL) {
nickname = PORT_ZAlloc(len+1);
if (nickname == NULL) {
- return CKR_HOST_MEMORY;
+ crv = CKR_HOST_MEMORY;
+ goto done;
}
PORT_Memcpy(nickname,value,len);
nickname[len] = 0;
}
- rv = nsslowkey_UpdateNickname(to->obj.slot->keyDB, privKey, &to->dbKey,
+ rv = nsslowkey_UpdateNickname(keyHandle, privKey, &to->dbKey,
nickname, to->obj.slot->password);
- if (nickname) PORT_Free(nickname);
- if (rv != SECSuccess) {
- return CKR_DEVICE_ERROR;
+ crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
+done:
+ if (nickname) {
+ PORT_Free(nickname);
}
- return CKR_OK;
+ if (keyHandle) {
+ sftk_freeKeyDB(keyHandle);
+ }
+ return crv;
}
static CK_RV
@@ -1549,22 +1689,29 @@ sftk_SetTrustAttribute(SFTKTokenObject *to, CK_ATTRIBUTE_TYPE type,
{
unsigned int flags;
CK_TRUST trust;
- NSSLOWCERTCertificate *cert;
- NSSLOWCERTCertTrust dbTrust;
+ NSSLOWCERTCertificate *cert;
+ NSSLOWCERTCertDBHandle *certHandle;
+ NSSLOWCERTCertTrust dbTrust;
SECStatus rv;
+ CK_RV crv;
- if (to->obj.slot->certDB == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
if (len != sizeof (CK_TRUST)) {
return CKR_ATTRIBUTE_VALUE_INVALID;
}
trust = *(CK_TRUST *)value;
flags = sftk_MapTrust(trust, (PRBool) (type == CKA_TRUST_SERVER_AUTH));
- cert = sftk_getCert(to);
+ certHandle = sftk_getCertDB(to->obj.slot);
+
+ if (certHandle == NULL) {
+ crv = CKR_TOKEN_WRITE_PROTECTED;
+ goto done;
+ }
+
+ cert = sftk_getCert(to, certHandle);
if (cert == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
+ crv = CKR_OBJECT_HANDLE_INVALID;
+ goto done;
}
dbTrust = *cert->trust;
@@ -1586,14 +1733,17 @@ sftk_SetTrustAttribute(SFTKTokenObject *to, CK_ATTRIBUTE_TYPE type,
(CERTDB_PRESERVE_TRUST_BITS|CERTDB_TRUSTED_CLIENT_CA));
break;
default:
- return CKR_ATTRIBUTE_READ_ONLY;
+ crv = CKR_ATTRIBUTE_READ_ONLY;
+ goto done;
}
- rv = nsslowcert_ChangeCertTrust(to->obj.slot->certDB,cert,&dbTrust);
- if (rv != SECSuccess) {
- return CKR_DEVICE_ERROR;
+ rv = nsslowcert_ChangeCertTrust(certHandle, cert, &dbTrust);
+ crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
+done:
+ if (certHandle) {
+ sftk_freeCertDB(certHandle);
}
- return CKR_OK;
+ return crv;
}
static CK_RV
@@ -1936,12 +2086,18 @@ sftk_deleteTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle)
return rem ? SECSuccess : SECFailure;
}
+/* must be called holding sftk_tokenKeyLock(slot) */
static SECStatus
sftk_addTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle, SECItem *key)
{
PLHashEntry *entry;
SECItem *item;
+ /* don't add a new handle in the middle of closing down a slot */
+ if (!slot->present) {
+ return SECFailure;
+ }
+
item = SECITEM_DupItem(key);
if (item == NULL) {
return SECFailure;
@@ -1954,6 +2110,7 @@ sftk_addTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle, SECItem *key)
return SECSuccess;
}
+/* must be called holding sftk_tokenKeyLock(slot) */
static SECItem *
sftk_lookupTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle)
{
@@ -1975,6 +2132,25 @@ sftk_tokenKeyUnlock(SFTKSlot *slot) {
PZ_Unlock(slot->objectLock);
}
+static PRIntn
+sftk_freeHashItem(PLHashEntry* entry, PRIntn index, void *arg)
+{
+ SECItem *item = (SECItem *)entry->value;
+
+ SECITEM_FreeItem(item, PR_TRUE);
+ return HT_ENUMERATE_NEXT;
+}
+
+CK_RV
+SFTK_ClearTokenKeyHashTable(SFTKSlot *slot)
+{
+ sftk_tokenKeyLock(slot);
+ PORT_Assert(!slot->present);
+ PL_HashTableEnumerateEntries(slot->tokenHashTable, sftk_freeHashItem, NULL);
+ sftk_tokenKeyUnlock(slot);
+ return CKR_OK;
+}
+
/* allocation hooks that allow us to recycle old object structures */
static SFTKObjectFreeList sessionObjectList = { NULL, NULL, 0 };
@@ -2328,6 +2504,9 @@ sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
sftkqueue_clear_deleted_element(object);
sftk_FreeObject(object); /* reduce it's reference count */
} else {
+ NSSLOWKEYDBHandle *keyHandle;
+ NSSLOWCERTCertDBHandle *certHandle;
+
PORT_Assert(to);
/* remove the objects from the real data base */
switch (object->handle & SFTK_TOKEN_TYPE_MASK) {
@@ -2335,30 +2514,57 @@ sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
case SFTK_TOKEN_TYPE_KEY:
/* KEYID is the public KEY for DSA and DH, and the MODULUS for
* RSA */
- PORT_Assert(slot->keyDB);
- rv = nsslowkey_DeleteKey(slot->keyDB, &to->dbKey);
- if (rv != SECSuccess) crv= CKR_DEVICE_ERROR;
+ keyHandle = sftk_getKeyDB(slot);
+ if (!keyHandle) {
+ crv = CKR_TOKEN_WRITE_PROTECTED;
+ break;
+ }
+ rv = nsslowkey_DeleteKey(keyHandle, &to->dbKey);
+ sftk_freeKeyDB(keyHandle);
+ if (rv != SECSuccess) {
+ crv = CKR_DEVICE_ERROR;
+ }
break;
case SFTK_TOKEN_TYPE_PUB:
break; /* public keys only exist at the behest of the priv key */
case SFTK_TOKEN_TYPE_CERT:
- cert = nsslowcert_FindCertByKey(slot->certDB,&to->dbKey);
+ certHandle = sftk_getCertDB(slot);
+ if (!certHandle) {
+ crv = CKR_TOKEN_WRITE_PROTECTED;
+ break;
+ }
+ cert = nsslowcert_FindCertByKey(certHandle,&to->dbKey);
+ sftk_freeCertDB(certHandle);
if (cert == NULL) {
crv = CKR_DEVICE_ERROR;
break;
}
rv = nsslowcert_DeletePermCertificate(cert);
- if (rv != SECSuccess) crv = CKR_DEVICE_ERROR;
+ if (rv != SECSuccess) {
+ crv = CKR_DEVICE_ERROR;
+ }
nsslowcert_DestroyCertificate(cert);
break;
case SFTK_TOKEN_TYPE_CRL:
+ certHandle = sftk_getCertDB(slot);
+ if (!certHandle) {
+ crv = CKR_TOKEN_WRITE_PROTECTED;
+ break;
+ }
isKrl = (PRBool) (object->handle == SFTK_TOKEN_KRL_HANDLE);
- rv = nsslowcert_DeletePermCRL(slot->certDB,&to->dbKey,isKrl);
+ rv = nsslowcert_DeletePermCRL(certHandle, &to->dbKey, isKrl);
+ sftk_freeCertDB(certHandle);
if (rv == SECFailure) crv = CKR_DEVICE_ERROR;
break;
case SFTK_TOKEN_TYPE_TRUST:
- cert = nsslowcert_FindCertByKey(slot->certDB,&to->dbKey);
+ certHandle = sftk_getCertDB(slot);
+ if (!certHandle) {
+ crv = CKR_TOKEN_WRITE_PROTECTED;
+ break;
+ }
+ cert = nsslowcert_FindCertByKey(certHandle, &to->dbKey);
if (cert == NULL) {
+ sftk_freeCertDB(certHandle);
crv = CKR_DEVICE_ERROR;
break;
}
@@ -2369,7 +2575,8 @@ sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
tmptrust.sslFlags |= CERTDB_TRUSTED_UNKNOWN;
tmptrust.emailFlags |= CERTDB_TRUSTED_UNKNOWN;
tmptrust.objectSigningFlags |= CERTDB_TRUSTED_UNKNOWN;
- rv = nsslowcert_ChangeCertTrust(slot->certDB,cert,&tmptrust);
+ rv = nsslowcert_ChangeCertTrust(certHandle, cert, &tmptrust);
+ sftk_freeCertDB(certHandle);
if (rv != SECSuccess) crv = CKR_DEVICE_ERROR;
nsslowcert_DestroyCertificate(cert);
break;
@@ -2384,6 +2591,342 @@ sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
}
/*
+ * Token objects don't explicitly store their attributes, so we need to know
+ * what attributes make up a particular token object before we can copy it.
+ * below are the tables by object type.
+ */
+static const CK_ATTRIBUTE_TYPE commonAttrs[] = {
+ CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_MODIFIABLE
+};
+static const CK_ULONG commonAttrsCount =
+ sizeof(commonAttrs)/sizeof(commonAttrs[0]);
+
+static const CK_ATTRIBUTE_TYPE commonKeyAttrs[] = {
+ CKA_ID, CKA_START_DATE, CKA_END_DATE, CKA_DERIVE, CKA_LOCAL, CKA_KEY_TYPE
+};
+static const CK_ULONG commonKeyAttrsCount =
+ sizeof(commonKeyAttrs)/sizeof(commonKeyAttrs[0]);
+
+static const CK_ATTRIBUTE_TYPE secretKeyAttrs[] = {
+ CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_ENCRYPT, CKA_DECRYPT, CKA_SIGN,
+ CKA_VERIFY, CKA_WRAP, CKA_UNWRAP, CKA_VALUE
+};
+static const CK_ULONG secretKeyAttrsCount =
+ sizeof(secretKeyAttrs)/sizeof(secretKeyAttrs[0]);
+
+static const CK_ATTRIBUTE_TYPE commonPubKeyAttrs[] = {
+ CKA_ENCRYPT, CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_WRAP, CKA_SUBJECT
+};
+static const CK_ULONG commonPubKeyAttrsCount =
+ sizeof(commonPubKeyAttrs)/sizeof(commonPubKeyAttrs[0]);
+
+static const CK_ATTRIBUTE_TYPE rsaPubKeyAttrs[] = {
+ CKA_MODULUS, CKA_PUBLIC_EXPONENT
+};
+static const CK_ULONG rsaPubKeyAttrsCount =
+ sizeof(rsaPubKeyAttrs)/sizeof(rsaPubKeyAttrs[0]);
+
+static const CK_ATTRIBUTE_TYPE dsaPubKeyAttrs[] = {
+ CKA_SUBPRIME, CKA_PRIME, CKA_BASE, CKA_VALUE
+};
+static const CK_ULONG dsaPubKeyAttrsCount =
+ sizeof(dsaPubKeyAttrs)/sizeof(dsaPubKeyAttrs[0]);
+
+static const CK_ATTRIBUTE_TYPE dhPubKeyAttrs[] = {
+ CKA_PRIME, CKA_BASE, CKA_VALUE
+};
+static const CK_ULONG dhPubKeyAttrsCount =
+ sizeof(dhPubKeyAttrs)/sizeof(dhPubKeyAttrs[0]);
+#ifdef NSS_ENABLE_ECC
+static const CK_ATTRIBUTE_TYPE ecPubKeyAttrs[] = {
+ CKA_EC_PARAMS, CKA_EC_POINT
+};
+static const CK_ULONG ecPubKeyAttrsCount =
+ sizeof(ecPubKeyAttrs)/sizeof(ecPubKeyAttrs[0]);
+#endif
+
+static const CK_ATTRIBUTE_TYPE commonPrivKeyAttrs[] = {
+ CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER, CKA_UNWRAP, CKA_SUBJECT,
+ CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_NETSCAPE_DB
+};
+static const CK_ULONG commonPrivKeyAttrsCount =
+ sizeof(commonPrivKeyAttrs)/sizeof(commonPrivKeyAttrs[0]);
+
+static const CK_ATTRIBUTE_TYPE rsaPrivKeyAttrs[] = {
+ CKA_MODULUS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT,
+ CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT
+};
+static const CK_ULONG rsaPrivKeyAttrsCount =
+ sizeof(rsaPrivKeyAttrs)/sizeof(rsaPrivKeyAttrs[0]);
+
+static const CK_ATTRIBUTE_TYPE dsaPrivKeyAttrs[] = {
+ CKA_SUBPRIME, CKA_PRIME, CKA_BASE, CKA_VALUE
+};
+static const CK_ULONG dsaPrivKeyAttrsCount =
+ sizeof(dsaPrivKeyAttrs)/sizeof(dsaPrivKeyAttrs[0]);
+
+static const CK_ATTRIBUTE_TYPE dhPrivKeyAttrs[] = {
+ CKA_PRIME, CKA_BASE, CKA_VALUE
+};
+static const CK_ULONG dhPrivKeyAttrsCount =
+ sizeof(dhPrivKeyAttrs)/sizeof(dhPrivKeyAttrs[0]);
+#ifdef NSS_ENABLE_ECC
+static const CK_ATTRIBUTE_TYPE ecPrivKeyAttrs[] = {
+ CKA_EC_PARAMS, CKA_VALUE
+};
+static const CK_ULONG ecPrivKeyAttrsCount =
+ sizeof(ecPrivKeyAttrs)/sizeof(ecPrivKeyAttrs[0]);
+#endif
+
+static const CK_ATTRIBUTE_TYPE certAttrs[] = {
+ CKA_CERTIFICATE_TYPE, CKA_VALUE, CKA_SUBJECT, CKA_ISSUER, CKA_SERIAL_NUMBER
+};
+static const CK_ULONG certAttrsCount =
+ sizeof(certAttrs)/sizeof(certAttrs[0]);
+
+static const CK_ATTRIBUTE_TYPE trustAttrs[] = {
+ CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
+ CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, CKA_TRUST_EMAIL_PROTECTION,
+ CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED
+};
+static const CK_ULONG trustAttrsCount =
+ sizeof(trustAttrs)/sizeof(trustAttrs[0]);
+
+static const CK_ATTRIBUTE_TYPE smimeAttrs[] = {
+ CKA_SUBJECT, CKA_NETSCAPE_EMAIL, CKA_NETSCAPE_SMIME_TIMESTAMP, CKA_VALUE
+};
+static const CK_ULONG smimeAttrsCount =
+ sizeof(smimeAttrs)/sizeof(smimeAttrs[0]);
+
+static const CK_ATTRIBUTE_TYPE crlAttrs[] = {
+ CKA_SUBJECT, CKA_VALUE, CKA_NETSCAPE_URL, CKA_NETSCAPE_KRL
+};
+static const CK_ULONG crlAttrsCount =
+ sizeof(crlAttrs)/sizeof(crlAttrs[0]);
+
+/* copy an object based on it's table */
+CK_RV
+stfk_CopyTokenAttributes(SFTKObject *destObject,SFTKTokenObject *src_to,
+ const CK_ATTRIBUTE_TYPE *attrArray, CK_ULONG attrCount)
+{
+ SFTKAttribute *attribute;
+ SFTKAttribute *newAttribute;
+ CK_RV crv = CKR_OK;
+ unsigned int i;
+
+ for (i=0; i < attrCount; i++) {
+ if (!sftk_hasAttribute(destObject,attrArray[i])) {
+ attribute =sftk_FindAttribute(&src_to->obj, attrArray[i]);
+ if (!attribute) {
+ continue; /* return CKR_ATTRIBUTE_VALUE_INVALID; */
+ }
+ /* we need to copy the attribute since each attribute
+ * only has one set of link list pointers */
+ newAttribute = sftk_NewAttribute( destObject,
+ sftk_attr_expand(&attribute->attrib));
+ sftk_FreeAttribute(attribute); /* free the old attribute */
+ if (!newAttribute) {
+ return CKR_HOST_MEMORY;
+ }
+ sftk_AddAttribute(destObject,newAttribute);
+ }
+ }
+ return crv;
+}
+
+CK_RV
+stfk_CopyTokenPrivateKey(SFTKObject *destObject,SFTKTokenObject *src_to)
+{
+ CK_RV crv;
+ CK_KEY_TYPE key_type;
+ SFTKAttribute *attribute;
+
+ /* copy the common attributes for all keys first */
+ crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
+ commonKeyAttrsCount);
+ if (crv != CKR_OK) {
+ goto fail;
+ }
+ /* copy the common attributes for all private keys next */
+ crv = stfk_CopyTokenAttributes(destObject, src_to, commonPrivKeyAttrs,
+ commonKeyAttrsCount);
+ if (crv != CKR_OK) {
+ goto fail;
+ }
+ attribute =sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE);
+ PORT_Assert(attribute); /* if it wasn't here, ww should have failed
+ * copying the common attributes */
+ if (!attribute) {
+ /* OK, so CKR_ATTRIBUTE_VALUE_INVALID is the immediate error, but
+ * the fact is, the only reason we couldn't get the attribute would
+ * be a memory error or database error (an error in the 'device').
+ * if we have a database error code, we could return it here */
+ crv = CKR_DEVICE_ERROR;
+ goto fail;
+ }
+ key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
+ sftk_FreeAttribute(attribute);
+
+ /* finally copy the attributes for various private key types */
+ switch (key_type) {
+ case CKK_RSA:
+ crv = stfk_CopyTokenAttributes(destObject, src_to, rsaPrivKeyAttrs,
+ rsaPrivKeyAttrsCount);
+ break;
+ case CKK_DSA:
+ crv = stfk_CopyTokenAttributes(destObject, src_to, dsaPrivKeyAttrs,
+ dsaPrivKeyAttrsCount);
+ break;
+ case CKK_DH:
+ crv = stfk_CopyTokenAttributes(destObject, src_to, dhPrivKeyAttrs,
+ dhPrivKeyAttrsCount);
+ break;
+#ifdef NSS_ENABLE_ECC
+ case CKK_EC:
+ crv = stfk_CopyTokenAttributes(destObject, src_to, ecPrivKeyAttrs,
+ ecPrivKeyAttrsCount);
+ break;
+#endif
+ default:
+ crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
+ * of token keys into our database. */
+ }
+fail:
+ return crv;
+}
+
+CK_RV
+stfk_CopyTokenPublicKey(SFTKObject *destObject,SFTKTokenObject *src_to)
+{
+ CK_RV crv;
+ CK_KEY_TYPE key_type;
+ SFTKAttribute *attribute;
+
+ /* copy the common attributes for all keys first */
+ crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
+ commonKeyAttrsCount);
+ if (crv != CKR_OK) {
+ goto fail;
+ }
+
+ /* copy the common attributes for all public keys next */
+ crv = stfk_CopyTokenAttributes(destObject, src_to, commonPubKeyAttrs,
+ commonPubKeyAttrsCount);
+ if (crv != CKR_OK) {
+ goto fail;
+ }
+ attribute =sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE);
+ PORT_Assert(attribute); /* if it wasn't here, ww should have failed
+ * copying the common attributes */
+ if (!attribute) {
+ /* OK, so CKR_ATTRIBUTE_VALUE_INVALID is the immediate error, but
+ * the fact is, the only reason we couldn't get the attribute would
+ * be a memory error or database error (an error in the 'device').
+ * if we have a database error code, we could return it here */
+ crv = CKR_DEVICE_ERROR;
+ goto fail;
+ }
+ key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
+ sftk_FreeAttribute(attribute);
+
+ /* finally copy the attributes for various public key types */
+ switch (key_type) {
+ case CKK_RSA:
+ crv = stfk_CopyTokenAttributes(destObject, src_to, rsaPubKeyAttrs,
+ rsaPubKeyAttrsCount);
+ break;
+ case CKK_DSA:
+ crv = stfk_CopyTokenAttributes(destObject, src_to, dsaPubKeyAttrs,
+ dsaPubKeyAttrsCount);
+ break;
+ case CKK_DH:
+ crv = stfk_CopyTokenAttributes(destObject, src_to, dhPubKeyAttrs,
+ dhPubKeyAttrsCount);
+ break;
+#ifdef NSS_ENABLE_ECC
+ case CKK_EC:
+ crv = stfk_CopyTokenAttributes(destObject, src_to, ecPubKeyAttrs,
+ ecPubKeyAttrsCount);
+ break;
+#endif
+ default:
+ crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
+ * of token keys into our database. */
+ }
+fail:
+ return crv;
+}
+CK_RV
+stfk_CopyTokenSecretKey(SFTKObject *destObject,SFTKTokenObject *src_to)
+{
+ CK_RV crv;
+ crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
+ commonKeyAttrsCount);
+ if (crv != CKR_OK) {
+ goto fail;
+ }
+ crv = stfk_CopyTokenAttributes(destObject, src_to, secretKeyAttrs,
+ secretKeyAttrsCount);
+fail:
+ return crv;
+}
+
+/*
+ * Copy a token object. We need to explicitly copy the relevant
+ * attributes since token objects don't store those attributes in
+ * the token itself.
+ */
+CK_RV
+sftk_CopyTokenObject(SFTKObject *destObject,SFTKObject *srcObject)
+{
+ SFTKTokenObject *src_to = sftk_narrowToTokenObject(srcObject);
+ CK_RV crv;
+
+ PORT_Assert(src_to);
+ if (src_to == NULL) {
+ return CKR_DEVICE_ERROR; /* internal state inconsistant */
+ }
+
+ crv = stfk_CopyTokenAttributes(destObject, src_to, commonAttrs,
+ commonAttrsCount);
+ if (crv != CKR_OK) {
+ goto fail;
+ }
+ switch (src_to->obj.objclass) {
+ case CKO_CERTIFICATE:
+ crv = stfk_CopyTokenAttributes(destObject, src_to, certAttrs,
+ certAttrsCount);
+ break;
+ case CKO_NETSCAPE_TRUST:
+ crv = stfk_CopyTokenAttributes(destObject, src_to, trustAttrs,
+ trustAttrsCount);
+ break;
+ case CKO_NETSCAPE_SMIME:
+ crv = stfk_CopyTokenAttributes(destObject, src_to, smimeAttrs,
+ smimeAttrsCount);
+ break;
+ case CKO_NETSCAPE_CRL:
+ crv = stfk_CopyTokenAttributes(destObject, src_to, crlAttrs,
+ crlAttrsCount);
+ break;
+ case CKO_PRIVATE_KEY:
+ crv = stfk_CopyTokenPrivateKey(destObject,src_to);
+ break;
+ case CKO_PUBLIC_KEY:
+ crv = stfk_CopyTokenPublicKey(destObject,src_to);
+ break;
+ case CKO_SECRET_KEY:
+ crv = stfk_CopyTokenSecretKey(destObject,src_to);
+ break;
+ default:
+ crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
+ * of token keys into our database. */
+ }
+fail:
+ return crv;
+}
+
+/*
* copy the attributes from one object to another. Don't overwrite existing
* attributes. NOTE: This is a pretty expensive operation since it
* grabs the attribute locks for the src object for a *long* time.
@@ -2396,7 +2939,7 @@ sftk_CopyObject(SFTKObject *destObject,SFTKObject *srcObject)
unsigned int i;
if (src_so == NULL) {
- return CKR_DEVICE_ERROR; /* can't copy token objects yet */
+ return sftk_CopyTokenObject(destObject,srcObject);
}
PZ_Lock(src_so->attributeLock);
@@ -2420,6 +2963,7 @@ sftk_CopyObject(SFTKObject *destObject,SFTKObject *srcObject)
} while (attribute != NULL);
}
PZ_Unlock(src_so->attributeLock);
+
return CKR_OK;
}
@@ -2602,7 +3146,7 @@ sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication,
CK_FLAGS flags)
{
SFTKSession *session;
- SFTKSlot *slot = sftk_SlotFromID(slotID);
+ SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE);
if (slot == NULL) return NULL;
@@ -2676,7 +3220,10 @@ sftk_SessionFromHandle(CK_SESSION_HANDLE handle)
{
SFTKSlot *slot = sftk_SlotFromSessionHandle(handle);
SFTKSession *session;
- PZLock *lock = SFTK_SESSION_LOCK(slot,handle);
+ PZLock *lock;
+
+ if (!slot) return NULL;
+ lock = SFTK_SESSION_LOCK(slot,handle);
PZ_Lock(lock);
sftkqueue_find(session,handle,slot->head,slot->sessHashSize);
diff --git a/security/nss/lib/softoken/tlsprf.c b/security/nss/lib/softoken/tlsprf.c
index 8bf589dff..23e996d5f 100644
--- a/security/nss/lib/softoken/tlsprf.c
+++ b/security/nss/lib/softoken/tlsprf.c
@@ -38,132 +38,10 @@
/* $Id$ */
#include "pkcs11i.h"
-#include "sechash.h"
-#include "alghmac.h"
+#include "blapi.h"
#define SFTK_OFFSETOF(str, memb) ((PRPtrdiff)(&(((str *)0)->memb)))
-#define PHASH_STATE_MAX_LEN 20
-
-/* TLS P_hash function */
-static SECStatus
-sftk_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,
- SECItem *seed, SECItem *result, PRBool isFIPS)
-{
- unsigned char state[PHASH_STATE_MAX_LEN];
- unsigned char outbuf[PHASH_STATE_MAX_LEN];
- unsigned int state_len = 0, label_len = 0, outbuf_len = 0, chunk_size;
- unsigned int remaining;
- unsigned char *res;
- SECStatus status;
- HMACContext *cx;
- SECStatus rv = SECFailure;
- const SECHashObject *hashObj = &SECRawHashObjects[hashType];
-
- PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
- PORT_Assert((seed != NULL) && (seed->data != NULL));
- PORT_Assert((result != NULL) && (result->data != NULL));
-
- remaining = result->len;
- res = result->data;
-
- if (label != NULL)
- label_len = PORT_Strlen(label);
-
- cx = HMAC_Create(hashObj, secret->data, secret->len, isFIPS);
- if (cx == NULL)
- goto loser;
-
- /* initialize the state = A(1) = HMAC_hash(secret, seed) */
- HMAC_Begin(cx);
- HMAC_Update(cx, (unsigned char *)label, label_len);
- HMAC_Update(cx, seed->data, seed->len);
- status = HMAC_Finish(cx, state, &state_len, PHASH_STATE_MAX_LEN);
- if (status != SECSuccess)
- goto loser;
-
- /* generate a block at a time until we're done */
- while (remaining > 0) {
-
- HMAC_Begin(cx);
- HMAC_Update(cx, state, state_len);
- if (label_len)
- HMAC_Update(cx, (unsigned char *)label, label_len);
- HMAC_Update(cx, seed->data, seed->len);
- status = HMAC_Finish(cx, outbuf, &outbuf_len, PHASH_STATE_MAX_LEN);
- if (status != SECSuccess)
- goto loser;
-
- /* Update the state = A(i) = HMAC_hash(secret, A(i-1)) */
- HMAC_Begin(cx);
- HMAC_Update(cx, state, state_len);
- status = HMAC_Finish(cx, state, &state_len, PHASH_STATE_MAX_LEN);
- if (status != SECSuccess)
- goto loser;
-
- chunk_size = PR_MIN(outbuf_len, remaining);
- PORT_Memcpy(res, &outbuf, chunk_size);
- res += chunk_size;
- remaining -= chunk_size;
- }
-
- rv = SECSuccess;
-
-loser:
- /* if (cx) HMAC_Destroy(cx); */
- /* clear out state so it's not left on the stack */
- if (cx) HMAC_Destroy(cx);
- PORT_Memset(state, 0, sizeof(state));
- PORT_Memset(outbuf, 0, sizeof(outbuf));
- return rv;
-}
-
-SECStatus
-sftk_PRF(const SECItem *secret, const char *label, SECItem *seed,
- SECItem *result, PRBool isFIPS)
-{
- SECStatus rv = SECFailure, status;
- unsigned int i;
- SECItem tmp = { siBuffer, NULL, 0};
- SECItem S1;
- SECItem S2;
-
- PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
- PORT_Assert((seed != NULL) && (seed->data != NULL));
- PORT_Assert((result != NULL) && (result->data != NULL));
-
- S1.type = siBuffer;
- S1.len = (secret->len / 2) + (secret->len & 1);
- S1.data = secret->data;
-
- S2.type = siBuffer;
- S2.len = S1.len;
- S2.data = secret->data + (secret->len - S2.len);
-
- tmp.data = (unsigned char*)PORT_Alloc(result->len);
- if (tmp.data == NULL)
- goto loser;
- tmp.len = result->len;
-
- status = sftk_P_hash(HASH_AlgMD5, &S1, label, seed, result, isFIPS);
- if (status != SECSuccess)
- goto loser;
-
- status = sftk_P_hash(HASH_AlgSHA1, &S2, label, seed, &tmp, isFIPS);
- if (status != SECSuccess)
- goto loser;
-
- for (i = 0; i < result->len; i++)
- result->data[i] ^= tmp.data[i];
-
- rv = SECSuccess;
-
-loser:
- if (tmp.data != NULL)
- PORT_ZFree(tmp.data, tmp.len);
- return rv;
-}
-
static void sftk_TLSPRFNull(void *data, PRBool freeit)
{
return;
@@ -243,7 +121,7 @@ sftk_TLSPRFUpdate(TLSPRFContext *cx,
sigItem.data = sig;
sigItem.len = maxLen;
- rv = sftk_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS);
+ rv = TLS_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS);
if (rv == SECSuccess && sigLen != NULL)
*sigLen = sigItem.len;
return rv;
diff --git a/security/nss/lib/ssl/config.mk b/security/nss/lib/ssl/config.mk
index d506b12a9..35e4147b5 100644
--- a/security/nss/lib/ssl/config.mk
+++ b/security/nss/lib/ssl/config.mk
@@ -52,6 +52,7 @@ ifdef NS_USE_GCC
EXTRA_SHARED_LIBS += \
-L$(DIST)/lib \
-lnss3 \
+ -L$(NSPR_LIB_DIR) \
-lplc4 \
-lplds4 \
-lnspr4 \
@@ -59,20 +60,45 @@ EXTRA_SHARED_LIBS += \
else # ! NS_USE_GCC
EXTRA_SHARED_LIBS += \
$(DIST)/lib/nss3.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(DIST)/lib/$(NSPR31_LIB_PREFIX)nspr4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
$(NULL)
endif # NS_USE_GCC
+# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
+CRYPTOLIB=$(DIST)/lib/$(LIB_PREFIX)freebl.$(LIB_SUFFIX)
+CRYPTODIR=../freebl
+ifdef MOZILLA_SECURITY_BUILD
+ CRYPTOLIB=$(DIST)/lib/$(LIB_PREFIX)crypto.$(LIB_SUFFIX)
+ CRYPTODIR=../crypto
+endif
+
+EXTRA_LIBS += \
+ $(CRYPTOLIB) \
+ $(NULL)
+
else
+# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
+CRYPTOLIB=$(DIST)/lib/$(LIB_PREFIX)freebl.$(LIB_SUFFIX)
+CRYPTODIR=../freebl
+ifdef MOZILLA_SECURITY_BUILD
+ CRYPTOLIB=$(DIST)/lib/$(LIB_PREFIX)crypto.$(LIB_SUFFIX)
+ CRYPTODIR=../crypto
+endif
+
+EXTRA_LIBS += \
+ $(CRYPTOLIB) \
+ $(NULL)
+
# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib/ \
+ -L$(DIST)/lib \
-lnss3 \
+ -L$(NSPR_LIB_DIR) \
-lplc4 \
-lplds4 \
-lnspr4 \
@@ -90,6 +116,10 @@ ifeq ($(OS_TARGET),SunOS)
# The -R '$ORIGIN' linker option instructs this library to search for its
# dependencies in the same directory where it resides.
MKSHLIB += -R '$$ORIGIN'
+#EXTRA_SHARED_LIBS += -ldl -lrt -lc -z defs
endif
endif
+
+# indicates dependency on freebl static lib
+$(SHARED_LIBRARY): $(CRYPTOLIB)
diff --git a/security/nss/lib/ssl/derive.c b/security/nss/lib/ssl/derive.c
new file mode 100644
index 000000000..c00822bee
--- /dev/null
+++ b/security/nss/lib/ssl/derive.c
@@ -0,0 +1,481 @@
+/*
+ * Key Derivation that doesn't use PKCS11
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/* $Id$ */
+
+#include "ssl.h" /* prereq to sslimpl.h */
+#include "certt.h" /* prereq to sslimpl.h */
+#include "keythi.h" /* prereq to sslimpl.h */
+#include "sslimpl.h"
+#include "blapi.h"
+
+/* make this a macro! */
+#ifdef NOT_A_MACRO
+static void
+buildSSLKey(unsigned char * keyBlock, unsigned int keyLen, SECItem * result)
+{
+ result->type = siBuffer;
+ result->data = keyBlock;
+ result->len = keyLen;
+}
+#else
+#define buildSSLKey(keyBlock, keyLen, result) \
+{ \
+ (result)->type = siBuffer; \
+ (result)->data = keyBlock; \
+ (result)->len = keyLen; \
+}
+#endif
+
+/*
+ * SSL Key generation given pre master secret
+ */
+#ifndef NUM_MIXERS
+#define NUM_MIXERS 9
+#endif
+static const char * const mixers[NUM_MIXERS] = {
+ "A",
+ "BB",
+ "CCC",
+ "DDDD",
+ "EEEEE",
+ "FFFFFF",
+ "GGGGGGG",
+ "HHHHHHHH",
+ "IIIIIIIII"
+};
+
+
+SECStatus
+ssl3_KeyAndMacDeriveBypass(
+ ssl3CipherSpec * pwSpec,
+ const unsigned char * cr,
+ const unsigned char * sr,
+ PRBool isTLS,
+ PRBool isExport)
+{
+ const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def;
+ unsigned char * key_block = pwSpec->key_block;
+ unsigned char * key_block2 = NULL;
+ unsigned int block_bytes = 0;
+ unsigned int block_needed = 0;
+ unsigned int i;
+ unsigned int keySize; /* actual size of cipher keys */
+ unsigned int effKeySize; /* effective size of cipher keys */
+ unsigned int macSize; /* size of MAC secret */
+ unsigned int IVSize; /* size of IV */
+ SECStatus rv = SECFailure;
+ SECStatus status = SECSuccess;
+ PRBool isFIPS = PR_FALSE;
+
+ SECItem srcr;
+ SECItem crsr;
+
+ unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2];
+ unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
+ PRUint64 md5buf[22];
+ PRUint64 shabuf[40];
+
+#define md5Ctx ((MD5Context *)md5buf)
+#define shaCtx ((SHA1Context *)shabuf)
+
+ static const SECItem zed = { siBuffer, NULL, 0 };
+
+ if (pwSpec->msItem.data == NULL ||
+ pwSpec->msItem.len != SSL3_MASTER_SECRET_LENGTH) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return rv;
+ }
+
+ /* figure out how much is needed */
+ macSize = pwSpec->mac_size;
+ keySize = cipher_def->key_size;
+ effKeySize = cipher_def->secret_key_size;
+ IVSize = cipher_def->iv_size;
+ if (keySize == 0) {
+ effKeySize = IVSize = 0; /* only MACing */
+ }
+ block_needed = 2 * (macSize + effKeySize + ((!isExport) * IVSize));
+
+ /*
+ * clear out our returned keys so we can recover on failure
+ */
+ pwSpec->client.write_key_item = zed;
+ pwSpec->client.write_mac_key_item = zed;
+ pwSpec->server.write_key_item = zed;
+ pwSpec->server.write_mac_key_item = zed;
+
+ /* initialize the server random, client random block */
+ srcr.type = siBuffer;
+ srcr.data = srcrdata;
+ srcr.len = sizeof srcrdata;
+ PORT_Memcpy(srcrdata, sr, SSL3_RANDOM_LENGTH);
+ PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, cr, SSL3_RANDOM_LENGTH);
+
+ /* initialize the client random, server random block */
+ crsr.type = siBuffer;
+ crsr.data = crsrdata;
+ crsr.len = sizeof crsrdata;
+ PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH);
+ PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH);
+
+ /*
+ * generate the key material:
+ */
+ if (isTLS) {
+ SECItem keyblk;
+
+ keyblk.type = siBuffer;
+ keyblk.data = key_block;
+ keyblk.len = block_needed;
+
+ status = TLS_PRF(&pwSpec->msItem, "key expansion", &srcr, &keyblk,
+ isFIPS);
+ if (status != SECSuccess) {
+ goto key_and_mac_derive_fail;
+ }
+ block_bytes = keyblk.len;
+ } else {
+ /* key_block =
+ * MD5(master_secret + SHA('A' + master_secret +
+ * ServerHello.random + ClientHello.random)) +
+ * MD5(master_secret + SHA('BB' + master_secret +
+ * ServerHello.random + ClientHello.random)) +
+ * MD5(master_secret + SHA('CCC' + master_secret +
+ * ServerHello.random + ClientHello.random)) +
+ * [...];
+ */
+ int made = 0;
+ for (i = 0; made < block_needed && i < NUM_MIXERS; ++i) {
+ unsigned int outLen;
+ unsigned char sha_out[SHA1_LENGTH];
+
+ SHA1_Begin(shaCtx);
+ SHA1_Update(shaCtx, (unsigned char*)(mixers[i]), i+1);
+ SHA1_Update(shaCtx, pwSpec->msItem.data, pwSpec->msItem.len);
+ SHA1_Update(shaCtx, srcr.data, srcr.len);
+ SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH);
+ PORT_Assert(outLen == SHA1_LENGTH);
+
+ MD5_Begin(md5Ctx);
+ MD5_Update(md5Ctx, pwSpec->msItem.data, pwSpec->msItem.len);
+ MD5_Update(md5Ctx, sha_out, outLen);
+ MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH);
+ PORT_Assert(outLen == MD5_LENGTH);
+ made += MD5_LENGTH;
+ }
+ block_bytes = made;
+ }
+ PORT_Assert(block_bytes >= block_needed);
+ PORT_Assert(block_bytes <= sizeof pwSpec->key_block);
+
+ /*
+ * Put the key material where it goes.
+ */
+ key_block2 = key_block + block_bytes;
+ i = 0; /* now shows how much consumed */
+
+ /*
+ * The key_block is partitioned as follows:
+ * client_write_MAC_secret[CipherSpec.hash_size]
+ */
+ buildSSLKey(&key_block[i],macSize, &pwSpec->client.write_mac_key_item);
+ i += macSize;
+
+ /*
+ * server_write_MAC_secret[CipherSpec.hash_size]
+ */
+ buildSSLKey(&key_block[i],macSize, &pwSpec->server.write_mac_key_item);
+ i += macSize;
+
+ if (!keySize) {
+ /* only MACing */
+ buildSSLKey(NULL, 0, &pwSpec->client.write_key_item);
+ buildSSLKey(NULL, 0, &pwSpec->server.write_key_item);
+ buildSSLKey(NULL, 0, &pwSpec->client.write_iv_item);
+ buildSSLKey(NULL, 0, &pwSpec->server.write_iv_item);
+ } else if (!isExport) {
+ /*
+ ** Generate Domestic write keys and IVs.
+ ** client_write_key[CipherSpec.key_material]
+ */
+ buildSSLKey(&key_block[i], keySize, &pwSpec->client.write_key_item);
+ i += keySize;
+
+ /*
+ ** server_write_key[CipherSpec.key_material]
+ */
+ buildSSLKey(&key_block[i], keySize, &pwSpec->server.write_key_item);
+ i += keySize;
+
+ if (IVSize > 0) {
+ /*
+ ** client_write_IV[CipherSpec.IV_size]
+ */
+ buildSSLKey(&key_block[i], IVSize, &pwSpec->client.write_iv_item);
+ i += IVSize;
+
+ /*
+ ** server_write_IV[CipherSpec.IV_size]
+ */
+ buildSSLKey(&key_block[i], IVSize, &pwSpec->server.write_iv_item);
+ i += IVSize;
+ }
+ PORT_Assert(i <= block_bytes);
+
+ } else if (!isTLS) {
+ /*
+ ** Generate SSL3 Export write keys and IVs.
+ */
+ unsigned int outLen;
+
+ /*
+ ** client_write_key[CipherSpec.key_material]
+ ** final_client_write_key = MD5(client_write_key +
+ ** ClientHello.random + ServerHello.random);
+ */
+ MD5_Begin(md5Ctx);
+ MD5_Update(md5Ctx, &key_block[i], effKeySize);
+ MD5_Update(md5Ctx, crsr.data, crsr.len);
+ MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH);
+ i += effKeySize;
+ buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item);
+ key_block2 += keySize;
+
+ /*
+ ** server_write_key[CipherSpec.key_material]
+ ** final_server_write_key = MD5(server_write_key +
+ ** ServerHello.random + ClientHello.random);
+ */
+ MD5_Begin(md5Ctx);
+ MD5_Update(md5Ctx, &key_block[i], effKeySize);
+ MD5_Update(md5Ctx, srcr.data, srcr.len);
+ MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH);
+ i += effKeySize;
+ buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item);
+ key_block2 += keySize;
+ PORT_Assert(i <= block_bytes);
+
+ if (IVSize) {
+ /*
+ ** client_write_IV =
+ ** MD5(ClientHello.random + ServerHello.random);
+ */
+ MD5_Begin(md5Ctx);
+ MD5_Update(md5Ctx, crsr.data, crsr.len);
+ MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH);
+ buildSSLKey(key_block2, IVSize, &pwSpec->client.write_iv_item);
+ key_block2 += IVSize;
+
+ /*
+ ** server_write_IV =
+ ** MD5(ServerHello.random + ClientHello.random);
+ */
+ MD5_Begin(md5Ctx);
+ MD5_Update(md5Ctx, srcr.data, srcr.len);
+ MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH);
+ buildSSLKey(key_block2, IVSize, &pwSpec->server.write_iv_item);
+ key_block2 += IVSize;
+ }
+
+ PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block);
+ } else {
+ /*
+ ** Generate TLS Export write keys and IVs.
+ */
+ SECItem secret ;
+ SECItem keyblk ;
+
+ secret.type = siBuffer;
+ keyblk.type = siBuffer;
+ /*
+ ** client_write_key[CipherSpec.key_material]
+ ** final_client_write_key = PRF(client_write_key,
+ ** "client write key",
+ ** client_random + server_random);
+ */
+ secret.data = &key_block[i];
+ secret.len = effKeySize;
+ i += effKeySize;
+ keyblk.data = key_block2;
+ keyblk.len = keySize;
+ status = TLS_PRF(&secret, "client write key", &crsr, &keyblk, isFIPS);
+ if (status != SECSuccess) {
+ goto key_and_mac_derive_fail;
+ }
+ buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item);
+ key_block2 += keySize;
+
+ /*
+ ** server_write_key[CipherSpec.key_material]
+ ** final_server_write_key = PRF(server_write_key,
+ ** "server write key",
+ ** client_random + server_random);
+ */
+ secret.data = &key_block[i];
+ secret.len = effKeySize;
+ i += effKeySize;
+ keyblk.data = key_block2;
+ keyblk.len = keySize;
+ status = TLS_PRF(&secret, "server write key", &crsr, &keyblk, isFIPS);
+ if (status != SECSuccess) {
+ goto key_and_mac_derive_fail;
+ }
+ buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item);
+ key_block2 += keySize;
+
+ /*
+ ** iv_block = PRF("", "IV block", client_random + server_random);
+ ** client_write_IV[SecurityParameters.IV_size]
+ ** server_write_IV[SecurityParameters.IV_size]
+ */
+ if (IVSize) {
+ secret.data = NULL;
+ secret.len = 0;
+ keyblk.data = key_block2;
+ keyblk.len = 2 * IVSize;
+ status = TLS_PRF(&secret, "IV block", &crsr, &keyblk, isFIPS);
+ if (status != SECSuccess) {
+ goto key_and_mac_derive_fail;
+ }
+ buildSSLKey(key_block2, IVSize, &pwSpec->client.write_iv_item);
+ buildSSLKey(key_block2 + IVSize, IVSize, &pwSpec->server.write_iv_item);
+ key_block2 += 2 * IVSize;
+ }
+ PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block);
+ }
+ rv = SECSuccess;
+
+key_and_mac_derive_fail:
+
+ MD5_DestroyContext(md5Ctx, PR_FALSE);
+ SHA1_DestroyContext(shaCtx, PR_FALSE);
+
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
+ }
+
+ return rv;
+}
+
+
+/* derive the Master Secret from the PMS */
+/* Presently, this is only done wtih RSA PMS, os isRSA is always true. */
+SECStatus
+ssl3_MasterKeyDeriveBypass(
+ ssl3CipherSpec * pwSpec,
+ const unsigned char * cr,
+ const unsigned char * sr,
+ const SECItem * pms,
+ PRBool isTLS,
+ PRBool isRSA)
+{
+ unsigned char * key_block = pwSpec->key_block;
+ SECStatus rv = SECSuccess;
+ PRBool isFIPS = PR_FALSE;
+
+ SECItem crsr;
+
+ unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
+ PRUint64 md5buf[22];
+ PRUint64 shabuf[40];
+
+#define md5Ctx ((MD5Context *)md5buf)
+#define shaCtx ((SHA1Context *)shabuf)
+
+ /* first do the consistancy checks */
+ if (isRSA) {
+ PORT_Assert(pms->len == SSL3_RSA_PMS_LENGTH);
+ if (pms->len != SSL3_RSA_PMS_LENGTH) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ /* caller must test PMS version for rollback */
+ }
+
+ /* initialize the client random, server random block */
+ crsr.type = siBuffer;
+ crsr.data = crsrdata;
+ crsr.len = sizeof crsrdata;
+ PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH);
+ PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH);
+
+ /* finally do the key gen */
+ if (isTLS) {
+ SECItem master = { siBuffer, NULL, 0 };
+
+ master.data = key_block;
+ master.len = SSL3_MASTER_SECRET_LENGTH;
+
+ rv = TLS_PRF(pms, "master secret", &crsr, &master, isFIPS);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
+ }
+ } else {
+ int i;
+ int made = 0;
+ for (i = 0; i < 3; i++) {
+ unsigned int outLen;
+ unsigned char sha_out[SHA1_LENGTH];
+
+ SHA1_Begin(shaCtx);
+ SHA1_Update(shaCtx, (unsigned char*) mixers[i], i+1);
+ SHA1_Update(shaCtx, pms->data, pms->len);
+ SHA1_Update(shaCtx, crsr.data, crsr.len);
+ SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH);
+ PORT_Assert(outLen == SHA1_LENGTH);
+
+ MD5_Begin(md5Ctx);
+ MD5_Update(md5Ctx, pms->data, pms->len);
+ MD5_Update(md5Ctx, sha_out, outLen);
+ MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH);
+ PORT_Assert(outLen == MD5_LENGTH);
+ made += outLen;
+ }
+ }
+
+ /* store the results */
+ PORT_Memcpy(pwSpec->raw_master_secret, key_block,
+ SSL3_MASTER_SECRET_LENGTH);
+ pwSpec->msItem.data = pwSpec->raw_master_secret;
+ pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH;
+
+ return rv;
+}
+
+
diff --git a/security/nss/lib/ssl/manifest.mn b/security/nss/lib/ssl/manifest.mn
index f49a8e038..6428ce5c7 100644
--- a/security/nss/lib/ssl/manifest.mn
+++ b/security/nss/lib/ssl/manifest.mn
@@ -55,6 +55,7 @@ MODULE = nss
MAPFILE = $(OBJDIR)/ssl.def
CSRCS = \
+ derive.c \
emulate.c \
prelib.c \
ssl3con.c \
@@ -77,14 +78,13 @@ CSRCS = \
cmpcert.c \
nsskea.c \
sslinfo.c \
+ ssl3ecc.c \
$(NULL)
-
-REQUIRES = dbm
-
ifdef NSS_ENABLE_ECC
DEFINES += -DNSS_ENABLE_ECC
endif
LIBRARY_NAME = ssl
LIBRARY_VERSION = 3
+
diff --git a/security/nss/lib/ssl/nsskea.c b/security/nss/lib/ssl/nsskea.c
index b61ac71e4..beafc506e 100644
--- a/security/nss/lib/ssl/nsskea.c
+++ b/security/nss/lib/ssl/nsskea.c
@@ -58,12 +58,6 @@ NSS_FindCertKEAType(CERTCertificate * cert)
case SEC_OID_PKCS1_RSA_ENCRYPTION:
keaType = kt_rsa;
break;
- case SEC_OID_MISSI_KEA_DSS_OLD:
- case SEC_OID_MISSI_KEA_DSS:
- case SEC_OID_MISSI_DSS_OLD:
- case SEC_OID_MISSI_DSS:
- keaType = kt_fortezza;
- break;
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
keaType = kt_dh;
break;
diff --git a/security/nss/lib/ssl/preenc.h b/security/nss/lib/ssl/preenc.h
index 9b6d3104a..f7c9093cb 100644
--- a/security/nss/lib/ssl/preenc.h
+++ b/security/nss/lib/ssl/preenc.h
@@ -1,8 +1,7 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
/*
- * Functions and types used by https servers to send (download) pre-encrypted
- * files over SSL connections that use Fortezza ciphersuites.
+ * Fortezza support is removed.
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
@@ -41,6 +40,11 @@
* ***** END LICENSE BLOCK ***** */
/* $Id$ */
+/* Fortezza support is removed.
+ * This file remains so that old programs will continue to compile,
+ * But this functionality is no longer supported or implemented.
+ */
+
#include "seccomon.h"
#include "prio.h"
@@ -48,53 +52,44 @@ typedef struct PEHeaderStr PEHeader;
#define PE_MIME_TYPE "application/pre-encrypted"
-
-/*
- * unencrypted header. The 'top' half of this header is generic. The union
- * is type specific, and may include bulk cipher type information
- * (Fortezza supports only Fortezza Bulk encryption). Only fortezza
- * pre-encrypted is defined.
- */
typedef struct PEFortezzaHeaderStr PEFortezzaHeader;
typedef struct PEFortezzaGeneratedHeaderStr PEFortezzaGeneratedHeader;
typedef struct PEFixedKeyHeaderStr PEFixedKeyHeader;
typedef struct PERSAKeyHeaderStr PERSAKeyHeader;
struct PEFortezzaHeaderStr {
- unsigned char key[12]; /* Ks wrapped MEK */
- unsigned char iv[24]; /* iv for this MEK */
- unsigned char hash[20]; /* SHA hash of file */
- unsigned char serial[8]; /* serial number of the card that owns
- * Ks */
+ unsigned char key[12];
+ unsigned char iv[24];
+ unsigned char hash[20];
+ unsigned char serial[8];
};
struct PEFortezzaGeneratedHeaderStr {
- unsigned char key[12]; /* TEK wrapped MEK */
- unsigned char iv[24]; /* iv for this MEK */
- unsigned char hash[20]; /* SHA hash of file */
- unsigned char Ra[128]; /* RA to generate TEK */
- unsigned char Y[128]; /* Y to generate TEK */
+ unsigned char key[12];
+ unsigned char iv[24];
+ unsigned char hash[20];
+ unsigned char Ra[128];
+ unsigned char Y[128];
};
struct PEFixedKeyHeaderStr {
- unsigned char pkcs11Mech[4]; /* Symetric key operation */
- unsigned char labelLen[2]; /* length of the token label */
- unsigned char keyIDLen[2]; /* length of the token Key ID */
- unsigned char ivLen[2]; /* length of IV */
- unsigned char keyLen[2]; /* length of key (DES3_ECB encrypted) */
- unsigned char data[1]; /* start of data */
+ unsigned char pkcs11Mech[4];
+ unsigned char labelLen[2];
+ unsigned char keyIDLen[2];
+ unsigned char ivLen[2];
+ unsigned char keyLen[2];
+ unsigned char data[1];
};
struct PERSAKeyHeaderStr {
- unsigned char pkcs11Mech[4]; /* Symetric key operation */
- unsigned char issuerLen[2]; /* length of cert issuer */
- unsigned char serialLen[2]; /* length of the cert serial */
- unsigned char ivLen[2]; /* length of IV */
- unsigned char keyLen[2]; /* length of key (RSA encrypted) */
- unsigned char data[1]; /* start of data */
+ unsigned char pkcs11Mech[4];
+ unsigned char issuerLen[2];
+ unsigned char serialLen[2];
+ unsigned char ivLen[2];
+ unsigned char keyLen[2];
+ unsigned char data[1];
};
-/* macros to get at the variable length data fields */
#define PEFIXED_Label(header) (header->data)
#define PEFIXED_KeyID(header) (&header->data[GetInt2(header->labelLen)])
#define PEFIXED_IV(header) (&header->data[GetInt2(header->labelLen)\
@@ -108,10 +103,10 @@ struct PERSAKeyHeaderStr {
#define PERSA_Key(header) (&header->data[GetInt2(header->issuerLen)\
+GetInt2(header->serialLen)+GetInt2(header->keyLen)])
struct PEHeaderStr {
- unsigned char magic [2]; /* always 0xC0DE */
- unsigned char len [2]; /* length of PEHeader */
- unsigned char type [2]; /* FORTEZZA, DIFFIE-HELMAN, RSA */
- unsigned char version[2]; /* version number: 1.0 */
+ unsigned char magic [2];
+ unsigned char len [2];
+ unsigned char type [2];
+ unsigned char version[2];
union {
PEFortezzaHeader fortezza;
PEFortezzaGeneratedHeader g_fortezza;
@@ -124,12 +119,9 @@ struct PEHeaderStr {
#define PE_INTRO_LEN 4
#define PE_BASE_HEADER_LEN 8
-#define PRE_BLOCK_SIZE 8 /* for decryption blocks */
+#define PRE_BLOCK_SIZE 8
-/*
- * Platform neutral encode/decode macros.
- */
#define GetInt2(c) ((c[0] << 8) | c[1])
#define GetInt4(c) (((unsigned long)c[0] << 24)|((unsigned long)c[1] << 16)\
|((unsigned long)c[2] << 8)| ((unsigned long)c[3]))
@@ -137,28 +129,18 @@ struct PEHeaderStr {
#define PutInt4(c,i) ((c[0]=((i) >> 24) & 0xff),(c[1]=((i) >> 16) & 0xff),\
(c[2] = ((i) >> 8) & 0xff), (c[3] = (i) & 0xff))
-/*
- * magic numbers.
- */
#define PRE_MAGIC 0xc0de
#define PRE_VERSION 0x1010
-#define PRE_FORTEZZA_FILE 0x00ff /* pre-encrypted file on disk */
-#define PRE_FORTEZZA_STREAM 0x00f5 /* pre-encrypted file in stream */
-#define PRE_FORTEZZA_GEN_STREAM 0x00f6 /* Generated pre-encrypted file */
-#define PRE_FIXED_FILE 0x000f /* fixed key on disk */
-#define PRE_RSA_FILE 0x001f /* RSA in file */
-#define PRE_FIXED_STREAM 0x0005 /* fixed key in stream */
-
-/*
- * internal implementation info
- */
-
+#define PRE_FORTEZZA_FILE 0x00ff
+#define PRE_FORTEZZA_STREAM 0x00f5
+#define PRE_FORTEZZA_GEN_STREAM 0x00f6
+#define PRE_FIXED_FILE 0x000f
+#define PRE_RSA_FILE 0x001f
+#define PRE_FIXED_STREAM 0x0005
-/* convert an existing stream header to a version with local parameters */
PEHeader *SSL_PreencryptedStreamToFile(PRFileDesc *fd, PEHeader *,
int *headerSize);
-/* convert an existing file header to one suitable for streaming out */
PEHeader *SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *,
int *headerSize);
diff --git a/security/nss/lib/ssl/prelib.c b/security/nss/lib/ssl/prelib.c
index b24399b98..c63483924 100644
--- a/security/nss/lib/ssl/prelib.c
+++ b/security/nss/lib/ssl/prelib.c
@@ -50,205 +50,18 @@
#include "preenc.h"
#include "pk11func.h"
-static unsigned char fromHex(char x) {
- if ((x >= '0') && (x <= '9')) return x-'0';
- if ((x >= 'a') && (x <= 'f')) return x-'a'+10;
- return x-'A'+10;
-}
-
PEHeader *SSL_PreencryptedStreamToFile(PRFileDesc *fd, PEHeader *inHeader,
- int *headerSize)
+ int *headerSize)
{
- PK11SymKey *key, *tek, *Ks;
- sslSocket *ss;
- PK11SlotInfo *slot;
- CK_TOKEN_INFO info;
- int oldHeaderSize;
- PEHeader *header;
- SECStatus rv;
- SECItem item;
- int i;
-
- if (fd == NULL) {
- /* XXX set an error */
- return NULL;
- }
-
- ss = ssl_FindSocket(fd);
- if (ss == NULL) {
- return NULL;
- }
-
- PORT_Assert(ss->ssl3 != NULL);
- if (ss->ssl3 == NULL) {
- return NULL;
- }
-
- if (GetInt2(inHeader->magic) != PRE_MAGIC) {
- return NULL;
- }
-
- oldHeaderSize = GetInt2(inHeader->len);
- header = (PEHeader *) PORT_ZAlloc(oldHeaderSize);
- if (header == NULL) {
- return NULL;
- }
-
- switch (GetInt2(inHeader->type)) {
- case PRE_FORTEZZA_FILE:
- case PRE_FORTEZZA_GEN_STREAM:
- case PRE_FIXED_FILE:
- case PRE_RSA_FILE:
- default:
- *headerSize = oldHeaderSize;
- PORT_Memcpy(header,inHeader,oldHeaderSize);
- return header;
-
- case PRE_FORTEZZA_STREAM:
- *headerSize = PE_BASE_HEADER_LEN + sizeof(PEFortezzaHeader);
- PutInt2(header->magic,PRE_MAGIC);
- PutInt2(header->len,*headerSize);
- PutInt2(header->type, PRE_FORTEZZA_FILE);
- PORT_Memcpy(header->version,inHeader->version,sizeof(header->version));
- PORT_Memcpy(header->u.fortezza.hash,inHeader->u.fortezza.hash,
- sizeof(header->u.fortezza.hash));
- PORT_Memcpy(header->u.fortezza.iv,inHeader->u.fortezza.iv,
- sizeof(header->u.fortezza.iv));
-
- /* get the kea context from the session */
- tek = ss->ssl3->fortezza.tek;
- if (tek == NULL) {
- PORT_Free(header);
- return NULL;
- }
-
-
- /* get the slot and the serial number */
- slot = PK11_GetSlotFromKey(tek);
- if (slot == NULL) {
- PORT_Free(header);
- return NULL;
- }
- rv = PK11_GetTokenInfo(slot,&info);
- if (rv != SECSuccess) {
- PORT_Free(header);
- PK11_FreeSlot(slot);
- return NULL;
- }
-
- /* Look up the Token Fixed Key */
- Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL, ss->pkcs11PinArg);
- PK11_FreeSlot(slot);
- if (Ks == NULL) {
- PORT_Free(header);
- return NULL;
- }
-
- /* unwrap the key with the TEK */
- item.data = inHeader->u.fortezza.key;
- item.len = sizeof(inHeader->u.fortezza.key);
- key = PK11_UnwrapSymKey(tek,CKM_SKIPJACK_WRAP,
- NULL, &item, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
- if (key == NULL) {
- PORT_Free(header);
- PK11_FreeSymKey(Ks);
- return NULL;
- }
-
- /* rewrap with the local Ks */
- item.data = header->u.fortezza.key;
- item.len = sizeof(header->u.fortezza.key);
- rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, Ks, key, &item);
- PK11_FreeSymKey(Ks);
- PK11_FreeSymKey(key);
- if (rv != SECSuccess) {
- PORT_Free(header);
- return NULL;
- }
-
- /* copy our local serial number into header */
- for (i=0; i < sizeof(header->u.fortezza.serial); i++) {
- header->u.fortezza.serial[i] =
- (fromHex(info.serialNumber[i*2]) << 4) |
- fromHex(info.serialNumber[i*2 + 1]);
- }
- break;
- case PRE_FIXED_STREAM:
- /* not implemented yet */
- PORT_Free(header);
- return NULL;
- }
-
- return(header);
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return NULL;
}
-/*
- * this one needs to allocate space and work for RSA & FIXED key files as well
- */
PEHeader *SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *header,
int *headerSize)
{
- PK11SymKey *key, *tek, *Ks;
- sslSocket *ss;
- PK11SlotInfo *slot;
- SECStatus rv;
- SECItem item;
-
- *headerSize = 0; /* hack */
-
- if (fd == NULL) {
- /* XXX set an error */
- return NULL;
- }
-
- ss = ssl_FindSocket(fd);
- if (ss == NULL) {
- return NULL;
- }
-
- PORT_Assert(ss->ssl3 != NULL);
- if (ss->ssl3 == NULL) {
- return NULL;
- }
-
- /* get the kea context from the session */
- tek = ss->ssl3->fortezza.tek;
- if (tek == NULL) {
- return NULL;
- }
-
- slot = PK11_GetSlotFromKey(tek);
- if (slot == NULL) return NULL;
- Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL, PK11_GetWindow(tek));
- PK11_FreeSlot(slot);
- if (Ks == NULL) return NULL;
-
-
- /* unwrap with the local Ks */
- item.data = header->u.fortezza.key;
- item.len = sizeof(header->u.fortezza.key);
- /* rewrap the key with the TEK */
- key = PK11_UnwrapSymKey(Ks,CKM_SKIPJACK_WRAP,
- NULL, &item, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
- if (key == NULL) {
- PK11_FreeSymKey(Ks);
- return NULL;
- }
-
- rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, key, &item);
- PK11_FreeSymKey(Ks);
- PK11_FreeSymKey(key);
- if (rv != SECSuccess) {
- return NULL;
- }
-
- /* copy over our local serial number */
- PORT_Memset(header->u.fortezza.serial,0,sizeof(header->u.fortezza.serial));
-
- /* change type to stream */
- PutInt2(header->type, PRE_FORTEZZA_STREAM);
-
- return(header);
+ PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
+ return NULL;
}
diff --git a/security/nss/lib/ssl/ssl.h b/security/nss/lib/ssl/ssl.h
index f6ab20af7..afd139d1c 100644
--- a/security/nss/lib/ssl/ssl.h
+++ b/security/nss/lib/ssl/ssl.h
@@ -110,6 +110,8 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd);
/* if step-down keys are needed. */
/* default: off, generate */
/* step-down keys if needed. */
+#define SSL_BYPASS_PKCS11 16 /* use PKCS#11 for pub key only */
+#define SSL_NO_LOCKS 17 /* Don't use locks for protection */
#ifdef SSL_DEPRECATED_FUNCTION
/* Old deprecated function names */
@@ -171,6 +173,12 @@ SSL_IMPORT SECStatus SSL_ResetHandshake(PRFileDesc *fd, PRBool asServer);
SSL_IMPORT SECStatus SSL_ForceHandshake(PRFileDesc *fd);
/*
+** Same as above, but with an I/O timeout.
+ */
+SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
+ PRIntervalTime timeout);
+
+/*
** Query security status of socket. *on is set to one if security is
** enabled. *keySize will contain the stream key size used. *issuer will
** contain the RFC1485 verison of the name of the issuer of the
@@ -190,7 +198,7 @@ SSL_IMPORT SECStatus SSL_SecurityStatus(PRFileDesc *fd, int *on, char **cipher,
#define SSL_SECURITY_STATUS_OFF 0
#define SSL_SECURITY_STATUS_ON_HIGH 1
#define SSL_SECURITY_STATUS_ON_LOW 2
-#define SSL_SECURITY_STATUS_FORTEZZA 3
+#define SSL_SECURITY_STATUS_FORTEZZA 3 /* NO LONGER SUPPORTED */
/*
** Return the certificate for our SSL peer. If the client calls this
@@ -335,6 +343,14 @@ SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd,
*/
SSL_IMPORT SECStatus SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache);
+/*
+** Same as above, but with an I/O timeout.
+ */
+SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd,
+ PRBool flushCache,
+ PRIntervalTime timeout);
+
+
#ifdef SSL_DEPRECATED_FUNCTION
/* deprecated!
** For the server, request a new handshake. For the client, begin a new
diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c
index 1e7f7411a..2b34b9519 100644
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -62,6 +62,7 @@
#include "secmod.h"
#include "nsslocks.h"
#include "ec.h"
+#include "blapi.h"
#include <stdio.h>
@@ -70,10 +71,11 @@
(x)->pValue=(v); (x)->ulValueLen = (l);
#endif
-static void ssl3_CleanupPeerCerts(ssl3State *ssl3);
+static void ssl3_CleanupPeerCerts(sslSocket *ss);
static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
PK11SlotInfo * serverKeySlot);
-static SECStatus ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms);
+static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, const PK11SymKey *pms);
+static SECStatus ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss);
static SECStatus ssl3_HandshakeFailure( sslSocket *ss);
static SECStatus ssl3_InitState( sslSocket *ss);
static sslSessionID *ssl3_NewSessionID( sslSocket *ss, PRBool is_server);
@@ -109,7 +111,6 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
#endif /* NSS_ENABLE_ECC */
{ TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
#ifdef NSS_ENABLE_ECC
{ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
{ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
@@ -136,7 +137,6 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
{ SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
{ SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
{ SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
{ SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
@@ -152,7 +152,6 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
{ SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
{ SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { SSL_FORTEZZA_DMS_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
#ifdef NSS_ENABLE_ECC
{ TLS_ECDH_RSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDH_ECDSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
@@ -177,9 +176,6 @@ static const /*SSL3ClientCertificateType */ uint8 certificate_types [] = {
#endif /* NSS_ENABLE_ECC */
};
-static const /*SSL3ClientCertificateType */ uint8 fortezza_certificate_types [] = {
- ct_Fortezza,
-};
/*
* make sure there is room in the write buffer for padding and
@@ -187,11 +183,6 @@ static const /*SSL3ClientCertificateType */ uint8 fortezza_certificate_types []
*/
#define SSL3_BUFFER_FUDGE 100
-#define SET_ERROR_CODE /* reminder */
-#define SEND_ALERT /* reminder */
-#define TEST_FOR_FAILURE /* reminder */
-#define DEAL_WITH_FAILURE /* reminder */
-
#define EXPORT_RSA_KEY_LENGTH 64 /* bytes */
@@ -217,13 +208,13 @@ static const ssl3BulkCipherDef bulk_cipher_defs[] = {
{cipher_3des, calg_3des, 24, 24, type_block, 8, 8, kg_strong},
{cipher_des40, calg_des, 8, 5, type_block, 8, 8, kg_export},
{cipher_idea, calg_idea, 16, 16, type_block, 8, 8, kg_strong},
- {cipher_fortezza, calg_fortezza, 10, 10, type_block, 24, 8, kg_null},
{cipher_aes_128, calg_aes, 16, 16, type_block, 16,16, kg_strong},
{cipher_aes_256, calg_aes, 32, 32, type_block, 16,16, kg_strong},
{cipher_missing, calg_null, 0, 0, type_stream, 0, 0, kg_null},
};
-static const ssl3KEADef kea_defs[] = { /* indexed by SSL3KeyExchangeAlgorithm */
+static const ssl3KEADef kea_defs[] =
+{ /* indexed by SSL3KeyExchangeAlgorithm */
/* kea exchKeyType signKeyType is_limited limit tls_keygen */
{kea_null, kt_null, sign_null, PR_FALSE, 0, PR_FALSE},
{kea_rsa, kt_rsa, sign_rsa, PR_FALSE, 0, PR_FALSE},
@@ -239,7 +230,6 @@ static const ssl3KEADef kea_defs[] = { /* indexed by SSL3KeyExchangeAlgorithm */
{kea_dhe_rsa_export, kt_dh, sign_rsa, PR_TRUE, 512, PR_FALSE},
{kea_dh_anon, kt_dh, sign_null, PR_FALSE, 0, PR_FALSE},
{kea_dh_anon_export, kt_dh, sign_null, PR_TRUE, 512, PR_FALSE},
- {kea_fortezza, kt_fortezza, sign_dsa, PR_FALSE, 0, PR_FALSE},
{kea_rsa_fips, kt_rsa, sign_rsa, PR_FALSE, 0, PR_TRUE },
#ifdef NSS_ENABLE_ECC
{kea_ecdh_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE},
@@ -250,7 +240,8 @@ static const ssl3KEADef kea_defs[] = { /* indexed by SSL3KeyExchangeAlgorithm */
};
/* must use ssl_LookupCipherSuiteDef to access */
-static const ssl3CipherSuiteDef cipher_suite_defs[] = {
+static const ssl3CipherSuiteDef cipher_suite_defs[] =
+{
/* cipher_suite bulk_cipher_alg mac_alg key_exchange_alg */
{SSL_NULL_WITH_NULL_NULL, cipher_null, mac_null, kea_null},
@@ -298,10 +289,6 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] = {
{SSL_DH_ANON_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_anon},
#endif
- {SSL_FORTEZZA_DMS_WITH_NULL_SHA, cipher_null, mac_sha, kea_fortezza},
- {SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA,
- cipher_fortezza, mac_sha, kea_fortezza},
- {SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_fortezza},
/* New TLS cipher suites */
{TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_rsa},
@@ -362,14 +349,16 @@ typedef struct SSLCipher2MechStr {
CK_MECHANISM_TYPE cmech;
} SSLCipher2Mech;
+/* indexed by type SSLCipherAlgorithm */
static const SSLCipher2Mech alg2Mech[] = {
+ /* calg, cmech */
{ calg_null , (CK_MECHANISM_TYPE)0x80000000L },
{ calg_rc4 , CKM_RC4 },
{ calg_rc2 , CKM_RC2_CBC },
{ calg_des , CKM_DES_CBC },
{ calg_3des , CKM_DES3_CBC },
{ calg_idea , CKM_IDEA_CBC },
- { calg_fortezza , CKM_SKIPJACK_CBC64 },
+ { calg_fortezza , CKM_SKIPJACK_CBC64 },
{ calg_aes , CKM_AES_CBC },
/* { calg_init , (CK_MECHANISM_TYPE)0x7fffffffL } */
};
@@ -401,114 +390,11 @@ const char * const ssl3_cipherName[] = {
"3DES-EDE-CBC",
"DES-CBC-40",
"IDEA-CBC",
- "FORTEZZA",
"AES-128",
"AES-256",
"missing"
};
-#ifdef NSS_ENABLE_ECC
-/* Types and names of elliptic curves used in TLS */
-typedef enum { ec_type_explicitPrime = 1,
- ec_type_explicitChar2Curve,
- ec_type_named
-} ECType;
-
-typedef enum { ec_noName = 0,
- ec_sect163k1, ec_sect163r1, ec_sect163r2,
- ec_sect193r1, ec_sect193r2, ec_sect233k1,
- ec_sect233r1, ec_sect239k1, ec_sect283k1,
- ec_sect283r1, ec_sect409k1, ec_sect409r1,
- ec_sect571k1, ec_sect571r1, ec_secp160k1,
- ec_secp160r1, ec_secp160r2, ec_secp192k1,
- ec_secp192r1, ec_secp224k1, ec_secp224r1,
- ec_secp256k1, ec_secp256r1, ec_secp384r1,
- ec_secp521r1,
- ec_pastLastName
-} ECName;
-
-#define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName))
-
-/* Table containing OID tags for elliptic curves named in the
- * ECC-TLS IETF draft.
- */
-static const SECOidTag ecName2OIDTag[] = {
- 0,
- SEC_OID_SECG_EC_SECT163K1, /* 1 */
- SEC_OID_SECG_EC_SECT163R1, /* 2 */
- SEC_OID_SECG_EC_SECT163R2, /* 3 */
- SEC_OID_SECG_EC_SECT193R1, /* 4 */
- SEC_OID_SECG_EC_SECT193R2, /* 5 */
- SEC_OID_SECG_EC_SECT233K1, /* 6 */
- SEC_OID_SECG_EC_SECT233R1, /* 7 */
- SEC_OID_SECG_EC_SECT239K1, /* 8 */
- SEC_OID_SECG_EC_SECT283K1, /* 9 */
- SEC_OID_SECG_EC_SECT283R1, /* 10 */
- SEC_OID_SECG_EC_SECT409K1, /* 11 */
- SEC_OID_SECG_EC_SECT409R1, /* 12 */
- SEC_OID_SECG_EC_SECT571K1, /* 13 */
- SEC_OID_SECG_EC_SECT571R1, /* 14 */
- SEC_OID_SECG_EC_SECP160K1, /* 15 */
- SEC_OID_SECG_EC_SECP160R1, /* 16 */
- SEC_OID_SECG_EC_SECP160R2, /* 17 */
- SEC_OID_SECG_EC_SECP192K1, /* 18 */
- SEC_OID_SECG_EC_SECP192R1, /* 19 */
- SEC_OID_SECG_EC_SECP224K1, /* 20 */
- SEC_OID_SECG_EC_SECP224R1, /* 21 */
- SEC_OID_SECG_EC_SECP256K1, /* 22 */
- SEC_OID_SECG_EC_SECP256R1, /* 23 */
- SEC_OID_SECG_EC_SECP384R1, /* 24 */
- SEC_OID_SECG_EC_SECP521R1, /* 25 */
-};
-
-static SECStatus
-ecName2params(PRArenaPool * arena, ECName curve, SECKEYECParams * params)
-{
- SECOidData *oidData = NULL;
-
- if ((curve <= ec_noName) || (curve >= ec_pastLastName) ||
- ((oidData = SECOID_FindOIDByTag(ecName2OIDTag[curve])) == NULL)) {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
- return SECFailure;
- }
-
- SECITEM_AllocItem(arena, params, (2 + oidData->oid.len));
- /*
- * params->data needs to contain the ASN encoding of an object ID (OID)
- * representing the named curve. The actual OID is in
- * oidData->oid.data so we simply prepend 0x06 and OID length
- */
- params->data[0] = SEC_ASN1_OBJECT_ID;
- params->data[1] = oidData->oid.len;
- memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
-
- return SECSuccess;
-}
-
-static ECName
-params2ecName(SECKEYECParams * params)
-{
- SECItem oid = { siBuffer, NULL, 0};
- SECOidData *oidData = NULL;
- ECName i;
-
- /*
- * params->data needs to contain the ASN encoding of an object ID (OID)
- * representing a named curve. Here, we strip away everything
- * before the actual OID and use the OID to look up a named curve.
- */
- if (params->data[0] != SEC_ASN1_OBJECT_ID) return ec_noName;
- oid.len = params->len - 2;
- oid.data = params->data + 2;
- if ((oidData = SECOID_FindOID(&oid)) == NULL) return ec_noName;
- for (i = ec_noName + 1; i < ec_pastLastName; i++) {
- if (ecName2OIDTag[i] == oidData->offset)
- return i;
- }
-
- return ec_noName;
-}
-#endif /* NSS_ENABLE_ECC */
#if defined(TRACE)
@@ -618,7 +504,7 @@ ssl3_config_match_init(sslSocket *ss)
PRBool isServer;
sslServerCerts *svrAuth;
- if (!ss->enableSSL3 && !ss->enableTLS) {
+ if (!ss->opt.enableSSL3 && !ss->opt.enableTLS) {
return 0;
}
isServer = (PRBool)( ss && ss->sec.isServer );
@@ -671,7 +557,8 @@ ssl3_config_match_init(sslSocket *ss)
/* Mark the suites that are backed by real tokens, certs and keys */
suite->isPresent = (PRBool)
(((exchKeyType == kt_null) ||
- ((!isServer || (svrAuth->serverKey &&
+ ((!isServer || (svrAuth->serverKeyPair &&
+ svrAuth->SERVERKEY &&
svrAuth->serverCertChain)) &&
PK11_TokenExists(kea_alg_defs[exchKeyType]))) &&
((cipher_alg == calg_null) || PK11_TokenExists(cipher_mech)));
@@ -713,7 +600,7 @@ count_cipher_suites(sslSocket *ss, int policy, PRBool enabled)
{
int i, count = 0;
- if (!ss->enableSSL3 && !ss->enableTLS) {
+ if (!ss->opt.enableSSL3 && !ss->opt.enableTLS) {
return 0;
}
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
@@ -731,7 +618,7 @@ anyRestrictedEnabled(sslSocket *ss)
{
int i;
- if (!ss->enableSSL3 && !ss->enableTLS) {
+ if (!ss->opt.enableSSL3 && !ss->opt.enableTLS) {
return PR_FALSE;
}
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
@@ -758,7 +645,6 @@ Null_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen,
return SECSuccess;
}
-
/*
* SSL3 Utility functions
*/
@@ -769,21 +655,21 @@ ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion)
SSL3ProtocolVersion version;
SSL3ProtocolVersion maxVersion;
- if (ss->enableTLS) {
+ if (ss->opt.enableTLS) {
maxVersion = SSL_LIBRARY_VERSION_3_1_TLS;
- } else if (ss->enableSSL3) {
+ } else if (ss->opt.enableSSL3) {
maxVersion = SSL_LIBRARY_VERSION_3_0;
} else {
/* what are we doing here? */
- PORT_Assert(ss->enableSSL3 || ss->enableTLS);
+ PORT_Assert(ss->opt.enableSSL3 || ss->opt.enableTLS);
PORT_SetError(SSL_ERROR_SSL_DISABLED);
return SECFailure;
}
ss->version = version = PR_MIN(maxVersion, peerVersion);
- if ((version == SSL_LIBRARY_VERSION_3_1_TLS && ss->enableTLS) ||
- (version == SSL_LIBRARY_VERSION_3_0 && ss->enableSSL3)) {
+ if ((version == SSL_LIBRARY_VERSION_3_1_TLS && ss->opt.enableTLS) ||
+ (version == SSL_LIBRARY_VERSION_3_0 && ss->opt.enableSSL3)) {
return SECSuccess;
}
@@ -811,7 +697,8 @@ ssl3_GetNewRandom(SSL3Random *random)
return rv;
}
-static SECStatus
+/* Called by ssl3_SendServerKeyExchange and ssl3_SendCertificateVerify */
+SECStatus
ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf,
PRBool isTLS)
{
@@ -838,7 +725,6 @@ ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf,
hashItem.len = sizeof(SSL3Hashes);
break;
case dsaKey:
- case fortezzaKey:
doDerEncode = isTLS;
hashItem.data = hash->sha;
hashItem.len = sizeof(hash->sha);
@@ -881,8 +767,8 @@ done:
return rv;
}
-
-static SECStatus
+/* Called from ssl3_HandleServerKeyExchange, ssl3_HandleCertificateVerify */
+SECStatus
ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert,
SECItem *buf, PRBool isTLS, void *pwArg)
{
@@ -911,7 +797,6 @@ ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert,
hashItem.len = sizeof(SSL3Hashes);
break;
case dsaKey:
- case fortezzaKey:
hashItem.data = hash->sha;
hashItem.len = sizeof(hash->sha);
if (isTLS) {
@@ -970,17 +855,49 @@ ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert,
/* Caller must set hiLevel error code. */
+/* Called from ssl3_ComputeExportRSAKeyHash
+ * ssl3_ComputeDHKeyHash
+ * which are called from ssl3_HandleServerKeyExchange.
+ */
+SECStatus
+ssl3_ComputeCommonKeyHash(PRUint8 * hashBuf, unsigned int bufLen,
+ SSL3Hashes *hashes, PRBool bypassPKCS11)
+{
+ SECStatus rv = SECSuccess;
+
+ if (bypassPKCS11) {
+ MD5_HashBuf (hashes->md5, hashBuf, bufLen);
+ SHA1_HashBuf(hashes->sha, hashBuf, bufLen);
+ } else {
+ rv = PK11_HashBuf(SEC_OID_MD5, hashes->md5, hashBuf, bufLen);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+ rv = SECFailure;
+ goto done;
+ }
+
+ rv = PK11_HashBuf(SEC_OID_SHA1, hashes->sha, hashBuf, bufLen);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ rv = SECFailure;
+ }
+ }
+done:
+ return rv;
+}
+
+/* Caller must set hiLevel error code.
+** Called from ssl3_SendServerKeyExchange and
+** ssl3_HandleServerKeyExchange.
+*/
static SECStatus
ssl3_ComputeExportRSAKeyHash(SECItem modulus, SECItem publicExponent,
SSL3Random *client_rand, SSL3Random *server_rand,
- SSL3Hashes *hashes)
+ SSL3Hashes *hashes, PRBool bypassPKCS11)
{
- PK11Context * md5 = NULL;
- PK11Context * sha = NULL;
PRUint8 * hashBuf;
PRUint8 * pBuf;
SECStatus rv = SECSuccess;
- unsigned int outLen;
unsigned int bufLen;
PRUint8 buf[2*SSL3_RANDOM_LENGTH + 2 + 4096/8 + 2 + 4096/8];
@@ -994,19 +911,6 @@ ssl3_ComputeExportRSAKeyHash(SECItem modulus, SECItem publicExponent,
}
}
- md5 = PK11_CreateDigestContext(SEC_OID_MD5);
- if (md5 == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure; /* Caller must set hiLevel error code. */
- goto done;
- }
- sha = PK11_CreateDigestContext(SEC_OID_SHA1);
- if (sha == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure; /* Caller must set hiLevel error code. */
- goto done;
- }
-
memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
pBuf = hashBuf + SSL3_RANDOM_LENGTH;
memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
@@ -1023,50 +927,27 @@ ssl3_ComputeExportRSAKeyHash(SECItem modulus, SECItem publicExponent,
pBuf += publicExponent.len;
PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
- rv = PK11_DigestBegin(md5);
- rv |= PK11_DigestOp(md5, hashBuf, bufLen);
- rv |= PK11_DigestFinal(md5, hashes->md5, &outLen, MD5_LENGTH);
- PORT_Assert(rv != SECSuccess || outLen == MD5_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto done;
- }
-
- rv = PK11_DigestBegin(sha);
- rv |= PK11_DigestOp(sha, hashBuf, bufLen);
- rv |= PK11_DigestFinal(sha, hashes->sha, &outLen, SHA1_LENGTH);
- PORT_Assert(rv != SECSuccess || outLen == SHA1_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
- goto done;
- }
+ rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11);
PRINT_BUF(95, (NULL, "RSAkey hash: ", hashBuf, bufLen));
PRINT_BUF(95, (NULL, "RSAkey hash: MD5 result", hashes->md5, MD5_LENGTH));
PRINT_BUF(95, (NULL, "RSAkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));
-done:
- if (md5 != NULL) PK11_DestroyContext(md5, PR_TRUE);
- if (sha != NULL) PK11_DestroyContext(sha, PR_TRUE);
if (hashBuf != buf && hashBuf != NULL)
PORT_Free(hashBuf);
return rv;
}
/* Caller must set hiLevel error code. */
+/* Called from ssl3_HandleServerKeyExchange. */
static SECStatus
ssl3_ComputeDHKeyHash(SECItem dh_p, SECItem dh_g, SECItem dh_Ys,
SSL3Random *client_rand, SSL3Random *server_rand,
- SSL3Hashes *hashes)
+ SSL3Hashes *hashes, PRBool bypassPKCS11)
{
- PK11Context * md5 = NULL;
- PK11Context * sha = NULL;
PRUint8 * hashBuf;
PRUint8 * pBuf;
SECStatus rv = SECSuccess;
- unsigned int outLen;
unsigned int bufLen;
PRUint8 buf[2*SSL3_RANDOM_LENGTH + 2 + 4096/8 + 2 + 4096/8];
@@ -1080,19 +961,6 @@ ssl3_ComputeDHKeyHash(SECItem dh_p, SECItem dh_g, SECItem dh_Ys,
}
}
- md5 = PK11_CreateDigestContext(SEC_OID_MD5);
- if (md5 == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure; /* Caller must set hiLevel error code. */
- goto done;
- }
- sha = PK11_CreateDigestContext(SEC_OID_SHA1);
- if (sha == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure; /* Caller must set hiLevel error code. */
- goto done;
- }
-
memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
pBuf = hashBuf + SSL3_RANDOM_LENGTH;
memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
@@ -1114,129 +982,17 @@ ssl3_ComputeDHKeyHash(SECItem dh_p, SECItem dh_g, SECItem dh_Ys,
pBuf += dh_Ys.len;
PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
- rv = PK11_DigestBegin(md5);
- rv |= PK11_DigestOp(md5, hashBuf, bufLen);
- rv |= PK11_DigestFinal(md5, hashes->md5, &outLen, MD5_LENGTH);
- PORT_Assert(rv != SECSuccess || outLen == MD5_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto done;
- }
-
- rv = PK11_DigestBegin(sha);
- rv |= PK11_DigestOp(sha, hashBuf, bufLen);
- rv |= PK11_DigestFinal(sha, hashes->sha, &outLen, SHA1_LENGTH);
- PORT_Assert(rv != SECSuccess || outLen == SHA1_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
- goto done;
- }
+ rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11);
PRINT_BUF(95, (NULL, "DHkey hash: ", hashBuf, bufLen));
PRINT_BUF(95, (NULL, "DHkey hash: MD5 result", hashes->md5, MD5_LENGTH));
PRINT_BUF(95, (NULL, "DHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));
-done:
- if (md5 != NULL) PK11_DestroyContext(md5, PR_TRUE);
- if (sha != NULL) PK11_DestroyContext(sha, PR_TRUE);
if (hashBuf != buf && hashBuf != NULL)
PORT_Free(hashBuf);
return rv;
}
-#ifdef NSS_ENABLE_ECC
-/* Caller must set hiLevel error code. */
-static SECStatus
-ssl3_ComputeECDHKeyHash(SECItem ec_params, SECItem server_ecpoint,
- SSL3Random *client_rand, SSL3Random *server_rand,
- SSL3Hashes *hashes)
-{
- PRUint8 * hashBuf;
- PRUint8 * pBuf;
- SECStatus rv = SECSuccess;
- unsigned int bufLen;
- /*
- * XXX For now, we only support named curves (the appropriate
- * checks are made before this method is called) so ec_params
- * takes up only two bytes. ECPoint needs to fit in 256 bytes
- * (because the spec says the length must fit in one byte)
- */
- PRUint8 buf[2*SSL3_RANDOM_LENGTH + 2 + 1 + 256];
-
- bufLen = 2*SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len;
- if (bufLen <= sizeof buf) {
- hashBuf = buf;
- } else {
- hashBuf = PORT_Alloc(bufLen);
- if (!hashBuf) {
- return SECFailure;
- }
- }
-
- memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
- pBuf = hashBuf + SSL3_RANDOM_LENGTH;
- memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
- pBuf += SSL3_RANDOM_LENGTH;
- memcpy(pBuf, ec_params.data, ec_params.len);
- pBuf += ec_params.len;
- pBuf[0] = (PRUint8)(server_ecpoint.len);
- pBuf += 1;
- memcpy(pBuf, server_ecpoint.data, server_ecpoint.len);
- pBuf += server_ecpoint.len;
- PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
-
- rv = PK11_HashBuf(SEC_OID_MD5, hashes->md5, hashBuf, bufLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto done;
- }
-
- rv = PK11_HashBuf(SEC_OID_SHA1, hashes->sha, hashBuf, bufLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
- goto done;
- }
-
- PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen));
- PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result", hashes->md5, MD5_LENGTH));
- PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));
-
-done:
- if (hashBuf != buf && hashBuf != NULL)
- PORT_Free(hashBuf);
- return rv;
-}
-#endif /* NSS_ENABLE_ECC */
-
-/* Caller must set hiLevel error code. */
-static SECStatus
-ssl3_ComputeFortezzaPublicKeyHash(SECItem publicValue, unsigned char * hash)
-{
- PK11Context *sha = NULL;
- SECStatus rv = SECFailure;
- unsigned int outLen;
-
- sha = PK11_CreateDigestContext(SEC_OID_SHA1);
- if (sha == NULL) {
- return rv; /* Caller must set hiLevel error code. */
- }
-
- rv = PK11_DigestBegin(sha);
- rv |= PK11_DigestOp(sha, (unsigned char *)publicValue.data, publicValue.len);
- rv |= PK11_DigestFinal(sha, hash, &outLen, SHA1_LENGTH);
- PORT_Assert(rv != SECSuccess || outLen == SHA1_LENGTH);
- if (rv != SECSuccess)
- rv = SECFailure;
- PK11_DestroyContext(sha, PR_TRUE);
-
- return rv;
-}
-
-
static void
ssl3_BumpSequenceNumber(SSL3SequenceNumber *num)
{
@@ -1245,7 +1001,7 @@ ssl3_BumpSequenceNumber(SSL3SequenceNumber *num)
num->high++;
}
-/* Called only from ssl3_DestroyCipherSpec (immediately below). */
+/* Called twice, only from ssl3_DestroyCipherSpec (immediately below). */
static void
ssl3_CleanupKeyMaterial(ssl3KeyMaterial *mat)
{
@@ -1263,18 +1019,19 @@ ssl3_CleanupKeyMaterial(ssl3KeyMaterial *mat)
}
}
-/* Called from ssl3_SendChangeCipherSpecs() and ssl3_HandleChangeCipherSpecs()
+/* Called from ssl3_SendChangeCipherSpecs() and
+** ssl3_HandleChangeCipherSpecs()
+** ssl3_DestroySSL3Info
** Caller must hold SpecWriteLock.
*/
static void
ssl3_DestroyCipherSpec(ssl3CipherSpec *spec)
{
-
-/* PORT_Assert( ssl_HaveSpecWriteLock(ss)); Don't have ss! */
-
+ PRBool freeit = (PRBool)(!spec->bypassCiphers);
+/* PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); Don't have ss! */
if (spec->destroy) {
- spec->destroy(spec->encodeContext,PR_TRUE);
- spec->destroy(spec->decodeContext,PR_TRUE);
+ spec->destroy(spec->encodeContext, freeit);
+ spec->destroy(spec->decodeContext, freeit);
spec->encodeContext = NULL; /* paranoia */
spec->decodeContext = NULL;
}
@@ -1282,36 +1039,41 @@ ssl3_DestroyCipherSpec(ssl3CipherSpec *spec)
PK11_FreeSymKey(spec->master_secret);
spec->master_secret = NULL;
}
+ spec->msItem.data = NULL;
+ spec->msItem.len = 0;
ssl3_CleanupKeyMaterial(&spec->client);
ssl3_CleanupKeyMaterial(&spec->server);
+ spec->bypassCiphers = PR_FALSE;
spec->destroy=NULL;
}
-/* Called from ssl3_HandleServerHello(), ssl3_SendServerHello()
+/* Fill in the pending cipher spec with info from the selected ciphersuite.
+** This is as much initialization as we can do without having key material.
+** Called from ssl3_HandleServerHello(), ssl3_SendServerHello()
** Caller must hold the ssl3 handshake lock.
** Acquires & releases SpecWriteLock.
*/
static SECStatus
-ssl3_SetupPendingCipherSpec(sslSocket *ss, ssl3State *ssl3)
+ssl3_SetupPendingCipherSpec(sslSocket *ss)
{
ssl3CipherSpec * pwSpec;
ssl3CipherSpec * cwSpec;
- ssl3CipherSuite suite = ssl3->hs.cipher_suite;
+ ssl3CipherSuite suite = ss->ssl3.hs.cipher_suite;
SSL3MACAlgorithm mac;
SSL3BulkCipher cipher;
SSL3KeyExchangeAlgorithm kea;
const ssl3CipherSuiteDef *suite_def;
PRBool isTLS;
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
ssl_GetSpecWriteLock(ss); /*******************************/
- pwSpec = ssl3->pwSpec;
- PORT_Assert(pwSpec == ssl3->prSpec);
+ pwSpec = ss->ssl3.pwSpec;
+ PORT_Assert(pwSpec == ss->ssl3.prSpec);
/* This hack provides maximal interoperability with SSL 3 servers. */
- cwSpec = ss->ssl3->cwSpec;
+ cwSpec = ss->ssl3.cwSpec;
if (cwSpec->mac_def->mac == mac_null) {
/* SSL records are not being MACed. */
cwSpec->version = ss->version;
@@ -1336,9 +1098,9 @@ ssl3_SetupPendingCipherSpec(sslSocket *ss, ssl3State *ssl3)
if (isTLS)
mac += 2;
- ssl3->hs.suite_def = suite_def;
- ssl3->hs.kea_def = &kea_defs[kea];
- PORT_Assert(ssl3->hs.kea_def->kea == kea);
+ ss->ssl3.hs.suite_def = suite_def;
+ ss->ssl3.hs.kea_def = &kea_defs[kea];
+ PORT_Assert(ss->ssl3.hs.kea_def->kea == kea);
pwSpec->cipher_def = &bulk_cipher_defs[cipher];
PORT_Assert(pwSpec->cipher_def->cipher == cipher);
@@ -1346,7 +1108,6 @@ ssl3_SetupPendingCipherSpec(sslSocket *ss, ssl3State *ssl3)
pwSpec->mac_def = &mac_defs[mac];
PORT_Assert(pwSpec->mac_def->mac == mac);
-
ss->sec.keyBits = pwSpec->cipher_def->key_size * BPB;
ss->sec.secretKeyBits = pwSpec->cipher_def->secret_key_size * BPB;
ss->sec.cipherType = cipher;
@@ -1360,83 +1121,233 @@ ssl3_SetupPendingCipherSpec(sslSocket *ss, ssl3State *ssl3)
return SECSuccess;
}
-/*
- * Called from: ssl3_SendClientKeyExchange (for Full handshake)
- * ssl3_HandleClientKeyExchange (for Full handshake)
- * ssl3_HandleServerHello (for session restart)
- * ssl3_HandleClientHello (for session restart)
- * Sets error code, but caller probably should override to disambiguate.
- * NULL pms means re-use old master_secret.
+/* Initialize encryption and MAC contexts for pending spec.
+ * Master Secret already is derived in spec->msItem
+ * Caller holds Spec write lock.
*/
static SECStatus
-ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms)
+ssl3_InitPendingContextsBypass(sslSocket *ss)
{
ssl3CipherSpec * pwSpec;
const ssl3BulkCipherDef *cipher_def;
- PK11Context * serverContext = NULL;
- PK11Context * clientContext = NULL;
- SECItem * param;
+ void * serverContext = NULL;
+ void * clientContext = NULL;
+ BLapiInitContextFunc initFn = (BLapiInitContextFunc)NULL;
+ int mode = 0;
+ unsigned int optArg1 = 0;
+ unsigned int optArg2 = 0;
+ PRBool server_encrypts = ss->sec.isServer;
CK_ULONG macLength;
SSLCipherAlgorithm calg;
SECStatus rv;
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
+
+ pwSpec = ss->ssl3.pwSpec;
+ cipher_def = pwSpec->cipher_def;
+ macLength = pwSpec->mac_size;
+
+ /* MAC setup is done when computing the mac, not here.
+ * Now setup the crypto contexts.
+ */
+
+ calg = cipher_def->calg;
+
+ serverContext = pwSpec->server.cipher_context;
+ clientContext = pwSpec->client.cipher_context;
+
+ switch (calg) {
+ case ssl_calg_null:
+ pwSpec->encode = Null_Cipher;
+ pwSpec->decode = Null_Cipher;
+ pwSpec->destroy = NULL;
+ goto success;
+
+ case ssl_calg_rc4:
+ initFn = (BLapiInitContextFunc)RC4_InitContext;
+ pwSpec->encode = (SSLCipher) RC4_Encrypt;
+ pwSpec->decode = (SSLCipher) RC4_Decrypt;
+ pwSpec->destroy = (SSLDestroy) RC4_DestroyContext;
+ break;
+ case ssl_calg_rc2:
+ initFn = (BLapiInitContextFunc)RC2_InitContext;
+ mode = NSS_RC2_CBC;
+ optArg1 = cipher_def->key_size;
+ pwSpec->encode = (SSLCipher) RC2_Encrypt;
+ pwSpec->decode = (SSLCipher) RC2_Decrypt;
+ pwSpec->destroy = (SSLDestroy) RC2_DestroyContext;
+ break;
+ case ssl_calg_des:
+ initFn = (BLapiInitContextFunc)DES_InitContext;
+ mode = NSS_DES_CBC;
+ optArg1 = server_encrypts;
+ pwSpec->encode = (SSLCipher) DES_Encrypt;
+ pwSpec->decode = (SSLCipher) DES_Decrypt;
+ pwSpec->destroy = (SSLDestroy) DES_DestroyContext;
+ break;
+ case ssl_calg_3des:
+ initFn = (BLapiInitContextFunc)DES_InitContext;
+ mode = NSS_DES_EDE3_CBC;
+ optArg1 = server_encrypts;
+ pwSpec->encode = (SSLCipher) DES_Encrypt;
+ pwSpec->decode = (SSLCipher) DES_Decrypt;
+ pwSpec->destroy = (SSLDestroy) DES_DestroyContext;
+ break;
+ case ssl_calg_aes:
+ initFn = (BLapiInitContextFunc)AES_InitContext;
+ mode = NSS_AES_CBC;
+ optArg1 = server_encrypts;
+ optArg2 = AES_BLOCK_SIZE;
+ pwSpec->encode = (SSLCipher) AES_Encrypt;
+ pwSpec->decode = (SSLCipher) AES_Decrypt;
+ pwSpec->destroy = (SSLDestroy) AES_DestroyContext;
+ break;
+
+ case ssl_calg_idea:
+ case ssl_calg_fortezza :
+ default:
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ goto bail_out;
+ }
+ rv = (*initFn)(serverContext,
+ pwSpec->server.write_key_item.data,
+ pwSpec->server.write_key_item.len,
+ pwSpec->server.write_iv_item.data,
+ mode, optArg1, optArg2);
+ if (rv != SECSuccess) {
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ goto bail_out;
+ }
+
+ if (calg == ssl_calg_des || calg == ssl_calg_3des || calg == ssl_calg_aes) {
+ /* For block ciphers, if the server is encrypting, then the client
+ * is decrypting, and vice versa.
+ */
+ optArg1 = !optArg1;
+ }
+
+ rv = (*initFn)(clientContext,
+ pwSpec->client.write_key_item.data,
+ pwSpec->client.write_key_item.len,
+ pwSpec->client.write_iv_item.data,
+ mode, optArg1, optArg2);
+ if (rv != SECSuccess) {
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ goto bail_out;
+ }
+
+ pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext;
+ pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext;
+
+success:
+ return SECSuccess;
+
+bail_out:
+ return SECFailure;
+}
+
+/* This function should probably be moved to pk11wrap and be named
+ * PK11_ParamFromIVAndEffectiveKeyBits
+ */
+static SECItem *
+ssl3_ParamFromIV(CK_MECHANISM_TYPE mtype, SECItem *iv, CK_ULONG ulEffectiveBits)
+{
+ SECItem * param = PK11_ParamFromIV(mtype, iv);
+ if (param && param->data && param->len >= sizeof(CK_RC2_PARAMS)) {
+ switch (mtype) {
+ case CKM_RC2_KEY_GEN:
+ case CKM_RC2_ECB:
+ case CKM_RC2_CBC:
+ case CKM_RC2_MAC:
+ case CKM_RC2_MAC_GENERAL:
+ case CKM_RC2_CBC_PAD:
+ *(CK_RC2_PARAMS *)param->data = ulEffectiveBits;
+ default: break;
+ }
+ }
+ return param;
+}
+
+/* Initialize encryption and MAC contexts for pending spec.
+ * Master Secret already is derived.
+ * Caller holds Spec write lock.
+ */
+static SECStatus
+ssl3_InitPendingContextsPKCS11(sslSocket *ss)
+{
+ ssl3CipherSpec * pwSpec;
+const ssl3BulkCipherDef *cipher_def;
+ PK11Context * serverContext = NULL;
+ PK11Context * clientContext = NULL;
+ SECItem * param;
CK_MECHANISM_TYPE mechanism;
CK_MECHANISM_TYPE mac_mech;
+ CK_ULONG macLength;
+ CK_ULONG effKeyBits;
SECItem iv;
SECItem mac_param;
+ SSLCipherAlgorithm calg;
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- ssl_GetSpecWriteLock(ss); /**************************************/
+ PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
- PORT_Assert(ss->ssl3->prSpec == ss->ssl3->pwSpec);
-
- pwSpec = ss->ssl3->pwSpec;
+ pwSpec = ss->ssl3.pwSpec;
cipher_def = pwSpec->cipher_def;
macLength = pwSpec->mac_size;
- /* generate session keys from pms (if pms is not NULL) or ms */
- rv = ssl3_GenerateSessionKeys(ss, pms);
- if (rv != SECSuccess) {
- goto bail_out; /* err code set by ssl3_GenerateSessionKeys */
- }
+ /*
+ ** Now setup the MAC contexts,
+ ** crypto contexts are setup below.
+ */
pwSpec->client.write_mac_context = NULL;
pwSpec->server.write_mac_context = NULL;
-
+ mac_mech = pwSpec->mac_def->mmech;
mac_param.data = (unsigned char *)&macLength;
mac_param.len = sizeof(macLength);
mac_param.type = 0;
- mac_mech = pwSpec->mac_def->mmech;
- if (cipher_def->calg == calg_null) {
- pwSpec->encode = Null_Cipher;
- pwSpec->decode = Null_Cipher;
- pwSpec->destroy = NULL;
- pwSpec->client.write_mac_context = PK11_CreateContextBySymKey(
- mac_mech, CKA_SIGN, pwSpec->client.write_mac_key, &mac_param);
- if (pwSpec->client.write_mac_context == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
- pwSpec->server.write_mac_context = PK11_CreateContextBySymKey(
- mac_mech, CKA_SIGN, pwSpec->server.write_mac_key, &mac_param);
- if (pwSpec->server.write_mac_context == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
- goto success;
+ pwSpec->client.write_mac_context = PK11_CreateContextBySymKey(
+ mac_mech, CKA_SIGN, pwSpec->client.write_mac_key, &mac_param);
+ if (pwSpec->client.write_mac_context == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
+ goto fail;
+ }
+ pwSpec->server.write_mac_context = PK11_CreateContextBySymKey(
+ mac_mech, CKA_SIGN, pwSpec->server.write_mac_key, &mac_param);
+ if (pwSpec->server.write_mac_context == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
+ goto fail;
}
+ /*
+ ** Now setup the crypto contexts.
+ */
+
calg = cipher_def->calg;
PORT_Assert(alg2Mech[calg].calg == calg);
+
+ if (calg == calg_null) {
+ pwSpec->encode = Null_Cipher;
+ pwSpec->decode = Null_Cipher;
+ pwSpec->destroy = NULL;
+ return SECSuccess;
+ }
mechanism = alg2Mech[calg].cmech;
+ effKeyBits = cipher_def->key_size * BPB;
/*
* build the server context
*/
iv.data = pwSpec->server.write_iv;
iv.len = cipher_def->iv_size;
- param = PK11_ParamFromIV(mechanism, &iv);
+ param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits);
if (param == NULL) {
ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
goto fail;
@@ -1458,7 +1369,8 @@ const ssl3BulkCipherDef *cipher_def;
*/
iv.data = pwSpec->client.write_iv;
iv.len = cipher_def->iv_size;
- param = PK11_ParamFromIV(mechanism, &iv);
+
+ param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits);
if (param == NULL) {
ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
goto fail;
@@ -1474,30 +1386,16 @@ const ssl3BulkCipherDef *cipher_def;
ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
goto fail;
}
-
- pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext;
- pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext;
pwSpec->encode = (SSLCipher) PK11_CipherOp;
pwSpec->decode = (SSLCipher) PK11_CipherOp;
pwSpec->destroy = (SSLDestroy) PK11_DestroyContext;
+ pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext;
+ pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext;
+
serverContext = NULL;
clientContext = NULL;
- pwSpec->client.write_mac_context = PK11_CreateContextBySymKey(
- mac_mech,CKA_SIGN, pwSpec->client.write_mac_key,&mac_param);
- if (pwSpec->client.write_mac_context == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
- pwSpec->server.write_mac_context = PK11_CreateContextBySymKey(
- mac_mech, CKA_SIGN, pwSpec->server.write_mac_key,&mac_param);
- if (pwSpec->server.write_mac_context == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
-success:
- ssl_ReleaseSpecWriteLock(ss); /******************************/
return SECSuccess;
fail:
@@ -1511,11 +1409,74 @@ fail:
PK11_DestroyContext(pwSpec->server.write_mac_context,PR_TRUE);
pwSpec->server.write_mac_context = NULL;
}
-bail_out:
- ssl_ReleaseSpecWriteLock(ss);
+
return SECFailure;
}
+/* Complete the initialization of all keys, ciphers, MACs and their contexts
+ * for the pending Cipher Spec.
+ * Called from: ssl3_SendClientKeyExchange (for Full handshake)
+ * ssl3_HandleRSAClientKeyExchange (for Full handshake)
+ * ssl3_HandleServerHello (for session restart)
+ * ssl3_HandleClientHello (for session restart)
+ * Sets error code, but caller probably should override to disambiguate.
+ * NULL pms means re-use old master_secret.
+ *
+ * This code is common to the bypass and PKCS11 execution paths.
+ * For the bypass case, pms is NULL.
+ */
+SECStatus
+ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms)
+{
+ ssl3CipherSpec * pwSpec;
+ SECStatus rv;
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ ssl_GetSpecWriteLock(ss); /**************************************/
+
+ PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
+
+ pwSpec = ss->ssl3.pwSpec;
+
+ if (pms || (!pwSpec->msItem.len && !pwSpec->master_secret)) {
+ rv = ssl3_DeriveMasterSecret(ss, pms);
+ if (rv != SECSuccess) {
+ goto done; /* err code set by ssl3_DeriveMasterSecret */
+ }
+ }
+ if (pwSpec->msItem.len && pwSpec->msItem.data) {
+ /* Double Bypass */
+ const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
+ PRBool isTLS = (PRBool)(kea_def->tls_keygen ||
+ (pwSpec->version > SSL_LIBRARY_VERSION_3_0));
+ pwSpec->bypassCiphers = PR_TRUE;
+ rv = ssl3_KeyAndMacDeriveBypass( pwSpec,
+ (const unsigned char *)&ss->ssl3.hs.client_random,
+ (const unsigned char *)&ss->ssl3.hs.server_random,
+ isTLS,
+ (PRBool)(kea_def->is_limited));
+ if (rv == SECSuccess) {
+ rv = ssl3_InitPendingContextsBypass(ss);
+ }
+ } else if (pwSpec->master_secret) {
+ rv = ssl3_DeriveConnectionKeysPKCS11(ss);
+ if (rv == SECSuccess) {
+ rv = ssl3_InitPendingContextsPKCS11(ss);
+ }
+ } else {
+ PORT_Assert(pwSpec->master_secret);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ rv = SECFailure;
+ }
+
+done:
+ ssl_ReleaseSpecWriteLock(ss); /******************************/
+ if (rv != SECSuccess)
+ ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
+ return rv;
+}
+
/*
* 60 bytes is 3 times the maximum length MAC size that is supported.
*/
@@ -1547,29 +1508,21 @@ static const unsigned char mac_pad_2 [60] = {
static SECStatus
ssl3_ComputeRecordMAC(
ssl3CipherSpec * spec,
- PK11Context * mac_context,
+ PRBool useServerMacKey,
SSL3ContentType type,
SSL3ProtocolVersion version,
SSL3SequenceNumber seq_num,
- SSL3Opaque * input,
+ const SSL3Opaque * input,
int inputLength,
unsigned char * outbuf,
unsigned int * outLength)
{
const ssl3MACDef * mac_def;
SECStatus rv;
+ PRBool isTLS;
unsigned int tempLen;
unsigned char temp[MAX_MAC_LENGTH];
-/* ssl_GetSpecReadLock(ss); Don't have "ss"! */
-
- mac_def = spec->mac_def;
- if (mac_def->mac == mac_null) {
- *outLength = 0;
-/* ssl_ReleaseSpecReadLock(ss); */
- return SECSuccess;
- }
-
temp[0] = (unsigned char)(seq_num.high >> 24);
temp[1] = (unsigned char)(seq_num.high >> 16);
temp[2] = (unsigned char)(seq_num.high >> 8);
@@ -1581,7 +1534,7 @@ ssl3_ComputeRecordMAC(
temp[8] = type;
/* TLS MAC includes the record's version field, SSL's doesn't.
- ** We decide which MAC defintion to use based on the version of
+ ** We decide which MAC defintiion to use based on the version of
** the protocol that was negotiated when the spec became current,
** NOT based on the version value in the record itself.
** But, we use the record'v version value in the computation.
@@ -1590,6 +1543,7 @@ ssl3_ComputeRecordMAC(
temp[9] = MSB(inputLength);
temp[10] = LSB(inputLength);
tempLen = 11;
+ isTLS = PR_FALSE;
} else {
/* New TLS hash includes version. */
temp[9] = MSB(version);
@@ -1597,20 +1551,112 @@ ssl3_ComputeRecordMAC(
temp[11] = MSB(inputLength);
temp[12] = LSB(inputLength);
tempLen = 13;
+ isTLS = PR_TRUE;
}
PRINT_BUF(95, (NULL, "frag hash1: temp", temp, tempLen));
PRINT_BUF(95, (NULL, "frag hash1: input", input, inputLength));
- rv = PK11_DigestBegin(mac_context);
- rv |= PK11_DigestOp(mac_context, temp, tempLen);
- rv |= PK11_DigestOp(mac_context, input, inputLength);
+ mac_def = spec->mac_def;
+ if (mac_def->mac == mac_null) {
+ *outLength = 0;
+ return SECSuccess;
+ }
+ if (! spec->bypassCiphers) {
+ PK11Context *mac_context =
+ (useServerMacKey ? spec->server.write_mac_context
+ : spec->client.write_mac_context);
+ rv = PK11_DigestBegin(mac_context);
+ rv |= PK11_DigestOp(mac_context, temp, tempLen);
+ rv |= PK11_DigestOp(mac_context, input, inputLength);
+ rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size);
+ } else {
+ /* bypass version */
+ const SECHashObject *hashObj = NULL;
+ unsigned int pad_bytes;
+ PRUint64 write_mac_context[MAX_MAC_CONTEXT_LLONGS];
+
+ switch (mac_def->mac) {
+ case ssl_mac_null:
+ *outLength = 0;
+ return SECSuccess;
+ case ssl_mac_md5:
+ pad_bytes = 48;
+ hashObj = HASH_GetRawHashObject(HASH_AlgMD5);
+ break;
+ case ssl_mac_sha:
+ pad_bytes = 40;
+ hashObj = HASH_GetRawHashObject(HASH_AlgSHA1);
+ break;
+ case ssl_hmac_md5: /* used with TLS */
+ hashObj = HASH_GetRawHashObject(HASH_AlgMD5);
+ break;
+ case ssl_hmac_sha: /* used with TLS */
+ hashObj = HASH_GetRawHashObject(HASH_AlgSHA1);
+ break;
+ default:
+ break;
+ }
+ if (!hashObj) {
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ if (!isTLS) {
+ /* compute "inner" part of SSL3 MAC */
+ hashObj->begin(write_mac_context);
+ if (useServerMacKey)
+ hashObj->update(write_mac_context,
+ spec->server.write_mac_key_item.data,
+ spec->server.write_mac_key_item.len);
+ else
+ hashObj->update(write_mac_context,
+ spec->client.write_mac_key_item.data,
+ spec->client.write_mac_key_item.len);
+ hashObj->update(write_mac_context, mac_pad_1, pad_bytes);
+ hashObj->update(write_mac_context, temp, tempLen);
+ hashObj->update(write_mac_context, input, inputLength);
+ hashObj->end(write_mac_context, temp, &tempLen, sizeof temp);
+
+ /* compute "outer" part of SSL3 MAC */
+ hashObj->begin(write_mac_context);
+ if (useServerMacKey)
+ hashObj->update(write_mac_context,
+ spec->server.write_mac_key_item.data,
+ spec->server.write_mac_key_item.len);
+ else
+ hashObj->update(write_mac_context,
+ spec->client.write_mac_key_item.data,
+ spec->client.write_mac_key_item.len);
+ hashObj->update(write_mac_context, mac_pad_2, pad_bytes);
+ hashObj->update(write_mac_context, temp, tempLen);
+ hashObj->end(write_mac_context, outbuf, outLength, spec->mac_size);
+ rv = SECSuccess;
+ } else { /* is TLS */
+#define cx ((HMACContext *)write_mac_context)
+ if (useServerMacKey) {
+ rv = HMAC_Init(cx, hashObj,
+ spec->server.write_mac_key_item.data,
+ spec->server.write_mac_key_item.len, PR_FALSE);
+ } else {
+ rv = HMAC_Init(cx, hashObj,
+ spec->client.write_mac_key_item.data,
+ spec->client.write_mac_key_item.len, PR_FALSE);
+ }
+ if (rv == SECSuccess) {
+ HMAC_Begin(cx);
+ HMAC_Update(cx, temp, tempLen);
+ HMAC_Update(cx, input, inputLength);
+ rv = HMAC_Finish(cx, outbuf, outLength, spec->mac_size);
+ HMAC_Destroy(cx, PR_FALSE);
+ }
+#undef cx
+ }
+ }
- rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size);
PORT_Assert(rv != SECSuccess || *outLength == (unsigned)spec->mac_size);
-/* ssl_ReleaseSpecReadLock(ss); */
-
PRINT_BUF(95, (NULL, "frag hash2: result", outbuf, *outLength));
if (rv != SECSuccess) {
@@ -1667,23 +1713,20 @@ ssl3_SendRecord( sslSocket * ss,
SECStatus rv;
PRUint32 bufSize = 0;
PRInt32 sent = 0;
- PRInt32 cipherBytes = -1;
PRBool isBlocking = ssl_SocketIsBlocking(ss);
- PRBool ssl3WasNull = PR_FALSE;
SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s bytes=%d",
SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
bytes));
PRINT_BUF(3, (ss, "Send record (plain text)", buf, bytes));
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
- if (ss->ssl3 == NULL) {
+ if (ss->ssl3.initialized == PR_FALSE) {
/* This can happen on a server if the very first incoming record
** looks like a defective ssl3 record (e.g. too long), and we're
** trying to send an alert.
*/
- ssl3WasNull = PR_TRUE;
PR_ASSERT(type == content_alert);
rv = ssl3_InitState(ss);
if (rv != SECSuccess) {
@@ -1702,6 +1745,8 @@ ssl3_SendRecord( sslSocket * ss,
PRUint32 contentLen;
PRUint32 fragLen;
PRUint32 macLen;
+ PRInt32 cipherBytes = 0;
+ PRUint32 p1Len, p2Len, oddLen = 0;
contentLen = PR_MIN(bytes, MAX_FRAGMENT_LENGTH);
if (write->space < contentLen + SSL3_BUFFER_FUDGE) {
@@ -1713,39 +1758,34 @@ ssl3_SendRecord( sslSocket * ss,
}
}
- /* This variable records
- * the actual size of the buffer we allocated above. Some
- * algorithms (FORTEZZA) will expand the number of bytes it needs to
- * send data. If we only supply the output buffer with the same number
+ /* This variable records the actual size of the buffer allocated above.
+ * Some algorithms may expand the number of bytes needed to send data.
+ * If we only supply the output buffer with the same number
* of bytes as the input buffer, we will fail.
*/
bufSize = contentLen + SSL3_BUFFER_FUDGE;
/*
* null compression is easy to do
- */
PORT_Memcpy(write->buf + SSL3_RECORD_HEADER_LENGTH, buf, contentLen);
- buf += contentLen;
- bytes -= contentLen;
- PORT_Assert( bytes >= 0 );
+ */
ssl_GetSpecReadLock(ss); /********************************/
- cwSpec = ss->ssl3->cwSpec;
+ cwSpec = ss->ssl3.cwSpec;
cipher_def = cwSpec->cipher_def;
/*
* Add the MAC
*/
- rv = ssl3_ComputeRecordMAC(
- cwSpec, (ss->sec.isServer) ? cwSpec->server.write_mac_context
- : cwSpec->client.write_mac_context,
- type, cwSpec->version, cwSpec->write_seq_num,
- write->buf + SSL3_RECORD_HEADER_LENGTH, contentLen,
+ rv = ssl3_ComputeRecordMAC( cwSpec, (PRBool)(ss->sec.isServer),
+ type, cwSpec->version, cwSpec->write_seq_num, buf, contentLen,
write->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
goto spec_locked_loser;
}
+ p1Len = contentLen;
+ p2Len = macLen;
fragLen = contentLen + macLen; /* needs to be encrypted */
PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024);
@@ -1754,10 +1794,11 @@ ssl3_SendRecord( sslSocket * ss,
* then Encrypt it
*/
if (cipher_def->type == type_block) {
+ unsigned char * pBuf;
int padding_length;
int i;
- unsigned char * pBuf;
+ oddLen = contentLen % cipher_def->block_size;
/* Assume blockSize is a power of two */
padding_length = cipher_def->block_size - 1 -
((fragLen) & (cipher_def->block_size - 1));
@@ -1769,11 +1810,49 @@ ssl3_SendRecord( sslSocket * ss,
for (i = padding_length + 1; i > 0; --i) {
*pBuf-- = padding_length;
}
+ /* now, if contentLen is not a multiple of block size, fix it */
+ p2Len = fragLen - p1Len;
+ }
+ if (p1Len < 256) {
+ oddLen = p1Len;
+ p1Len = 0;
+ } else {
+ p1Len -= oddLen;
+ }
+ if (oddLen) {
+ p2Len += oddLen;
+ PORT_Assert( (cipher_def->block_size < 2) || \
+ (p2Len % cipher_def->block_size) == 0);
+ memcpy(write->buf + SSL3_RECORD_HEADER_LENGTH + p1Len,
+ buf + p1Len, oddLen);
+ }
+ if (p1Len > 0) {
+ rv = cwSpec->encode( cwSpec->encodeContext,
+ write->buf + SSL3_RECORD_HEADER_LENGTH, /* output */
+ &cipherBytes, /* actual outlen */
+ p1Len, /* max outlen */
+ buf, p1Len); /* input, and inputlen */
+ PORT_Assert(rv == SECSuccess && cipherBytes == p1Len);
+ if (rv != SECSuccess || cipherBytes != p1Len) {
+ PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
+ goto spec_locked_loser;
+ }
}
- rv = cwSpec->encode(
- cwSpec->encodeContext, write->buf + SSL3_RECORD_HEADER_LENGTH,
- &cipherBytes, bufSize, write->buf + SSL3_RECORD_HEADER_LENGTH,
- fragLen);
+ if (p2Len > 0) {
+ PRInt32 cipherBytesPart2 = -1;
+ rv = cwSpec->encode( cwSpec->encodeContext,
+ write->buf + SSL3_RECORD_HEADER_LENGTH + p1Len,
+ &cipherBytesPart2, /* output and actual outLen */
+ p2Len, /* max outlen */
+ write->buf + SSL3_RECORD_HEADER_LENGTH + p1Len,
+ p2Len); /* input and inputLen*/
+ PORT_Assert(rv == SECSuccess && cipherBytesPart2 == p2Len);
+ if (rv != SECSuccess || cipherBytesPart2 != p2Len) {
+ PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
+ goto spec_locked_loser;
+ }
+ cipherBytes += cipherBytesPart2;
+ }
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_ENCRYPTION_FAILURE);
spec_locked_loser:
@@ -1791,6 +1870,10 @@ spec_locked_loser:
ssl_ReleaseSpecReadLock(ss); /************************************/
+ buf += contentLen;
+ bytes -= contentLen;
+ PORT_Assert( bytes >= 0 );
+
/* PORT_Assert(fragLen == cipherBytes); */
write->len = cipherBytes + SSL3_RECORD_HEADER_LENGTH;
write->buf[0] = type;
@@ -1870,7 +1953,7 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
{
PRInt32 sent = 0;
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
while (len > 0) {
PRInt32 count;
@@ -1914,8 +1997,8 @@ ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags)
{
PRInt32 rv;
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
return SECSuccess;
@@ -1946,7 +2029,7 @@ ssl3_HandleNoCertificate(sslSocket *ss)
CERT_DestroyCertificate(ss->sec.peerCert);
ss->sec.peerCert = NULL;
}
- ssl3_CleanupPeerCerts(ss->ssl3);
+ ssl3_CleanupPeerCerts(ss);
/* If the server has required client-auth blindly but doesn't
* actually look at the certificate it won't know that no
@@ -1955,9 +2038,9 @@ ssl3_HandleNoCertificate(sslSocket *ss)
* first handshake because if we're redoing the handshake we
* know the server is paying attention to the certificate.
*/
- if ((ss->requireCertificate == SSL_REQUIRE_ALWAYS) ||
+ if ((ss->opt.requireCertificate == SSL_REQUIRE_ALWAYS) ||
(!ss->firstHsDone &&
- (ss->requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE))) {
+ (ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE))) {
PRFileDesc * lower;
ss->sec.uncache(ss->sec.ci.sid);
@@ -1994,7 +2077,6 @@ ssl3_HandleNoCertificate(sslSocket *ss)
** ssl3_HandleClientHello <-
** ssl3_HandleV2ClientHello <-
** ssl3_HandleCertificateVerify <-
-** ssl3_HandleFortezzaClientKeyExchange <-
** ssl3_HandleClientKeyExchange <-
** ssl3_HandleCertificate <-
** ssl3_HandleFinished <-
@@ -2042,7 +2124,7 @@ ssl3_IllegalParameter(sslSocket *ss)
{
PRBool isTLS;
- isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
+ isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT
: SSL_ERROR_BAD_SERVER );
@@ -2085,8 +2167,8 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
SSL3AlertDescription desc;
int error;
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
SSL_TRC(3, ("%d: SSL3[%d]: handle alert record", SSL_GETPID(), ss->fd));
@@ -2140,7 +2222,7 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
}
if (level == alert_fatal) {
ss->sec.uncache(ss->sec.ci.sid);
- if ((ss->ssl3->hs.ws == wait_server_hello) &&
+ if ((ss->ssl3.hs.ws == wait_server_hello) &&
(desc == handshake_failure)) {
/* XXX This is a hack. We're assuming that any handshake failure
* XXX on the client hello is a failure to match ciphers.
@@ -2150,12 +2232,12 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
PORT_SetError(error);
return SECFailure;
}
- if ((desc == no_certificate) && (ss->ssl3->hs.ws == wait_client_cert)) {
+ if ((desc == no_certificate) && (ss->ssl3.hs.ws == wait_client_cert)) {
/* I'm a server. I've requested a client cert. He hasn't got one. */
SECStatus rv;
PORT_Assert(ss->sec.isServer);
- ss->ssl3->hs.ws = wait_client_key;
+ ss->ssl3.hs.ws = wait_client_key;
rv = ssl3_HandleNoCertificate(ss);
return rv;
}
@@ -2176,7 +2258,6 @@ static SECStatus
ssl3_SendChangeCipherSpecs(sslSocket *ss)
{
uint8 change = change_cipher_spec_choice;
- ssl3State * ssl3 = ss->ssl3;
ssl3CipherSpec * pwSpec;
SECStatus rv;
PRInt32 sent;
@@ -2184,8 +2265,8 @@ ssl3_SendChangeCipherSpecs(sslSocket *ss)
SSL_TRC(3, ("%d: SSL3[%d]: send change_cipher_spec record",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
if (rv != SECSuccess) {
@@ -2199,12 +2280,12 @@ ssl3_SendChangeCipherSpecs(sslSocket *ss)
/* swap the pending and current write specs. */
ssl_GetSpecWriteLock(ss); /**************************************/
- pwSpec = ss->ssl3->pwSpec;
+ pwSpec = ss->ssl3.pwSpec;
pwSpec->write_seq_num.high = 0;
pwSpec->write_seq_num.low = 0;
- ssl3->pwSpec = ssl3->cwSpec;
- ssl3->cwSpec = pwSpec;
+ ss->ssl3.pwSpec = ss->ssl3.cwSpec;
+ ss->ssl3.cwSpec = pwSpec;
SSL_TRC(3, ("%d: SSL3[%d] Set Current Write Cipher Suite to Pending",
SSL_GETPID(), ss->fd ));
@@ -2213,8 +2294,8 @@ ssl3_SendChangeCipherSpecs(sslSocket *ss)
/* If we are really through with the old cipher spec
* (Both the read and write sides have changed) destroy it.
*/
- if (ss->ssl3->prSpec == ss->ssl3->pwSpec) {
- ssl3_DestroyCipherSpec(ss->ssl3->pwSpec);
+ if (ss->ssl3.prSpec == ss->ssl3.pwSpec) {
+ ssl3_DestroyCipherSpec(ss->ssl3.pwSpec);
}
ssl_ReleaseSpecWriteLock(ss); /**************************************/
@@ -2231,11 +2312,11 @@ static SECStatus
ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf)
{
ssl3CipherSpec * prSpec;
- SSL3WaitState ws = ss->ssl3->hs.ws;
+ SSL3WaitState ws = ss->ssl3.hs.ws;
SSL3ChangeCipherSpecChoice change;
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
SSL_TRC(3, ("%d: SSL3[%d]: handle change_cipher_spec record",
SSL_GETPID(), ss->fd));
@@ -2262,12 +2343,12 @@ ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf)
/* Swap the pending and current read specs. */
ssl_GetSpecWriteLock(ss); /*************************************/
- prSpec = ss->ssl3->prSpec;
+ prSpec = ss->ssl3.prSpec;
prSpec->read_seq_num.high = prSpec->read_seq_num.low = 0;
- ss->ssl3->prSpec = ss->ssl3->crSpec;
- ss->ssl3->crSpec = prSpec;
- ss->ssl3->hs.ws = wait_finished;
+ ss->ssl3.prSpec = ss->ssl3.crSpec;
+ ss->ssl3.crSpec = prSpec;
+ ss->ssl3.hs.ws = wait_finished;
SSL_TRC(3, ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending",
SSL_GETPID(), ss->fd ));
@@ -2275,65 +2356,45 @@ ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf)
/* If we are really through with the old cipher prSpec
* (Both the read and write sides have changed) destroy it.
*/
- if (ss->ssl3->prSpec == ss->ssl3->pwSpec) {
- ssl3_DestroyCipherSpec(ss->ssl3->prSpec);
+ if (ss->ssl3.prSpec == ss->ssl3.pwSpec) {
+ ssl3_DestroyCipherSpec(ss->ssl3.prSpec);
}
ssl_ReleaseSpecWriteLock(ss); /*************************************/
return SECSuccess;
}
-/*
- * Key generation given pre master secret, or master secret (if !pms).
- * Sets a useful error code when returning SECFailure.
- *
- * Called only from ssl3_InitPendingCipherSpec(),
- *
- * which in turn is called from
- * ssl3_SendClientKeyExchange (for Full handshake)
- * ssl3_HandleClientKeyExchange (for Full handshake)
- * ssl3_HandleServerHello (for session restart)
- * ssl3_HandleClientHello (for session restart)
- * Caller MUST hold the specWriteLock, and SSL3HandshakeLock.
- * ssl3_InitPendingCipherSpec does that.
- */
+/* This method uses PKCS11 to derive the MS from the PMS, where PMS
+** is a PKCS11 symkey. This is used in all cases except the
+** "triple bypass" with RSA key exchange.
+** Called from ssl3_InitPendingCipherSpec. prSpec is pwSpec.
+*/
static SECStatus
-ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms)
+ssl3_DeriveMasterSecret(sslSocket *ss, const PK11SymKey *pms)
{
- ssl3CipherSpec * pwSpec = ss->ssl3->pwSpec;
- const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def;
- const ssl3KEADef * kea_def = ss->ssl3->hs.kea_def;
- unsigned char * cr = (unsigned char *)&ss->ssl3->hs.client_random;
- unsigned char * sr = (unsigned char *)&ss->ssl3->hs.server_random;
- PK11SymKey * symKey = NULL;
- PK11SlotInfo * slot = NULL;
- void * pwArg = ss->pkcs11PinArg;
+ ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec;
+ const ssl3KEADef *kea_def= ss->ssl3.hs.kea_def;
+ unsigned char * cr = (unsigned char *)&ss->ssl3.hs.client_random;
+ unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random;
PRBool isTLS = (PRBool)(kea_def->tls_keygen ||
(pwSpec->version > SSL_LIBRARY_VERSION_3_0));
- PRBool skipKeysAndIVs = (PRBool)
- ((cipher_def->calg == calg_fortezza) ||
- (cipher_def->calg == calg_null));
/*
* Whenever isDH is true, we need to use CKM_TLS_MASTER_KEY_DERIVE_DH
* which, unlike CKM_TLS_MASTER_KEY_DERIVE, converts arbitrary size
* data into a 48-byte value.
*/
- PRBool isDH = (PRBool) ((ss->ssl3->hs.kea_def->exchKeyType == kt_dh) ||
- (ss->ssl3->hs.kea_def->exchKeyType == kt_ecdh));
+ PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) ||
+ (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh));
+ SECStatus rv = SECFailure;
CK_MECHANISM_TYPE master_derive;
CK_MECHANISM_TYPE key_derive;
- CK_MECHANISM_TYPE bulk_mechanism;
SECItem params;
- int keySize;
CK_FLAGS keyFlags;
CK_VERSION pms_version;
- CK_SSL3_KEY_MAT_PARAMS key_material_params;
- CK_SSL3_KEY_MAT_OUT returnedKeys;
CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params;
- SSLCipherAlgorithm calg;
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ssl_HaveSpecWriteLock(ss));
- PORT_Assert(ss->ssl3->prSpec == ss->ssl3->pwSpec);
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
+ PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
if (isTLS) {
if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH;
else master_derive = CKM_TLS_MASTER_KEY_DERIVE;
@@ -2361,7 +2422,7 @@ ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms)
pwSpec->master_secret = PK11_DeriveWithFlags((PK11SymKey *)pms,
master_derive, &params, key_derive,
CKA_DERIVE, 0, keyFlags);
- if (!isDH && pwSpec->master_secret && ss->detectRollBack) {
+ if (!isDH && pwSpec->master_secret && ss->opt.detectRollBack) {
SSL3ProtocolVersion client_version;
client_version = pms_version.major << 8 | pms_version.minor;
if (client_version != ss->clientHelloVersion) {
@@ -2405,9 +2466,81 @@ ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms)
}
if (pwSpec->master_secret == NULL) {
ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
- return SECFailure;
+ return rv;
}
+ if (ss->opt.bypassPKCS11) {
+ SECItem * keydata;
+ /* In hope of doing a "double bypass",
+ * need to extract the master secret's value from the key object
+ * and store it raw in the sslSocket struct.
+ */
+ rv = PK11_ExtractKeyValue(pwSpec->master_secret);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ /* This returns the address of the secItem inside the key struct,
+ * not a copy or a reference. So, there's no need to free it.
+ */
+ keydata = PK11_GetKeyData(pwSpec->master_secret);
+ if (keydata && keydata->len <= sizeof pwSpec->raw_master_secret) {
+ memcpy(pwSpec->raw_master_secret, keydata->data, keydata->len);
+ pwSpec->msItem.data = pwSpec->raw_master_secret;
+ pwSpec->msItem.len = keydata->len;
+ } else {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+ }
+ return SECSuccess;
+}
+
+/*
+ * Derive encryption and MAC Keys (and IVs) from master secret
+ * Sets a useful error code when returning SECFailure.
+ *
+ * Called only from ssl3_InitPendingCipherSpec(),
+ * which in turn is called from
+ * sendRSAClientKeyExchange (for Full handshake)
+ * sendDHClientKeyExchange (for Full handshake)
+ * ssl3_HandleClientKeyExchange (for Full handshake)
+ * ssl3_HandleServerHello (for session restart)
+ * ssl3_HandleClientHello (for session restart)
+ * Caller MUST hold the specWriteLock, and SSL3HandshakeLock.
+ * ssl3_InitPendingCipherSpec does that.
+ *
+ */
+static SECStatus
+ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss)
+{
+ ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec;
+ const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
+ unsigned char * cr = (unsigned char *)&ss->ssl3.hs.client_random;
+ unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random;
+ PRBool isTLS = (PRBool)(kea_def->tls_keygen ||
+ (pwSpec->version > SSL_LIBRARY_VERSION_3_0));
+ /* following variables used in PKCS11 path */
+ const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def;
+ PK11SlotInfo * slot = NULL;
+ PK11SymKey * symKey = NULL;
+ void * pwArg = ss->pkcs11PinArg;
+ int keySize;
+ CK_SSL3_KEY_MAT_PARAMS key_material_params;
+ CK_SSL3_KEY_MAT_OUT returnedKeys;
+ CK_MECHANISM_TYPE key_derive;
+ CK_MECHANISM_TYPE bulk_mechanism;
+ SSLCipherAlgorithm calg;
+ SECItem params;
+ PRBool skipKeysAndIVs = (PRBool)(cipher_def->calg == calg_null);
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
+ PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
+
+ if (!pwSpec->master_secret) {
+ PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
+ return SECFailure;
+ }
/*
* generate the key material
*/
@@ -2443,6 +2576,12 @@ ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms)
params.data = (unsigned char *)&key_material_params;
params.len = sizeof(key_material_params);
+ if (isTLS) {
+ key_derive = CKM_TLS_KEY_AND_MAC_DERIVE;
+ } else {
+ key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE;
+ }
+
/* CKM_SSL3_KEY_AND_MAC_DERIVE is defined to set ENCRYPT, DECRYPT, and
* DERIVE by DEFAULT */
symKey = PK11_Derive(pwSpec->master_secret, key_derive, &params,
@@ -2506,19 +2645,23 @@ loser:
static SECStatus
ssl3_UpdateHandshakeHashes(sslSocket *ss, unsigned char *b, unsigned int l)
{
- ssl3State *ssl3 = ss->ssl3;
- SECStatus rv;
+ SECStatus rv = SECSuccess;
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
PRINT_BUF(90, (NULL, "MD5 & SHA handshake hash input:", b, l));
- rv = PK11_DigestOp(ssl3->hs.md5, b, l);
+ if (ss->opt.bypassPKCS11) {
+ MD5_Update((MD5Context *)ss->ssl3.hs.md5_cx, b, l);
+ SHA1_Update((SHA1Context *)ss->ssl3.hs.sha_cx, b, l);
+ return rv;
+ }
+ rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
return rv;
}
- rv = PK11_DigestOp(ssl3->hs.sha, b, l);
+ rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
return rv;
@@ -2531,14 +2674,14 @@ ssl3_UpdateHandshakeHashes(sslSocket *ss, unsigned char *b, unsigned int l)
* All these functions set appropriate error codes.
* Most rely on ssl3_AppendHandshake to set the error code.
**************************************************************************/
-static SECStatus
+SECStatus
ssl3_AppendHandshake(sslSocket *ss, const void *void_src, PRInt32 bytes)
{
unsigned char * src = (unsigned char *)void_src;
int room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len;
SECStatus rv;
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) ); /* protects sendBuf. */
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); /* protects sendBuf. */
if (ss->sec.ci.sendBuf.space < MAX_SEND_BUF_LENGTH && room < bytes) {
rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, PR_MAX(MIN_SEND_BUF_LENGTH,
@@ -2594,7 +2737,7 @@ ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, PRInt32 lenSize)
return rv; /* error code set by AppendHandshake, if applicable. */
}
-static SECStatus
+SECStatus
ssl3_AppendHandshakeVariable(
sslSocket *ss, const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize)
{
@@ -2614,7 +2757,7 @@ ssl3_AppendHandshakeVariable(
return rv; /* error code set by AppendHandshake, if applicable. */
}
-static SECStatus
+SECStatus
ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length)
{
SECStatus rv;
@@ -2622,9 +2765,9 @@ ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length)
SSL_TRC(30,("%d: SSL3[%d]: append handshake header: type %s",
SSL_GETPID(), ss->fd, ssl3_DecodeHandshakeType(t)));
PRINT_BUF(60, (ss, "MD5 handshake hash:",
- (unsigned char*)ss->ssl3->hs.md5, MD5_LENGTH));
+ (unsigned char*)ss->ssl3.hs.md5_cx, MD5_LENGTH));
PRINT_BUF(95, (ss, "SHA handshake hash:",
- (unsigned char*)ss->ssl3->hs.sha, SHA1_LENGTH));
+ (unsigned char*)ss->ssl3.hs.sha_cx, SHA1_LENGTH));
rv = ssl3_AppendHandshakeNumber(ss, t, 1);
if (rv != SECSuccess) {
@@ -2649,12 +2792,12 @@ ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length)
* and has set a generic error code. The caller should probably
* override the generic error code by setting another.
*/
-static SECStatus
+SECStatus
ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b,
PRUint32 *length)
{
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
if ((PRUint32)bytes > *length) {
return ssl3_DecodeError(ss);
@@ -2681,18 +2824,23 @@ static PRInt32
ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b,
PRUint32 *length)
{
- PRInt32 num = 0;
+ uint8 *buf = *b;
int i;
- SECStatus status;
- uint8 buf[4];
+ PRInt32 num = 0;
- status = ssl3_ConsumeHandshake(ss, buf, bytes, b, length);
- if (status != SECSuccess) {
- /* ssl3_DecodeError has already been called */
- return SECFailure;
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( bytes <= sizeof num);
+
+ if ((PRUint32)bytes > *length) {
+ return ssl3_DecodeError(ss);
}
+ PRINT_BUF(60, (ss, "consume bytes:", *b, bytes));
+
for (i = 0; i < bytes; i++)
num = (num << 8) + buf[i];
+ *b += bytes;
+ *length -= bytes;
return num;
}
@@ -2704,13 +2852,17 @@ ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b,
*
* Returns SECFailure (-1) on failure.
* On error, an alert has been sent, and a generic error code has been set.
+ *
+ * RADICAL CHANGE for NSS 3.11. All callers of this function make copies
+ * of the data returned in the SECItem *i, so making a copy of it here
+ * is simply wasteful. So, This function now just sets SECItem *i to
+ * point to the values in the buffer **b.
*/
-static SECStatus
+SECStatus
ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes,
SSL3Opaque **b, PRUint32 *length)
{
PRInt32 count;
- SECStatus rv;
PORT_Assert(bytes <= 3);
i->len = 0;
@@ -2720,21 +2872,13 @@ ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes,
return SECFailure;
}
if (count > 0) {
- i->data = (unsigned char*)PORT_Alloc(count);
- if (i->data == NULL) {
- /* XXX inconsistent. In other places, we don't send alerts for
- * our own memory failures. But here we do... */
- (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- i->len = count;
- rv = ssl3_ConsumeHandshake(ss, i->data, i->len, b, length);
- if (rv != SECSuccess) {
- PORT_Free(i->data);
- i->data = NULL;
- return rv; /* alert has already been sent. */
+ if ((PRUint32)count > *length) {
+ return ssl3_DecodeError(ss);
}
+ i->data = *b;
+ i->len = count;
+ *b += count;
+ *length -= count;
}
return SECSuccess;
}
@@ -2758,155 +2902,241 @@ ssl3_ComputeHandshakeHashes(sslSocket * ss,
SSL3Hashes * hashes, /* output goes here. */
uint32 sender)
{
- ssl3State * ssl3 = ss->ssl3;
- PK11Context * md5;
- PK11Context * sha = NULL;
SECStatus rv = SECSuccess;
+ PRBool isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0);
unsigned int outLength;
- PRBool isTLS;
SSL3Opaque md5_inner[MAX_MAC_LENGTH];
SSL3Opaque sha_inner[MAX_MAC_LENGTH];
- unsigned char s[4];
- unsigned char md5StackBuf[256];
- unsigned char shaStackBuf[512];
- unsigned char *md5StateBuf = NULL;
- unsigned char *shaStateBuf = NULL;
- unsigned int md5StateLen, shaStateLen;
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0);
- if (!spec->master_secret) {
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
- return SECFailure;
- }
-
- md5StateBuf = PK11_SaveContextAlloc(ssl3->hs.md5, md5StackBuf,
- sizeof md5StackBuf, &md5StateLen);
- if (md5StateBuf == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- goto loser;
- }
- md5 = ssl3->hs.md5;
- shaStateBuf = PK11_SaveContextAlloc(ssl3->hs.sha, shaStackBuf,
- sizeof shaStackBuf, &shaStateLen);
- if (shaStateBuf == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- goto loser;
- }
- sha = ssl3->hs.sha;
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- if (!isTLS) {
- /* compute hashes for SSL3. */
+ if (ss->opt.bypassPKCS11) {
+ /* compute them without PKCS11 */
+ PRUint64 md5_cx[MAX_MAC_CONTEXT_LLONGS];
+ PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS];
- s[0] = (unsigned char)(sender >> 24);
- s[1] = (unsigned char)(sender >> 16);
- s[2] = (unsigned char)(sender >> 8);
- s[3] = (unsigned char)sender;
+#define md5cx ((MD5Context *)md5_cx)
+#define shacx ((SHA1Context *)sha_cx)
- if (sender != 0) {
- rv |= PK11_DigestOp(md5, s, 4);
- PRINT_BUF(95, (NULL, "MD5 inner: sender", s, 4));
+ if (!spec->msItem.data) {
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
+ return SECFailure;
}
- PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1, mac_defs[mac_md5].pad_size));
+ MD5_Clone (md5cx, (MD5Context *)ss->ssl3.hs.md5_cx);
+ SHA1_Clone(shacx, (SHA1Context *)ss->ssl3.hs.sha_cx);
- rv |= PK11_DigestKey(md5,spec->master_secret);
- rv |= PK11_DigestOp(md5, mac_pad_1, mac_defs[mac_md5].pad_size);
- rv |= PK11_DigestFinal(md5, md5_inner, &outLength, MD5_LENGTH);
- PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
+ if (!isTLS) {
+ /* compute hashes for SSL3. */
+ unsigned char s[4];
+
+ s[0] = (unsigned char)(sender >> 24);
+ s[1] = (unsigned char)(sender >> 16);
+ s[2] = (unsigned char)(sender >> 8);
+ s[3] = (unsigned char)sender;
+
+ if (sender != 0) {
+ MD5_Update(md5cx, s, 4);
+ PRINT_BUF(95, (NULL, "MD5 inner: sender", s, 4));
+ }
+
+ PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1,
+ mac_defs[mac_md5].pad_size));
+
+ MD5_Update(md5cx, spec->msItem.data, spec->msItem.len);
+ MD5_Update(md5cx, mac_pad_1, mac_defs[mac_md5].pad_size);
+ MD5_End(md5cx, md5_inner, &outLength, MD5_LENGTH);
+
+ PRINT_BUF(95, (NULL, "MD5 inner: result", md5_inner, outLength));
+
+ if (sender != 0) {
+ SHA1_Update(shacx, s, 4);
+ PRINT_BUF(95, (NULL, "SHA inner: sender", s, 4));
+ }
+
+ PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1,
+ mac_defs[mac_sha].pad_size));
+
+ SHA1_Update(shacx, spec->msItem.data, spec->msItem.len);
+ SHA1_Update(shacx, mac_pad_1, mac_defs[mac_sha].pad_size);
+ SHA1_End(shacx, sha_inner, &outLength, SHA1_LENGTH);
+
+ PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength));
+ PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2,
+ mac_defs[mac_md5].pad_size));
+ PRINT_BUF(95, (NULL, "MD5 outer: MD5 inner", md5_inner, MD5_LENGTH));
+
+ MD5_Begin(md5cx);
+ MD5_Update(md5cx, spec->msItem.data, spec->msItem.len);
+ MD5_Update(md5cx, mac_pad_2, mac_defs[mac_md5].pad_size);
+ MD5_Update(md5cx, md5_inner, MD5_LENGTH);
}
+ MD5_End(md5cx, hashes->md5, &outLength, MD5_LENGTH);
- PRINT_BUF(95, (NULL, "MD5 inner: result", md5_inner, outLength));
+ PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->md5, MD5_LENGTH));
- if (sender != 0) {
- rv |= PK11_DigestOp(sha, s, 4);
- PRINT_BUF(95, (NULL, "SHA inner: sender", s, 4));
+ if (!isTLS) {
+ PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2,
+ mac_defs[mac_sha].pad_size));
+ PRINT_BUF(95, (NULL, "SHA outer: SHA inner", sha_inner, SHA1_LENGTH));
+
+ SHA1_Begin(shacx);
+ SHA1_Update(shacx, spec->msItem.data, spec->msItem.len);
+ SHA1_Update(shacx, mac_pad_2, mac_defs[mac_sha].pad_size);
+ SHA1_Update(shacx, sha_inner, SHA1_LENGTH);
}
+ SHA1_End(shacx, hashes->sha, &outLength, SHA1_LENGTH);
- PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1, mac_defs[mac_sha].pad_size));
+ PRINT_BUF(60, (NULL, "SHA outer: result", hashes->sha, SHA1_LENGTH));
+ rv = SECSuccess;
+#undef md5cx
+#undef shacx
+ } else {
+ /* compute hases with PKCS11 */
+ PK11Context * md5;
+ PK11Context * sha = NULL;
+ unsigned char *md5StateBuf = NULL;
+ unsigned char *shaStateBuf = NULL;
+ unsigned int md5StateLen, shaStateLen;
+ unsigned char md5StackBuf[256];
+ unsigned char shaStackBuf[512];
+
+ if (!spec->master_secret) {
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
+ return SECFailure;
+ }
- rv |= PK11_DigestKey(sha, spec->master_secret);
- rv |= PK11_DigestOp(sha, mac_pad_1, mac_defs[mac_sha].pad_size);
- rv |= PK11_DigestFinal(sha, sha_inner, &outLength, SHA1_LENGTH);
- PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH);
- if (rv != SECSuccess) {
+ md5StateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.md5, md5StackBuf,
+ sizeof md5StackBuf, &md5StateLen);
+ if (md5StateBuf == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+ goto loser;
+ }
+ md5 = ss->ssl3.hs.md5;
+
+ shaStateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.sha, shaStackBuf,
+ sizeof shaStackBuf, &shaStateLen);
+ if (shaStateBuf == NULL) {
ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
goto loser;
}
+ sha = ss->ssl3.hs.sha;
- PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength));
+ if (!isTLS) {
+ /* compute hashes for SSL3. */
+ unsigned char s[4];
- PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2, mac_defs[mac_md5].pad_size));
- PRINT_BUF(95, (NULL, "MD5 outer: MD5 inner", md5_inner, MD5_LENGTH));
+ s[0] = (unsigned char)(sender >> 24);
+ s[1] = (unsigned char)(sender >> 16);
+ s[2] = (unsigned char)(sender >> 8);
+ s[3] = (unsigned char)sender;
- rv |= PK11_DigestBegin(md5);
- rv |= PK11_DigestKey(md5, spec->master_secret);
- rv |= PK11_DigestOp(md5, mac_pad_2, mac_defs[mac_md5].pad_size);
- rv |= PK11_DigestOp(md5, md5_inner, MD5_LENGTH);
- }
- rv |= PK11_DigestFinal(md5, hashes->md5, &outLength, MD5_LENGTH);
- PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
- }
+ if (sender != 0) {
+ rv |= PK11_DigestOp(md5, s, 4);
+ PRINT_BUF(95, (NULL, "MD5 inner: sender", s, 4));
+ }
- PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->md5, MD5_LENGTH));
+ PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1,
+ mac_defs[mac_md5].pad_size));
- if (!isTLS) {
- PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2, mac_defs[mac_sha].pad_size));
- PRINT_BUF(95, (NULL, "SHA outer: SHA inner", sha_inner, SHA1_LENGTH));
+ rv |= PK11_DigestKey(md5,spec->master_secret);
+ rv |= PK11_DigestOp(md5, mac_pad_1, mac_defs[mac_md5].pad_size);
+ rv |= PK11_DigestFinal(md5, md5_inner, &outLength, MD5_LENGTH);
+ PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+ rv = SECFailure;
+ goto loser;
+ }
- rv |= PK11_DigestBegin(sha);
- rv |= PK11_DigestKey(sha,spec->master_secret);
- rv |= PK11_DigestOp(sha, mac_pad_2, mac_defs[mac_sha].pad_size);
- rv |= PK11_DigestOp(sha, sha_inner, SHA1_LENGTH);
- }
- rv |= PK11_DigestFinal(sha, hashes->sha, &outLength, SHA1_LENGTH);
- PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
- }
+ PRINT_BUF(95, (NULL, "MD5 inner: result", md5_inner, outLength));
- PRINT_BUF(60, (NULL, "SHA outer: result", hashes->sha, SHA1_LENGTH));
+ if (sender != 0) {
+ rv |= PK11_DigestOp(sha, s, 4);
+ PRINT_BUF(95, (NULL, "SHA inner: sender", s, 4));
+ }
- rv = SECSuccess;
+ PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1,
+ mac_defs[mac_sha].pad_size));
-loser:
- if (md5StateBuf) {
- if (PK11_RestoreContext(ssl3->hs.md5, md5StateBuf, md5StateLen)
- != SECSuccess)
- {
+ rv |= PK11_DigestKey(sha, spec->master_secret);
+ rv |= PK11_DigestOp(sha, mac_pad_1, mac_defs[mac_sha].pad_size);
+ rv |= PK11_DigestFinal(sha, sha_inner, &outLength, SHA1_LENGTH);
+ PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ rv = SECFailure;
+ goto loser;
+ }
+
+ PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength));
+
+ PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2,
+ mac_defs[mac_md5].pad_size));
+ PRINT_BUF(95, (NULL, "MD5 outer: MD5 inner", md5_inner, MD5_LENGTH));
+
+ rv |= PK11_DigestBegin(md5);
+ rv |= PK11_DigestKey(md5, spec->master_secret);
+ rv |= PK11_DigestOp(md5, mac_pad_2, mac_defs[mac_md5].pad_size);
+ rv |= PK11_DigestOp(md5, md5_inner, MD5_LENGTH);
+ }
+ rv |= PK11_DigestFinal(md5, hashes->md5, &outLength, MD5_LENGTH);
+ PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH);
+ if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
rv = SECFailure;
+ goto loser;
}
- if (md5StateBuf != md5StackBuf) {
- PORT_ZFree(md5StateBuf, md5StateLen);
+
+ PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->md5, MD5_LENGTH));
+
+ if (!isTLS) {
+ PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2,
+ mac_defs[mac_sha].pad_size));
+ PRINT_BUF(95, (NULL, "SHA outer: SHA inner", sha_inner, SHA1_LENGTH));
+
+ rv |= PK11_DigestBegin(sha);
+ rv |= PK11_DigestKey(sha,spec->master_secret);
+ rv |= PK11_DigestOp(sha, mac_pad_2, mac_defs[mac_sha].pad_size);
+ rv |= PK11_DigestOp(sha, sha_inner, SHA1_LENGTH);
}
- }
- if (shaStateBuf) {
- if (PK11_RestoreContext(ssl3->hs.sha, shaStateBuf, shaStateLen)
- != SECSuccess)
- {
+ rv |= PK11_DigestFinal(sha, hashes->sha, &outLength, SHA1_LENGTH);
+ PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH);
+ if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
rv = SECFailure;
+ goto loser;
+ }
+
+ PRINT_BUF(60, (NULL, "SHA outer: result", hashes->sha, SHA1_LENGTH));
+
+ rv = SECSuccess;
+
+ loser:
+ if (md5StateBuf) {
+ if (PK11_RestoreContext(ss->ssl3.hs.md5, md5StateBuf, md5StateLen)
+ != SECSuccess)
+ {
+ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+ rv = SECFailure;
+ }
+ if (md5StateBuf != md5StackBuf) {
+ PORT_ZFree(md5StateBuf, md5StateLen);
+ }
}
- if (shaStateBuf != shaStackBuf) {
- PORT_ZFree(shaStateBuf, shaStateLen);
+ if (shaStateBuf) {
+ if (PK11_RestoreContext(ss->ssl3.hs.sha, shaStateBuf, shaStateLen)
+ != SECSuccess)
+ {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ rv = SECFailure;
+ }
+ if (shaStateBuf != shaStackBuf) {
+ PORT_ZFree(shaStateBuf, shaStateLen);
+ }
}
}
-
return rv;
}
@@ -2928,9 +3158,9 @@ ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length)
goto done; /* ssl3_InitState has set the error code. */
}
- PORT_Memset(&ss->ssl3->hs.client_random, 0, SSL3_RANDOM_LENGTH);
+ PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
PORT_Memcpy(
- &ss->ssl3->hs.client_random.rand[SSL3_RANDOM_LENGTH - SSL_CHALLENGE_BYTES],
+ &ss->ssl3.hs.client_random.rand[SSL3_RANDOM_LENGTH - SSL_CHALLENGE_BYTES],
&ss->sec.ci.clientChallenge,
SSL_CHALLENGE_BYTES);
@@ -2966,8 +3196,8 @@ ssl3_SendClientHello(sslSocket *ss)
SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(),
ss->fd));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
rv = ssl3_InitState(ss);
if (rv != SECSuccess) {
@@ -2976,59 +3206,60 @@ ssl3_SendClientHello(sslSocket *ss)
SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",
SSL_GETPID(), ss->fd ));
- rv = PK11_DigestBegin(ss->ssl3->hs.md5);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- return rv;
- }
- rv = PK11_DigestBegin(ss->ssl3->hs.sha);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return rv;
+ if (ss->opt.bypassPKCS11) {
+ MD5_Begin((MD5Context *)ss->ssl3.hs.md5_cx);
+ SHA1_Begin((SHA1Context *)ss->ssl3.hs.sha_cx);
+ } else {
+ rv = PK11_DigestBegin(ss->ssl3.hs.md5);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+ return rv;
+ }
+ rv = PK11_DigestBegin(ss->ssl3.hs.sha);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ return rv;
+ }
}
-
/* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup
* handles expired entries and other details.
* XXX If we've been called from ssl2_BeginClientHandshake, then
* this lookup is duplicative and wasteful.
*/
- sid = (ss->noCache) ? NULL
+ sid = (ss->opt.noCache) ? NULL
: ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->url);
/* We can't resume based on a different token. If the sid exists,
* make sure the token that holds the master secret still exists ...
* If we previously did client-auth, make sure that the token that holds
* the private key still exists, is logged in, hasn't been removed, etc.
- * Also for fortezza, make sure that the card that holds the session keys
- * exist as well... */
+ */
if (sid) {
- PK11SlotInfo *slot;
PRBool sidOK = PR_TRUE;
- slot = (!sid->u.ssl3.masterValid) ? NULL :
- SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
- sid->u.ssl3.masterSlotID);
- if (slot == NULL) {
- sidOK = PR_FALSE;
- } else {
- PK11SymKey *wrapKey = NULL;
- if (!PK11_IsPresent(slot) ||
- ((wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex,
- sid->u.ssl3.masterWrapMech,
- sid->u.ssl3.masterWrapSeries,
- ss->pkcs11PinArg)) == NULL) ) {
- sidOK = PR_FALSE;
+ if (sid->u.ssl3.keys.msIsWrapped) {
+ /* Session key was wrapped, which means it was using PKCS11, */
+ PK11SlotInfo *slot = NULL;
+ if (sid->u.ssl3.masterValid && !ss->opt.bypassPKCS11) {
+ slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
+ sid->u.ssl3.masterSlotID);
+ }
+ if (slot == NULL) {
+ sidOK = PR_FALSE;
+ } else {
+ PK11SymKey *wrapKey = NULL;
+ if (!PK11_IsPresent(slot) ||
+ ((wrapKey = PK11_GetWrapKey(slot,
+ sid->u.ssl3.masterWrapIndex,
+ sid->u.ssl3.masterWrapMech,
+ sid->u.ssl3.masterWrapSeries,
+ ss->pkcs11PinArg)) == NULL) ) {
+ sidOK = PR_FALSE;
+ }
+ if (wrapKey) PK11_FreeSymKey(wrapKey);
+ PK11_FreeSlot(slot);
+ slot = NULL;
}
- if (wrapKey) PK11_FreeSymKey(wrapKey);
- PK11_FreeSlot(slot);
- slot = NULL;
- }
- /* do sid-has-FORTEZZA-slot check */
- if (sid->u.ssl3.hasFortezza) {
- /* do has fortezza check */
- if (!PK11_VerifyKeyOK(sid->u.ssl3.tek))
- sidOK = PR_FALSE;
}
-
/* If we previously did client-auth, make sure that the token that
** holds the private key still exists, is logged in, hasn't been
** removed, etc.
@@ -3055,7 +3286,7 @@ ssl3_SendClientHello(sslSocket *ss)
PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,
sid->u.ssl3.sessionIDLength));
- ss->ssl3->policy = sid->u.ssl3.policy;
+ ss->ssl3.policy = sid->u.ssl3.policy;
} else {
++ssl3stats.sch_sid_cache_misses;
@@ -3070,7 +3301,7 @@ ssl3_SendClientHello(sslSocket *ss)
}
ssl_GetSpecWriteLock(ss);
- cwSpec = ss->ssl3->cwSpec;
+ cwSpec = ss->ssl3.cwSpec;
if (cwSpec->mac_def->mac == mac_null) {
/* SSL records are not being MACed. */
cwSpec->version = ss->version;
@@ -3085,8 +3316,8 @@ ssl3_SendClientHello(sslSocket *ss)
ss->sec.send = ssl3_SendApplicationData;
/* shouldn't get here if SSL3 is disabled, but ... */
- PORT_Assert(ss->enableSSL3 || ss->enableTLS);
- if (!ss->enableSSL3 && !ss->enableTLS) {
+ PORT_Assert(ss->opt.enableSSL3 || ss->opt.enableTLS);
+ if (!ss->opt.enableSSL3 && !ss->opt.enableTLS) {
PORT_SetError(SSL_ERROR_SSL_DISABLED);
return SECFailure;
}
@@ -3097,7 +3328,7 @@ ssl3_SendClientHello(sslSocket *ss)
return SECFailure; /* ssl3_config_match_init has set error code. */
/* how many suites are permitted by policy and user preference? */
- num_suites = count_cipher_suites(ss, ss->ssl3->policy, PR_TRUE);
+ num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE);
if (!num_suites)
return SECFailure; /* count_cipher_suites has set error code. */
@@ -3116,11 +3347,11 @@ ssl3_SendClientHello(sslSocket *ss)
if (rv != SECSuccess) {
return rv; /* err set by ssl3_AppendHandshake* */
}
- rv = ssl3_GetNewRandom(&ss->ssl3->hs.client_random);
+ rv = ssl3_GetNewRandom(&ss->ssl3.hs.client_random);
if (rv != SECSuccess) {
return rv; /* err set by GetNewRandom. */
}
- rv = ssl3_AppendHandshake(ss, &ss->ssl3->hs.client_random,
+ rv = ssl3_AppendHandshake(ss, &ss->ssl3.hs.client_random,
SSL3_RANDOM_LENGTH);
if (rv != SECSuccess) {
return rv; /* err set by ssl3_AppendHandshake* */
@@ -3143,7 +3374,7 @@ ssl3_SendClientHello(sslSocket *ss)
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
- if (config_match(suite, ss->ssl3->policy, PR_TRUE)) {
+ if (config_match(suite, ss->ssl3.policy, PR_TRUE)) {
actual_count++;
if (actual_count > num_suites) {
/* set error card removal/insertion error */
@@ -3183,7 +3414,7 @@ ssl3_SendClientHello(sslSocket *ss)
return rv; /* error code set by ssl3_FlushHandshake */
}
- ss->ssl3->hs.ws = wait_server_hello;
+ ss->ssl3.hs.ws = wait_server_hello;
return rv;
}
@@ -3201,13 +3432,12 @@ ssl3_HandleHelloRequest(sslSocket *ss)
SSL_TRC(3, ("%d: SSL3[%d]: handle hello_request handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert(ss->ssl3);
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- if (ss->ssl3->hs.ws == wait_server_hello)
+ if (ss->ssl3.hs.ws == wait_server_hello)
return SECSuccess;
- if (ss->ssl3->hs.ws != idle_handshake || ss->sec.isServer) {
+ if (ss->ssl3.hs.ws != idle_handshake || ss->sec.isServer) {
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST);
return SECFailure;
@@ -3279,35 +3509,6 @@ ssl_UnwrapSymWrappingKey(
PORT_Assert(wrappedKey.len <= sizeof pWswk->wrappedSymmetricWrappingkey);
switch (exchKeyType) {
- PK11SymKey * Ks;
- PK11SlotInfo * slot;
- SECItem param;
-
- case kt_fortezza:
- /* get the slot that the fortezza server private key is in. */
- slot = PK11_GetSlotFromPrivateKey(svrPrivKey);
- if (slot == NULL) {
- SET_ERROR_CODE
- goto loser;
- }
-
- /* Look up the Token Fixed Key */
- Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_CBC64, NULL, pwArg);
- PK11_FreeSlot(slot);
- if (Ks == NULL) {
- SET_ERROR_CODE
- goto loser;
- }
-
- /* unwrap client write key with the local Ks and IV */
- param.type = siBuffer;
- param.data = pWswk->wrapIV;
- param.len = pWswk->wrapIVLen;
- unwrappedWrappingKey =
- PK11_UnwrapSymKey(Ks, CKM_SKIPJACK_CBC64, &param, &wrappedKey,
- masterWrapMech, CKA_UNWRAP, 0);
- PK11_FreeSymKey(Ks);
- break;
case kt_rsa:
unwrappedWrappingKey =
@@ -3391,7 +3592,7 @@ getWrappingKey( sslSocket * ss,
SECItem wrappedKey;
SSLWrappedSymWrappingKey wswk;
- svrPrivKey = ss->serverCerts[exchKeyType].serverKey;
+ svrPrivKey = ss->serverCerts[exchKeyType].SERVERKEY;
PORT_Assert(svrPrivKey != NULL);
if (!svrPrivKey) {
return NULL; /* why are we here?!? */
@@ -3466,36 +3667,6 @@ getWrappingKey( sslSocket * ss,
/* wrap symmetric wrapping key in server's public key. */
switch (exchKeyType) {
- PK11SymKey * Ks;
- PK11SlotInfo * fSlot;
- SECItem param;
-
- case kt_fortezza:
- /* get the slot that the fortezza server private key is in. */
- fSlot = PK11_GetSlotFromPrivateKey(svrPrivKey);
- if (fSlot == NULL) {
- SET_ERROR_CODE
- goto loser;
- }
-
- /* Look up the Token Fixed Key */
- Ks = PK11_FindFixedKey(fSlot, CKM_SKIPJACK_CBC64, NULL, pwArg);
- PK11_FreeSlot(fSlot);
- if (Ks == NULL) {
- SET_ERROR_CODE
- goto loser;
- }
-
- /* wrap symmetricWrapping key with the local Ks */
- param.type = siBuffer;
- param.data = wswk.wrapIV;
- param.len = sizeof wswk.wrapIV;
- rv = PK11_WrapSymKey(CKM_SKIPJACK_CBC64, &param, Ks,
- unwrappedWrappingKey, &wrappedKey);
- wswk.wrapIVLen = param.len;
- PK11_FreeSymKey(Ks);
- asymWrapMechanism = CKM_SKIPJACK_CBC64;
- break;
case kt_rsa:
asymWrapMechanism = CKM_RSA_PKCS;
@@ -3554,21 +3725,8 @@ done:
}
-static SECStatus
-ssl3_FortezzaAppendHandshake(sslSocket *ss, unsigned char * data, int len)
-{
- SSL3FortezzaKeys *fortezza_CKE = NULL;
- SECStatus rv = SECFailure;
-
- rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
- (sizeof(*fortezza_CKE)-sizeof(fortezza_CKE->y_c)) + 1 + len);
- if (rv == SECSuccess) {
- rv = ssl3_AppendHandshakeVariable(ss, data, len, 1);
- }
- return rv; /* err set by ssl3_AppendHandshake* */
-}
-
/* Called from ssl3_SendClientKeyExchange(). */
+/* Presently, this always uses PKCS11. There is no bypass for this. */
static SECStatus
sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
{
@@ -3577,14 +3735,14 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
SECItem enc_pms = {siBuffer, NULL, 0};
PRBool isTLS;
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ssl_HaveXmitBufLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
/* Generate the pre-master secret ... */
ssl_GetSpecWriteLock(ss);
- isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
+ isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- pms = ssl3_GenerateRSAPMS(ss, ss->ssl3->pwSpec, NULL);
+ pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.pwSpec, NULL);
ssl_ReleaseSpecWriteLock(ss);
if (pms == NULL) {
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
@@ -3640,6 +3798,7 @@ loser:
}
/* Called from ssl3_SendClientKeyExchange(). */
+/* Presently, this always uses PKCS11. There is no bypass for this. */
static SECStatus
sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
{
@@ -3652,10 +3811,10 @@ sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
SECKEYPublicKey *pubKey = NULL; /* Ephemeral DH key */
SECKEYPrivateKey *privKey = NULL; /* Ephemeral DH key */
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ssl_HaveXmitBufLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
+ isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
/* Copy DH parameters from server key */
@@ -3725,522 +3884,9 @@ loser:
return rv;
}
-#ifdef NSS_ENABLE_ECC
-/* Called from ssl3_SendClientKeyExchange(). */
-static SECStatus
-sendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
-{
- PK11SymKey * pms = NULL;
- SECStatus rv = SECFailure;
- PRBool isTLS;
- CK_MECHANISM_TYPE target;
- SECKEYPublicKey *pubKey = NULL; /* Ephemeral ECDH key */
- SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH key */
- CK_EC_KDF_TYPE kdf;
-
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ssl_HaveXmitBufLock(ss));
-
- isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- /* Generate ephemeral EC keypair */
- privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams,
- &pubKey, NULL);
- if (!privKey || !pubKey) {
- ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
- rv = SECFailure;
- goto loser;
- }
- PRINT_BUF(50, (ss, "ECDH public value:",
- pubKey->u.ec.publicValue.data,
- pubKey->u.ec.publicValue.len));
-
- if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
- else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
-
- /* If field size is not more than 24 octets, then use SHA-1 hash of result;
- * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt).
- */
- if ((pubKey->u.ec.publicValue.len - 1) / 2 <= 24) {
- kdf = CKD_SHA1_KDF;
- } else {
- kdf = CKD_NULL;
- }
-
- /* Determine the PMS */
- pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL,
- CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
- kdf, NULL, NULL);
-
- if (pms == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- SECKEY_DestroyPrivateKey(privKey);
- privKey = NULL;
-
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms); pms = NULL;
-
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
- pubKey->u.ec.publicValue.len + 1);
- if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
- }
-
- rv = ssl3_AppendHandshakeVariable(ss,
- pubKey->u.ec.publicValue.data,
- pubKey->u.ec.publicValue.len, 1);
- SECKEY_DestroyPublicKey(pubKey);
- pubKey = NULL;
-
- if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
- }
-
- rv = SECSuccess;
-
-loser:
- if(pms) PK11_FreeSymKey(pms);
- if(privKey) SECKEY_DestroyPrivateKey(privKey);
- if(pubKey) SECKEY_DestroyPublicKey(pubKey);
- return rv;
-}
-#endif /* NSS_ENABLE_ECC */
-
-/* fortezza client-auth portion of ClientKeyExchange message
- * This function appends the KEA public key from the client's V3 cert
- * (empty for a V1 cert) to the outgoing ClientKeyExchange message.
- * For a V3 cert, it also computes the Fortezza public key hash of that key
- * and signs that hash with the client's signing private key.
- * It also finds and returns the client's KEA private key.
- *
- * Called from sendFortezzaClientKeyExchange <- ssl3_SendClientKeyExchange()
- */
-static SECKEYPrivateKey *
-sendFortezzaCKXClientAuth(sslSocket *ss, SSL3FortezzaKeys * fortezza_CKE)
-{
- SECKEYPublicKey * pubKey = NULL;
- SECKEYPrivateKey * privKeaKey = NULL;
- CERTCertificate * peerCert = ss->sec.peerCert;
- void * pwArg = ss->pkcs11PinArg;
- SECStatus rv = SECFailure;
- SECItem sigItem;
- SECItem hashItem;
-
- /* extract our own local public key. */
- pubKey = CERT_ExtractPublicKey(ss->ssl3->clientCertificate);
- if (!pubKey) {
- ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- goto loser;
- }
-
- if (pubKey->keyType == fortezzaKey) {
- /* fortezza clientauth with fortezza V1 certificate */
- rv = ssl3_FortezzaAppendHandshake(ss, NULL, 0);
- if (rv != SECSuccess) {
- goto loser; /* err was set by AppendHandshake. */
- }
- privKeaKey = PK11_FindKeyByAnyCert(ss->ssl3->clientCertificate, pwArg);
- if (!privKeaKey) {
- ssl_MapLowLevelError(SEC_ERROR_NO_KEY);
- }
-
- } else {
- /* fortezza clientauth w/ V3 certificate or non fortezza cert*/
- CERTCertificate * ccert = NULL;
- SECKEYPublicKey * foundPubKey = NULL;
- unsigned char hash[SHA1_LENGTH];
- ccert = PK11_FindBestKEAMatch(peerCert, pwArg);
- if (ccert == NULL) {
- PORT_SetError(SSL_ERROR_FORTEZZA_PQG);
- goto v3_loser;
- }
- foundPubKey = CERT_ExtractPublicKey(ccert);
- if (foundPubKey == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- goto v3_loser;
- }
- if (foundPubKey->keyType == keaKey) {
- rv = ssl3_FortezzaAppendHandshake(ss,
- foundPubKey->u.kea.publicValue.data,
- foundPubKey->u.kea.publicValue.len);
- if (rv != SECSuccess) {
- goto v3_loser; /* err was set by AppendHandshake. */
- }
-
- rv = ssl3_ComputeFortezzaPublicKeyHash(
- foundPubKey->u.kea.publicValue, hash);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto v3_loser;
- }
- } else {
- rv = ssl3_FortezzaAppendHandshake(ss,
- foundPubKey->u.fortezza.KEAKey.data,
- foundPubKey->u.fortezza.KEAKey.len);
- if (rv != SECSuccess) {
- goto v3_loser; /* err was set by AppendHandshake. */
- }
-
- rv = ssl3_ComputeFortezzaPublicKeyHash(
- foundPubKey->u.fortezza.KEAKey, hash);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto v3_loser;
- }
- }
-
- hashItem.data = (unsigned char *) hash;
- hashItem.len = SHA1_LENGTH;
-
- sigItem.data = fortezza_CKE->y_signature;
- sigItem.len = sizeof fortezza_CKE->y_signature;
-
- rv = PK11_Sign(ss->ssl3->clientPrivateKey, &sigItem, &hashItem);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto v3_loser;
- }
-
- privKeaKey = PK11_FindKeyByAnyCert(ccert, pwArg);
- if (!privKeaKey) {
- ssl_MapLowLevelError(SEC_ERROR_NO_KEY);
- }
-
-v3_loser:
- if (foundPubKey)
- SECKEY_DestroyPublicKey(foundPubKey);
- if (ccert)
- CERT_DestroyCertificate(ccert);
- } /* fortezza clientauth w/ V3 certificate or non fortezza cert*/
-
-loser:
-
- if (pubKey)
- SECKEY_DestroyPublicKey(pubKey);
- return privKeaKey;
-} /* End of fortezza client-auth. */
-
-
-/* fortezza without client-auth */
-/* fortezza client-auth portion of ClientKeyExchange message
- * This function appends the public KEA key from the client's cert
- * to the outgoing ClientKeyExchange message.
- * It also finds and returns the client's KEA private key.
- *
- * Called from sendFortezzaClientKeyExchange <- ssl3_SendClientKeyExchange()
- */
-static SECKEYPrivateKey *
-sendFortezzaCKXNoClientAuth(sslSocket *ss)
-{
- SECKEYPublicKey * foundPubKey = NULL;
- SECKEYPrivateKey * privKeaKey = NULL;
- CERTCertificate * ccert = NULL;
- CERTCertificate * peerCert = ss->sec.peerCert;
- void * pwArg = ss->pkcs11PinArg;
- SECStatus rv = SECFailure;
-
- ccert = PK11_FindBestKEAMatch(peerCert, pwArg);
- if (ccert == NULL) {
- PORT_SetError(SSL_ERROR_FORTEZZA_PQG);
- goto loser;
- }
-
- foundPubKey = CERT_ExtractPublicKey(ccert);
- if (foundPubKey == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- goto loser;
- }
-
- if (foundPubKey->keyType == fortezzaKey) {
- /* fortezza V1 cert */
- rv = ssl3_FortezzaAppendHandshake(ss,
- foundPubKey->u.fortezza.KEAKey.data,
- foundPubKey->u.fortezza.KEAKey.len);
- if (rv != SECSuccess) {
- goto loser; /* err was set by AppendHandshake. */
- }
- privKeaKey = PK11_FindKeyByAnyCert(ccert, pwArg);
- if (!privKeaKey) {
- ssl_MapLowLevelError(SEC_ERROR_NO_KEY);
- }
- } else {
- /* fortezza V3 cert */
- rv = ssl3_FortezzaAppendHandshake(ss,
- foundPubKey->u.kea.publicValue.data,
- foundPubKey->u.kea.publicValue.len);
- if (rv != SECSuccess) {
- goto loser; /* err was set by AppendHandshake. */
- }
- privKeaKey = PK11_FindKeyByAnyCert(ccert, pwArg);
- if (!privKeaKey) {
- ssl_MapLowLevelError(SEC_ERROR_NO_KEY);
- }
- }
-
-loser:
- if (foundPubKey)
- SECKEY_DestroyPublicKey(foundPubKey);
- if (ccert)
- CERT_DestroyCertificate(ccert);
- return privKeaKey;
-}
-
-/* Called from ssl3_SendClientKeyExchange(). */
-static SECStatus
-sendFortezzaClientKeyExchange(sslSocket * ss, SECKEYPublicKey * serverKey)
-{
- ssl3CipherSpec * pwSpec = NULL;
- sslSessionID * sid = ss->sec.ci.sid;
- PK11SlotInfo * slot = NULL;
- PK11SymKey * pms = NULL;
- PK11SymKey * tek = NULL;
- PK11SymKey * client_write_key = NULL;
- PK11SymKey * server_write_key = NULL;
- SECKEYPrivateKey * privKeaKey = NULL;
- void * pwArg = ss->pkcs11PinArg;
- SECStatus rv = SECFailure;
- CK_VERSION version;
- SECItem param;
- SECItem raItem;
- SECItem rbItem;
- SECItem enc_pms;
- SECItem item;
- SSL3FortezzaKeys fortezza_CKE;
- PRBool releaseSpecWriteLock = PR_FALSE;
-
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- /* first get an appropriate slot for doing MACing.
- * Note: This slot will NOT be a Fortezza slot because Fortezza
- * cannot generate an SSL3 pre-master-secret.
- */
- slot = PK11_GetBestSlot(CKM_SSL3_PRE_MASTER_KEY_GEN, pwArg);
- if (slot == NULL) {
- PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND);
- goto loser;
- }
-
- /* create a pre-Master secret */
- version.major = MSB(ss->version);
- version.minor = LSB(ss->version);
-
- param.data = (unsigned char *)&version;
- param.len = sizeof version;
-
- pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN,
- &param, 0, pwArg);
- PK11_FreeSlot(slot);
- slot = NULL;
- if (pms == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- /* If we don't have a certificate, we need to read out your public key.
- * This changes a bit when we need to deal with the PQG stuff
- */
- PORT_Memset(fortezza_CKE.y_signature, 0, sizeof fortezza_CKE.y_signature);
-
- /* Send the KEA public key and get the KEA private key. */
- if (ss->ssl3->clientCertificate != NULL) {
- /* with client-auth */
- privKeaKey = sendFortezzaCKXClientAuth(ss, &fortezza_CKE);
- } else {
- /* without client-auth */
- privKeaKey = sendFortezzaCKXNoClientAuth(ss);
- }
- if (privKeaKey == NULL) {
- rv = SECFailure;
- goto loser; /* error was already set. */
- }
-
- /* Now we derive the TEK, and generate r_c the client's "random" public key.
- * r_c is generated and filled in by the PubDerive call below.
- */
- raItem.data = fortezza_CKE.r_c;
- raItem.len = sizeof fortezza_CKE.r_c;
-
- /* R_s == server's "random" public key, sent in the Server Key Exchange */
- rbItem.data = ss->ssl3->fortezza.R_s;
- rbItem.len = sizeof ss->ssl3->fortezza.R_s;
-
- tek = PK11_PubDerive(privKeaKey, serverKey, PR_TRUE, /* generate r_c */
- &raItem, &rbItem, CKM_KEA_KEY_DERIVE,
- CKM_SKIPJACK_WRAP, CKA_WRAP, 0, pwArg);
- SECKEY_DestroyPrivateKey(privKeaKey);
- privKeaKey = NULL;
- if (tek == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- ss->ssl3->fortezza.tek = PK11_ReferenceSymKey(tek); /* can't fail. */
-
- /* encrypt the pms with the TEK.
- * NB: PK11_WrapSymKey will generate and output the encrypted PMS
- * AND the IV for decrypting the PMS.
- */
- param.data = fortezza_CKE.master_secret_iv;
- param.len = sizeof fortezza_CKE.master_secret_iv;
-
- enc_pms.data = fortezza_CKE.encrypted_preMasterSecret;
- enc_pms.len = sizeof fortezza_CKE.encrypted_preMasterSecret;
-
- rv = PK11_WrapSymKey(CKM_SKIPJACK_CBC64, &param, tek, pms, &enc_pms);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
- rv = SECFailure; /* not there yet. */
-
- slot = PK11_GetSlotFromKey(tek);
-
- ssl_GetSpecWriteLock(ss); releaseSpecWriteLock = PR_TRUE;
-
- pwSpec = ss->ssl3->pwSpec;
- pwSpec->client.write_key = client_write_key =
- PK11_KeyGen(slot, CKM_SKIPJACK_CBC64, NULL, 0, pwArg);
- if (client_write_key == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
- /* the -1 is a hack. It's supposed to be key size, but we use it
- * to tell the wrapper that we're doing a weird PKCS #11 key gen.
- * Usually the result of key gen is an encrypt key. This is not
- * the case with SSL, where this key is a decrypt key.
- */
- pwSpec->server.write_key = server_write_key =
- PK11_KeyGen(slot, CKM_SKIPJACK_CBC64, NULL, -1, pwArg);
- if (server_write_key == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms); pms = NULL;
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- /* copy the keys and IVs out now */
- item.data = fortezza_CKE.wrapped_client_write_key;
- item.len = sizeof fortezza_CKE.wrapped_client_write_key;
- rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, client_write_key, &item);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- item.data = fortezza_CKE.wrapped_server_write_key;
- item.len = sizeof fortezza_CKE.wrapped_server_write_key;
- rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, server_write_key, &item);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- /* we only get the generated IV's if we're doing skipjack. */
- if (pwSpec->cipher_def->calg == calg_fortezza) {
- PORT_Memcpy(fortezza_CKE.client_write_iv, pwSpec->client.write_iv,
- sizeof fortezza_CKE.client_write_iv);
- PORT_Memcpy(fortezza_CKE.server_write_iv, pwSpec->server.write_iv,
- sizeof fortezza_CKE.server_write_iv);
- } else {
- /* generate IVs to make old servers happy */
- rv = PK11_GenerateFortezzaIV(client_write_key,
- fortezza_CKE.client_write_iv,
- sizeof fortezza_CKE.client_write_iv);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
- rv = PK11_GenerateFortezzaIV(server_write_key,
- fortezza_CKE.server_write_iv,
- sizeof fortezza_CKE.server_write_iv);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
- }
-
- /* NOTE: This technique of writing out the struct, rather than writing
- * out the individual members works only because all the rest of the
- * values are fixed-length strings of well-defined byte order.
- * Add one SECItem or one Number and we will need to break the elements out.
- */
- rv = ssl3_AppendHandshake(ss, &fortezza_CKE.r_c,
- (sizeof fortezza_CKE - sizeof fortezza_CKE.y_c));
- if (rv != SECSuccess) {
- goto loser; /* err was set by AppendHandshake. */
- }
-
- /* now we initialize our contexts */
- sid->u.ssl3.hasFortezza = PR_TRUE;
- sid->u.ssl3.tek = tek; tek = NULL; /* adopt.. */
-
- if (pwSpec->cipher_def->calg == calg_fortezza) {
- sid->u.ssl3.clientWriteKey =
- PK11_ReferenceSymKey(pwSpec->client.write_key);
- sid->u.ssl3.serverWriteKey=
- PK11_ReferenceSymKey(pwSpec->server.write_key);
-
- PORT_Memcpy(sid->u.ssl3.keys.client_write_iv,
- pwSpec->client.write_iv,
- sizeof sid->u.ssl3.keys.client_write_iv);
- PORT_Memcpy(sid->u.ssl3.keys.server_write_iv,
- pwSpec->server.write_iv,
- sizeof sid->u.ssl3.keys.server_write_iv);
-
- rv = PK11_SaveContext((PK11Context *)pwSpec->encodeContext,
- sid->u.ssl3.clientWriteSave,
- &sid->u.ssl3.clientWriteSaveLen,
- sizeof sid->u.ssl3.clientWriteSave);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
- } else {
- PK11_FreeSymKey(client_write_key);
- pwSpec->client.write_key = client_write_key = NULL;
-
- PK11_FreeSymKey(server_write_key);
- pwSpec->server.write_key = server_write_key = NULL;
-
- rv = SECSuccess;
- }
- /* FALL THROUGH */
-
-loser:
- if (tek) PK11_FreeSymKey(tek);
- if (slot) PK11_FreeSlot(slot);
- if (pms) PK11_FreeSymKey(pms);
- if (rv != SECSuccess) {
- if (client_write_key) {
- PK11_FreeSymKey(client_write_key);
- pwSpec->client.write_key = client_write_key = NULL;
- }
- if (server_write_key) {
- PK11_FreeSymKey(server_write_key);
- pwSpec->server.write_key = server_write_key = NULL;
- }
- }
- if (releaseSpecWriteLock)
- ssl_GetSpecWriteLock(ss);
- return rv;
-}
/* Called from ssl3_HandleServerHelloDone(). */
static SECStatus
@@ -4253,8 +3899,8 @@ ssl3_SendClientKeyExchange(sslSocket *ss)
SSL_TRC(3, ("%d: SSL3[%d]: send client_key_exchange handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
if (ss->sec.peerKey == NULL) {
serverKey = CERT_ExtractPublicKey(ss->sec.peerCert);
@@ -4267,12 +3913,12 @@ ssl3_SendClientKeyExchange(sslSocket *ss)
ss->sec.peerKey = NULL; /* we're done with it now */
}
- isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
+ isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
/* enforce limits on kea key sizes. */
- if (ss->ssl3->hs.kea_def->is_limited) {
+ if (ss->ssl3.hs.kea_def->is_limited) {
int keyLen = SECKEY_PublicKeyStrength(serverKey); /* bytes */
- if (keyLen * BPB > ss->ssl3->hs.kea_def->key_size_limit) {
+ if (keyLen * BPB > ss->ssl3.hs.kea_def->key_size_limit) {
if (isTLS)
(void)SSL3_SendAlert(ss, alert_fatal, export_restriction);
else
@@ -4282,25 +3928,21 @@ ssl3_SendClientKeyExchange(sslSocket *ss)
}
}
- ss->sec.keaType = ss->ssl3->hs.kea_def->exchKeyType;
+ ss->sec.keaType = ss->ssl3.hs.kea_def->exchKeyType;
ss->sec.keaKeyBits = SECKEY_PublicKeyStrengthInBits(serverKey);
- switch (ss->ssl3->hs.kea_def->exchKeyType) {
+ switch (ss->ssl3.hs.kea_def->exchKeyType) {
case kt_rsa:
rv = sendRSAClientKeyExchange(ss, serverKey);
break;
- case kt_fortezza:
- rv = sendFortezzaClientKeyExchange(ss, serverKey);
- break;
-
case kt_dh:
rv = sendDHClientKeyExchange(ss, serverKey);
break;
#ifdef NSS_ENABLE_ECC
case kt_ecdh:
- rv = sendECDHClientKeyExchange(ss, serverKey);
+ rv = ssl3_SendECDHClientKeyExchange(ss, serverKey);
break;
#endif /* NSS_ENABLE_ECC */
@@ -4324,27 +3966,26 @@ loser:
static SECStatus
ssl3_SendCertificateVerify(sslSocket *ss)
{
- ssl3State * ssl3 = ss->ssl3;
SECStatus rv = SECFailure;
PRBool isTLS;
SECItem buf = {siBuffer, NULL, 0};
SSL3Hashes hashes;
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
SSL_TRC(3, ("%d: SSL3[%d]: send certificate_verify handshake",
SSL_GETPID(), ss->fd));
ssl_GetSpecReadLock(ss);
- rv = ssl3_ComputeHandshakeHashes(ss, ssl3->pwSpec, &hashes, 0);
+ rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
ssl_ReleaseSpecReadLock(ss);
if (rv != SECSuccess) {
goto done; /* err code was set by ssl3_ComputeHandshakeHashes */
}
- isTLS = (PRBool)(ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- rv = ssl3_SignHashes(&hashes, ssl3->clientPrivateKey, &buf, isTLS);
+ isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
+ rv = ssl3_SignHashes(&hashes, ss->ssl3.clientPrivateKey, &buf, isTLS);
if (rv == SECSuccess) {
PK11SlotInfo * slot;
sslSessionID * sid = ss->sec.ci.sid;
@@ -4353,7 +3994,7 @@ ssl3_SendCertificateVerify(sslSocket *ss)
** Later, when doing an SSL restart handshake, verify this.
** These calls are mere accessors, and can't fail.
*/
- slot = PK11_GetSlotFromPrivateKey(ss->ssl3->clientPrivateKey);
+ slot = PK11_GetSlotFromPrivateKey(ss->ssl3.clientPrivateKey);
sid->u.ssl3.clAuthSeries = PK11_GetSlotSeries(slot);
sid->u.ssl3.clAuthSlotID = PK11_GetSlotID(slot);
sid->u.ssl3.clAuthModuleID = PK11_GetModuleID(slot);
@@ -4361,12 +4002,12 @@ ssl3_SendCertificateVerify(sslSocket *ss)
PK11_FreeSlot(slot);
}
/* If we're doing RSA key exchange, we're all done with the private key
- * here. Diffie-Hellman & Fortezza key exchanges need the client's
+ * here. Diffie-Hellman key exchanges need the client's
* private key for the key exchange.
*/
- if (ssl3->hs.kea_def->exchKeyType == kt_rsa) {
- SECKEY_DestroyPrivateKey(ssl3->clientPrivateKey);
- ssl3->clientPrivateKey = NULL;
+ if (ss->ssl3.hs.kea_def->exchKeyType == kt_rsa) {
+ SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
+ ss->ssl3.clientPrivateKey = NULL;
}
if (rv != SECSuccess) {
goto done; /* err code was set by ssl3_SignHashes */
@@ -4408,15 +4049,15 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
rv = ssl3_InitState(ss);
if (rv != SECSuccess) {
errCode = PORT_GetError(); /* ssl3_InitState has set the error code. */
goto alert_loser;
}
- if (ss->ssl3->hs.ws != wait_server_hello) {
+ if (ss->ssl3.hs.ws != wait_server_hello) {
errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO;
desc = unexpected_message;
goto alert_loser;
@@ -4432,20 +4073,22 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
** know SSL 3.x.
*/
if (MSB(version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
- desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version : handshake_failure;
+ desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version
+ : handshake_failure;
goto alert_loser;
}
rv = ssl3_NegotiateVersion(ss, version);
if (rv != SECSuccess) {
- desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version : handshake_failure;
+ desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version
+ : handshake_failure;
errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
goto alert_loser;
}
isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
rv = ssl3_ConsumeHandshake(
- ss, &ss->ssl3->hs.server_random, SSL3_RANDOM_LENGTH, &b, &length);
+ ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH, &b, &length);
if (rv != SECSuccess) {
goto loser; /* alert has been sent */
}
@@ -4469,7 +4112,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
if ((temp == suite->cipher_suite) &&
- (config_match(suite, ss->ssl3->policy, PR_TRUE))) {
+ (config_match(suite, ss->ssl3.policy, PR_TRUE))) {
suite_found = PR_TRUE;
break; /* success */
}
@@ -4479,10 +4122,10 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
goto alert_loser;
}
- ss->ssl3->hs.cipher_suite = (ssl3CipherSuite)temp;
- ss->ssl3->hs.suite_def = ssl_LookupCipherSuiteDef((ssl3CipherSuite)temp);
- PORT_Assert(ss->ssl3->hs.suite_def);
- if (!ss->ssl3->hs.suite_def) {
+ ss->ssl3.hs.cipher_suite = (ssl3CipherSuite)temp;
+ ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef((ssl3CipherSuite)temp);
+ PORT_Assert(ss->ssl3.hs.suite_def);
+ if (!ss->ssl3.hs.suite_def) {
PORT_SetError(errCode = SEC_ERROR_LIBRARY_FAILURE);
goto loser; /* we don't send alerts for our screw-ups. */
}
@@ -4504,18 +4147,20 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP;
goto alert_loser;
}
- ss->ssl3->hs.compression = (SSL3CompressionMethod)temp;
+ ss->ssl3.hs.compression = (SSL3CompressionMethod)temp;
+#ifdef DISALLOW_SERVER_HELLO_EXTENSIONS
if (length != 0) { /* malformed */
goto alert_loser;
}
+#endif
/* Any errors after this point are not "malformed" errors. */
desc = handshake_failure;
/* we need to call ssl3_SetupPendingCipherSpec here so we can check the
* key exchange algorithm. */
- rv = ssl3_SetupPendingCipherSpec(ss, ss->ssl3);
+ rv = ssl3_SetupPendingCipherSpec(ss);
if (rv != SECSuccess) {
goto alert_loser; /* error code is set. */
}
@@ -4531,96 +4176,105 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (sid_match &&
sid->version == ss->version &&
- sid->u.ssl3.cipherSuite == ss->ssl3->hs.cipher_suite) do {
- PK11SlotInfo *slot;
- PK11SymKey * wrapKey; /* wrapping key */
+ sid->u.ssl3.cipherSuite == ss->ssl3.hs.cipher_suite) do {
+ ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
+
SECItem wrappedMS; /* wrapped master secret. */
- CK_FLAGS keyFlags = 0;
- ss->sec.authAlgorithm = sid->authAlgorithm;
+ ss->sec.authAlgorithm = sid->authAlgorithm;
ss->sec.authKeyBits = sid->authKeyBits;
ss->sec.keaType = sid->keaType;
ss->sec.keaKeyBits = sid->keaKeyBits;
- slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
- sid->u.ssl3.masterSlotID);
- if (slot == NULL) {
- break; /* not considered an error. */
- }
- if (!PK11_IsPresent(slot)) {
+ /* 3 cases here:
+ * a) key is wrapped (implies using PKCS11)
+ * b) key is unwrapped, but we're still using PKCS11
+ * c) key is unwrapped, and we're bypassing PKCS11.
+ */
+ if (sid->u.ssl3.keys.msIsWrapped) {
+ PK11SlotInfo *slot;
+ PK11SymKey * wrapKey; /* wrapping key */
+ CK_FLAGS keyFlags = 0;
+
+ if (ss->opt.bypassPKCS11) {
+ /* we cannot restart a non-bypass session in a
+ ** bypass socket.
+ */
+ break;
+ }
+ /* unwrap master secret with PKCS11 */
+ slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
+ sid->u.ssl3.masterSlotID);
+ if (slot == NULL) {
+ break; /* not considered an error. */
+ }
+ if (!PK11_IsPresent(slot)) {
+ PK11_FreeSlot(slot);
+ break; /* not considered an error. */
+ }
+ wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex,
+ sid->u.ssl3.masterWrapMech,
+ sid->u.ssl3.masterWrapSeries,
+ ss->pkcs11PinArg);
PK11_FreeSlot(slot);
- break; /* not considered an error. */
- }
- wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex,
- sid->u.ssl3.masterWrapMech,
- sid->u.ssl3.masterWrapSeries,
- ss->pkcs11PinArg);
- PK11_FreeSlot(slot);
- if (wrapKey == NULL) {
- break; /* not considered an error. */
- }
+ if (wrapKey == NULL) {
+ break; /* not considered an error. */
+ }
- if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
- keyFlags = CKF_SIGN | CKF_VERIFY;
- }
+ if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
+ keyFlags = CKF_SIGN | CKF_VERIFY;
+ }
- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
- ss->ssl3->pwSpec->master_secret =
- PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
- NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
- CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
- errCode = PORT_GetError();
- PK11_FreeSymKey(wrapKey);
- if (ss->ssl3->pwSpec->master_secret == NULL) {
- break; /* errorCode set just after call to UnwrapSymKey. */
+ wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
+ wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
+ pwSpec->master_secret =
+ PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
+ NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
+ CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
+ errCode = PORT_GetError();
+ PK11_FreeSymKey(wrapKey);
+ if (pwSpec->master_secret == NULL) {
+ break; /* errorCode set just after call to UnwrapSymKey. */
+ }
+ } else if (ss->opt.bypassPKCS11) {
+ /* MS is not wrapped */
+ wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
+ wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
+ memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
+ pwSpec->msItem.data = pwSpec->raw_master_secret;
+ pwSpec->msItem.len = wrappedMS.len;
+ } else {
+ /* We CAN restart a bypass session in a non-bypass socket. */
+ /* need to import the raw master secret to session object */
+ PK11SlotInfo *slot = PK11_GetInternalSlot();
+ wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
+ wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
+ pwSpec->master_secret =
+ PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE,
+ PK11_OriginUnwrap, CKA_ENCRYPT,
+ &wrappedMS, NULL);
+ PK11_FreeSlot(slot);
+ if (pwSpec->master_secret == NULL) {
+ break;
+ }
}
/* Got a Match */
++ssl3stats.hsh_sid_cache_hits;
- ss->ssl3->hs.ws = wait_change_cipher;
- ss->ssl3->hs.isResuming = PR_TRUE;
+ ss->ssl3.hs.ws = wait_change_cipher;
+ ss->ssl3.hs.isResuming = PR_TRUE;
/* copy the peer cert from the SID */
if (sid->peerCert != NULL) {
ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
}
- /* reload the FORTEZZA key material. These keys aren't generated
- * by the master secret, but by the key exchange. We restart by
- * reusing these keys. */
- if (sid->u.ssl3.hasFortezza) {
- ss->ssl3->fortezza.tek = PK11_ReferenceSymKey(sid->u.ssl3.tek);
- }
- if (ss->ssl3->hs.suite_def->bulk_cipher_alg == cipher_fortezza) {
- ss->ssl3->pwSpec->client.write_key =
- PK11_ReferenceSymKey(sid->u.ssl3.clientWriteKey);
- ss->ssl3->pwSpec->server.write_key =
- PK11_ReferenceSymKey(sid->u.ssl3.serverWriteKey);
- /* add the tek later for pre-encrypted files */
- PORT_Memcpy(ss->ssl3->pwSpec->client.write_iv,
- sid->u.ssl3.keys.client_write_iv,
- sizeof sid->u.ssl3.keys.client_write_iv);
- PORT_Memcpy(ss->ssl3->pwSpec->server.write_iv,
- sid->u.ssl3.keys.server_write_iv,
- sizeof sid->u.ssl3.keys.server_write_iv);
- }
/* NULL value for PMS signifies re-use of the old MS */
rv = ssl3_InitPendingCipherSpec(ss, NULL);
if (rv != SECSuccess) {
- goto alert_loser; /* err code was set by ssl3_InitPendingCipherSpec */
- }
- if (ss->ssl3->hs.suite_def->bulk_cipher_alg == cipher_fortezza) {
- rv = PK11_RestoreContext(
- (PK11Context *)ss->ssl3->pwSpec->encodeContext,
- sid->u.ssl3.clientWriteSave,
- sid->u.ssl3.clientWriteSaveLen);
- if (rv != SECSuccess) {
- goto alert_loser; /* err is set. */
- }
+ goto alert_loser; /* err code was set */
}
- SECITEM_ZfreeItem(&sidBytes, PR_FALSE);
return SECSuccess;
} while (0);
@@ -4630,7 +4284,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
++ssl3stats.hsh_sid_cache_misses;
/* throw the old one away */
- sid->u.ssl3.resumable = PR_FALSE;
+ sid->u.ssl3.keys.resumable = PR_FALSE;
(*ss->sec.uncache)(sid);
ssl_FreeSID(sid);
@@ -4643,18 +4297,15 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
sid->version = ss->version;
sid->u.ssl3.sessionIDLength = sidBytes.len;
PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len);
- SECITEM_ZfreeItem(&sidBytes, PR_FALSE);
- ss->ssl3->hs.isResuming = PR_FALSE;
- ss->ssl3->hs.ws = wait_server_cert;
+ ss->ssl3.hs.isResuming = PR_FALSE;
+ ss->ssl3.hs.ws = wait_server_cert;
return SECSuccess;
alert_loser:
(void)SSL3_SendAlert(ss, alert_fatal, desc);
loser:
- if (sidBytes.data != NULL)
- SECITEM_ZfreeItem(&sidBytes, PR_FALSE);
errCode = ssl_MapLowLevelError(errCode);
return SECFailure;
}
@@ -4672,25 +4323,16 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECStatus rv;
int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
SSL3AlertDescription desc = illegal_parameter;
- SECItem modulus = {siBuffer, NULL, 0};
- SECItem exponent = {siBuffer, NULL, 0};
- SECItem signature = {siBuffer, NULL, 0};
- SECItem dh_p = {siBuffer, NULL, 0};
- SECItem dh_g = {siBuffer, NULL, 0};
- SECItem dh_Ys = {siBuffer, NULL, 0};
SSL3Hashes hashes;
-#ifdef NSS_ENABLE_ECC
- SECItem ec_params = {siBuffer, NULL, 0};
- SECItem ec_point = {siBuffer, NULL, 0};
-#endif /* NSS_ENABLE_ECC */
+ SECItem signature = {siBuffer, NULL, 0};
SSL_TRC(3, ("%d: SSL3[%d]: handle server_key_exchange handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- if (ss->ssl3->hs.ws != wait_server_key &&
- ss->ssl3->hs.ws != wait_server_cert) {
+ if (ss->ssl3.hs.ws != wait_server_key &&
+ ss->ssl3.hs.ws != wait_server_cert) {
errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
desc = unexpected_message;
goto alert_loser;
@@ -4701,11 +4343,14 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto alert_loser;
}
- isTLS = (PRBool)(ss->ssl3->prSpec->version > SSL_LIBRARY_VERSION_3_0);
+ isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
- switch (ss->ssl3->hs.kea_def->exchKeyType) {
+ switch (ss->ssl3.hs.kea_def->exchKeyType) {
+
+ case kt_rsa: {
+ SECItem modulus = {siBuffer, NULL, 0};
+ SECItem exponent = {siBuffer, NULL, 0};
- case kt_rsa:
rv = ssl3_ConsumeHandshakeVariable(ss, &modulus, 2, &b, &length);
if (rv != SECSuccess) {
goto loser; /* malformed. */
@@ -4732,8 +4377,9 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
* check to make sure the hash is signed by right guy
*/
rv = ssl3_ComputeExportRSAKeyHash(modulus, exponent,
- &ss->ssl3->hs.client_random,
- &ss->ssl3->hs.server_random, &hashes);
+ &ss->ssl3.hs.client_random,
+ &ss->ssl3.hs.server_random,
+ &hashes, ss->opt.bypassPKCS11);
if (rv != SECSuccess) {
errCode =
ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
@@ -4774,13 +4420,15 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto no_memory;
}
ss->sec.peerKey = peerKey;
- SECITEM_FreeItem(&modulus, PR_FALSE);
- SECITEM_FreeItem(&exponent, PR_FALSE);
- SECITEM_FreeItem(&signature, PR_FALSE);
- ss->ssl3->hs.ws = wait_cert_request;
+ ss->ssl3.hs.ws = wait_cert_request;
return SECSuccess;
+ }
+
+ case kt_dh: {
+ SECItem dh_p = {siBuffer, NULL, 0};
+ SECItem dh_g = {siBuffer, NULL, 0};
+ SECItem dh_Ys = {siBuffer, NULL, 0};
- case kt_dh:
rv = ssl3_ConsumeHandshakeVariable(ss, &dh_p, 2, &b, &length);
if (rv != SECSuccess) {
goto loser; /* malformed. */
@@ -4815,8 +4463,9 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
* check to make sure the hash is signed by right guy
*/
rv = ssl3_ComputeDHKeyHash(dh_p, dh_g, dh_Ys,
- &ss->ssl3->hs.client_random,
- &ss->ssl3->hs.server_random, &hashes);
+ &ss->ssl3.hs.client_random,
+ &ss->ssl3.hs.server_random,
+ &hashes, ss->opt.bypassPKCS11);
if (rv != SECSuccess) {
errCode =
ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
@@ -4858,142 +4507,16 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto no_memory;
}
ss->sec.peerKey = peerKey;
- SECITEM_FreeItem(&dh_p, PR_FALSE);
- SECITEM_FreeItem(&dh_g, PR_FALSE);
- SECITEM_FreeItem(&dh_Ys, PR_FALSE);
- ss->ssl3->hs.ws = wait_cert_request;
+ ss->ssl3.hs.ws = wait_cert_request;
return SECSuccess;
+ }
#ifdef NSS_ENABLE_ECC
case kt_ecdh:
- /* XXX This works only for named curves, revisit this when
- * we support generic curves.
- */
- ec_params.len = 2;
- ec_params.data = (unsigned char*)PORT_Alloc(ec_params.len);
- rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
-
- /* Fail if the curve is not a named curve */
- if ((ec_params.data[0] != ec_type_named) ||
- !supportedCurve(ec_params.data[1])) {
- errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
- desc = handshake_failure;
- goto alert_loser;
- }
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- /* Fail if the ec point uses compressed representation */
- if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
- errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM;
- desc = handshake_failure;
- goto alert_loser;
- }
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
-
- if (length != 0) {
- if (isTLS)
- desc = decode_error;
- goto alert_loser; /* malformed. */
- }
-
- PRINT_BUF(60, (NULL, "Server EC params", ec_params.data,
- ec_params.len));
- PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len));
-
- /* failures after this point are not malformed handshakes. */
- /* TLS: send decrypt_error if signature failed. */
- desc = isTLS ? decrypt_error : handshake_failure;
-
- /*
- * check to make sure the hash is signed by right guy
- */
- rv = ssl3_ComputeECDHKeyHash(ec_params, ec_point,
- &ss->ssl3->hs.client_random,
- &ss->ssl3->hs.server_random, &hashes);
-
- if (rv != SECSuccess) {
- errCode =
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto alert_loser;
- }
- rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
- isTLS, ss->pkcs11PinArg);
- if (rv != SECSuccess) {
- errCode =
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto alert_loser;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- goto no_memory;
- }
-
- ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
- if (peerKey == NULL) {
- goto no_memory;
- }
-
- peerKey->arena = arena;
- peerKey->keyType = ecKey;
-
- /* set up EC parameters in peerKey */
- if (ecName2params(arena, ec_params.data[1],
- &peerKey->u.ec.DEREncodedParams) != SECSuccess) {
- /* we should never get here since we already
- * checked that we are dealing with a supported curve
- */
- errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
- goto alert_loser;
- }
-
- /* copy publicValue in peerKey */
- if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue, &ec_point))
- {
- PORT_FreeArena(arena, PR_FALSE);
- goto no_memory;
- }
- peerKey->pkcs11Slot = NULL;
- peerKey->pkcs11ID = CK_INVALID_HANDLE;
-
- ss->sec.peerKey = peerKey;
- SECITEM_FreeItem(&ec_params, PR_FALSE);
- SECITEM_FreeItem(&ec_point, PR_FALSE);
- ss->ssl3->hs.ws = wait_cert_request;
-
- return SECSuccess;
+ rv = ssl3_HandleECDHServerKeyExchange(ss, b, length);
+ return rv;
#endif /* NSS_ENABLE_ECC */
- case kt_fortezza:
-
- /* Fortezza needs *BOTH* a server cert message
- * and a server key exchange message.
- */
- if (ss->ssl3->hs.ws == wait_server_cert) {
- errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
- desc = unexpected_message;
- goto alert_loser;
- }
- /* Get the server's "random" public key. */
- rv = ssl3_ConsumeHandshake(ss, ss->ssl3->fortezza.R_s,
- sizeof ss->ssl3->fortezza.R_s, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed */
- }
-
- ss->ssl3->hs.ws = wait_cert_request;
- return SECSuccess;
-
default:
desc = handshake_failure;
errCode = SEC_ERROR_UNSUPPORTED_KEYALG;
@@ -5003,30 +4526,10 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
alert_loser:
(void)SSL3_SendAlert(ss, alert_fatal, desc);
loser:
- if (modulus.data != NULL) SECITEM_FreeItem(&modulus, PR_FALSE);
- if (exponent.data != NULL) SECITEM_FreeItem(&exponent, PR_FALSE);
- if (signature.data != NULL) SECITEM_FreeItem(&signature, PR_FALSE);
- if (dh_p.data != NULL) SECITEM_FreeItem(&dh_p, PR_FALSE);
- if (dh_g.data != NULL) SECITEM_FreeItem(&dh_g, PR_FALSE);
- if (dh_Ys.data != NULL) SECITEM_FreeItem(&dh_Ys, PR_FALSE);
-#ifdef NSS_ENABLE_ECC
- if (ec_params.data != NULL) SECITEM_FreeItem(&ec_params, PR_FALSE);
- if (ec_point.data != NULL) SECITEM_FreeItem(&ec_point, PR_FALSE);
-#endif /* NSS_ENABLE_ECC */
PORT_SetError( errCode );
return SECFailure;
no_memory: /* no-memory error has already been set. */
- if (modulus.data != NULL) SECITEM_FreeItem(&modulus, PR_FALSE);
- if (exponent.data != NULL) SECITEM_FreeItem(&exponent, PR_FALSE);
- if (signature.data != NULL) SECITEM_FreeItem(&signature, PR_FALSE);
- if (dh_p.data != NULL) SECITEM_FreeItem(&dh_p, PR_FALSE);
- if (dh_g.data != NULL) SECITEM_FreeItem(&dh_g, PR_FALSE);
- if (dh_Ys.data != NULL) SECITEM_FreeItem(&dh_Ys, PR_FALSE);
-#ifdef NSS_ENABLE_ECC
- if (ec_params.data != NULL) SECITEM_FreeItem(&ec_params, PR_FALSE);
- if (ec_point.data != NULL) SECITEM_FreeItem(&ec_point, PR_FALSE);
-#endif /* NSS_ENABLE_ECC */
ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
return SECFailure;
}
@@ -5044,7 +4547,6 @@ typedef struct dnameNode {
static SECStatus
ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
- ssl3State * ssl3 = ss->ssl3;
PRArenaPool * arena = NULL;
dnameNode * node;
PRInt32 remaining;
@@ -5059,23 +4561,23 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- if (ssl3->hs.ws != wait_cert_request &&
- ssl3->hs.ws != wait_server_key) {
+ if (ss->ssl3.hs.ws != wait_cert_request &&
+ ss->ssl3.hs.ws != wait_server_key) {
desc = unexpected_message;
errCode = SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST;
goto alert_loser;
}
/* clean up anything left from previous handshake. */
- if (ssl3->clientCertChain != NULL) {
- CERT_DestroyCertificateList(ssl3->clientCertChain);
- ssl3->clientCertChain = NULL;
+ if (ss->ssl3.clientCertChain != NULL) {
+ CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
+ ss->ssl3.clientCertChain = NULL;
}
- isTLS = (PRBool)(ssl3->prSpec->version > SSL_LIBRARY_VERSION_3_0);
+ isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
rv = ssl3_ConsumeHandshakeVariable(ss, &cert_types, 1, &b, &length);
if (rv != SECSuccess)
goto loser; /* malformed, alert has been sent */
@@ -5124,7 +4626,7 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
ca_list.nnames = nnames;
- ca_list.names = (SECItem*)PORT_ArenaAlloc(arena, nnames * sizeof(SECItem));
+ ca_list.names = PORT_ArenaNewArray(arena, SECItem, nnames);
if (nnames > 0 && ca_list.names == NULL)
goto no_mem;
@@ -5138,7 +4640,7 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto alert_loser; /* malformed */
desc = no_certificate;
- ssl3->hs.ws = wait_hello_done;
+ ss->ssl3.hs.ws = wait_hello_done;
if (ss->getClientAuthData == NULL) {
rv = SECFailure; /* force it to send a no_certificate alert */
@@ -5146,8 +4648,8 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
/* XXX Should pass cert_types in this call!! */
rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg,
ss->fd, &ca_list,
- &ssl3->clientCertificate,
- &ssl3->clientPrivateKey);
+ &ss->ssl3.clientCertificate,
+ &ss->ssl3.clientPrivateKey);
}
switch (rv) {
case SECWouldBlock: /* getClientAuthData has put up a dialog box. */
@@ -5156,33 +4658,34 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
case SECSuccess:
/* check what the callback function returned */
- if ((!ssl3->clientCertificate) || (!ssl3->clientPrivateKey)) {
+ if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) {
/* we are missing either the key or cert */
- if (ssl3->clientCertificate) {
+ if (ss->ssl3.clientCertificate) {
/* got a cert, but no key - free it */
- CERT_DestroyCertificate(ssl3->clientCertificate);
- ssl3->clientCertificate = NULL;
+ CERT_DestroyCertificate(ss->ssl3.clientCertificate);
+ ss->ssl3.clientCertificate = NULL;
}
- if (ssl3->clientPrivateKey) {
+ if (ss->ssl3.clientPrivateKey) {
/* got a key, but no cert - free it */
- SECKEY_DestroyPrivateKey(ssl3->clientPrivateKey);
- ssl3->clientPrivateKey = NULL;
+ SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
+ ss->ssl3.clientPrivateKey = NULL;
}
goto send_no_certificate;
}
- /* Setting ssl3->clientCertChain non-NULL will cause
+ /* Setting ssl3.clientCertChain non-NULL will cause
* ssl3_HandleServerHelloDone to call SendCertificate.
*/
- ssl3->clientCertChain = CERT_CertChainFromCert(ssl3->clientCertificate,
- certUsageSSLClient, PR_FALSE);
- if (ssl3->clientCertChain == NULL) {
- if (ssl3->clientCertificate != NULL) {
- CERT_DestroyCertificate(ssl3->clientCertificate);
- ssl3->clientCertificate = NULL;
+ ss->ssl3.clientCertChain = CERT_CertChainFromCert(
+ ss->ssl3.clientCertificate,
+ certUsageSSLClient, PR_FALSE);
+ if (ss->ssl3.clientCertChain == NULL) {
+ if (ss->ssl3.clientCertificate != NULL) {
+ CERT_DestroyCertificate(ss->ssl3.clientCertificate);
+ ss->ssl3.clientCertificate = NULL;
}
- if (ssl3->clientPrivateKey != NULL) {
- SECKEY_DestroyPrivateKey(ssl3->clientPrivateKey);
- ssl3->clientPrivateKey = NULL;
+ if (ss->ssl3.clientPrivateKey != NULL) {
+ SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
+ ss->ssl3.clientPrivateKey = NULL;
}
goto send_no_certificate;
}
@@ -5192,7 +4695,7 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
default:
send_no_certificate:
if (isTLS) {
- ssl3->sendEmptyCert = PR_TRUE;
+ ss->ssl3.sendEmptyCert = PR_TRUE;
} else {
(void)SSL3_SendAlert(ss, alert_warning, no_certificate);
}
@@ -5216,8 +4719,6 @@ loser:
done:
if (arena != NULL)
PORT_FreeArena(arena, PR_FALSE);
- if (cert_types.data != NULL)
- SECITEM_FreeItem(&cert_types, PR_FALSE);
return rv;
}
@@ -5261,16 +4762,16 @@ ssl3_RestartHandshakeAfterCertReq(sslSocket * ss,
*/
if (ss->handshake != 0) {
ss->handshake = ssl_GatherRecord1stHandshake;
- ss->ssl3->clientCertificate = cert;
- ss->ssl3->clientCertChain = certChain;
+ ss->ssl3.clientCertificate = cert;
+ ss->ssl3.clientCertChain = certChain;
if (key == NULL) {
(void)SSL3_SendAlert(ss, alert_warning, no_certificate);
- ss->ssl3->clientPrivateKey = NULL;
+ ss->ssl3.clientPrivateKey = NULL;
} else {
- ss->ssl3->clientPrivateKey = SECKEY_CopyPrivateKey(key);
+ ss->ssl3.clientPrivateKey = SECKEY_CopyPrivateKey(key);
}
ssl_GetRecvBufLock(ss);
- if (ss->ssl3->hs.msgState.buf != NULL) {
+ if (ss->ssl3.hs.msgState.buf != NULL) {
rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
}
ssl_ReleaseRecvBufLock(ss);
@@ -5289,13 +4790,13 @@ static SECStatus
ssl3_HandleServerHelloDone(sslSocket *ss)
{
SECStatus rv;
- SSL3WaitState ws = ss->ssl3->hs.ws;
+ SSL3WaitState ws = ss->ssl3.hs.ws;
PRBool send_verify = PR_FALSE;
SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello_done handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
if (ws != wait_hello_done &&
ws != wait_server_cert &&
@@ -5308,16 +4809,16 @@ ssl3_HandleServerHelloDone(sslSocket *ss)
ssl_GetXmitBufLock(ss); /*******************************/
- if (ss->ssl3->sendEmptyCert) {
- ss->ssl3->sendEmptyCert = PR_FALSE;
+ if (ss->ssl3.sendEmptyCert) {
+ ss->ssl3.sendEmptyCert = PR_FALSE;
rv = ssl3_SendEmptyCertificate(ss);
/* Don't send verify */
if (rv != SECSuccess) {
goto loser; /* error code is set. */
}
} else
- if (ss->ssl3->clientCertChain != NULL &&
- ss->ssl3->clientPrivateKey != NULL) {
+ if (ss->ssl3.clientCertChain != NULL &&
+ ss->ssl3.clientPrivateKey != NULL) {
send_verify = PR_TRUE;
rv = ssl3_SendCertificate(ss);
if (rv != SECSuccess) {
@@ -5347,7 +4848,7 @@ ssl3_HandleServerHelloDone(sslSocket *ss)
ssl_ReleaseXmitBufLock(ss); /*******************************/
- ss->ssl3->hs.ws = wait_change_cipher;
+ ss->ssl3.hs.ws = wait_change_cipher;
return SECSuccess;
loser:
@@ -5366,8 +4867,8 @@ ssl3_SendHelloRequest(sslSocket *ss)
SSL_TRC(3, ("%d: SSL3[%d]: send hello_request handshake", SSL_GETPID(),
ss->fd));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
rv = ssl3_AppendHandshakeHeader(ss, hello_request, 0);
if (rv != SECSuccess) {
@@ -5377,7 +4878,7 @@ ssl3_SendHelloRequest(sslSocket *ss)
if (rv != SECSuccess) {
return rv; /* error code set by ssl3_FlushHandshake */
}
- ss->ssl3->hs.ws = wait_client_hello;
+ ss->ssl3.hs.ws = wait_client_hello;
return SECSuccess;
}
@@ -5405,12 +4906,10 @@ ssl3_NewSessionID(sslSocket *ss, PRBool is_server)
sid->cached = never_cached;
sid->version = ss->version;
- sid->u.ssl3.resumable = PR_TRUE;
+ sid->u.ssl3.keys.resumable = PR_TRUE;
sid->u.ssl3.policy = SSL_ALLOWED;
- sid->u.ssl3.hasFortezza = PR_FALSE;
sid->u.ssl3.clientWriteKey = NULL;
sid->u.ssl3.serverWriteKey = NULL;
- sid->u.ssl3.tek = NULL;
if (is_server) {
SECStatus rv;
@@ -5440,8 +4939,8 @@ ssl3_SendServerHelloSequence(sslSocket *ss)
SSL_TRC(3, ("%d: SSL3[%d]: begin send server_hello sequence",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
rv = ssl3_SendServerHello(ss);
if (rv != SECSuccess) {
@@ -5454,26 +4953,22 @@ ssl3_SendServerHelloSequence(sslSocket *ss)
/* We have to do this after the call to ssl3_SendServerHello,
* because kea_def is set up by ssl3_SendServerHello().
*/
- kea_def = ss->ssl3->hs.kea_def;
- ss->ssl3->hs.usedStepDownKey = PR_FALSE;
- if (kea_def->kea == kea_fortezza) {
- rv = ssl3_SendServerKeyExchange(ss);
- if (rv != SECSuccess) {
- return rv; /* err code was set. */
- }
- } else if (kea_def->is_limited && kea_def->exchKeyType == kt_rsa) {
+ kea_def = ss->ssl3.hs.kea_def;
+ ss->ssl3.hs.usedStepDownKey = PR_FALSE;
+
+ if (kea_def->is_limited && kea_def->exchKeyType == kt_rsa) {
/* see if we can legally use the key in the cert. */
int keyLen; /* bytes */
keyLen = PK11_GetPrivateModulusLen(
- ss->serverCerts[kea_def->exchKeyType].serverKey);
+ ss->serverCerts[kea_def->exchKeyType].SERVERKEY);
if (keyLen > 0 &&
keyLen * BPB <= kea_def->key_size_limit ) {
/* XXX AND cert is not signing only!! */
/* just fall through and use it. */
} else if (ss->stepDownKeyPair != NULL) {
- ss->ssl3->hs.usedStepDownKey = PR_TRUE;
+ ss->ssl3.hs.usedStepDownKey = PR_TRUE;
rv = ssl3_SendServerKeyExchange(ss);
if (rv != SECSuccess) {
return rv; /* err code was set. */
@@ -5494,7 +4989,7 @@ ssl3_SendServerHelloSequence(sslSocket *ss)
#endif /* NSS_ENABLE_ECC */
}
- if (ss->requestCertificate) {
+ if (ss->opt.requestCertificate) {
rv = ssl3_SendCertificateRequest(ss);
if (rv != SECSuccess) {
return rv; /* err code is set. */
@@ -5505,7 +5000,7 @@ ssl3_SendServerHelloSequence(sslSocket *ss)
return rv; /* err code is set. */
}
- ss->ssl3->hs.ws = (ss->requestCertificate) ? wait_client_cert
+ ss->ssl3.hs.ws = (ss->opt.requestCertificate) ? wait_client_cert
: wait_client_key;
return SECSuccess;
}
@@ -5518,7 +5013,6 @@ static SECStatus
ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
sslSessionID * sid = NULL;
- ssl3State * ssl3;
PRInt32 tmp;
unsigned int i;
int j;
@@ -5535,8 +5029,8 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SSL_TRC(3, ("%d: SSL3[%d]: handle client_hello handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
/* Get peer name of client */
rv = ssl_GetPeerInfo(ss);
@@ -5548,10 +5042,9 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (rv != SECSuccess) {
return rv; /* ssl3_InitState has set the error code. */
}
- ssl3 = ss->ssl3;
- if ((ssl3->hs.ws != wait_client_hello) &&
- (ssl3->hs.ws != idle_handshake)) {
+ if ((ss->ssl3.hs.ws != wait_client_hello) &&
+ (ss->ssl3.hs.ws != idle_handshake)) {
desc = unexpected_message;
errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO;
goto alert_loser;
@@ -5570,7 +5063,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
/* grab the client random data. */
rv = ssl3_ConsumeHandshake(
- ss, &ssl3->hs.client_random, SSL3_RANDOM_LENGTH, &b, &length);
+ ss, &ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH, &b, &length);
if (rv != SECSuccess) {
goto loser; /* malformed */
}
@@ -5581,7 +5074,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto loser; /* malformed */
}
- if (sidBytes.len > 0 && !ss->noCache) {
+ if (sidBytes.len > 0 && !ss->opt.noCache) {
SSL_TRC(7, ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
ss->sec.ci.peer.pr_s6_addr32[1],
@@ -5595,7 +5088,6 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto loser;
}
}
- SECITEM_FreeItem(&sidBytes, PR_FALSE);
/* grab the list of cipher suites. */
rv = ssl3_ConsumeHandshakeVariable(ss, &suites, 2, &b, &length);
@@ -5623,10 +5115,10 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
* and this is the first handshake on this connection (not a redo),
* then drop this old cache entry and start a new session.
*/
- if ((sid->peerCert == NULL) && ss->requestCertificate &&
- ((ss->requireCertificate == SSL_REQUIRE_ALWAYS) ||
- (ss->requireCertificate == SSL_REQUIRE_NO_ERROR) ||
- ((ss->requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE)
+ if ((sid->peerCert == NULL) && ss->opt.requestCertificate &&
+ ((ss->opt.requireCertificate == SSL_REQUIRE_ALWAYS) ||
+ (ss->opt.requireCertificate == SSL_REQUIRE_NO_ERROR) ||
+ ((ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE)
&& !ss->firstHsDone))) {
++ssl3stats.hch_sid_cache_not_ok;
@@ -5654,15 +5146,15 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
if (!j)
break;
- if (!config_match(suite, ssl3->policy, PR_TRUE))
+ if (!config_match(suite, ss->ssl3.policy, PR_TRUE))
break;
for (i = 0; i < suites.len; i += 2) {
if ((suites.data[i] == MSB(suite->cipher_suite)) &&
(suites.data[i + 1] == LSB(suite->cipher_suite))) {
- ssl3->hs.cipher_suite = suite->cipher_suite;
- ssl3->hs.suite_def =
- ssl_LookupCipherSuiteDef(ssl3->hs.cipher_suite);
+ ss->ssl3.hs.cipher_suite = suite->cipher_suite;
+ ss->ssl3.hs.suite_def =
+ ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
goto suite_found;
}
}
@@ -5674,15 +5166,15 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
*/
for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
- if (!config_match(suite, ssl3->policy, PR_TRUE))
+ if (!config_match(suite, ss->ssl3.policy, PR_TRUE))
continue;
for (i = 0; i < suites.len; i += 2) {
if ((suites.data[i] == MSB(suite->cipher_suite)) &&
(suites.data[i + 1] == LSB(suite->cipher_suite))) {
- ssl3->hs.cipher_suite = suite->cipher_suite;
- ssl3->hs.suite_def =
- ssl_LookupCipherSuiteDef(ssl3->hs.cipher_suite);
+ ss->ssl3.hs.cipher_suite = suite->cipher_suite;
+ ss->ssl3.hs.suite_def =
+ ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
goto suite_found;
}
}
@@ -5695,7 +5187,8 @@ suite_found:
for (i = 0; i < comps.len; i++) {
for (j = 0; j < compressionMethodsCount; j++) {
if (comps.data[i] == compressions[j]) {
- ssl3->hs.compression = (SSL3CompressionMethod)compressions[j];
+ ss->ssl3.hs.compression =
+ (SSL3CompressionMethod)compressions[j];
goto compression_found;
}
}
@@ -5705,9 +5198,7 @@ suite_found:
goto alert_loser;
compression_found:
- PORT_Free(suites.data);
suites.data = NULL;
- PORT_Free(comps.data);
comps.data = NULL;
ss->sec.send = ssl3_SendApplicationData;
@@ -5717,14 +5208,11 @@ compression_found:
* as if the client had sent us no sid to begin with, and make a new one.
*/
if (sid != NULL) do {
- PK11SlotInfo * slot;
- PK11SymKey * wrapKey; /* wrapping key */
- SECItem wrappedKey; /* wrapped key */
ssl3CipherSpec *pwSpec;
- CK_FLAGS keyFlags = 0;
+ SECItem wrappedMS; /* wrapped key */
if (sid->version != ss->version ||
- sid->u.ssl3.cipherSuite != ssl3->hs.cipher_suite) {
+ sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite) {
break; /* not an error */
}
@@ -5739,30 +5227,62 @@ compression_found:
/* we need to resurrect the master secret.... */
ssl_GetSpecWriteLock(ss); haveSpecWriteLock = PR_TRUE;
- pwSpec = ssl3->pwSpec;
+ pwSpec = ss->ssl3.pwSpec;
+ if (sid->u.ssl3.keys.msIsWrapped) {
+ PK11SymKey * wrapKey; /* wrapping key */
+ CK_FLAGS keyFlags = 0;
+ if (ss->opt.bypassPKCS11) {
+ /* we cannot restart a non-bypass session in a
+ ** bypass socket.
+ */
+ break;
+ }
- wrapKey = getWrappingKey(ss, NULL, sid->u.ssl3.exchKeyType,
- sid->u.ssl3.masterWrapMech, ss->pkcs11PinArg);
- if (!wrapKey) {
- /* we have a SID cache entry, but no wrapping key for it??? */
- break;
- }
+ wrapKey = getWrappingKey(ss, NULL, sid->u.ssl3.exchKeyType,
+ sid->u.ssl3.masterWrapMech,
+ ss->pkcs11PinArg);
+ if (!wrapKey) {
+ /* we have a SID cache entry, but no wrapping key for it??? */
+ break;
+ }
- if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
- keyFlags = CKF_SIGN | CKF_VERIFY;
- }
+ if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
+ keyFlags = CKF_SIGN | CKF_VERIFY;
+ }
- wrappedKey.data = sid->u.ssl3.keys.wrapped_master_secret;
- wrappedKey.len = sid->u.ssl3.keys.wrapped_master_secret_len;
+ wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
+ wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
- /* unwrap the master secret. */
- pwSpec->master_secret =
- PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
- NULL, &wrappedKey, CKM_SSL3_MASTER_KEY_DERIVE,
- CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
- PK11_FreeSymKey(wrapKey);
- if (pwSpec->master_secret == NULL) {
- break; /* not an error */
+ /* unwrap the master secret. */
+ pwSpec->master_secret =
+ PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
+ NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
+ CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
+ PK11_FreeSymKey(wrapKey);
+ if (pwSpec->master_secret == NULL) {
+ break; /* not an error */
+ }
+ } else if (ss->opt.bypassPKCS11) {
+ wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
+ wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
+ memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
+ pwSpec->msItem.data = pwSpec->raw_master_secret;
+ pwSpec->msItem.len = wrappedMS.len;
+ } else {
+ /* We CAN restart a bypass session in a non-bypass socket. */
+ /* need to import the raw master secret to session object */
+ PK11SlotInfo * slot;
+ wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
+ wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
+ slot = PK11_GetInternalSlot();
+ pwSpec->master_secret =
+ PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE,
+ PK11_OriginUnwrap, CKA_ENCRYPT, &wrappedMS,
+ NULL);
+ PK11_FreeSlot(slot);
+ if (pwSpec->master_secret == NULL) {
+ break; /* not an error */
+ }
}
ss->sec.ci.sid = sid;
if (sid->peerCert != NULL) {
@@ -5775,7 +5295,7 @@ compression_found:
* XXX make sure compression still matches
*/
++ssl3stats.hch_sid_cache_hits;
- ssl3->hs.isResuming = PR_TRUE;
+ ss->ssl3.hs.isResuming = PR_TRUE;
ss->sec.authAlgorithm = sid->authAlgorithm;
ss->sec.authKeyBits = sid->authKeyBits;
@@ -5798,74 +5318,6 @@ compression_found:
goto loser;
}
- /* reload the FORTEZZA key material.
- * On Fortezza, the following keys & IVs are generated by the KEA,
- * not from the PMS. Since we're not going to redo the KEA, we
- * have to save & restore them for Fortezza.
- * use kea because we haven't call InitCipher Specs yet...?
- */
- if (ssl3->hs.suite_def->bulk_cipher_alg == cipher_fortezza) {
- PK11SymKey * Ks;
- SECItem item;
-
- PORT_Memcpy(pwSpec->client.write_iv,
- sid->u.ssl3.keys.client_write_iv,
- sizeof sid->u.ssl3.keys.client_write_iv);
- PORT_Memcpy(pwSpec->server.write_iv,
- sid->u.ssl3.keys.server_write_iv,
- sizeof sid->u.ssl3.keys.server_write_iv);
-
- /* Now, unwrap the client and server write keys with Ks */
-
- /* get the slot that the fortezza server private key is in. */
- slot = PK11_GetSlotFromPrivateKey(
- ss->serverCerts[kt_fortezza].serverKey);
- if (slot == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- /* Look up the Token Fixed Key */
- Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL,
- ss->pkcs11PinArg);
- PK11_FreeSlot(slot);
- if (Ks == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- /* unwrap client write key with the local Ks */
- item.data = sid->u.ssl3.keys.wrapped_client_write_key;
- item.len = sizeof sid->u.ssl3.keys.wrapped_client_write_key;
-
- pwSpec->client.write_key =
- PK11_UnwrapSymKey(Ks, CKM_SKIPJACK_WRAP, NULL, &item,
- CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
- if (pwSpec->client.write_key == NULL) {
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
- goto loser;
- }
-
- /* unwrap server write key with the local Ks */
- item.data = sid->u.ssl3.keys.wrapped_server_write_key;
- item.len = sizeof sid->u.ssl3.keys.wrapped_server_write_key;
-
- pwSpec->server.write_key =
- PK11_UnwrapSymKey(Ks, CKM_SKIPJACK_WRAP, NULL, &item,
- CKM_SKIPJACK_CBC64, CKA_ENCRYPT, 0);
- if (pwSpec->server.write_key == NULL) {
- PK11_FreeSymKey(pwSpec->client.write_key);
- pwSpec->client.write_key = NULL;
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
- goto loser;
- }
- /* Set flag that says "generate 8 byte random prefix plaintext." */
- PK11_SetFortezzaHack(pwSpec->server.write_key); /* can't fail */
-
- }
-
if (haveSpecWriteLock) {
ssl_ReleaseSpecWriteLock(ss);
haveSpecWriteLock = PR_FALSE;
@@ -5884,7 +5336,7 @@ compression_found:
goto loser;
}
rv = ssl3_SendFinished(ss, 0);
- ssl3->hs.ws = wait_change_cipher;
+ ss->ssl3.hs.ws = wait_change_cipher;
if (rv != SECSuccess) {
errCode = PORT_GetError();
goto loser;
@@ -5918,7 +5370,7 @@ compression_found:
}
ss->sec.ci.sid = sid;
- ssl3->hs.isResuming = PR_FALSE;
+ ss->ssl3.hs.isResuming = PR_FALSE;
ssl_GetXmitBufLock(ss);
rv = ssl3_SendServerHelloSequence(ss);
ssl_ReleaseXmitBufLock(ss);
@@ -5947,10 +5399,6 @@ loser:
haveSpecWriteLock = PR_FALSE;
}
- if (sidBytes.data != NULL) SECITEM_FreeItem(&sidBytes, PR_FALSE);
- if (suites.data != NULL) SECITEM_FreeItem(&suites, PR_FALSE);
- if (comps.data != NULL) SECITEM_FreeItem(&comps, PR_FALSE);
-
if (haveXmitBufLock) {
ssl_ReleaseXmitBufLock(ss);
haveXmitBufLock = PR_FALSE;
@@ -5983,7 +5431,7 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
SSL_TRC(3, ("%d: SSL3[%d]: handle v2 client_hello", SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
ssl_GetSSL3HandshakeLock(ss);
@@ -5993,7 +5441,7 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
return rv; /* ssl3_InitState has set the error code. */
}
- if (ss->ssl3->hs.ws != wait_client_hello) {
+ if (ss->ssl3.hs.ws != wait_client_hello) {
desc = unexpected_message;
errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO;
goto loser; /* alert_loser */
@@ -6033,12 +5481,12 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
PORT_Assert(SSL_MAX_CHALLENGE_BYTES == SSL3_RANDOM_LENGTH);
- PORT_Memset(&ss->ssl3->hs.client_random, 0, SSL3_RANDOM_LENGTH);
+ PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
PORT_Memcpy(
- &ss->ssl3->hs.client_random.rand[SSL3_RANDOM_LENGTH - rand_length],
+ &ss->ssl3.hs.client_random.rand[SSL3_RANDOM_LENGTH - rand_length],
random, rand_length);
- PRINT_BUF(60, (ss, "client random:", &ss->ssl3->hs.client_random.rand[0],
+ PRINT_BUF(60, (ss, "client random:", &ss->ssl3.hs.client_random.rand[0],
SSL3_RANDOM_LENGTH));
i = ssl3_config_match_init(ss);
@@ -6053,16 +5501,16 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
*/
for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
- if (!config_match(suite, ss->ssl3->policy, PR_TRUE))
+ if (!config_match(suite, ss->ssl3.policy, PR_TRUE))
continue;
for (i = 0; i < suite_length; i += 3) {
if ((suites[i] == 0) &&
(suites[i+1] == MSB(suite->cipher_suite)) &&
(suites[i+2] == LSB(suite->cipher_suite))) {
- ss->ssl3->hs.cipher_suite = suite->cipher_suite;
- ss->ssl3->hs.suite_def =
- ssl_LookupCipherSuiteDef(ss->ssl3->hs.cipher_suite);
+ ss->ssl3.hs.cipher_suite = suite->cipher_suite;
+ ss->ssl3.hs.suite_def =
+ ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
goto suite_found;
}
}
@@ -6072,7 +5520,7 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
suite_found:
- ss->ssl3->hs.compression = compression_null;
+ ss->ssl3.hs.compression = compression_null;
ss->sec.send = ssl3_SendApplicationData;
/* we don't even search for a cache hit here. It's just a miss. */
@@ -6134,8 +5582,8 @@ ssl3_SendServerHello(sslSocket *ss)
SSL_TRC(3, ("%d: SSL3[%d]: send server_hello handshake", SSL_GETPID(),
ss->fd));
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
PORT_Assert( MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0));
if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
@@ -6156,13 +5604,13 @@ ssl3_SendServerHello(sslSocket *ss)
if (rv != SECSuccess) {
return rv; /* err set by AppendHandshake. */
}
- rv = ssl3_GetNewRandom(&ss->ssl3->hs.server_random);
+ rv = ssl3_GetNewRandom(&ss->ssl3.hs.server_random);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
return rv;
}
rv = ssl3_AppendHandshake(
- ss, &ss->ssl3->hs.server_random, SSL3_RANDOM_LENGTH);
+ ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH);
if (rv != SECSuccess) {
return rv; /* err set by AppendHandshake. */
}
@@ -6176,15 +5624,15 @@ ssl3_SendServerHello(sslSocket *ss)
return rv; /* err set by AppendHandshake. */
}
- rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3->hs.cipher_suite, 2);
+ rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.cipher_suite, 2);
if (rv != SECSuccess) {
return rv; /* err set by AppendHandshake. */
}
- rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3->hs.compression, 1);
+ rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.compression, 1);
if (rv != SECSuccess) {
return rv; /* err set by AppendHandshake. */
}
- rv = ssl3_SetupPendingCipherSpec(ss, ss->ssl3);
+ rv = ssl3_SetupPendingCipherSpec(ss);
if (rv != SECSuccess) {
return rv; /* err set by ssl3_SetupPendingCipherSpec */
}
@@ -6196,25 +5644,19 @@ ssl3_SendServerHello(sslSocket *ss)
static SECStatus
ssl3_SendServerKeyExchange(sslSocket *ss)
{
-const ssl3KEADef * kea_def = ss->ssl3->hs.kea_def;
+const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
SECStatus rv = SECFailure;
int length;
PRBool isTLS;
SECItem signed_hash = {siBuffer, NULL, 0};
SSL3Hashes hashes;
SECKEYPublicKey * sdPub; /* public key for step-down */
-#ifdef NSS_ENABLE_ECC
- SECKEYPublicKey * ecdhePub;
- SECItem ec_params = {siBuffer, NULL, 0};
- ECName curve;
- SSL3KEAType certIndex;
-#endif /* NSS_ENABLE_ECC */
SSL_TRC(3, ("%d: SSL3[%d]: send server_key_exchange handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
switch (kea_def->exchKeyType) {
case kt_rsa:
@@ -6227,16 +5669,16 @@ const ssl3KEADef * kea_def = ss->ssl3->hs.kea_def;
}
rv = ssl3_ComputeExportRSAKeyHash(sdPub->u.rsa.modulus,
sdPub->u.rsa.publicExponent,
- &ss->ssl3->hs.client_random,
- &ss->ssl3->hs.server_random,
- &hashes);
+ &ss->ssl3.hs.client_random,
+ &ss->ssl3.hs.server_random,
+ &hashes, ss->opt.bypassPKCS11);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
return rv;
}
- isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- rv = ssl3_SignHashes(&hashes, ss->serverCerts[kt_rsa].serverKey,
+ isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
+ rv = ssl3_SignHashes(&hashes, ss->serverCerts[kt_rsa].SERVERKEY,
&signed_hash, isTLS);
if (rv != SECSuccess) {
goto loser; /* ssl3_SignHashes has set err. */
@@ -6276,112 +5718,11 @@ const ssl3KEADef * kea_def = ss->ssl3->hs.kea_def;
PORT_Free(signed_hash.data);
return SECSuccess;
- case kt_fortezza:
-
- /* Set server's "random" public key R_s to the email value == 1 */
- PORT_Memset(ss->ssl3->fortezza.R_s, 0, sizeof(ss->ssl3->fortezza.R_s));
- ss->ssl3->fortezza.R_s[127] = 1;
-
- /* don't waste time signing the random number */
- length = sizeof (ss->ssl3->fortezza.R_s) /*+ 2 + signed_hash.len*/;
-
- rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshake( ss, &ss->ssl3->fortezza.R_s,
- sizeof(ss->ssl3->fortezza.R_s));
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
- return SECSuccess;
-
#ifdef NSS_ENABLE_ECC
- case kt_ecdh:
- /* Generate ephemeral ECDH key pair and send the public key */
- rv = ssl3_CreateECDHEphemeralKeys(ss);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
- ecdhePub = ss->ephemeralECDHKeyPair->pubKey;
- PORT_Assert(ecdhePub != NULL);
- if (!ecdhePub) {
- PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- return SECFailure;
- }
-
- ec_params.len = 2;
- ec_params.data = (unsigned char*)PORT_Alloc(ec_params.len);
- curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams);
- if (curve != ec_noName) {
- ec_params.data[0] = ec_type_named;
- ec_params.data[1] = curve;
- } else {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
- goto loser;
- }
-
- rv = ssl3_ComputeECDHKeyHash(ec_params, ecdhePub->u.ec.publicValue,
- &ss->ssl3->hs.client_random,
- &ss->ssl3->hs.server_random,
- &hashes);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- /* XXX SSLKEAType isn't really a good choice for
- * indexing certificates but that's all we have
- * for now.
- */
- if (kea_def->kea == kea_ecdhe_rsa)
- certIndex = kt_rsa;
- else /* kea_def->kea == kea_ecdhe_ecdsa */
- certIndex = kt_ecdh;
-
- rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].serverKey,
- &signed_hash, isTLS);
- if (rv != SECSuccess) {
- goto loser; /* ssl3_SignHashes has set err. */
- }
- if (signed_hash.data == NULL) {
- /* how can this happen and rv == SECSuccess ?? */
- PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- length = ec_params.len +
- 1 + ecdhePub->u.ec.publicValue.len +
- 2 + signed_hash.len;
-
- rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data,
- ecdhePub->u.ec.publicValue.len, 1);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
- signed_hash.len, 2);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- PORT_Free(ec_params.data);
- PORT_Free(signed_hash.data);
- return SECSuccess;
+ case kt_ecdh: {
+ rv = ssl3_SendECDHServerKeyExchange(ss);
+ return rv;
+ }
#endif /* NSS_ENABLE_ECC */
case kt_dh:
@@ -6391,10 +5732,6 @@ const ssl3KEADef * kea_def = ss->ssl3->hs.kea_def;
break;
}
loser:
-#ifdef NSS_ENABLE_ECC
- if (ec_params.data != NULL)
- PORT_Free(ec_params.data);
-#endif /* NSS_ENABLE_ECC */
if (signed_hash.data != NULL)
PORT_Free(signed_hash.data);
return SECFailure;
@@ -6418,11 +5755,11 @@ const uint8 * certTypes;
SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- /* ssl3->ca_list is initialized to NULL, and never changed. */
- ca_list = ss->ssl3->ca_list;
+ /* ssl3.ca_list is initialized to NULL, and never changed. */
+ ca_list = ss->ssl3.ca_list;
if (!ca_list) {
ca_list = ssl3_server_ca_list;
}
@@ -6441,13 +5778,8 @@ const uint8 * certTypes;
calen += 2 + name->len;
}
- if (ss->ssl3->hs.kea_def->exchKeyType == kt_fortezza) {
- certTypes = fortezza_certificate_types;
- certTypesLength = sizeof fortezza_certificate_types;
- } else {
- certTypes = certificate_types;
- certTypesLength = sizeof certificate_types;
- }
+ certTypes = certificate_types;
+ certTypesLength = sizeof certificate_types;
length = 1 + certTypesLength + 2 + calen;
@@ -6481,8 +5813,8 @@ ssl3_SendServerHelloDone(sslSocket *ss)
SSL_TRC(3, ("%d: SSL3[%d]: send server_hello_done handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
rv = ssl3_AppendHandshakeHeader(ss, server_hello_done, 0);
if (rv != SECSuccess) {
@@ -6511,10 +5843,10 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_verify handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- if (ss->ssl3->hs.ws != wait_cert_verify || ss->sec.peerCert == NULL) {
+ if (ss->ssl3.hs.ws != wait_cert_verify || ss->sec.peerCert == NULL) {
desc = unexpected_message;
errCode = SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY;
goto alert_loser;
@@ -6525,7 +5857,7 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
goto loser; /* malformed. */
}
- isTLS = (PRBool)(ss->ssl3->prSpec->version > SSL_LIBRARY_VERSION_3_0);
+ isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
/* XXX verify that the key & kea match */
rv = ssl3_VerifySignedHashes(hashes, ss->sec.peerCert, &signed_hash,
@@ -6536,281 +5868,29 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
goto alert_loser;
}
- PORT_Free(signed_hash.data);
signed_hash.data = NULL;
if (length != 0) {
desc = isTLS ? decode_error : illegal_parameter;
goto alert_loser; /* malformed */
}
- ss->ssl3->hs.ws = wait_change_cipher;
+ ss->ssl3.hs.ws = wait_change_cipher;
return SECSuccess;
alert_loser:
SSL3_SendAlert(ss, alert_fatal, desc);
loser:
- if (signed_hash.data != NULL) SECITEM_FreeItem(&signed_hash, PR_FALSE);
PORT_SetError(errCode);
return SECFailure;
}
-/*
-** Called from ssl3_HandleClientKeyExchange()
-*/
-static SECStatus
-ssl3_HandleFortezzaClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
- PRUint32 length,
- SECKEYPrivateKey *serverKey)
-{
- SECKEYPublicKey * pubKey = NULL;
- PK11SymKey * tek = NULL;
- PK11SymKey * pms;
- PK11SymKey * Ks = NULL;
- sslSessionID * sid = ss->sec.ci.sid;
- ssl3CipherSpec * pwSpec = ss->ssl3->pwSpec;
- void * pwArg = ss->pkcs11PinArg;
- SECStatus rv;
- SECItem raItem;
- SECItem rbItem;
- SECItem param;
- SECItem item;
- SECItem enc_pms;
- SSL3FortezzaKeys fortezza_CKE;
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- fortezza_CKE.y_c.data = NULL;
- rv = ssl3_ConsumeHandshakeVariable(ss, &fortezza_CKE.y_c, 1, &b, &length);
- if (rv != SECSuccess) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH);
- goto fortezza_loser;
- }
- rv = ssl3_ConsumeHandshake(ss, &fortezza_CKE.r_c,
- sizeof fortezza_CKE - sizeof fortezza_CKE.y_c,
- &b, &length);
- if (rv != SECSuccess) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH);
- goto fortezza_loser;
- }
-
- /* Build a Token Encryption key (tek). TEK's can never be unloaded
- * from the card, but given these parameters, and *OUR* fortezza
- * card, we can always regenerate the same one on the fly.
- */
- if (ss->sec.peerCert != NULL) {
- /* client-auth case */
-
- pubKey = CERT_ExtractPublicKey(ss->sec.peerCert);
- if (pubKey == NULL) {
- SEND_ALERT
- PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- rv = SECFailure;
- goto fortezza_loser;
- }
-
- if (pubKey->keyType != fortezzaKey) {
- /* handle V3 client-auth case */
- SECItem sigItem;
- SECItem hashItem;
- unsigned char hash[SHA1_LENGTH];
-
- rv = ssl3_ComputeFortezzaPublicKeyHash(fortezza_CKE.y_c, hash);
- if (rv != SECSuccess) {
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
- sigItem.data = fortezza_CKE.y_signature;
- sigItem.len = sizeof fortezza_CKE.y_signature;
-
- hashItem.data = hash;
- hashItem.len = sizeof hash;
-
- rv = PK11_Verify(pubKey, &sigItem, &hashItem, pwArg);
- if (rv != SECSuccess) {
- SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
- SECKEY_DestroyPublicKey(pubKey); pubKey = NULL;
- }
- }
- rv = SECFailure;
-
- /* Make the public key if necessary */
- if (fortezza_CKE.y_c.len != 0) {
- if (pubKey != NULL) {
- /* The client is not allowed to send the public key
- * if it can be extracted from the certificate. */
- SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
- PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
- pubKey = PK11_MakeKEAPubKey(fortezza_CKE.y_c.data,
- fortezza_CKE.y_c.len);
- }
- if (pubKey == NULL) {
- /* no public Key in either the cert or the protocol message*/
- SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
- PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
-
- /* Now we derive the TEK. r_c is the client's "random" public key. */
- raItem.data = fortezza_CKE.r_c;
- raItem.len = sizeof(fortezza_CKE.r_c);
-
- /* R_s == server's "random" public key, sent in the Server Key Exchange */
- rbItem.data = ss->ssl3->fortezza.R_s;
- rbItem.len = sizeof ss->ssl3->fortezza.R_s;
-
- tek = PK11_PubDerive(serverKey, pubKey, PR_FALSE, /* don't gen r_c */
- &raItem, &rbItem, CKM_KEA_KEY_DERIVE,
- CKM_SKIPJACK_WRAP, CKA_WRAP, 0, pwArg);
- SECKEY_DestroyPublicKey(pubKey); pubKey = NULL;
- if (tek == NULL) {
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
-
- ss->ssl3->fortezza.tek = PK11_ReferenceSymKey(tek);
-
- if (pwSpec->cipher_def->calg == calg_fortezza) {
- item.data = fortezza_CKE.wrapped_client_write_key;
- item.len = sizeof fortezza_CKE.wrapped_client_write_key;
-
- pwSpec->client.write_key =
- PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL, &item,
- CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
- if (pwSpec->client.write_key == NULL) {
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
- goto fortezza_loser;
- }
-
- item.data = fortezza_CKE.wrapped_server_write_key;
- item.len = sizeof fortezza_CKE.wrapped_server_write_key;
-
- pwSpec->server.write_key =
- PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL, &item,
- CKM_SKIPJACK_CBC64, CKA_ENCRYPT, 0);
- if (pwSpec->server.write_key == NULL) {
- PK11_FreeSymKey(pwSpec->client.write_key);
- pwSpec->client.write_key = NULL;
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
- goto fortezza_loser;
- }
- /* Set a flag that says "generate 8 byte random prefix plaintext." */
- PK11_SetFortezzaHack(pwSpec->server.write_key); /* can't fail */
-
- PORT_Memcpy(pwSpec->client.write_iv, fortezza_CKE.client_write_iv,
- sizeof fortezza_CKE.client_write_iv);
- PORT_Memcpy(pwSpec->server.write_iv, fortezza_CKE.server_write_iv,
- sizeof fortezza_CKE.server_write_iv);
-
- }
-
- /* decrypt the pms with the TEK */
- enc_pms.data = fortezza_CKE.encrypted_preMasterSecret;
- enc_pms.len = sizeof fortezza_CKE.encrypted_preMasterSecret;
-
- param.data = fortezza_CKE.master_secret_iv;
- param.len = sizeof fortezza_CKE.master_secret_iv;
-
- pms = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_CBC64, &param, &enc_pms,
- CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
- if (pms == NULL) {
- SEND_ALERT
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
- goto fortezza_loser;
- }
-
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms);
- if (rv != SECSuccess) {
- SEND_ALERT
- goto fortezza_loser; /* err code is set. */
- }
-
- if (pwSpec->cipher_def->calg == calg_fortezza) {
- PK11SlotInfo * slot;
-
- sid->u.ssl3.clientWriteKey =
- PK11_ReferenceSymKey(pwSpec->client.write_key);
- sid->u.ssl3.serverWriteKey =
- PK11_ReferenceSymKey(pwSpec->server.write_key);
-
- PORT_Memcpy(sid->u.ssl3.keys.client_write_iv, pwSpec->client.write_iv,
- sizeof sid->u.ssl3.keys.client_write_iv);
- PORT_Memcpy(sid->u.ssl3.keys.server_write_iv, pwSpec->server.write_iv,
- sizeof sid->u.ssl3.keys.server_write_iv);
-
- /* Now, wrap the client and server write keys in Ks for storage
- * in the on-disk sid.
- */
-
- slot = PK11_GetSlotFromKey(tek); /* get ref to the slot */
- if (slot == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
-
- /* Look up the Token Fixed Key */
- Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL, ss->pkcs11PinArg);
- PK11_FreeSlot(slot);
- if (Ks == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
-
- /* rewrap server write key with the local Ks */
- item.data = sid->u.ssl3.keys.wrapped_server_write_key;
- item.len = sizeof sid->u.ssl3.keys.wrapped_server_write_key;
- rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, Ks,
- pwSpec->server.write_key, &item);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
-
- /* rewrap client write key with the local Ks */
- item.data = sid->u.ssl3.keys.wrapped_client_write_key;
- item.len = sizeof sid->u.ssl3.keys.wrapped_client_write_key;
- rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, Ks,
- pwSpec->client.write_key, &item);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto fortezza_loser;
- }
-
- /* wrap the master secret later, when we handle the client's
- * finished message.
- */
- }
-
- sid->u.ssl3.hasFortezza = PR_TRUE;
- sid->u.ssl3.tek = tek; tek = NULL;
-
- rv = SECSuccess;
-
-fortezza_loser:
- if (Ks) PK11_FreeSymKey(Ks);
- if (tek) PK11_FreeSymKey(tek);
- if (pubKey) SECKEY_DestroyPublicKey(pubKey);
- if (fortezza_CKE.y_c.data != NULL)
- SECITEM_FreeItem(&fortezza_CKE.y_c, PR_FALSE);
- return rv;
-}
/* find a slot that is able to generate a PMS and wrap it with RSA.
* Then generate and return the PMS.
* If the serverKeySlot parameter is non-null, this function will use
* that slot to do the job, otherwise it will find a slot.
*
- * Called from ssl3_GenerateSessionKeys() (above)
+ * Called from ssl3_DeriveConnectionKeysPKCS11() (above)
* sendRSAClientKeyExchange() (above)
* ssl3_HandleRSAClientKeyExchange() (below)
* Caller must hold the SpecWriteLock, the SSL3HandshakeLock
@@ -6826,7 +5906,7 @@ ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
CK_VERSION version;
CK_MECHANISM_TYPE mechanism_array[3];
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
if (slot == NULL) {
SSLCipherAlgorithm calg;
@@ -6834,8 +5914,8 @@ ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
** read locks. Also, all the callers who call with a non-null
** slot already hold the SpecWriteLock.
*/
- PORT_Assert( ssl_HaveSpecWriteLock(ss));
- PORT_Assert(ss->ssl3->prSpec == ss->ssl3->pwSpec);
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
+ PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
calg = spec->cipher_def->calg;
PORT_Assert(alg2Mech[calg].calg == calg);
@@ -6891,16 +5971,23 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
SECKEYPrivateKey *serverKey)
{
PK11SymKey * pms;
+ unsigned char * cr = (unsigned char *)&ss->ssl3.hs.client_random;
+ unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random;
+ ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec;
+ unsigned int outLen = 0;
+ PRBool isTLS = PR_FALSE;
SECStatus rv;
SECItem enc_pms;
+ unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH];
+ SECItem pmsItem = {siBuffer, rsaPmsBuf, sizeof rsaPmsBuf};
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
enc_pms.data = b;
enc_pms.len = length;
- if (ss->ssl3->prSpec->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
+ if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
PRInt32 kLen;
kLen = ssl3_ConsumeHandshakeNumber(ss, 2, &enc_pms.data, &enc_pms.len);
if (kLen < 0) {
@@ -6910,114 +5997,83 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
if ((unsigned)kLen < enc_pms.len) {
enc_pms.len = kLen;
}
- }
- /*
- * decrypt pms out of the incoming buffer
- * Note: CKM_SSL3_PRE_MASTER_KEY_GEN is NOT the mechanism used to do
- * the unwrap. Rather, it is the mechanism with which the unwrapped
- * pms will be used.
- */
- pms = PK11_PubUnwrapSymKey(serverKey, &enc_pms,
- CKM_SSL3_PRE_MASTER_KEY_GEN, CKA_DERIVE, 0);
- if (pms != NULL) {
- PRINT_BUF(60, (ss, "decrypted premaster secret:",
- PK11_GetKeyData(pms)->data,
- PK11_GetKeyData(pms)->len));
+ isTLS = PR_TRUE;
} else {
- /* unwrap failed. Generate a bogus pre-master secret and carry on. */
- PK11SlotInfo * slot = PK11_GetSlotFromPrivateKey(serverKey);
-
- ssl_GetSpecWriteLock(ss);
- pms = ssl3_GenerateRSAPMS(ss, ss->ssl3->prSpec, slot);
- ssl_ReleaseSpecWriteLock(ss);
-
- PK11_FreeSlot(slot);
- }
-
- if (pms == NULL) {
- /* last gasp. */
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- return SECFailure;
- }
-
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms);
- if (rv != SECSuccess) {
- SEND_ALERT
- return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
+ isTLS = (PRBool)(ss->ssl3.hs.kea_def->tls_keygen != 0);
}
- return SECSuccess;
-}
-#ifdef NSS_ENABLE_ECC
-/*
-** Called from ssl3_HandleClientKeyExchange()
-*/
-static SECStatus
-ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
- PRUint32 length,
- SECKEYPublicKey *srvrPubKey,
- SECKEYPrivateKey *srvrPrivKey)
-{
- PK11SymKey * pms;
- SECStatus rv;
- SECKEYPublicKey clntPubKey;
- CK_MECHANISM_TYPE target;
- PRBool isTLS;
- CK_EC_KDF_TYPE kdf;
-
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
-
- clntPubKey.keyType = ecKey;
- clntPubKey.u.ec.DEREncodedParams.len =
- srvrPubKey->u.ec.DEREncodedParams.len;
- clntPubKey.u.ec.DEREncodedParams.data =
- srvrPubKey->u.ec.DEREncodedParams.data;
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue,
- 1, &b, &length);
- if (rv != SECSuccess) {
- SEND_ALERT
- return SECFailure; /* XXX Who sets the error code?? */
- }
-
- isTLS = (PRBool)(ss->ssl3->prSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
- else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
+ if (ss->opt.bypassPKCS11) {
+ /* TRIPLE BYPASS, get PMS directly from RSA decryption.
+ * Use PK11_PrivDecryptPKCS1 to decrypt the PMS to a buffer,
+ * then, check for version rollback attack, then
+ * do the equivalent of ssl3_DeriveMasterSecret, placing the MS in
+ * pwSpec->msItem. Finally call ssl3_InitPendingCipherSpec with
+ * ss and NULL, so that it will use the MS we've already derived here.
+ */
- /* If field size is not more than 24 octets, then use SHA-1 hash of result;
- * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt).
- */
- if (srvrPubKey->u.ec.size <= 24 * 8) {
- kdf = CKD_SHA1_KDF;
+ rv = PK11_PrivDecryptPKCS1(serverKey, rsaPmsBuf, &outLen,
+ sizeof rsaPmsBuf, enc_pms.data, enc_pms.len);
+ if (rv != SECSuccess) {
+ /* avoid Bleichenbacker attack. generate faux pms. */
+ rv = PK11_GenerateRandom(rsaPmsBuf, sizeof rsaPmsBuf);
+ /* ignore failure */
+ } else if (ss->opt.detectRollBack) {
+ SSL3ProtocolVersion client_version =
+ (rsaPmsBuf[0] << 8) | rsaPmsBuf[1];
+ if (client_version != ss->clientHelloVersion) {
+ /* Version roll-back detected. ensure failure. */
+ rv = PK11_GenerateRandom(rsaPmsBuf, sizeof rsaPmsBuf);
+ }
+ }
+ /* have PMS, build MS without PKCS11 */
+ rv = ssl3_MasterKeyDeriveBypass(pwSpec, cr, sr, &pmsItem, isTLS,
+ PR_TRUE);
+ if (rv != SECSuccess) {
+ pwSpec->msItem.data = pwSpec->raw_master_secret;
+ pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH;
+ PK11_GenerateRandom(pwSpec->msItem.data, pwSpec->msItem.len);
+ }
+ rv = ssl3_InitPendingCipherSpec(ss, NULL);
} else {
- kdf = CKD_NULL;
- }
+ /*
+ * unwrap pms out of the incoming buffer
+ * Note: CKM_SSL3_MASTER_KEY_DERIVE is NOT the mechanism used to do
+ * the unwrap. Rather, it is the mechanism with which the
+ * unwrapped pms will be used.
+ */
+ pms = PK11_PubUnwrapSymKey(serverKey, &enc_pms,
+ CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
+ if (pms != NULL) {
+ PRINT_BUF(60, (ss, "decrypted premaster secret:",
+ PK11_GetKeyData(pms)->data,
+ PK11_GetKeyData(pms)->len));
+ } else {
+ /* unwrap failed. Generate a bogus PMS and carry on. */
+ PK11SlotInfo * slot = PK11_GetSlotFromPrivateKey(serverKey);
- /* Determine the PMS */
- pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL,
- CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
- kdf, NULL, NULL);
+ ssl_GetSpecWriteLock(ss);
+ pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.prSpec, slot);
+ ssl_ReleaseSpecWriteLock(ss);
+ PK11_FreeSlot(slot);
+ }
- PORT_Free(clntPubKey.u.ec.publicValue.data);
+ if (pms == NULL) {
+ /* last gasp. */
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ return SECFailure;
+ }
- if (pms == NULL) {
- /* last gasp. */
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- return SECFailure;
+ rv = ssl3_InitPendingCipherSpec(ss, pms);
+ PK11_FreeSymKey(pms);
}
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms);
if (rv != SECSuccess) {
SEND_ALERT
- return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
+ return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
}
return SECSuccess;
}
-#endif /* NSS_ENABLE_ECC */
+
/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
* ssl3 ClientKeyExchange message from the remote client
@@ -7036,16 +6092,16 @@ const ssl3KEADef * kea_def;
SSL_TRC(3, ("%d: SSL3[%d]: handle client_key_exchange handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- if (ss->ssl3->hs.ws != wait_client_key) {
+ if (ss->ssl3.hs.ws != wait_client_key) {
SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH);
return SECFailure;
}
- kea_def = ss->ssl3->hs.kea_def;
+ kea_def = ss->ssl3.hs.kea_def;
#ifdef NSS_ENABLE_ECC
/* XXX Using SSLKEAType to index server certifiates
@@ -7064,16 +6120,16 @@ const ssl3KEADef * kea_def;
} else {
#endif /* NSS_ENABLE_ECC */
- serverKey = (ss->ssl3->hs.usedStepDownKey
+ serverKey = (ss->ssl3.hs.usedStepDownKey
#ifdef DEBUG
&& kea_def->is_limited /* XXX OR cert is signing only */
&& kea_def->exchKeyType == kt_rsa
&& ss->stepDownKeyPair != NULL
#endif
) ? ss->stepDownKeyPair->privKey
- : ss->serverCerts[kea_def->exchKeyType].serverKey;
+ : ss->serverCerts[kea_def->exchKeyType].SERVERKEY;
- if (ss->ssl3->hs.usedStepDownKey
+ if (ss->ssl3.hs.usedStepDownKey
#ifdef DEBUG
&& kea_def->is_limited /* XXX OR cert is signing only */
&& kea_def->exchKeyType == kt_rsa
@@ -7084,7 +6140,7 @@ const ssl3KEADef * kea_def;
ss->sec.keaKeyBits = EXPORT_RSA_KEY_LENGTH * BPB;
} else {
sslServerCerts * sc = ss->serverCerts + kea_def->exchKeyType;
- serverKey = sc->serverKey;
+ serverKey = sc->SERVERKEY;
ss->sec.keaKeyBits = sc->serverKeyBits;
}
@@ -7105,17 +6161,11 @@ const ssl3KEADef * kea_def;
rv = ssl3_HandleRSAClientKeyExchange(ss, b, length, serverKey);
if (rv != SECSuccess) {
SEND_ALERT
- return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
- }
- break;
-
- case kt_fortezza:
- rv = ssl3_HandleFortezzaClientKeyExchange(ss, b, length, serverKey);
- if (rv != SECSuccess) {
return SECFailure; /* error code set */
}
break;
+
#ifdef NSS_ENABLE_ECC
case kt_ecdh:
/* XXX We really ought to be able to store multiple
@@ -7150,7 +6200,7 @@ const ssl3KEADef * kea_def;
PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
return SECFailure;
}
- ss->ssl3->hs.ws = ss->sec.peerCert ? wait_cert_verify : wait_change_cipher;
+ ss->ssl3.hs.ws = ss->sec.peerCert ? wait_cert_verify : wait_change_cipher;
return SECSuccess;
}
@@ -7250,8 +6300,8 @@ ssl3_SendCertificate(sslSocket *ss)
SSL_TRC(3, ("%d: SSL3[%d]: send certificate handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
if (ss->sec.localCert)
CERT_DestroyCertificate(ss->sec.localCert);
@@ -7266,20 +6316,20 @@ ssl3_SendCertificate(sslSocket *ss)
* for ECDHE-ECDSA or client-side authentication
* using EC certificates.
*/
- if ((ss->ssl3->hs.kea_def->kea == kea_ecdhe_rsa) ||
- (ss->ssl3->hs.kea_def->kea == kea_dhe_rsa)) {
+ if ((ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) ||
+ (ss->ssl3.hs.kea_def->kea == kea_dhe_rsa)) {
certIndex = kt_rsa;
} else {
- certIndex = ss->ssl3->hs.kea_def->exchKeyType;
+ certIndex = ss->ssl3.hs.kea_def->exchKeyType;
}
sc = ss->serverCerts + certIndex;
certChain = sc->serverCertChain;
ss->sec.authKeyBits = sc->serverKeyBits;
- ss->sec.authAlgorithm = ss->ssl3->hs.kea_def->signKeyType;
+ ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType;
ss->sec.localCert = CERT_DupCertificate(sc->serverCert);
} else {
- certChain = ss->ssl3->clientCertChain;
- ss->sec.localCert = CERT_DupCertificate(ss->ssl3->clientCertificate);
+ certChain = ss->ssl3.clientCertChain;
+ ss->sec.localCert = CERT_DupCertificate(ss->ssl3.clientCertificate);
}
#ifdef NISCC_TEST
@@ -7334,17 +6384,17 @@ ssl3_SendCertificate(sslSocket *ss)
* from the cert database after they've been validated.
*/
static void
-ssl3_CleanupPeerCerts(ssl3State *ssl3)
+ssl3_CleanupPeerCerts(sslSocket *ss)
{
- PRArenaPool * arena = ssl3->peerCertArena;
- ssl3CertNode *certs = (ssl3CertNode *)ssl3->peerCertChain;
+ PRArenaPool * arena = ss->ssl3.peerCertArena;
+ ssl3CertNode *certs = (ssl3CertNode *)ss->ssl3.peerCertChain;
for (; certs; certs = certs->next) {
CERT_DestroyCertificate(certs->cert);
}
if (arena) PORT_FreeArena(arena, PR_FALSE);
- ssl3->peerCertArena = NULL;
- ssl3->peerCertChain = NULL;
+ ss->ssl3.peerCertArena = NULL;
+ ss->ssl3.peerCertChain = NULL;
}
/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
@@ -7357,7 +6407,6 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
ssl3CertNode * c;
ssl3CertNode * certs = NULL;
PRArenaPool * arena = NULL;
- ssl3State * ssl3 = ss->ssl3;
CERTCertificate *cert;
PRInt32 remaining = 0;
PRInt32 size;
@@ -7371,11 +6420,11 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SSL_TRC(3, ("%d: SSL3[%d]: handle certificate handshake",
SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- if ((ssl3->hs.ws != wait_server_cert) &&
- (ssl3->hs.ws != wait_client_cert)) {
+ if ((ss->ssl3.hs.ws != wait_server_cert) &&
+ (ss->ssl3.hs.ws != wait_client_cert)) {
desc = unexpected_message;
errCode = SSL_ERROR_RX_UNEXPECTED_CERTIFICATE;
goto alert_loser;
@@ -7390,8 +6439,8 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
ss->sec.peerCert = NULL;
}
- ssl3_CleanupPeerCerts(ssl3);
- isTLS = (PRBool)(ssl3->prSpec->version > SSL_LIBRARY_VERSION_3_0);
+ ssl3_CleanupPeerCerts(ss);
+ isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
/* It is reported that some TLS client sends a Certificate message
** with a zero-length message body. We'll treat that case like a
@@ -7418,7 +6467,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto cert_block;
}
- ssl3->peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ ss->ssl3.peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( arena == NULL ) {
goto loser; /* don't send alerts on memory errors */
}
@@ -7493,18 +6542,8 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECKEY_UpdateCertPQG(ss->sec.peerCert);
/*
- * We're making a fortezza connection, and the card hasn't unloaded it's
- * certs, try to unload those certs now.
+ * Ask caller-supplied callback function to validate cert chain.
*/
- if (!trusted) {
- CERTCertificate *ccert;
-
- ccert = PK11_FindBestKEAMatch(ss->sec.peerCert, ss->pkcs11PinArg);
- if (ccert)
- CERT_DestroyCertificate(ccert);
- }
-
-
rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, ss->fd,
PR_TRUE, isServer);
if (rv) {
@@ -7518,7 +6557,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
/* someone will handle this connection asynchronously*/
SSL_DBG(("%d: SSL3[%d]: go to async cert handler",
SSL_GETPID(), ss->fd));
- ssl3->peerCertChain = certs;
+ ss->ssl3.peerCertChain = certs;
certs = NULL;
ssl_SetAlwaysBlock(ss);
goto cert_block;
@@ -7533,14 +6572,14 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
cert = ss->sec.peerCert;
if (!isServer &&
ssl3_global_policy_some_restricted &&
- ssl3->policy == SSL_ALLOWED &&
+ ss->ssl3.policy == SSL_ALLOWED &&
anyRestrictedEnabled(ss) &&
SECSuccess == CERT_VerifyCertNow(cert->dbhandle, cert,
PR_FALSE, /* checkSig */
certUsageSSLServerWithStepUp,
/*XXX*/ ss->authCertificateArg) ) {
- ssl3->policy = SSL_RESTRICTED;
- ssl3->hs.rehandshake = PR_TRUE;
+ ss->ssl3.policy = SSL_RESTRICTED;
+ ss->ssl3.hs.rehandshake = PR_TRUE;
}
ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
@@ -7551,8 +6590,8 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
** it will get fixed when we handle the server key exchange message.
*/
SECKEYPublicKey * pubKey = CERT_ExtractPublicKey(cert);
- ss->sec.authAlgorithm = ssl3->hs.kea_def->signKeyType;
- ss->sec.keaType = ssl3->hs.kea_def->exchKeyType;
+ ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType;
+ ss->sec.keaType = ss->ssl3.hs.kea_def->exchKeyType;
if (pubKey) {
ss->sec.keaKeyBits = ss->sec.authKeyBits =
SECKEY_PublicKeyStrengthInBits(pubKey);
@@ -7565,7 +6604,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
* cert->signatureWrap.signature.len contains the
* length of the encoded signature in bits.
*/
- if (ss->ssl3->hs.kea_def->kea == kea_ecdh_ecdsa) {
+ if (ss->ssl3.hs.kea_def->kea == kea_ecdh_ecdsa) {
ss->sec.authKeyBits =
cert->signatureWrap.signature.data[3]*8;
if (cert->signatureWrap.signature.data[4] == 0x00)
@@ -7574,7 +6613,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
* XXX: if cert is not signed by ecdsa we should
* destroy pubKey and goto bad_cert
*/
- } else if (ss->ssl3->hs.kea_def->kea == kea_ecdh_rsa) {
+ } else if (ss->ssl3.hs.kea_def->kea == kea_ecdh_rsa) {
ss->sec.authKeyBits = cert->signatureWrap.signature.len;
/*
* XXX: if cert is not signed by rsa we should
@@ -7588,22 +6627,21 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
}
- ssl3->peerCertChain = certs; certs = NULL; arena = NULL;
+ ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL;
cert_block:
if (ss->sec.isServer) {
- ssl3->hs.ws = wait_client_key;
+ ss->ssl3.hs.ws = wait_client_key;
} else {
- ssl3->hs.ws = wait_cert_request; /* disallow server_key_exchange */
- if (ssl3->hs.kea_def->is_limited ||
+ ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */
+ if (ss->ssl3.hs.kea_def->is_limited ||
/* XXX OR server cert is signing only. */
- ssl3->hs.kea_def->kea == kea_fortezza ||
#ifdef NSS_ENABLE_ECC
- ssl3->hs.kea_def->kea == kea_ecdhe_ecdsa ||
- ssl3->hs.kea_def->kea == kea_ecdhe_rsa ||
+ ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
+ ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa ||
#endif /* NSS_ENABLE_ECC */
- ssl3->hs.kea_def->exchKeyType == kt_dh) {
- ssl3->hs.ws = wait_server_key; /* allow server_key_exchange */
+ ss->ssl3.hs.kea_def->exchKeyType == kt_dh) {
+ ss->ssl3.hs.ws = wait_server_key; /* allow server_key_exchange */
}
}
@@ -7660,8 +6698,8 @@ alert_loser:
(void)SSL3_SendAlert(ss, alert_fatal, desc);
loser:
- ssl3->peerCertChain = certs; certs = NULL; arena = NULL;
- ssl3_CleanupPeerCerts(ssl3);
+ ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL;
+ ssl3_CleanupPeerCerts(ss);
if (ss->sec.peerCert != NULL) {
CERT_DestroyCertificate(ss->sec.peerCert);
@@ -7687,14 +6725,13 @@ int
ssl3_RestartHandshakeAfterServerCert(sslSocket *ss)
{
CERTCertificate * cert;
- ssl3State * ssl3 = ss->ssl3;
int rv = SECSuccess;
if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
SET_ERROR_CODE
return SECFailure;
}
- if (!ss->ssl3) {
+ if (!ss->ssl3.initialized) {
SET_ERROR_CODE
return SECFailure;
}
@@ -7704,14 +6741,14 @@ ssl3_RestartHandshakeAfterServerCert(sslSocket *ss)
/* Permit step up if user decided to accept the cert */
if (!ss->sec.isServer &&
ssl3_global_policy_some_restricted &&
- ssl3->policy == SSL_ALLOWED &&
+ ss->ssl3.policy == SSL_ALLOWED &&
anyRestrictedEnabled(ss) &&
(SECSuccess == CERT_VerifyCertNow(cert->dbhandle, cert,
PR_FALSE, /* checksig */
certUsageSSLServerWithStepUp,
/*XXX*/ ss->authCertificateArg) )) {
- ssl3->policy = SSL_RESTRICTED;
- ssl3->hs.rehandshake = PR_TRUE;
+ ss->ssl3.policy = SSL_RESTRICTED;
+ ss->ssl3.hs.rehandshake = PR_TRUE;
}
if (ss->handshake != NULL) {
@@ -7719,7 +6756,7 @@ ssl3_RestartHandshakeAfterServerCert(sslSocket *ss)
ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
ssl_GetRecvBufLock(ss);
- if (ssl3->hs.msgState.buf != NULL) {
+ if (ss->ssl3.hs.msgState.buf != NULL) {
rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
}
ssl_ReleaseRecvBufLock(ss);
@@ -7734,29 +6771,43 @@ ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
const SSL3Finished * hashes,
TLSFinished * tlsFinished)
{
- PK11Context *prf_context;
const char * label;
unsigned int len;
SECStatus rv;
- SECItem param = {siBuffer, NULL, 0};
label = isServer ? "server finished" : "client finished";
len = 15;
- prf_context =
- PK11_CreateContextBySymKey(CKM_TLS_PRF_GENERAL, CKA_SIGN,
- spec->master_secret, &param);
- if (!prf_context)
- return SECFailure;
+ if (spec->master_secret && !spec->bypassCiphers) {
+ SECItem param = {siBuffer, NULL, 0};
+ PK11Context *prf_context =
+ PK11_CreateContextBySymKey(CKM_TLS_PRF_GENERAL, CKA_SIGN,
+ spec->master_secret, &param);
+ if (!prf_context)
+ return SECFailure;
- rv = PK11_DigestBegin(prf_context);
- rv |= PK11_DigestOp(prf_context, (const unsigned char *) label, len);
- rv |= PK11_DigestOp(prf_context, hashes->md5, sizeof *hashes);
- rv |= PK11_DigestFinal(prf_context, tlsFinished->verify_data,
- &len, sizeof *tlsFinished);
- PORT_Assert(rv != SECSuccess || len == sizeof *tlsFinished);
+ rv = PK11_DigestBegin(prf_context);
+ rv |= PK11_DigestOp(prf_context, (const unsigned char *) label, len);
+ rv |= PK11_DigestOp(prf_context, hashes->md5, sizeof *hashes);
+ rv |= PK11_DigestFinal(prf_context, tlsFinished->verify_data,
+ &len, sizeof tlsFinished->verify_data);
+ PORT_Assert(rv != SECSuccess || len == sizeof *tlsFinished);
- PK11_DestroyContext(prf_context, PR_TRUE);
+ PK11_DestroyContext(prf_context, PR_TRUE);
+ } else {
+ /* bypass PKCS11 */
+ SECItem inData = { siBuffer, };
+ SECItem outData = { siBuffer, };
+ PRBool isFIPS = PR_FALSE;
+
+ inData.data = (unsigned char *)hashes->md5;
+ inData.len = sizeof hashes[0];
+ outData.data = tlsFinished->verify_data;
+ outData.len = sizeof tlsFinished->verify_data;
+ rv = TLS_PRF(&spec->msItem, label, &inData, &outData, isFIPS);
+ PORT_Assert(rv != SECSuccess || \
+ outData.len == sizeof tlsFinished->verify_data);
+ }
return rv;
}
@@ -7777,11 +6828,11 @@ ssl3_SendFinished(sslSocket *ss, PRInt32 flags)
SSL_TRC(3, ("%d: SSL3[%d]: send finished handshake", SSL_GETPID(), ss->fd));
- PORT_Assert( ssl_HaveXmitBufLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
ssl_GetSpecReadLock(ss);
- cwSpec = ss->ssl3->cwSpec;
+ cwSpec = ss->ssl3.cwSpec;
isTLS = (PRBool)(cwSpec->version > SSL_LIBRARY_VERSION_3_0);
rv = ssl3_ComputeHandshakeHashes(ss, cwSpec, &hashes, sender);
if (isTLS && rv == SECSuccess) {
@@ -7817,7 +6868,88 @@ fail:
return rv;
}
+/* wrap the master secret, and put it into the SID.
+ * Caller holds the Spec read lock.
+ */
+static SECStatus
+ssl3_CacheWrappedMasterSecret(sslSocket *ss, SSL3KEAType effectiveExchKeyType)
+{
+ sslSessionID * sid = ss->sec.ci.sid;
+ PK11SymKey * wrappingKey = NULL;
+ PK11SlotInfo * symKeySlot;
+ void * pwArg = ss->pkcs11PinArg;
+ SECStatus rv = SECFailure;
+ PRBool isServer = ss->sec.isServer;
+ CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
+ symKeySlot = PK11_GetSlotFromKey(ss->ssl3.crSpec->master_secret);
+ if (!isServer) {
+ int wrapKeyIndex;
+ int incarnation;
+
+ /* these next few functions are mere accessors and don't fail. */
+ sid->u.ssl3.masterWrapIndex = wrapKeyIndex =
+ PK11_GetCurrentWrapIndex(symKeySlot);
+ PORT_Assert(wrapKeyIndex == 0); /* array has only one entry! */
+
+ sid->u.ssl3.masterWrapSeries = incarnation =
+ PK11_GetSlotSeries(symKeySlot);
+ sid->u.ssl3.masterSlotID = PK11_GetSlotID(symKeySlot);
+ sid->u.ssl3.masterModuleID = PK11_GetModuleID(symKeySlot);
+ sid->u.ssl3.masterValid = PR_TRUE;
+ /* Get the default wrapping key, for wrapping the master secret before
+ * placing it in the SID cache entry. */
+ wrappingKey = PK11_GetWrapKey(symKeySlot, wrapKeyIndex,
+ CKM_INVALID_MECHANISM, incarnation,
+ pwArg);
+ if (wrappingKey) {
+ mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
+ } else {
+ int keyLength;
+ /* if the wrappingKey doesn't exist, attempt to create it.
+ * Note: we intentionally ignore errors here. If we cannot
+ * generate a wrapping key, it is not fatal to this SSL connection,
+ * but we will not be able to restart this session.
+ */
+ mechanism = PK11_GetBestWrapMechanism(symKeySlot);
+ keyLength = PK11_GetBestKeyLength(symKeySlot, mechanism);
+ /* Zero length means fixed key length algorithm, or error.
+ * It's ambiguous.
+ */
+ wrappingKey = PK11_KeyGen(symKeySlot, mechanism, NULL,
+ keyLength, pwArg);
+ if (wrappingKey) {
+ PK11_SetWrapKey(symKeySlot, wrapKeyIndex, wrappingKey);
+ }
+ }
+ } else {
+ /* server socket using session cache. */
+ mechanism = PK11_GetBestWrapMechanism(symKeySlot);
+ if (mechanism != CKM_INVALID_MECHANISM) {
+ wrappingKey =
+ getWrappingKey(ss, symKeySlot, effectiveExchKeyType,
+ mechanism, pwArg);
+ if (wrappingKey) {
+ mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
+ }
+ }
+ }
+
+ sid->u.ssl3.masterWrapMech = mechanism;
+ PK11_FreeSlot(symKeySlot);
+ if (wrappingKey) {
+ SECItem wmsItem;
+
+ wmsItem.data = sid->u.ssl3.keys.wrapped_master_secret;
+ wmsItem.len = sizeof sid->u.ssl3.keys.wrapped_master_secret;
+ rv = PK11_WrapSymKey(mechanism, NULL, wrappingKey,
+ ss->ssl3.crSpec->master_secret, &wmsItem);
+ /* rv is examined below. */
+ sid->u.ssl3.keys.wrapped_master_secret_len = wmsItem.len;
+ PK11_FreeSymKey(wrappingKey);
+ }
+ return rv;
+}
/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
* ssl3 Finished message from the peer.
@@ -7827,31 +6959,26 @@ static SECStatus
ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
const SSL3Hashes *hashes)
{
- ssl3State * ssl3 = ss->ssl3;
sslSessionID * sid = ss->sec.ci.sid;
- PK11SymKey * wrappingKey = NULL;
- PK11SlotInfo * symKeySlot;
- void * pwArg = ss->pkcs11PinArg;
- SECStatus rv;
+ SECStatus rv = SECSuccess;
PRBool isServer = ss->sec.isServer;
PRBool isTLS;
PRBool doStepUp;
- CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
SSL3KEAType effectiveExchKeyType;
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
SSL_TRC(3, ("%d: SSL3[%d]: handle finished handshake",
SSL_GETPID(), ss->fd));
- if (ssl3->hs.ws != wait_finished) {
+ if (ss->ssl3.hs.ws != wait_finished) {
SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_FINISHED);
return SECFailure;
}
- isTLS = (PRBool)(ssl3->crSpec->version > SSL_LIBRARY_VERSION_3_0);
+ isTLS = (PRBool)(ss->ssl3.crSpec->version > SSL_LIBRARY_VERSION_3_0);
if (isTLS) {
TLSFinished tlsFinished;
@@ -7860,7 +6987,7 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED);
return SECFailure;
}
- rv = ssl3_ComputeTLSFinished(ssl3->crSpec, !isServer,
+ rv = ssl3_ComputeTLSFinished(ss->ssl3.crSpec, !isServer,
hashes, &tlsFinished);
if (rv != SECSuccess ||
0 != PORT_Memcmp(&tlsFinished, b, length)) {
@@ -7882,12 +7009,12 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
}
}
- doStepUp = (PRBool)(!isServer && ssl3->hs.rehandshake);
+ doStepUp = (PRBool)(!isServer && ss->ssl3.hs.rehandshake);
ssl_GetXmitBufLock(ss); /*************************************/
- if ((isServer && !ssl3->hs.isResuming) ||
- (!isServer && ssl3->hs.isResuming)) {
+ if ((isServer && !ss->ssl3.hs.isResuming) ||
+ (!isServer && ss->ssl3.hs.isResuming)) {
PRInt32 flags = 0;
rv = ssl3_SendChangeCipherSpecs(ss);
@@ -7913,7 +7040,7 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
if (doStepUp) {
ssl_FreeSID(sid);
ss->sec.ci.sid = sid = NULL;
- ssl3->hs.rehandshake = PR_FALSE;
+ ss->ssl3.hs.rehandshake = PR_FALSE;
rv = ssl3_SendClientHello(ss);
xmit_loser:
ssl_ReleaseXmitBufLock(ss);
@@ -7928,113 +7055,52 @@ xmit_loser:
ss->gs.writeOffset = 0;
ss->gs.readOffset = 0;
- if (ssl3->hs.kea_def->kea == kea_ecdhe_rsa) {
+ if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
effectiveExchKeyType = kt_rsa;
} else {
- effectiveExchKeyType = ssl3->hs.kea_def->exchKeyType;
- }
-
- if (sid->cached == never_cached) {
-
- /* fill in the sid */
- sid->u.ssl3.cipherSuite = ssl3->hs.cipher_suite;
- sid->u.ssl3.compression = ssl3->hs.compression;
- sid->u.ssl3.policy = ssl3->policy;
- sid->u.ssl3.exchKeyType = effectiveExchKeyType;
- sid->version = ss->version;
- sid->authAlgorithm = ss->sec.authAlgorithm;
- sid->authKeyBits = ss->sec.authKeyBits;
- sid->keaType = ss->sec.keaType;
- sid->keaKeyBits = ss->sec.keaKeyBits;
- sid->lastAccessTime = sid->creationTime = ssl_Time();
- sid->expirationTime = sid->creationTime + ssl3_sid_timeout;
- sid->localCert = CERT_DupCertificate(ss->sec.localCert);
-
- ssl_GetSpecReadLock(ss); /*************************************/
- symKeySlot = PK11_GetSlotFromKey(ssl3->crSpec->master_secret);
- if (!isServer) {
- int wrapKeyIndex;
- int incarnation;
-
- /* these next few functions are mere accessors and don't fail. */
- sid->u.ssl3.masterWrapIndex = wrapKeyIndex =
- PK11_GetCurrentWrapIndex(symKeySlot);
- PORT_Assert(wrapKeyIndex == 0); /* array has only one entry! */
-
- sid->u.ssl3.masterWrapSeries = incarnation =
- PK11_GetSlotSeries(symKeySlot);
- sid->u.ssl3.masterSlotID = PK11_GetSlotID(symKeySlot);
- sid->u.ssl3.masterModuleID = PK11_GetModuleID(symKeySlot);
- sid->u.ssl3.masterValid = PR_TRUE;
-
- /* Get the default wrapping key, for wrapping the master secret before
- * placing it in the SID cache entry. */
- wrappingKey = PK11_GetWrapKey(symKeySlot, wrapKeyIndex,
- CKM_INVALID_MECHANISM, incarnation,
- pwArg);
- if (wrappingKey) {
- mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
+ effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
+ }
+
+ if (sid->cached == never_cached && !ss->opt.noCache && ss->sec.cache) {
+ /* fill in the sid */
+ sid->u.ssl3.cipherSuite = ss->ssl3.hs.cipher_suite;
+ sid->u.ssl3.compression = ss->ssl3.hs.compression;
+ sid->u.ssl3.policy = ss->ssl3.policy;
+ sid->u.ssl3.exchKeyType = effectiveExchKeyType;
+ sid->version = ss->version;
+ sid->authAlgorithm = ss->sec.authAlgorithm;
+ sid->authKeyBits = ss->sec.authKeyBits;
+ sid->keaType = ss->sec.keaType;
+ sid->keaKeyBits = ss->sec.keaKeyBits;
+ sid->lastAccessTime = sid->creationTime = ssl_Time();
+ sid->expirationTime = sid->creationTime + ssl3_sid_timeout;
+ sid->localCert = CERT_DupCertificate(ss->sec.localCert);
+
+ ssl_GetSpecReadLock(ss); /*************************************/
+
+ /* Copy the master secret (wrapped or unwrapped) into the sid */
+ if (ss->ssl3.crSpec->msItem.len && ss->ssl3.crSpec->msItem.data) {
+ sid->u.ssl3.keys.wrapped_master_secret_len =
+ ss->ssl3.crSpec->msItem.len;
+ memcpy(sid->u.ssl3.keys.wrapped_master_secret,
+ ss->ssl3.crSpec->msItem.data, ss->ssl3.crSpec->msItem.len);
+ sid->u.ssl3.masterValid = PR_TRUE;
+ sid->u.ssl3.keys.msIsWrapped = PR_FALSE;
+ rv = SECSuccess;
} else {
- int keyLength;
- /* if the wrappingKey doesn't exist, attempt to create it.
- * Note: we intentionally ignore errors here. If we cannot
- * generate a wrapping key, it is not fatal to this SSL connection,
- * but we will not be able to restart this session.
- */
- mechanism = PK11_GetBestWrapMechanism(symKeySlot);
- keyLength = PK11_GetBestKeyLength(symKeySlot, mechanism);
- /* Zero length means fixed key length algorithm, or error.
- * It's ambiguous.
- */
- wrappingKey = PK11_KeyGen(symKeySlot, mechanism, NULL,
- keyLength, pwArg);
- if (wrappingKey) {
- PK11_SetWrapKey(symKeySlot, wrapKeyIndex, wrappingKey);
- }
- }
- } else if (!ss->noCache) {
- /* server socket using session cache. */
- mechanism = PK11_GetBestWrapMechanism(symKeySlot);
- if (mechanism != CKM_INVALID_MECHANISM) {
- wrappingKey =
- getWrappingKey(ss, symKeySlot, effectiveExchKeyType,
- mechanism, pwArg);
- if (wrappingKey) {
- mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
- }
+ rv = ssl3_CacheWrappedMasterSecret(ss, effectiveExchKeyType);
+ sid->u.ssl3.keys.msIsWrapped = PR_TRUE;
}
- }
-
- sid->u.ssl3.masterWrapMech = mechanism;
- PK11_FreeSlot(symKeySlot);
-
- rv = SECFailure;
- if (wrappingKey) {
- SECItem msItem;
+ ssl_ReleaseSpecReadLock(ss); /*************************************/
- msItem.data = sid->u.ssl3.keys.wrapped_master_secret;
- msItem.len = sizeof sid->u.ssl3.keys.wrapped_master_secret;
- rv = PK11_WrapSymKey(mechanism, NULL, wrappingKey,
- ssl3->crSpec->master_secret, &msItem);
- /* rv is examined below. */
- sid->u.ssl3.keys.wrapped_master_secret_len = msItem.len;
- PK11_FreeSymKey(wrappingKey);
- }
- ssl_ReleaseSpecReadLock(ss); /*************************************/
-
- /* If the wrap failed, we don't cache the sid.
- * The connection continues normally however.
- */
- if (!ss->noCache && rv == SECSuccess) {
- if (ss->sec.cache) {
+ /* If the wrap failed, we don't cache the sid.
+ * The connection continues normally however.
+ */
+ if (rv == SECSuccess) {
(*ss->sec.cache)(sid);
- } else {
- PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED);
- return SECFailure;
}
}
- }
- ss->ssl3->hs.ws = idle_handshake;
+ ss->ssl3.hs.ws = idle_handshake;
/* Do the handshake callback for sslv3 here. */
if (ss->handshakeCallback != NULL) {
@@ -8052,12 +7118,12 @@ static SECStatus
ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
{
SECStatus rv = SECSuccess;
- SSL3HandshakeType type = ss->ssl3->hs.msg_type;
+ SSL3HandshakeType type = ss->ssl3.hs.msg_type;
SSL3Hashes hashes; /* computed hashes are put here. */
PRUint8 hdr[4];
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
/*
* We have to compute the hashes before we update them with the
* current message.
@@ -8065,11 +7131,11 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
ssl_GetSpecReadLock(ss); /************************************/
if((type == finished) || (type == certificate_verify)) {
SSL3Sender sender = (SSL3Sender)0;
- ssl3CipherSpec *rSpec = ss->ssl3->prSpec;
+ ssl3CipherSpec *rSpec = ss->ssl3.prSpec;
if (type == finished) {
sender = ss->sec.isServer ? sender_client : sender_server;
- rSpec = ss->ssl3->crSpec;
+ rSpec = ss->ssl3.crSpec;
}
rv = ssl3_ComputeHandshakeHashes(ss, rSpec, &hashes, sender);
}
@@ -8078,34 +7144,39 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
return rv; /* error code was set by ssl3_ComputeHandshakeHashes*/
}
SSL_TRC(30,("%d: SSL3[%d]: handle handshake message: %s", SSL_GETPID(),
- ss->fd, ssl3_DecodeHandshakeType(ss->ssl3->hs.msg_type)));
+ ss->fd, ssl3_DecodeHandshakeType(ss->ssl3.hs.msg_type)));
PRINT_BUF(60, (ss, "MD5 handshake hash:",
- (unsigned char*)ss->ssl3->hs.md5, MD5_LENGTH));
+ (unsigned char*)ss->ssl3.hs.md5_cx, MD5_LENGTH));
PRINT_BUF(95, (ss, "SHA handshake hash:",
- (unsigned char*)ss->ssl3->hs.sha, SHA1_LENGTH));
+ (unsigned char*)ss->ssl3.hs.sha_cx, SHA1_LENGTH));
- hdr[0] = (PRUint8)ss->ssl3->hs.msg_type;
+ hdr[0] = (PRUint8)ss->ssl3.hs.msg_type;
hdr[1] = (PRUint8)(length >> 16);
hdr[2] = (PRUint8)(length >> 8);
hdr[3] = (PRUint8)(length );
/* Start new handshake hashes when we start a new handshake */
- if (ss->ssl3->hs.msg_type == client_hello) {
+ if (ss->ssl3.hs.msg_type == client_hello) {
SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",
SSL_GETPID(), ss->fd ));
- rv = PK11_DigestBegin(ss->ssl3->hs.md5);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- return rv;
- }
- rv = PK11_DigestBegin(ss->ssl3->hs.sha);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return rv;
+ if (ss->opt.bypassPKCS11) {
+ MD5_Begin((MD5Context *)ss->ssl3.hs.md5_cx);
+ SHA1_Begin((SHA1Context *)ss->ssl3.hs.sha_cx);
+ } else {
+ rv = PK11_DigestBegin(ss->ssl3.hs.md5);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+ return rv;
+ }
+ rv = PK11_DigestBegin(ss->ssl3.hs.sha);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ return rv;
+ }
}
}
/* We should not include hello_request messages in the handshake hashes */
- if (ss->ssl3->hs.msg_type != hello_request) {
+ if (ss->ssl3.hs.msg_type != hello_request) {
rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) hdr, 4);
if (rv != SECSuccess) return rv; /* err code already set. */
rv = ssl3_UpdateHandshakeHashes(ss, b, length);
@@ -8113,7 +7184,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
}
PORT_SetError(0); /* each message starts with no error. */
- switch (ss->ssl3->hs.msg_type) {
+ switch (ss->ssl3.hs.msg_type) {
case hello_request:
if (length != 0) {
(void)ssl3_DecodeError(ss);
@@ -8217,30 +7288,29 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
* Each message is made contiguous before being passed to the actual
* message parser.
*/
- ssl3State *ssl3 = ss->ssl3;
- sslBuffer *buf = &ssl3->hs.msgState; /* do not lose the original buffer pointer */
+ sslBuffer *buf = &ss->ssl3.hs.msgState; /* do not lose the original buffer pointer */
SECStatus rv;
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
if (buf->buf == NULL) {
*buf = *origBuf;
}
while (buf->len > 0) {
- if (ssl3->hs.header_bytes < 4) {
+ if (ss->ssl3.hs.header_bytes < 4) {
uint8 t;
t = *(buf->buf++);
buf->len--;
- if (ssl3->hs.header_bytes++ == 0)
- ssl3->hs.msg_type = (SSL3HandshakeType)t;
+ if (ss->ssl3.hs.header_bytes++ == 0)
+ ss->ssl3.hs.msg_type = (SSL3HandshakeType)t;
else
- ssl3->hs.msg_len = (ssl3->hs.msg_len << 8) + t;
- if (ssl3->hs.header_bytes < 4)
+ ss->ssl3.hs.msg_len = (ss->ssl3.hs.msg_len << 8) + t;
+ if (ss->ssl3.hs.header_bytes < 4)
continue;
#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
- if (ssl3->hs.msg_len > MAX_HANDSHAKE_MSG_LEN) {
+ if (ss->ssl3.hs.msg_len > MAX_HANDSHAKE_MSG_LEN) {
(void)ssl3_DecodeError(ss);
PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
return SECFailure;
@@ -8250,7 +7320,7 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
/* If msg_len is zero, be sure we fall through,
** even if buf->len is zero.
*/
- if (ssl3->hs.msg_len > 0)
+ if (ss->ssl3.hs.msg_len > 0)
continue;
}
@@ -8259,9 +7329,9 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
* data available for this message. If it can be done right out
* of the original buffer, then use it from there.
*/
- if (ssl3->hs.msg_body.len == 0 && buf->len >= ssl3->hs.msg_len) {
+ if (ss->ssl3.hs.msg_body.len == 0 && buf->len >= ss->ssl3.hs.msg_len) {
/* handle it from input buffer */
- rv = ssl3_HandleHandshakeMessage(ss, buf->buf, ssl3->hs.msg_len);
+ rv = ssl3_HandleHandshakeMessage(ss, buf->buf, ss->ssl3.hs.msg_len);
if (rv == SECFailure) {
/* This test wants to fall through on either
* SECSuccess or SECWouldBlock.
@@ -8269,10 +7339,10 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
*/
return rv;
}
- buf->buf += ssl3->hs.msg_len;
- buf->len -= ssl3->hs.msg_len;
- ssl3->hs.msg_len = 0;
- ssl3->hs.header_bytes = 0;
+ buf->buf += ss->ssl3.hs.msg_len;
+ buf->len -= ss->ssl3.hs.msg_len;
+ ss->ssl3.hs.msg_len = 0;
+ ss->ssl3.hs.header_bytes = 0;
if (rv != SECSuccess) { /* return if SECWouldBlock. */
return rv;
}
@@ -8280,28 +7350,28 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
/* must be copied to msg_body and dealt with from there */
unsigned int bytes;
- PORT_Assert(ssl3->hs.msg_body.len <= ssl3->hs.msg_len);
- bytes = PR_MIN(buf->len, ssl3->hs.msg_len - ssl3->hs.msg_body.len);
+ PORT_Assert(ss->ssl3.hs.msg_body.len <= ss->ssl3.hs.msg_len);
+ bytes = PR_MIN(buf->len, ss->ssl3.hs.msg_len - ss->ssl3.hs.msg_body.len);
/* Grow the buffer if needed */
- rv = sslBuffer_Grow(&ssl3->hs.msg_body, ssl3->hs.msg_len);
+ rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, ss->ssl3.hs.msg_len);
if (rv != SECSuccess) {
/* sslBuffer_Grow has set a memory error code. */
return SECFailure;
}
- PORT_Memcpy(ssl3->hs.msg_body.buf + ssl3->hs.msg_body.len,
+ PORT_Memcpy(ss->ssl3.hs.msg_body.buf + ss->ssl3.hs.msg_body.len,
buf->buf, bytes);
- ssl3->hs.msg_body.len += bytes;
+ ss->ssl3.hs.msg_body.len += bytes;
buf->buf += bytes;
buf->len -= bytes;
- PORT_Assert(ssl3->hs.msg_body.len <= ssl3->hs.msg_len);
+ PORT_Assert(ss->ssl3.hs.msg_body.len <= ss->ssl3.hs.msg_len);
/* if we have a whole message, do it */
- if (ssl3->hs.msg_body.len == ssl3->hs.msg_len) {
+ if (ss->ssl3.hs.msg_body.len == ss->ssl3.hs.msg_len) {
rv = ssl3_HandleHandshakeMessage(
- ss, ssl3->hs.msg_body.buf, ssl3->hs.msg_len);
+ ss, ss->ssl3.hs.msg_body.buf, ss->ssl3.hs.msg_len);
/*
* XXX This appears to be wrong. This error handling
* should clean up after a SECWouldBlock return, like the
@@ -8311,9 +7381,9 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
/* ssl3_HandleHandshakeMessage MUST set error code. */
return rv;
}
- ssl3->hs.msg_body.len = 0;
- ssl3->hs.msg_len = 0;
- ssl3->hs.header_bytes = 0;
+ ss->ssl3.hs.msg_body.len = 0;
+ ss->ssl3.hs.msg_len = 0;
+ ss->ssl3.hs.header_bytes = 0;
} else {
PORT_Assert(buf->len == 0);
break;
@@ -8353,7 +7423,6 @@ SECStatus
ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
{
const ssl3BulkCipherDef *cipher_def;
- ssl3State * ssl3 = ss->ssl3;
ssl3CipherSpec * crSpec;
SECStatus rv;
unsigned int hashBytes = MAX_MAC_LENGTH + 1;
@@ -8363,9 +7432,9 @@ const ssl3BulkCipherDef *cipher_def;
SSL3ContentType rType;
SSL3Opaque hash[MAX_MAC_LENGTH];
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- if (ssl3 == NULL) {
+ if (!ss->ssl3.initialized) {
ssl_GetSSL3HandshakeLock(ss);
rv = ssl3_InitState(ss);
ssl_ReleaseSSL3HandshakeLock(ss);
@@ -8374,8 +7443,6 @@ const ssl3BulkCipherDef *cipher_def;
}
}
- ssl3 = ss->ssl3;
-
/* check for Token Presence */
if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
@@ -8409,7 +7476,7 @@ const ssl3BulkCipherDef *cipher_def;
ssl_GetSpecReadLock(ss); /******************************************/
- crSpec = ssl3->crSpec;
+ crSpec = ss->ssl3.crSpec;
cipher_def = crSpec->cipher_def;
isTLS = (PRBool)(crSpec->version > SSL_LIBRARY_VERSION_3_0);
@@ -8457,9 +7524,7 @@ const ssl3BulkCipherDef *cipher_def;
/* compute the MAC */
rType = cText->type;
- rv = ssl3_ComputeRecordMAC(
- crSpec, (ss->sec.isServer) ? crSpec->client.write_mac_context
- : crSpec->server.write_mac_context,
+ rv = ssl3_ComputeRecordMAC( crSpec, (PRBool)(!ss->sec.isServer),
rType, cText->version, crSpec->read_seq_num,
databuf->buf, databuf->len, hash, &hashBytes);
if (rv != SECSuccess) {
@@ -8566,6 +7631,10 @@ ssl3_InitCipherSpec(sslSocket *ss, ssl3CipherSpec *spec)
spec->destroy = NULL;
spec->mac_size = 0;
spec->master_secret = NULL;
+ spec->bypassCiphers = PR_FALSE;
+
+ spec->msItem.data = NULL;
+ spec->msItem.len = 0;
spec->client.write_key = NULL;
spec->client.write_mac_key = NULL;
@@ -8581,7 +7650,7 @@ ssl3_InitCipherSpec(sslSocket *ss, ssl3CipherSpec *spec)
spec->read_seq_num.high = 0;
spec->read_seq_num.low = 0;
- spec->version = ss->enableTLS
+ spec->version = ss->opt.enableTLS
? SSL_LIBRARY_VERSION_3_1_TLS
: SSL_LIBRARY_VERSION_3_0;
}
@@ -8601,33 +7670,24 @@ ssl3_InitCipherSpec(sslSocket *ss, ssl3CipherSpec *spec)
static SECStatus
ssl3_InitState(sslSocket *ss)
{
- ssl3State * ssl3 = NULL;
PK11Context *md5 = NULL;
PK11Context *sha = NULL;
SECStatus rv;
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));
-
- /* reinitialization for renegotiated sessions XXX */
- if (ss->ssl3 != NULL)
- return SECSuccess;
+ if (ss->ssl3.initialized)
+ return SECSuccess; /* Function should be idempotent */
- ssl3 = PORT_ZNew(ssl3State); /* zero on purpose */
- if (ssl3 == NULL)
- return SECFailure; /* PORT_ZAlloc has set memory error code. */
-
- /* note that entire HandshakeState is zero, including the buffer */
- ssl3->policy = SSL_ALLOWED;
+ ss->ssl3.policy = SSL_ALLOWED;
ssl_GetSpecWriteLock(ss);
- ssl3->crSpec = ssl3->cwSpec = &ssl3->specs[0];
- ssl3->prSpec = ssl3->pwSpec = &ssl3->specs[1];
- ssl3->hs.rehandshake = PR_FALSE;
- ssl3_InitCipherSpec(ss, ssl3->crSpec);
- ssl3_InitCipherSpec(ss, ssl3->prSpec);
- ssl3->fortezza.tek = NULL;
-
- ssl3->hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello;
+ ss->ssl3.crSpec = ss->ssl3.cwSpec = &ss->ssl3.specs[0];
+ ss->ssl3.prSpec = ss->ssl3.pwSpec = &ss->ssl3.specs[1];
+ ss->ssl3.hs.rehandshake = PR_FALSE;
+ ssl3_InitCipherSpec(ss, ss->ssl3.crSpec);
+ ssl3_InitCipherSpec(ss, ss->ssl3.prSpec);
+
+ ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello;
ssl_ReleaseSpecWriteLock(ss);
/*
@@ -8636,37 +7696,40 @@ ssl3_InitState(sslSocket *ss)
* that the master secret will wind up in ...
*/
SSL_TRC(30,("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd));
- ssl3->hs.md5 = md5 = PK11_CreateDigestContext(SEC_OID_MD5);
- if (md5 == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- goto loser;
- }
- rv = PK11_DigestBegin(ssl3->hs.md5);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- goto loser;
- }
+ if (ss->opt.bypassPKCS11) {
+ MD5_Begin((MD5Context *)ss->ssl3.hs.md5_cx);
+ SHA1_Begin((SHA1Context *)ss->ssl3.hs.sha_cx);
+ } else {
+ ss->ssl3.hs.md5 = md5 = PK11_CreateDigestContext(SEC_OID_MD5);
+ if (md5 == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+ goto loser;
+ }
+ rv = PK11_DigestBegin(ss->ssl3.hs.md5);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+ goto loser;
+ }
- sha = ssl3->hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1);
- if (sha == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- goto loser;
- }
- rv = PK11_DigestBegin(ssl3->hs.sha);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- goto loser;
+ sha = ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1);
+ if (sha == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ goto loser;
+ }
+ rv = PK11_DigestBegin(ss->ssl3.hs.sha);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ goto loser;
+ }
}
- /* Don't hide this from the rest of the world any more. */
- ss->ssl3 = ssl3;
+ ss->ssl3.initialized = PR_TRUE;
return SECSuccess;
loser:
if (md5 != NULL) PK11_DestroyContext(md5, PR_TRUE);
if (sha != NULL) PK11_DestroyContext(sha, PR_TRUE);
- if (ssl3 != NULL) PORT_Free(ssl3);
return SECFailure;
}
@@ -8679,7 +7742,8 @@ ssl3_NewKeyPair( SECKEYPrivateKey * privKey, SECKEYPublicKey * pubKey)
{
ssl3KeyPair * pair;
- if (!privKey || !pubKey) {
+ if (!privKey && !pubKey) {
+ /* one or the other may be NULL, but not both. */
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
return NULL;
}
@@ -8704,8 +7768,10 @@ ssl3_FreeKeyPair(ssl3KeyPair * keyPair)
{
PRInt32 newCount = PR_AtomicDecrement(&keyPair->refCount);
if (!newCount) {
- SECKEY_DestroyPrivateKey(keyPair->privKey);
- SECKEY_DestroyPublicKey( keyPair->pubKey);
+ if (keyPair->privKey)
+ SECKEY_DestroyPrivateKey(keyPair->privKey);
+ if (keyPair->pubKey)
+ SECKEY_DestroyPublicKey( keyPair->pubKey);
PORT_Free(keyPair);
}
}
@@ -8728,7 +7794,7 @@ ssl3_CreateRSAStepDownKeys(sslSocket *ss)
ss->stepDownKeyPair = NULL;
#ifndef HACKED_EXPORT_SERVER
/* Sigh, should have a get key strength call for private keys */
- if (PK11_GetPrivateModulusLen(ss->serverCerts[kt_rsa].serverKey) >
+ if (PK11_GetPrivateModulusLen(ss->serverCerts[kt_rsa].SERVERKEY) >
EXPORT_RSA_KEY_LENGTH) {
/* need to ask for the key size in bits */
privKey = SECKEY_CreateRSAPrivateKey(EXPORT_RSA_KEY_LENGTH * BPB,
@@ -8743,40 +7809,6 @@ ssl3_CreateRSAStepDownKeys(sslSocket *ss)
return rv;
}
-#ifdef NSS_ENABLE_ECC
-/*
- * Creates the ephemeral public and private ECDH keys used by
- * server in ECDHE_RSA and ECDHE_ECDSA handshakes.
- * XXX For now, the elliptic curve is hardcoded to NIST P-224.
- * We need an API to specify the curve. This won't be a real
- * issue until we further develop server-side support for ECC
- * cipher suites.
- */
-SECStatus
-ssl3_CreateECDHEphemeralKeys(sslSocket *ss)
-{
- SECStatus rv = SECSuccess;
- SECKEYPrivateKey * privKey;
- SECKEYPublicKey * pubKey;
- SECKEYECParams ecParams = { siBuffer, NULL, 0 };
-
- if (ss->ephemeralECDHKeyPair)
- ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
- ss->ephemeralECDHKeyPair = NULL;
-
- if (ecName2params(NULL, ec_secp224r1, &ecParams) == SECFailure)
- return SECFailure;
- privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL);
- if (!privKey || !pubKey ||
- !(ss->ephemeralECDHKeyPair = ssl3_NewKeyPair(privKey, pubKey))) {
- ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
- rv = SECFailure;
- }
-
- PORT_Free(ecParams.data);
- return rv;
-}
-#endif /* NSS_ENABLE_ECC */
/* record the export policy for this cipher suite */
SECStatus
@@ -8902,7 +7934,7 @@ ssl3_ConstructV2CipherSpecsHack(sslSocket *ss, unsigned char *cs, int *size)
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
return SECFailure;
}
- if (!ss->enableSSL3 && !ss->enableTLS) {
+ if (!ss->opt.enableSSL3 && !ss->opt.enableTLS) {
*size = 0;
return SECSuccess;
}
@@ -8941,11 +7973,12 @@ ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache)
sslSessionID * sid = ss->sec.ci.sid;
SECStatus rv;
- PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
if (!ss->firstHsDone ||
((ss->version >= SSL_LIBRARY_VERSION_3_0) &&
- ss->ssl3 && (ss->ssl3->hs.ws != idle_handshake))) {
+ ss->ssl3.initialized &&
+ (ss->ssl3.hs.ws != idle_handshake))) {
PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
return SECFailure;
}
@@ -8967,44 +8000,43 @@ ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache)
/* Called from ssl_FreeSocket() in sslsock.c */
void
-ssl3_DestroySSL3Info(ssl3State *ssl3)
+ssl3_DestroySSL3Info(sslSocket *ss)
{
- if (ssl3 == NULL)
- return; /* success the easy way. */
- if (ssl3->clientCertificate != NULL)
- CERT_DestroyCertificate(ssl3->clientCertificate);
+ if (ss->ssl3.clientCertificate != NULL)
+ CERT_DestroyCertificate(ss->ssl3.clientCertificate);
- if (ssl3->clientPrivateKey != NULL)
- SECKEY_DestroyPrivateKey(ssl3->clientPrivateKey);
+ if (ss->ssl3.clientPrivateKey != NULL)
+ SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
- if (ssl3->peerCertArena != NULL)
- ssl3_CleanupPeerCerts(ssl3);
+ if (ss->ssl3.peerCertArena != NULL)
+ ssl3_CleanupPeerCerts(ss);
- if (ssl3->clientCertChain != NULL) {
- CERT_DestroyCertificateList(ssl3->clientCertChain);
- ssl3->clientCertChain = NULL;
+ if (ss->ssl3.clientCertChain != NULL) {
+ CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
+ ss->ssl3.clientCertChain = NULL;
}
/* clean up handshake */
- if (ssl3->hs.md5) {
- PK11_DestroyContext(ssl3->hs.md5,PR_TRUE);
+ if (ss->opt.bypassPKCS11) {
+ SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE);
+ MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE);
+ }
+ if (ss->ssl3.hs.md5) {
+ PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE);
}
- if (ssl3->hs.sha) {
- PK11_DestroyContext(ssl3->hs.sha,PR_TRUE);
+ if (ss->ssl3.hs.sha) {
+ PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE);
}
- if (ssl3->fortezza.tek != NULL) {
- PK11_FreeSymKey(ssl3->fortezza.tek);
- }
/* free the SSL3Buffer (msg_body) */
- PORT_Free(ssl3->hs.msg_body.buf);
+ PORT_Free(ss->ssl3.hs.msg_body.buf);
/* free up the CipherSpecs */
- ssl3_DestroyCipherSpec(&ssl3->specs[0]);
- ssl3_DestroyCipherSpec(&ssl3->specs[1]);
+ ssl3_DestroyCipherSpec(&ss->ssl3.specs[0]);
+ ssl3_DestroyCipherSpec(&ss->ssl3.specs[1]);
- PORT_Free(ssl3);
+ ss->ssl3.initialized = PR_FALSE;
}
/* End of ssl3con.c */
diff --git a/security/nss/lib/ssl/ssl3ecc.c b/security/nss/lib/ssl/ssl3ecc.c
new file mode 100644
index 000000000..af7cdb30f
--- /dev/null
+++ b/security/nss/lib/ssl/ssl3ecc.c
@@ -0,0 +1,673 @@
+/*
+ * SSL3 Protocol
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * 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 Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Dr Vipul Gupta <vipul.gupta@sun.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.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* ECC code moved here from ssl3con.c */
+/* $Id$ */
+
+#ifdef NSS_ENABLE_ECC
+
+#include "nssrenam.h"
+#include "cert.h"
+#include "ssl.h"
+#include "cryptohi.h" /* for DSAU_ stuff */
+#include "keyhi.h"
+#include "secder.h"
+#include "secitem.h"
+
+#include "sslimpl.h"
+#include "sslproto.h"
+#include "sslerr.h"
+#include "prtime.h"
+#include "prinrval.h"
+#include "prerror.h"
+#include "pratom.h"
+#include "prthread.h"
+
+#include "pk11func.h"
+#include "secmod.h"
+#include "nsslocks.h"
+#include "ec.h"
+#include "blapi.h"
+
+#include <stdio.h>
+
+/*
+ line 297: implicit function declaration: ssl3_InitPendingCipherSpec
+ line 305: implicit function declaration: ssl3_AppendHandshakeHeader
+ line 311: implicit function declaration: ssl3_AppendHandshakeVariable
+ line 356: implicit function declaration: ssl3_ConsumeHandshakeVariable
+*/
+
+
+#ifndef PK11_SETATTRS
+#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
+ (x)->pValue=(v); (x)->ulValueLen = (l);
+#endif
+
+/* Types and names of elliptic curves used in TLS */
+typedef enum { ec_type_explicitPrime = 1,
+ ec_type_explicitChar2Curve,
+ ec_type_named
+} ECType;
+
+typedef enum { ec_noName = 0,
+ ec_sect163k1, ec_sect163r1, ec_sect163r2,
+ ec_sect193r1, ec_sect193r2, ec_sect233k1,
+ ec_sect233r1, ec_sect239k1, ec_sect283k1,
+ ec_sect283r1, ec_sect409k1, ec_sect409r1,
+ ec_sect571k1, ec_sect571r1, ec_secp160k1,
+ ec_secp160r1, ec_secp160r2, ec_secp192k1,
+ ec_secp192r1, ec_secp224k1, ec_secp224r1,
+ ec_secp256k1, ec_secp256r1, ec_secp384r1,
+ ec_secp521r1,
+ ec_pastLastName
+} ECName;
+
+#define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName))
+
+/* Table containing OID tags for elliptic curves named in the
+ * ECC-TLS IETF draft.
+ */
+static const SECOidTag ecName2OIDTag[] = {
+ 0,
+ SEC_OID_SECG_EC_SECT163K1, /* 1 */
+ SEC_OID_SECG_EC_SECT163R1, /* 2 */
+ SEC_OID_SECG_EC_SECT163R2, /* 3 */
+ SEC_OID_SECG_EC_SECT193R1, /* 4 */
+ SEC_OID_SECG_EC_SECT193R2, /* 5 */
+ SEC_OID_SECG_EC_SECT233K1, /* 6 */
+ SEC_OID_SECG_EC_SECT233R1, /* 7 */
+ SEC_OID_SECG_EC_SECT239K1, /* 8 */
+ SEC_OID_SECG_EC_SECT283K1, /* 9 */
+ SEC_OID_SECG_EC_SECT283R1, /* 10 */
+ SEC_OID_SECG_EC_SECT409K1, /* 11 */
+ SEC_OID_SECG_EC_SECT409R1, /* 12 */
+ SEC_OID_SECG_EC_SECT571K1, /* 13 */
+ SEC_OID_SECG_EC_SECT571R1, /* 14 */
+ SEC_OID_SECG_EC_SECP160K1, /* 15 */
+ SEC_OID_SECG_EC_SECP160R1, /* 16 */
+ SEC_OID_SECG_EC_SECP160R2, /* 17 */
+ SEC_OID_SECG_EC_SECP192K1, /* 18 */
+ SEC_OID_SECG_EC_SECP192R1, /* 19 */
+ SEC_OID_SECG_EC_SECP224K1, /* 20 */
+ SEC_OID_SECG_EC_SECP224R1, /* 21 */
+ SEC_OID_SECG_EC_SECP256K1, /* 22 */
+ SEC_OID_SECG_EC_SECP256R1, /* 23 */
+ SEC_OID_SECG_EC_SECP384R1, /* 24 */
+ SEC_OID_SECG_EC_SECP521R1, /* 25 */
+};
+
+static SECStatus
+ecName2params(PRArenaPool * arena, ECName curve, SECKEYECParams * params)
+{
+ SECOidData *oidData = NULL;
+
+ if ((curve <= ec_noName) || (curve >= ec_pastLastName) ||
+ ((oidData = SECOID_FindOIDByTag(ecName2OIDTag[curve])) == NULL)) {
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+ return SECFailure;
+ }
+
+ SECITEM_AllocItem(arena, params, (2 + oidData->oid.len));
+ /*
+ * params->data needs to contain the ASN encoding of an object ID (OID)
+ * representing the named curve. The actual OID is in
+ * oidData->oid.data so we simply prepend 0x06 and OID length
+ */
+ params->data[0] = SEC_ASN1_OBJECT_ID;
+ params->data[1] = oidData->oid.len;
+ memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
+
+ return SECSuccess;
+}
+
+static ECName
+params2ecName(SECKEYECParams * params)
+{
+ SECItem oid = { siBuffer, NULL, 0};
+ SECOidData *oidData = NULL;
+ ECName i;
+
+ /*
+ * params->data needs to contain the ASN encoding of an object ID (OID)
+ * representing a named curve. Here, we strip away everything
+ * before the actual OID and use the OID to look up a named curve.
+ */
+ if (params->data[0] != SEC_ASN1_OBJECT_ID) return ec_noName;
+ oid.len = params->len - 2;
+ oid.data = params->data + 2;
+ if ((oidData = SECOID_FindOID(&oid)) == NULL) return ec_noName;
+ for (i = ec_noName + 1; i < ec_pastLastName; i++) {
+ if (ecName2OIDTag[i] == oidData->offset)
+ return i;
+ }
+
+ return ec_noName;
+}
+
+/* Caller must set hiLevel error code. */
+static SECStatus
+ssl3_ComputeECDHKeyHash(SECItem ec_params, SECItem server_ecpoint,
+ SSL3Random *client_rand, SSL3Random *server_rand,
+ SSL3Hashes *hashes, PRBool bypassPKCS11)
+{
+ PRUint8 * hashBuf;
+ PRUint8 * pBuf;
+ SECStatus rv = SECSuccess;
+ unsigned int bufLen;
+ /*
+ * XXX For now, we only support named curves (the appropriate
+ * checks are made before this method is called) so ec_params
+ * takes up only two bytes. ECPoint needs to fit in 256 bytes
+ * (because the spec says the length must fit in one byte)
+ */
+ PRUint8 buf[2*SSL3_RANDOM_LENGTH + 2 + 1 + 256];
+
+ bufLen = 2*SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len;
+ if (bufLen <= sizeof buf) {
+ hashBuf = buf;
+ } else {
+ hashBuf = PORT_Alloc(bufLen);
+ if (!hashBuf) {
+ return SECFailure;
+ }
+ }
+
+ memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
+ pBuf = hashBuf + SSL3_RANDOM_LENGTH;
+ memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
+ pBuf += SSL3_RANDOM_LENGTH;
+ memcpy(pBuf, ec_params.data, ec_params.len);
+ pBuf += ec_params.len;
+ pBuf[0] = (PRUint8)(server_ecpoint.len);
+ pBuf += 1;
+ memcpy(pBuf, server_ecpoint.data, server_ecpoint.len);
+ pBuf += server_ecpoint.len;
+ PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
+
+ rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11);
+
+ PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen));
+ PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result", hashes->md5, MD5_LENGTH));
+ PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));
+
+done:
+ if (hashBuf != buf && hashBuf != NULL)
+ PORT_Free(hashBuf);
+ return rv;
+}
+
+
+/* Called from ssl3_SendClientKeyExchange(). */
+SECStatus
+ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
+{
+ PK11SymKey * pms = NULL;
+ SECStatus rv = SECFailure;
+ PRBool isTLS;
+ CK_MECHANISM_TYPE target;
+ SECKEYPublicKey *pubKey = NULL; /* Ephemeral ECDH key */
+ SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH key */
+ CK_EC_KDF_TYPE kdf;
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
+
+ isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
+
+ /* Generate ephemeral EC keypair */
+ privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams,
+ &pubKey, NULL);
+ if (!privKey || !pubKey) {
+ ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
+ rv = SECFailure;
+ goto loser;
+ }
+ PRINT_BUF(50, (ss, "ECDH public value:",
+ pubKey->u.ec.publicValue.data,
+ pubKey->u.ec.publicValue.len));
+
+ if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
+ else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
+
+ /* If field size is not more than 24 octets, then use SHA-1 hash of result;
+ * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt).
+ */
+ if ((pubKey->u.ec.publicValue.len - 1) / 2 <= 24) {
+ kdf = CKD_SHA1_KDF;
+ } else {
+ kdf = CKD_NULL;
+ }
+
+ /* Determine the PMS */
+ pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL,
+ CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
+ kdf, NULL, NULL);
+
+ if (pms == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ SECKEY_DestroyPrivateKey(privKey);
+ privKey = NULL;
+
+ rv = ssl3_InitPendingCipherSpec(ss, pms);
+ PK11_FreeSymKey(pms); pms = NULL;
+
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
+ pubKey->u.ec.publicValue.len + 1);
+ if (rv != SECSuccess) {
+ goto loser; /* err set by ssl3_AppendHandshake* */
+ }
+
+ rv = ssl3_AppendHandshakeVariable(ss,
+ pubKey->u.ec.publicValue.data,
+ pubKey->u.ec.publicValue.len, 1);
+ SECKEY_DestroyPublicKey(pubKey);
+ pubKey = NULL;
+
+ if (rv != SECSuccess) {
+ goto loser; /* err set by ssl3_AppendHandshake* */
+ }
+
+ rv = SECSuccess;
+
+loser:
+ if(pms) PK11_FreeSymKey(pms);
+ if(privKey) SECKEY_DestroyPrivateKey(privKey);
+ if(pubKey) SECKEY_DestroyPublicKey(pubKey);
+ return rv;
+}
+
+
+/*
+** Called from ssl3_HandleClientKeyExchange()
+*/
+SECStatus
+ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
+ PRUint32 length,
+ SECKEYPublicKey *srvrPubKey,
+ SECKEYPrivateKey *srvrPrivKey)
+{
+ PK11SymKey * pms;
+ SECStatus rv;
+ SECKEYPublicKey clntPubKey;
+ CK_MECHANISM_TYPE target;
+ PRBool isTLS;
+ CK_EC_KDF_TYPE kdf;
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+
+ clntPubKey.keyType = ecKey;
+ clntPubKey.u.ec.DEREncodedParams.len =
+ srvrPubKey->u.ec.DEREncodedParams.len;
+ clntPubKey.u.ec.DEREncodedParams.data =
+ srvrPubKey->u.ec.DEREncodedParams.data;
+
+ rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue,
+ 1, &b, &length);
+ if (rv != SECSuccess) {
+ SEND_ALERT
+ return SECFailure; /* XXX Who sets the error code?? */
+ }
+
+ isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
+
+ if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
+ else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
+
+ /* If field size is not more than 24 octets, then use SHA-1 hash of result;
+ * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt).
+ */
+ if (srvrPubKey->u.ec.size <= 24 * 8) {
+ kdf = CKD_SHA1_KDF;
+ } else {
+ kdf = CKD_NULL;
+ }
+
+ /* Determine the PMS */
+ pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL,
+ CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
+ kdf, NULL, NULL);
+
+ if (pms == NULL) {
+ /* last gasp. */
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ return SECFailure;
+ }
+
+ rv = ssl3_InitPendingCipherSpec(ss, pms);
+ PK11_FreeSymKey(pms);
+ if (rv != SECSuccess) {
+ SEND_ALERT
+ return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
+ }
+ return SECSuccess;
+}
+
+
+/*
+ * Creates the ephemeral public and private ECDH keys used by
+ * server in ECDHE_RSA and ECDHE_ECDSA handshakes.
+ * XXX For now, the elliptic curve is hardcoded to NIST P-224.
+ * We need an API to specify the curve. This won't be a real
+ * issue until we further develop server-side support for ECC
+ * cipher suites.
+ */
+SECStatus
+ssl3_CreateECDHEphemeralKeys(sslSocket *ss)
+{
+ SECStatus rv = SECSuccess;
+ SECKEYPrivateKey * privKey;
+ SECKEYPublicKey * pubKey;
+ SECKEYECParams ecParams = { siBuffer, NULL, 0 };
+
+ if (ss->ephemeralECDHKeyPair)
+ ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
+ ss->ephemeralECDHKeyPair = NULL;
+
+ if (ecName2params(NULL, ec_secp224r1, &ecParams) == SECFailure)
+ return SECFailure;
+ privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL);
+ if (!privKey || !pubKey ||
+ !(ss->ephemeralECDHKeyPair = ssl3_NewKeyPair(privKey, pubKey))) {
+ ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
+ rv = SECFailure;
+ }
+
+ PORT_Free(ecParams.data);
+ return rv;
+}
+
+SECStatus
+ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
+{
+ PRArenaPool * arena = NULL;
+ SECKEYPublicKey *peerKey = NULL;
+ PRBool isTLS;
+ SECStatus rv;
+ int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
+ SSL3AlertDescription desc = illegal_parameter;
+ SSL3Hashes hashes;
+ SECItem signature = {siBuffer, NULL, 0};
+
+ SECItem ec_params = {siBuffer, NULL, 0};
+ SECItem ec_point = {siBuffer, NULL, 0};
+ unsigned char paramBuf[2];
+
+ isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
+
+ /* XXX This works only for named curves, revisit this when
+ * we support generic curves.
+ */
+ ec_params.len = 2;
+ ec_params.data = paramBuf;
+ rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len,
+ &b, &length);
+ if (rv != SECSuccess) {
+ goto loser; /* malformed. */
+ }
+
+ /* Fail if the curve is not a named curve */
+ if ((ec_params.data[0] != ec_type_named) ||
+ !supportedCurve(ec_params.data[1])) {
+ errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
+ desc = handshake_failure;
+ goto alert_loser;
+ }
+
+ rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length);
+ if (rv != SECSuccess) {
+ goto loser; /* malformed. */
+ }
+ /* Fail if the ec point uses compressed representation */
+ if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
+ errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM;
+ desc = handshake_failure;
+ goto alert_loser;
+ }
+
+ rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
+ if (rv != SECSuccess) {
+ goto loser; /* malformed. */
+ }
+
+ if (length != 0) {
+ if (isTLS)
+ desc = decode_error;
+ goto alert_loser; /* malformed. */
+ }
+
+ PRINT_BUF(60, (NULL, "Server EC params", ec_params.data,
+ ec_params.len));
+ PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len));
+
+ /* failures after this point are not malformed handshakes. */
+ /* TLS: send decrypt_error if signature failed. */
+ desc = isTLS ? decrypt_error : handshake_failure;
+
+ /*
+ * check to make sure the hash is signed by right guy
+ */
+ rv = ssl3_ComputeECDHKeyHash(ec_params, ec_point,
+ &ss->ssl3.hs.client_random,
+ &ss->ssl3.hs.server_random,
+ &hashes, ss->opt.bypassPKCS11);
+
+ if (rv != SECSuccess) {
+ errCode =
+ ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
+ goto alert_loser;
+ }
+ rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
+ isTLS, ss->pkcs11PinArg);
+ if (rv != SECSuccess) {
+ errCode =
+ ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
+ goto alert_loser;
+ }
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) {
+ goto no_memory;
+ }
+
+ ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
+ if (peerKey == NULL) {
+ goto no_memory;
+ }
+
+ peerKey->arena = arena;
+ peerKey->keyType = ecKey;
+
+ /* set up EC parameters in peerKey */
+ if (ecName2params(arena, ec_params.data[1],
+ &peerKey->u.ec.DEREncodedParams) != SECSuccess) {
+ /* we should never get here since we already
+ * checked that we are dealing with a supported curve
+ */
+ errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
+ goto alert_loser;
+ }
+
+ /* copy publicValue in peerKey */
+ if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue, &ec_point))
+ {
+ PORT_FreeArena(arena, PR_FALSE);
+ goto no_memory;
+ }
+ peerKey->pkcs11Slot = NULL;
+ peerKey->pkcs11ID = CK_INVALID_HANDLE;
+
+ ss->sec.peerKey = peerKey;
+ ss->ssl3.hs.ws = wait_cert_request;
+
+ return SECSuccess;
+
+alert_loser:
+ (void)SSL3_SendAlert(ss, alert_fatal, desc);
+loser:
+ PORT_SetError( errCode );
+ return SECFailure;
+
+no_memory: /* no-memory error has already been set. */
+ ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
+ return SECFailure;
+}
+
+SECStatus
+ssl3_SendECDHServerKeyExchange(sslSocket *ss)
+{
+const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
+ SECStatus rv = SECFailure;
+ int length;
+ PRBool isTLS;
+ SECItem signed_hash = {siBuffer, NULL, 0};
+ SSL3Hashes hashes;
+
+ SECKEYPublicKey * ecdhePub;
+ SECItem ec_params = {siBuffer, NULL, 0};
+ ECName curve;
+ SSL3KEAType certIndex;
+
+
+ /* Generate ephemeral ECDH key pair and send the public key */
+ rv = ssl3_CreateECDHEphemeralKeys(ss);
+ if (rv != SECSuccess) {
+ goto loser; /* err set by AppendHandshake. */
+ }
+ ecdhePub = ss->ephemeralECDHKeyPair->pubKey;
+ PORT_Assert(ecdhePub != NULL);
+ if (!ecdhePub) {
+ PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
+ return SECFailure;
+ }
+
+ ec_params.len = 2;
+ ec_params.data = (unsigned char*)PORT_Alloc(ec_params.len);
+ curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams);
+ if (curve != ec_noName) {
+ ec_params.data[0] = ec_type_named;
+ ec_params.data[1] = curve;
+ } else {
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+ goto loser;
+ }
+
+ rv = ssl3_ComputeECDHKeyHash(ec_params, ecdhePub->u.ec.publicValue,
+ &ss->ssl3.hs.client_random,
+ &ss->ssl3.hs.server_random,
+ &hashes, ss->opt.bypassPKCS11);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
+
+ /* XXX SSLKEAType isn't really a good choice for
+ * indexing certificates but that's all we have
+ * for now.
+ */
+ if (kea_def->kea == kea_ecdhe_rsa)
+ certIndex = kt_rsa;
+ else /* kea_def->kea == kea_ecdhe_ecdsa */
+ certIndex = kt_ecdh;
+
+ rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY,
+ &signed_hash, isTLS);
+ if (rv != SECSuccess) {
+ goto loser; /* ssl3_SignHashes has set err. */
+ }
+ if (signed_hash.data == NULL) {
+ /* how can this happen and rv == SECSuccess ?? */
+ PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ length = ec_params.len +
+ 1 + ecdhePub->u.ec.publicValue.len +
+ 2 + signed_hash.len;
+
+ rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
+ if (rv != SECSuccess) {
+ goto loser; /* err set by AppendHandshake. */
+ }
+
+ rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len);
+ if (rv != SECSuccess) {
+ goto loser; /* err set by AppendHandshake. */
+ }
+
+ rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data,
+ ecdhePub->u.ec.publicValue.len, 1);
+ if (rv != SECSuccess) {
+ goto loser; /* err set by AppendHandshake. */
+ }
+
+ rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
+ signed_hash.len, 2);
+ if (rv != SECSuccess) {
+ goto loser; /* err set by AppendHandshake. */
+ }
+
+ PORT_Free(ec_params.data);
+ PORT_Free(signed_hash.data);
+ return SECSuccess;
+
+loser:
+ if (ec_params.data != NULL)
+ PORT_Free(ec_params.data);
+ if (signed_hash.data != NULL)
+ PORT_Free(signed_hash.data);
+ return SECFailure;
+}
+
+
+#endif /* NSS_ENABLE_ECC */
+
diff --git a/security/nss/lib/ssl/ssl3gthr.c b/security/nss/lib/ssl/ssl3gthr.c
index 7fbf7663e..4465c4359 100644
--- a/security/nss/lib/ssl/ssl3gthr.c
+++ b/security/nss/lib/ssl/ssl3gthr.c
@@ -72,7 +72,7 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags)
int err;
int rv = 1;
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
if (gs->state == GS_INIT) {
gs->state = GS_HEADER;
gs->remainder = 5;
@@ -189,7 +189,7 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
SSL3Ciphertext cText;
int rv;
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
do {
/* bring in the next sslv3 record. */
rv = ssl3_GatherData(ss, &ss->gs, flags);
@@ -207,7 +207,7 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
if (rv < 0) {
return ss->recvdCloseNotify ? 0 : rv;
}
- } while (ss->ssl3->hs.ws != idle_handshake && ss->gs.buf.len == 0);
+ } while (ss->ssl3.hs.ws != idle_handshake && ss->gs.buf.len == 0);
ss->gs.readOffset = 0;
ss->gs.writeOffset = ss->gs.buf.len;
@@ -230,7 +230,7 @@ ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
{
int rv;
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
do {
rv = ssl3_GatherCompleteHandshake(ss, flags);
} while (rv > 0 && ss->gs.buf.len == 0);
diff --git a/security/nss/lib/ssl/ssl3prot.h b/security/nss/lib/ssl/ssl3prot.h
index c68fa8270..d466c614d 100644
--- a/security/nss/lib/ssl/ssl3prot.h
+++ b/security/nss/lib/ssl/ssl3prot.h
@@ -1,4 +1,4 @@
-/*
+/* Private header file of libSSL.
* Various and sundry protocol constants. DON'T CHANGE THESE. These
* values are defined by the SSL 3.0 protocol specification.
*
@@ -206,7 +206,6 @@ typedef enum {
kea_dhe_rsa_export,
kea_dh_anon,
kea_dh_anon_export,
- kea_fortezza,
kea_rsa_fips,
kea_ecdh_ecdsa,
kea_ecdhe_ecdsa,
@@ -257,9 +256,8 @@ typedef enum {
*/
ct_ECDSA_sign = 7,
ct_RSA_fixed_ECDH = 8,
- ct_ECDSA_fixed_ECDH = 9,
+ ct_ECDSA_fixed_ECDH = 9
- ct_Fortezza = 20
} SSL3ClientCertificateType;
typedef SECItem *SSL3DistinquishedName;
@@ -271,18 +269,6 @@ typedef struct {
typedef SECItem SSL3EncryptedPreMasterSecret;
-/* Following struct is the format of a Fortezza ClientKeyExchange message. */
-typedef struct {
- SECItem y_c;
- SSL3Opaque r_c [128];
- SSL3Opaque y_signature [40];
- SSL3Opaque wrapped_client_write_key [12];
- SSL3Opaque wrapped_server_write_key [12];
- SSL3Opaque client_write_iv [24];
- SSL3Opaque server_write_iv [24];
- SSL3Opaque master_secret_iv [24];
- SSL3Opaque encrypted_preMasterSecret[48];
-} SSL3FortezzaKeys;
typedef SSL3Opaque SSL3MasterSecret[48];
@@ -299,7 +285,6 @@ typedef struct {
union {
SSL3EncryptedPreMasterSecret rsa;
SSL3ClientDiffieHellmanPublic diffie_helman;
- SSL3FortezzaKeys fortezza;
} exchange_keys;
} SSL3ClientKeyExchange;
diff --git a/security/nss/lib/ssl/sslauth.c b/security/nss/lib/ssl/sslauth.c
index 690008e42..848f5aa63 100644
--- a/security/nss/lib/ssl/sslauth.c
+++ b/security/nss/lib/ssl/sslauth.c
@@ -53,7 +53,7 @@ SSL_PeerCertificate(PRFileDesc *fd)
SSL_GETPID(), fd));
return 0;
}
- if (ss->useSecurity && ss->sec.peerCert) {
+ if (ss->opt.useSecurity && ss->sec.peerCert) {
return CERT_DupCertificate(ss->sec.peerCert);
}
return 0;
@@ -71,7 +71,7 @@ SSL_LocalCertificate(PRFileDesc *fd)
SSL_GETPID(), fd));
return NULL;
}
- if (ss->useSecurity) {
+ if (ss->opt.useSecurity) {
if (ss->sec.localCert) {
return CERT_DupCertificate(ss->sec.localCert);
}
@@ -109,7 +109,7 @@ SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1,
*op = SSL_SECURITY_STATUS_OFF;
}
- if (ss->useSecurity && ss->firstHsDone) {
+ if (ss->opt.useSecurity && ss->firstHsDone) {
if (ss->version < SSL_LIBRARY_VERSION_3_0) {
cipherName = ssl_cipherName[ss->sec.cipherType];
@@ -117,8 +117,7 @@ SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1,
cipherName = ssl3_cipherName[ss->sec.cipherType];
}
if (cipherName && PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE;
- /* do same key stuff for fortezza */
-
+
if (cp) {
*cp = PORT_Strdup(cipherName);
}
diff --git a/security/nss/lib/ssl/sslcon.c b/security/nss/lib/ssl/sslcon.c
index da20986b5..06ec09813 100644
--- a/security/nss/lib/ssl/sslcon.c
+++ b/security/nss/lib/ssl/sslcon.c
@@ -145,7 +145,7 @@ const char * const ssl_cipherName[] = {
"DES-CBC",
"DES-EDE3-CBC",
"unknown",
- "Fortezza",
+ "unknown", /* was fortezza, NO LONGER USED */
};
@@ -186,11 +186,11 @@ ssl2_ConstructCipherSpecs(sslSocket *ss)
int i;
SECStatus rv;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
count = 0;
PORT_Assert(ss != 0);
- allowed = !ss->enableSSL2 ? 0 :
+ allowed = !ss->opt.enableSSL2 ? 0 :
(ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED);
while (allowed) {
if (allowed & 1)
@@ -226,7 +226,7 @@ ssl2_ConstructCipherSpecs(sslSocket *ss)
ss->sizeCipherSpecs = count * 3;
/* fill in cipher specs for SSL2 cipher suites */
- allowed = !ss->enableSSL2 ? 0 :
+ allowed = !ss->opt.enableSSL2 ? 0 :
(ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED);
for (i = 0; i < ssl2_NUM_SUITES_IMPLEMENTED * 3; i += 3) {
const PRUint8 * hs = implementedCipherSuites + i;
@@ -271,17 +271,17 @@ ssl2_CheckConfigSanity(sslSocket *ss)
allowed = ss->allowedByPolicy & ss->chosenPreference;
if (! allowed)
- ss->enableSSL2 = PR_FALSE; /* not really enabled if no ciphers */
+ ss->opt.enableSSL2 = PR_FALSE; /* not really enabled if no ciphers */
/* ssl3_config_match_init was called in ssl2_ConstructCipherSpecs(). */
/* Ask how many ssl3 CipherSuites were enabled. */
rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3CipherCount);
if (rv != SECSuccess || ssl3CipherCount <= 0) {
- ss->enableSSL3 = PR_FALSE; /* not really enabled if no ciphers */
- ss->enableTLS = PR_FALSE;
+ ss->opt.enableSSL3 = PR_FALSE; /* not really enabled if no ciphers */
+ ss->opt.enableTLS = PR_FALSE;
}
- if (!ss->enableSSL2 && !ss->enableSSL3 && !ss->enableTLS) {
+ if (!ss->opt.enableSSL2 && !ss->opt.enableSSL3 && !ss->opt.enableTLS) {
SSL_DBG(("%d: SSL[%d]: Can't handshake! both v2 and v3 disabled.",
SSL_GETPID(), ss->fd));
disabled:
@@ -495,7 +495,7 @@ ssl2_GetSendBuffer(sslSocket *ss, unsigned int len)
{
SECStatus rv = SECSuccess;
- PORT_Assert(ssl_HaveXmitBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
if (len < 128) {
len = 128;
@@ -530,7 +530,7 @@ ssl2_SendErrorMessage(sslSocket *ss, int error)
int rv;
PRUint8 msg[SSL_HL_ERROR_HBYTES];
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
msg[0] = SSL_MT_ERROR;
msg[1] = MSB(error);
@@ -559,7 +559,7 @@ ssl2_SendClientFinishedMessage(sslSocket *ss)
int sent;
PRUint8 msg[1 + SSL_CONNECTIONID_BYTES];
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
ssl_GetXmitBufLock(ss); /***************************************/
@@ -595,7 +595,7 @@ ssl2_SendServerVerifyMessage(sslSocket *ss)
int sent;
SECStatus rv;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
ssl_GetXmitBufLock(ss); /***************************************/
@@ -630,7 +630,7 @@ ssl2_SendServerFinishedMessage(sslSocket *ss)
int sendLen, sent;
SECStatus rv = SECSuccess;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
ssl_GetXmitBufLock(ss); /***************************************/
@@ -660,7 +660,7 @@ ssl2_SendServerFinishedMessage(sslSocket *ss)
/* If send failed, it is now a bogus session-id */
(*ss->sec.uncache)(sid);
rv = (SECStatus)sent;
- } else if (!ss->noCache) {
+ } else if (!ss->opt.noCache) {
/* Put the sid in session-id cache, (may already be there) */
(*ss->sec.cache)(sid);
rv = SECSuccess;
@@ -689,7 +689,7 @@ ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize,
int sent;
SECStatus rv;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
ssl_GetXmitBufLock(ss); /***************************************/
@@ -735,7 +735,7 @@ ssl2_SendCertificateRequestMessage(sslSocket *ss)
int sendLen;
SECStatus rv;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
ssl_GetXmitBufLock(ss); /***************************************/
@@ -775,7 +775,7 @@ ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert,
PRUint8 *msg;
int rv, sendLen;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
ssl_GetXmitBufLock(ss); /***************************************/
@@ -887,7 +887,7 @@ ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
int amount;
int count = 0;
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes in the clear",
SSL_GETPID(), ss->fd, len));
@@ -962,7 +962,7 @@ ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
int nout;
int buflen;
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using stream cipher",
SSL_GETPID(), ss->fd, len));
@@ -1067,7 +1067,7 @@ ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
int nout; /* ciphertext size after header. */
int buflen; /* size of generated record. */
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using block cipher",
SSL_GETPID(), ss->fd, len));
@@ -1251,7 +1251,7 @@ ssl_GatherRecord1stHandshake(sslSocket *ss)
{
int rv;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
ssl_GetRecvBufLock(ss);
@@ -1369,7 +1369,7 @@ ssl2_ProduceKeys(sslSocket * ss,
readKey->data = 0;
writeKey->data = 0;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
rv = SECSuccess;
cx = PK11_CreateDigestContext(SEC_OID_MD5);
@@ -1441,7 +1441,7 @@ ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient)
readKey.data = 0;
writeKey.data = 0;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
if((ss->sec.ci.sid == 0))
goto sec_loser; /* don't crash if asserts are off */
@@ -1591,9 +1591,9 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits,
PRUint8 mkbuf[SSL_MAX_MASTER_KEY_BYTES];
sslServerCerts * sc = ss->serverCerts + kt_rsa;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert((sc->serverKey != 0));
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert((sc->SERVERKEY != 0));
PORT_Assert((ss->sec.ci.sid != 0));
sid = ss->sec.ci.sid;
@@ -1651,11 +1651,11 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits,
** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is
** desired behavior here.
*/
- rv = PK11_PubDecryptRaw(sc->serverKey, kbuf, &el1, ekLen, ek, ekLen);
+ rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &el1, ekLen, ek, ekLen);
if (rv != SECSuccess)
goto hide_loser;
- modulusLen = PK11_GetPrivateModulusLen(sc->serverKey);
+ modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY);
if (modulusLen == -1) {
/* If the key was really bad, then PK11_pubDecryptRaw
* would have failed, therefore the we must assume that the card
@@ -1679,7 +1679,7 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits,
}
/* Make sure we're not subject to a version rollback attack. */
- if (ss->enableSSL3 || ss->enableTLS) {
+ if (ss->opt.enableSSL3 || ss->opt.enableTLS) {
PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03 };
@@ -1763,8 +1763,8 @@ ssl2_QualifyCypherSpecs(sslSocket *ss,
int hc;
PRUint8 qualifiedSpecs[ssl2_NUM_SUITES_IMPLEMENTED * 3];
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
if (!ss->cipherSpecs) {
ssl2_ConstructCipherSpecs(ss);
@@ -1824,8 +1824,8 @@ ssl2_ChooseSessionCypher(sslSocket *ss,
int realKeySize;
PRUint8 * ohs = hs;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
if (!ss->cipherSpecs) {
ssl2_ConstructCipherSpecs(ss);
@@ -2044,7 +2044,7 @@ ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen)
PRUint8 keyData[SSL_MAX_MASTER_KEY_BYTES];
PRUint8 iv [8];
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
eblock = NULL;
@@ -2131,7 +2131,7 @@ ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen)
/* Set up the padding for version 2 rollback detection. */
/* XXX We should really use defines here */
- if (ss->enableSSL3 || ss->enableTLS) {
+ if (ss->opt.enableSSL3 || ss->opt.enableTLS) {
PORT_Assert((modulusLen - rek.len) > 12);
PORT_Memset(eblock + modulusLen - rek.len - 8 - 1, 0x03, 8);
}
@@ -2185,7 +2185,7 @@ ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s)
sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
}
- if (!ss->noCache)
+ if (!ss->opt.noCache)
(*ss->sec.cache)(sid);
}
@@ -2195,7 +2195,7 @@ ssl2_TriggerNextMessage(sslSocket *ss)
{
SECStatus rv;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
if ((ss->sec.ci.requiredElements & CIS_HAVE_CERTIFICATE) &&
!(ss->sec.ci.sentElements & CIS_HAVE_CERTIFICATE)) {
@@ -2223,7 +2223,7 @@ ssl2_TryToFinish(sslSocket *ss)
SECStatus rv;
char e, ef;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
e = ss->sec.ci.elements;
ef = e | CIS_HAVE_FINISHED;
@@ -2261,7 +2261,7 @@ ssl2_SignResponse(sslSocket *ss,
unsigned int len;
SECStatus rv = SECFailure;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
challenge = ss->sec.ci.serverChallenge;
len = ss->sec.ci.serverChallengeLen;
@@ -2424,8 +2424,8 @@ ssl2_HandleClientCertificate(sslSocket * ss,
SECItem certItem;
SECItem rep;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
/* Extract the certificate */
certItem.data = cd;
@@ -2512,7 +2512,7 @@ ssl2_HandleMessage(sslSocket *ss)
int rv;
int rv2;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
ssl_GetRecvBufLock(ss);
@@ -2706,7 +2706,7 @@ ssl2_HandleVerifyMessage(sslSocket *ss)
PRUint8 * data;
SECStatus rv;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
ssl_GetRecvBufLock(ss);
data = ss->gs.buf.buf + ss->gs.recordOffset;
@@ -2758,9 +2758,9 @@ ssl2_HandleServerHelloMessage(sslSocket *ss)
SECStatus rv;
int needed, sidHit, certLen, csLen, cidLen, certType, err;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
- if (!ss->enableSSL2) {
+ if (!ss->opt.enableSSL2) {
PORT_SetError(SSL_ERROR_SSL2_DISABLED);
return SECFailure;
}
@@ -2989,7 +2989,7 @@ ssl2_BeginClientHandshake(sslSocket *ss)
int sendLen, sidLen = 0;
SECStatus rv;
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
ss->sec.isServer = 0;
ss->sec.sendSequence = 0;
@@ -3035,7 +3035,7 @@ ssl2_BeginClientHandshake(sslSocket *ss)
SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd));
/* Try to find server in our session-id cache */
- if (ss->noCache) {
+ if (ss->opt.noCache) {
sid = NULL;
} else {
sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID,
@@ -3043,15 +3043,15 @@ ssl2_BeginClientHandshake(sslSocket *ss)
}
while (sid) { /* this isn't really a loop */
/* if we're not doing this SID's protocol any more, drop it. */
- if (((sid->version < SSL_LIBRARY_VERSION_3_0) && !ss->enableSSL2) ||
- ((sid->version == SSL_LIBRARY_VERSION_3_0) && !ss->enableSSL3) ||
- ((sid->version > SSL_LIBRARY_VERSION_3_0) && !ss->enableTLS)) {
+ if (((sid->version < SSL_LIBRARY_VERSION_3_0) && !ss->opt.enableSSL2) ||
+ ((sid->version == SSL_LIBRARY_VERSION_3_0) && !ss->opt.enableSSL3) ||
+ ((sid->version > SSL_LIBRARY_VERSION_3_0) && !ss->opt.enableTLS)) {
ss->sec.uncache(sid);
ssl_FreeSID(sid);
sid = NULL;
break;
}
- if (ss->enableSSL2 && sid->version < SSL_LIBRARY_VERSION_3_0) {
+ if (ss->opt.enableSSL2 && sid->version < SSL_LIBRARY_VERSION_3_0) {
/* If the cipher in this sid is not enabled, drop it. */
for (i = 0; i < ss->sizeCipherSpecs; i += 3) {
if (ss->cipherSpecs[i] == sid->u.ssl2.cipherType)
@@ -3096,8 +3096,8 @@ ssl2_BeginClientHandshake(sslSocket *ss)
PORT_Assert(sid != NULL);
- if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->v2CompatibleHello) &&
- (ss->enableSSL3 || ss->enableTLS)) {
+ if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->opt.v2CompatibleHello) &&
+ (ss->opt.enableSSL3 || ss->opt.enableTLS)) {
ss->gs.state = GS_INIT;
ss->handshake = ssl_GatherRecord1stHandshake;
@@ -3138,9 +3138,9 @@ ssl2_BeginClientHandshake(sslSocket *ss)
/* Construct client-hello message */
cp = msg = ss->sec.ci.sendBuf.buf;
msg[0] = SSL_MT_CLIENT_HELLO;
- if ( ss->enableTLS ) {
+ if ( ss->opt.enableTLS ) {
ss->clientHelloVersion = SSL_LIBRARY_VERSION_3_1_TLS;
- } else if ( ss->enableSSL3 ) {
+ } else if ( ss->opt.enableSSL3 ) {
ss->clientHelloVersion = SSL_LIBRARY_VERSION_3_0;
} else {
ss->clientHelloVersion = SSL_LIBRARY_VERSION_2;
@@ -3441,7 +3441,7 @@ ssl2_HandleClientHelloMessage(sslSocket *ss)
#endif
PRUint8 csImpl[sizeof implementedCipherSuites];
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
sc = ss->serverCerts + kt_rsa;
serverCert = sc->serverCert;
@@ -3470,7 +3470,7 @@ ssl2_HandleClientHelloMessage(sslSocket *ss)
*/
if ((data[0] == SSL_MT_CLIENT_HELLO) &&
(data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) &&
- (ss->enableSSL3 || ss->enableTLS)) {
+ (ss->opt.enableSSL3 || ss->opt.enableTLS)) {
rv = ssl3_HandleV2ClientHello(ss, data, ss->gs.recordLen);
if (rv != SECFailure) { /* Success */
ss->handshake = NULL;
@@ -3558,7 +3558,7 @@ ssl2_HandleClientHelloMessage(sslSocket *ss)
goto loser;
}
/* Since this handhsake is going to fail, don't cache it. */
- ss->noCache = 1;
+ ss->opt.noCache = 1;
}
/* Squirrel away the challenge for later */
@@ -3566,7 +3566,7 @@ ssl2_HandleClientHelloMessage(sslSocket *ss)
/* Examine message and see if session-id is good */
ss->sec.ci.elements = 0;
- if (sdLen > 0 && !ss->noCache) {
+ if (sdLen > 0 && !ss->opt.noCache) {
SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
ss->sec.ci.peer.pr_s6_addr32[1],
@@ -3648,7 +3648,7 @@ ssl2_HandleClientHelloMessage(sslSocket *ss)
/* Build up final list of required elements */
ss->sec.ci.requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED;
- if (ss->requestCertificate) {
+ if (ss->opt.requestCertificate) {
ss->sec.ci.requiredElements |= CIS_HAVE_CERTIFICATE;
}
ss->sec.ci.sentElements = 0;
@@ -3742,8 +3742,8 @@ ssl2_BeginServerHandshake(sslSocket *ss)
ss->sec.rcvSequence = 0;
/* don't turn on SSL2 if we don't have an RSA key and cert */
- if (!rsaAuth->serverKey || !rsaAuth->serverCert) {
- ss->enableSSL2 = PR_FALSE;
+ if (!rsaAuth->SERVERKEY || !rsaAuth->serverCert) {
+ ss->opt.enableSSL2 = PR_FALSE;
}
if (!ss->cipherSpecs) {
diff --git a/security/nss/lib/ssl/ssldef.c b/security/nss/lib/ssl/ssldef.c
index d42da2956..23ef9cafe 100644
--- a/security/nss/lib/ssl/ssldef.c
+++ b/security/nss/lib/ssl/ssldef.c
@@ -117,7 +117,7 @@ int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
/* Although this is overkill, we disable Nagle delays completely for
** SSL sockets.
*/
- if (ss->useSecurity && !ss->delayDisabled) {
+ if (ss->opt.useSecurity && !ss->delayDisabled) {
ssl_EnableNagleDelay(ss, PR_FALSE); /* ignore error */
ss->delayDisabled = 1;
}
diff --git a/security/nss/lib/ssl/sslenum.c b/security/nss/lib/ssl/sslenum.c
index 2745155af..d28d689b7 100644
--- a/security/nss/lib/ssl/sslenum.c
+++ b/security/nss/lib/ssl/sslenum.c
@@ -56,7 +56,6 @@ const PRUint16 SSL_ImplementedCiphers[] = {
TLS_RSA_WITH_AES_256_CBC_SHA,
/* 128-bit */
- SSL_FORTEZZA_DMS_WITH_RC4_128_SHA,
#ifdef NSS_ENABLE_ECC
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
@@ -84,9 +83,6 @@ const PRUint16 SSL_ImplementedCiphers[] = {
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA,
- /* 80 bit skipjack */
- SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* KEA + SkipJack */
-
/* 56-bit DES "domestic" cipher suites */
SSL_DHE_RSA_WITH_DES_CBC_SHA,
SSL_DHE_DSS_WITH_DES_CBC_SHA,
@@ -106,7 +102,6 @@ const PRUint16 SSL_ImplementedCiphers[] = {
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
/* ciphersuites with no encryption */
- SSL_FORTEZZA_DMS_WITH_NULL_SHA,
#ifdef NSS_ENABLE_ECC
TLS_ECDH_RSA_WITH_NULL_SHA,
TLS_ECDH_ECDSA_WITH_NULL_SHA,
diff --git a/security/nss/lib/ssl/sslgathr.c b/security/nss/lib/ssl/sslgathr.c
index 75c465099..8308ad194 100644
--- a/security/nss/lib/ssl/sslgathr.c
+++ b/security/nss/lib/ssl/sslgathr.c
@@ -90,7 +90,7 @@ ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags)
unsigned char * pBuf;
int nb, err, rv;
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
if (gs->state == GS_INIT) {
/* Initialize gathering engine */
@@ -141,9 +141,9 @@ ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags)
/* Probably finished this piece */
switch (gs->state) {
case GS_HEADER:
- if ((ss->enableSSL3 || ss->enableTLS) && !ss->firstHsDone) {
+ if ((ss->opt.enableSSL3 || ss->opt.enableTLS) && !ss->firstHsDone) {
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
/* If this looks like an SSL3 handshake record,
** and we're expecting an SSL2 Hello message from our peer,
@@ -185,7 +185,7 @@ ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags)
return SECFailure;
}
}
- } /* ((ss->enableSSL3 || ss->enableTLS) && !ss->firstHsDone) */
+ } /* ((ss->opt.enableSSL3 || ss->opt.enableTLS) && !ss->firstHsDone) */
/* we've got the first 3 bytes. The header may be two or three. */
if (gs->hdr[0] & 0x80) {
@@ -411,7 +411,7 @@ ssl2_StartGatherBytes(sslSocket *ss, sslGather *gs, unsigned int count)
{
int rv;
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
gs->state = GS_DATA;
gs->remainder = count;
gs->count = count;
@@ -455,8 +455,8 @@ ssl2_HandleV3HandshakeRecord(sslSocket *ss)
SECStatus rv;
SSL3ProtocolVersion version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
- PORT_Assert( ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
/* We've read in 3 bytes, there are 2 more to go in an ssl3 header. */
ss->gs.remainder = 2;
diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h
index f42bd4be3..1da55d59b 100644
--- a/security/nss/lib/ssl/sslimpl.h
+++ b/security/nss/lib/ssl/sslimpl.h
@@ -84,7 +84,7 @@ typedef SSLSignType SSL3SignType;
#define calg_des ssl_calg_des
#define calg_3des ssl_calg_3des
#define calg_idea ssl_calg_idea
-#define calg_fortezza ssl_calg_fortezza
+#define calg_fortezza ssl_calg_fortezza /* deprecated, must preserve */
#define calg_aes ssl_calg_aes
#define mac_null ssl_mac_null
@@ -93,6 +93,10 @@ typedef SSLSignType SSL3SignType;
#define hmac_md5 ssl_hmac_md5
#define hmac_sha ssl_hmac_sha
+#define SET_ERROR_CODE /* reminder */
+#define SEND_ALERT /* reminder */
+#define TEST_FOR_FAILURE /* reminder */
+#define DEAL_WITH_FAILURE /* reminder */
#if defined(DEBUG) || defined(TRACE)
#ifdef __cplusplus
@@ -162,12 +166,17 @@ typedef enum { SSLAppOpRead = 0,
#define SSL_MAX_MAC_BYTES 16
+#define SSL3_RSA_PMS_LENGTH 48
+#define SSL3_MASTER_SECRET_LENGTH 48
+
/* number of wrap mechanisms potentially used to wrap master secrets. */
#define SSL_NUM_WRAP_MECHS 13
/* This makes the cert cache entry exactly 4k. */
#define SSL_MAX_CACHED_CERT_LEN 4060
+#define NUM_MIXERS 9
+
#ifndef BPB
#define BPB 8 /* Bits Per Byte */
#endif
@@ -261,9 +270,9 @@ typedef struct {
} ssl3CipherSuiteCfg;
#ifdef NSS_ENABLE_ECC
-#define ssl_V3_SUITES_IMPLEMENTED 40
+#define ssl_V3_SUITES_IMPLEMENTED 37
#else
-#define ssl_V3_SUITES_IMPLEMENTED 26
+#define ssl_V3_SUITES_IMPLEMENTED 23
#endif /* NSS_ENABLE_ECC */
typedef struct sslOptionsStr {
@@ -281,6 +290,8 @@ typedef struct sslOptionsStr {
unsigned int v2CompatibleHello : 1; /* 13 */
unsigned int detectRollBack : 1; /* 14 */
unsigned int noStepDown : 1; /* 15 */
+ unsigned int bypassPKCS11 : 1; /* 16 */
+ unsigned int noLocks : 1; /* 17 */
} sslOptions;
typedef enum { sslHandshakingUndetermined = 0,
@@ -292,10 +303,11 @@ typedef struct sslServerCertsStr {
/* Configuration state for server sockets */
CERTCertificate * serverCert;
CERTCertificateList * serverCertChain;
- SECKEYPrivateKey * serverKey;
+ ssl3KeyPair * serverKeyPair;
unsigned int serverKeyBits;
} sslServerCerts;
+#define SERVERKEY serverKeyPair->privKey
#define SSL_LOCK_RANK_SPEC 255
#define SSL_LOCK_RANK_GLOBAL NSS_RWLOCK_RANK_NONE
@@ -414,7 +426,6 @@ typedef enum {
cipher_3des,
cipher_des40,
cipher_idea,
- cipher_fortezza,
cipher_aes_128,
cipher_aes_256,
cipher_missing /* reserved for no such supported cipher */
@@ -433,21 +444,31 @@ typedef struct {
uint32 low;
} SSL3SequenceNumber;
-typedef struct {
- SSL3Opaque write_iv[MAX_IV_LENGTH];
- PK11SymKey *write_key;
- PK11SymKey *write_mac_key;
- PK11Context *write_mac_context;
-} ssl3KeyMaterial;
+#define MAX_MAC_CONTEXT_BYTES 400
+#define MAX_MAC_CONTEXT_LLONGS (MAX_MAC_CONTEXT_BYTES / 8)
+
+#define MAX_CIPHER_CONTEXT_BYTES 2080
+#define MAX_CIPHER_CONTEXT_LLONGS (MAX_CIPHER_CONTEXT_BYTES / 8)
typedef struct {
- SSL3Opaque wrapped_client_write_key[12]; /* wrapped with Ks */
- SSL3Opaque wrapped_server_write_key[12]; /* wrapped with Ks */
SSL3Opaque client_write_iv [24];
SSL3Opaque server_write_iv [24];
SSL3Opaque wrapped_master_secret [48];
PRUint16 wrapped_master_secret_len;
-} ssl3SidKeys;
+ PRUint8 msIsWrapped;
+ PRUint8 resumable;
+} ssl3SidKeys; /* 100 bytes */
+
+typedef struct {
+ PK11SymKey *write_key;
+ PK11SymKey *write_mac_key;
+ PK11Context *write_mac_context;
+ SECItem write_key_item;
+ SECItem write_iv_item;
+ SECItem write_mac_key_item;
+ SSL3Opaque write_iv[MAX_IV_LENGTH];
+ PRUint64 cipher_context[MAX_CIPHER_CONTEXT_LLONGS];
+} ssl3KeyMaterial;
/*
** These are the "specs" in the "ssl3" struct.
@@ -459,16 +480,20 @@ typedef struct {
const ssl3MACDef * mac_def;
int mac_size;
SSLCipher encode;
- void * encodeContext;
SSLCipher decode;
- void * decodeContext;
SSLDestroy destroy;
+ void * encodeContext;
+ void * decodeContext;
+ PRBool bypassCiphers; /* did double bypass (at least) */
PK11SymKey * master_secret;
- ssl3KeyMaterial client;
- ssl3KeyMaterial server;
SSL3SequenceNumber write_seq_num;
SSL3SequenceNumber read_seq_num;
SSL3ProtocolVersion version;
+ ssl3KeyMaterial client;
+ ssl3KeyMaterial server;
+ SECItem msItem;
+ unsigned char key_block[NUM_MIXERS * MD5_LENGTH];
+ unsigned char raw_master_secret[56];
} ssl3CipherSpec;
typedef enum { never_cached,
@@ -520,9 +545,7 @@ struct sslSessionIDStr {
ssl3CipherSuite cipherSuite;
SSL3CompressionMethod compression;
- PRBool resumable;
int policy;
- PRBool hasFortezza;
ssl3SidKeys keys;
CK_MECHANISM_TYPE masterWrapMech;
/* mechanism used to wrap master secret */
@@ -535,7 +558,6 @@ struct sslSessionIDStr {
*/
PK11SymKey * clientWriteKey;
PK11SymKey * serverWriteKey;
- PK11SymKey * tek;
/* The following values pertain to the slot that wrapped the
** master secret. (used only in client)
@@ -560,11 +582,6 @@ struct sslSessionIDStr {
char masterValid;
char clAuthValid;
- /* the following values are used only in the client, and only
- * with fortezza.
- */
- SSL3Opaque clientWriteSave[80];
- int clientWriteSaveLen;
} ssl3;
} u;
};
@@ -638,6 +655,8 @@ typedef struct SSL3HandshakeStateStr {
SSL3Random server_random;
SSL3Random client_random;
SSL3WaitState ws;
+ PRUint64 md5_cx[MAX_MAC_CONTEXT_LLONGS];
+ PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS];
PK11Context * md5; /* handshake running hashes */
PK11Context * sha;
const ssl3KEADef * kea_def;
@@ -660,12 +679,7 @@ const ssl3CipherSuiteDef *suite_def;
/* protected by recvBufLock */
} SSL3HandshakeState;
-struct SSL3FortezzaKEAParamsStr {
- unsigned char R_s[128]; /* server's "random" public key */
- PK11SymKey * tek;
-};
-typedef struct SSL3FortezzaKEAParamsStr SSL3FortezzaKEAParams;
/*
** This is the "ssl3" struct, as in "ss->ssl3".
@@ -685,9 +699,6 @@ struct ssl3StateStr {
ssl3CipherSpec * prSpec; /* pending read spec. */
ssl3CipherSpec * cwSpec; /* current write spec. */
ssl3CipherSpec * pwSpec; /* pending write spec. */
- ssl3CipherSpec specs[2]; /* one is current, one is pending. */
-
- SSL3HandshakeState hs;
CERTCertificate * clientCertificate; /* used by client */
SECKEYPrivateKey * clientPrivateKey; /* used by client */
@@ -704,7 +715,9 @@ struct ssl3StateStr {
/* chain while we are trying to validate it. */
CERTDistNames * ca_list;
/* used by server. trusted CAs for this socket. */
- SSL3FortezzaKEAParams fortezza;
+ PRBool initialized;
+ SSL3HandshakeState hs;
+ ssl3CipherSpec specs[2]; /* one is current, one is pending. */
};
typedef struct {
@@ -751,7 +764,7 @@ typedef struct SSLWrappedSymWrappingKeyStr {
*/
/*
-** This is "ci", as in "ss->sec->ci".
+** This is "ci", as in "ss->sec.ci".
**
** Protection: All the variables in here are protected by
** firstHandshakeLock AND (in ssl3) ssl3HandshakeLock
@@ -873,30 +886,17 @@ struct sslSocketStr {
/* Pointer to operations vector for this socket */
const sslSocketOps * ops;
+ /* SSL socket options */
+ sslOptions opt;
+
/* State flags */
- unsigned int useSocks : 1;
- unsigned int useSecurity : 1;
- unsigned int requestCertificate : 1;
- unsigned int requireCertificate : 2;
- unsigned int handshakeAsClient : 1;
- unsigned int handshakeAsServer : 1;
- unsigned int enableSSL2 : 1;
-
- unsigned int enableSSL3 : 1;
- unsigned int enableTLS : 1;
- unsigned int clientAuthRequested: 1;
- unsigned int noCache : 1;
- unsigned int fdx : 1; /* simultaneous R/W threads */
- unsigned int v2CompatibleHello : 1; /* Send v3+ client hello in v2 format */
- unsigned int detectRollBack : 1; /* Detect rollback to SSL v3 */
- unsigned int firstHsDone : 1; /* first handshake is complete. */
-
- unsigned int recvdCloseNotify : 1; /* received SSL EOF. */
- unsigned int lastWriteBlocked : 1;
- unsigned int TCPconnected : 1;
- unsigned int handshakeBegun : 1;
- unsigned int delayDisabled : 1; /* Nagle delay disabled */
- unsigned int noStepDown : 1;
+ unsigned long clientAuthRequested;
+ unsigned long delayDisabled; /* Nagle delay disabled */
+ unsigned long firstHsDone; /* first handshake is complete. */
+ unsigned long handshakeBegun;
+ unsigned long lastWriteBlocked;
+ unsigned long recvdCloseNotify; /* received SSL EOF. */
+ unsigned long TCPconnected;
/* version of the protocol to use */
SSL3ProtocolVersion version;
@@ -907,28 +907,17 @@ struct sslSocketStr {
/* protected by firstHandshakeLock AND (in ssl3) ssl3HandshakeLock. */
const char *url; /* ssl 2 & 3 */
- /* Gather object used for gathering data */
- sslGather gs; /*recvBufLock*/
-
sslHandshakeFunc handshake; /*firstHandshakeLock*/
sslHandshakeFunc nextHandshake; /*firstHandshakeLock*/
sslHandshakeFunc securityHandshake; /*firstHandshakeLock*/
- sslBuffer saveBuf; /*xmitBufLock*/
- sslBuffer pendingBuf; /*xmitBufLock*/
-
/* the following variable is only used with socks or other proxies. */
char * peerID; /* String uniquely identifies target server. */
- ssl3State * ssl3;
unsigned char * cipherSpecs;
unsigned int sizeCipherSpecs;
const unsigned char * preferredCipher;
- /* Configuration state for server sockets */
- /* server cert and key for each KEA type */
- sslServerCerts serverCerts[kt_kea_size];
-
ssl3KeyPair * stepDownKeyPair; /* RSA step down keys */
/* Callbacks */
@@ -983,8 +972,21 @@ const unsigned char * preferredCipher;
sslHandshakingType handshaking;
+ /* Gather object used for gathering data */
+ sslGather gs; /*recvBufLock*/
+
+ sslBuffer saveBuf; /*xmitBufLock*/
+ sslBuffer pendingBuf; /*xmitBufLock*/
+
+ /* Configuration state for server sockets */
+ /* server cert and key for each KEA type */
+ sslServerCerts serverCerts[kt_kea_size];
+
ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED];
ssl3KeyPair * ephemeralECDHKeyPair; /* for ECDHE-* handshake */
+
+ /* SSL3 state info. Formerly was a pointer */
+ ssl3State ssl3;
};
@@ -1074,7 +1076,7 @@ extern int ssl2_StartGatherBytes(sslSocket *ss, sslGather *gs,
extern SECStatus ssl_CreateSecurityInfo(sslSocket *ss);
extern SECStatus ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os);
-extern void ssl_ResetSecurityInfo(sslSecurityInfo *sec);
+extern void ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset);
extern void ssl_DestroySecurityInfo(sslSecurityInfo *sec);
extern sslSocket * ssl_DupSocket(sslSocket *old);
@@ -1104,6 +1106,8 @@ extern int ssl3_SendApplicationData(sslSocket *ss, const PRUint8 *in,
extern PRBool ssl_FdIsBlocking(PRFileDesc *fd);
+extern SECStatus ssl_SetTimeout(PRFileDesc *fd, PRIntervalTime timeout);
+
extern PRBool ssl_SocketIsBlocking(sslSocket *ss);
extern void ssl_SetAlwaysBlock(sslSocket *ss);
@@ -1111,33 +1115,57 @@ extern void ssl_SetAlwaysBlock(sslSocket *ss);
extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled);
#define SSL_LOCK_READER(ss) if (ss->recvLock) PZ_Lock(ss->recvLock)
-#define SSL_UNLOCK_READER(ss) if (ss->recvLock) PZ_Unlock(ss->recvLock)
+#define SSL_UNLOCK_READER(ss) if (ss->recvLock) PZ_Unlock(ss->recvLock)
#define SSL_LOCK_WRITER(ss) if (ss->sendLock) PZ_Lock(ss->sendLock)
-#define SSL_UNLOCK_WRITER(ss) if (ss->sendLock) PZ_Unlock(ss->sendLock)
-
-#define ssl_Get1stHandshakeLock(ss) PZ_EnterMonitor((ss)->firstHandshakeLock)
-#define ssl_Release1stHandshakeLock(ss) PZ_ExitMonitor((ss)->firstHandshakeLock)
-#define ssl_Have1stHandshakeLock(ss) PZ_InMonitor( (ss)->firstHandshakeLock)
-
-#define ssl_GetSSL3HandshakeLock(ss) PZ_EnterMonitor((ss)->ssl3HandshakeLock)
-#define ssl_ReleaseSSL3HandshakeLock(ss) PZ_ExitMonitor((ss)->ssl3HandshakeLock)
-#define ssl_HaveSSL3HandshakeLock(ss) PZ_InMonitor( (ss)->ssl3HandshakeLock)
-
-#define ssl_GetSpecReadLock(ss) NSSRWLock_LockRead( (ss)->specLock)
-#define ssl_ReleaseSpecReadLock(ss) NSSRWLock_UnlockRead( (ss)->specLock)
-
-#define ssl_GetSpecWriteLock(ss) NSSRWLock_LockWrite( (ss)->specLock)
-#define ssl_ReleaseSpecWriteLock(ss) NSSRWLock_UnlockWrite((ss)->specLock)
-#define ssl_HaveSpecWriteLock(ss) NSSRWLock_HaveWriteLock((ss)->specLock)
-
-#define ssl_GetRecvBufLock(ss) PZ_EnterMonitor((ss)->recvBufLock)
-#define ssl_ReleaseRecvBufLock(ss) PZ_ExitMonitor( (ss)->recvBufLock)
-#define ssl_HaveRecvBufLock(ss) PZ_InMonitor( (ss)->recvBufLock)
-
-#define ssl_GetXmitBufLock(ss) PZ_EnterMonitor((ss)->xmitBufLock)
-#define ssl_ReleaseXmitBufLock(ss) PZ_ExitMonitor( (ss)->xmitBufLock)
-#define ssl_HaveXmitBufLock(ss) PZ_InMonitor( (ss)->xmitBufLock)
-
+#define SSL_UNLOCK_WRITER(ss) if (ss->sendLock) PZ_Unlock(ss->sendLock)
+
+#define ssl_Get1stHandshakeLock(ss) \
+ { if (!ss->opt.noLocks) PZ_EnterMonitor((ss)->firstHandshakeLock); }
+#define ssl_Release1stHandshakeLock(ss) \
+ { if (!ss->opt.noLocks) PZ_ExitMonitor((ss)->firstHandshakeLock); }
+#define ssl_Have1stHandshakeLock(ss) \
+ (PZ_InMonitor((ss)->firstHandshakeLock))
+
+#define ssl_GetSSL3HandshakeLock(ss) \
+ { if (!ss->opt.noLocks) PZ_EnterMonitor((ss)->ssl3HandshakeLock); }
+#define ssl_ReleaseSSL3HandshakeLock(ss) \
+ { if (!ss->opt.noLocks) PZ_ExitMonitor((ss)->ssl3HandshakeLock); }
+#define ssl_HaveSSL3HandshakeLock(ss) \
+ (PZ_InMonitor((ss)->ssl3HandshakeLock))
+
+#define ssl_GetSpecReadLock(ss) \
+ { if (!ss->opt.noLocks) NSSRWLock_LockRead((ss)->specLock); }
+#define ssl_ReleaseSpecReadLock(ss) \
+ { if (!ss->opt.noLocks) NSSRWLock_UnlockRead((ss)->specLock); }
+
+#define ssl_GetSpecWriteLock(ss) \
+ { if (!ss->opt.noLocks) NSSRWLock_LockWrite((ss)->specLock); }
+#define ssl_ReleaseSpecWriteLock(ss) \
+ { if (!ss->opt.noLocks) NSSRWLock_UnlockWrite((ss)->specLock); }
+#define ssl_HaveSpecWriteLock(ss) \
+ (NSSRWLock_HaveWriteLock((ss)->specLock))
+
+#define ssl_GetRecvBufLock(ss) \
+ { if (!ss->opt.noLocks) PZ_EnterMonitor((ss)->recvBufLock); }
+#define ssl_ReleaseRecvBufLock(ss) \
+ { if (!ss->opt.noLocks) PZ_ExitMonitor( (ss)->recvBufLock); }
+#define ssl_HaveRecvBufLock(ss) \
+ (PZ_InMonitor((ss)->recvBufLock))
+
+#define ssl_GetXmitBufLock(ss) \
+ { if (!ss->opt.noLocks) PZ_EnterMonitor((ss)->xmitBufLock); }
+#define ssl_ReleaseXmitBufLock(ss) \
+ { if (!ss->opt.noLocks) PZ_ExitMonitor( (ss)->xmitBufLock); }
+#define ssl_HaveXmitBufLock(ss) \
+ (PZ_InMonitor((ss)->xmitBufLock))
+
+
+extern SECStatus ssl3_KeyAndMacDeriveBypass(ssl3CipherSpec * pwSpec,
+ const unsigned char * cr, const unsigned char * sr,
+ PRBool isTLS, PRBool isExport);
+extern SECStatus ssl3_MasterKeyDeriveBypass( ssl3CipherSpec * pwSpec,
+ const unsigned char * cr, const unsigned char * sr,
+ const SECItem * pms, PRBool isTLS, PRBool isRSA);
/* These functions are called from secnav, even though they're "private". */
@@ -1220,13 +1248,46 @@ extern SECStatus ssl3_ConstructV2CipherSpecsHack(sslSocket *ss,
extern SECStatus ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache);
-extern void ssl3_DestroySSL3Info(ssl3State *ssl3);
+extern void ssl3_DestroySSL3Info(sslSocket *ss);
extern SECStatus ssl3_NegotiateVersion(sslSocket *ss,
SSL3ProtocolVersion peerVersion);
extern SECStatus ssl_GetPeerInfo(sslSocket *ss);
+#ifdef NSS_ENABLE_ECC
+/* ECDH functions */
+extern SECStatus ssl3_SendECDHClientKeyExchange(sslSocket * ss,
+ SECKEYPublicKey * svrPubKey);
+extern SECStatus ssl3_HandleECDHServerKeyExchange(sslSocket *ss,
+ SSL3Opaque *b, PRUint32 length);
+extern SECStatus ssl3_HandleECDHClientKeyExchange(sslSocket *ss,
+ SSL3Opaque *b, PRUint32 length,
+ SECKEYPublicKey *srvrPubKey,
+ SECKEYPrivateKey *srvrPrivKey);
+extern SECStatus ssl3_SendECDHServerKeyExchange(sslSocket *ss);
+#endif
+
+extern SECStatus ssl3_ComputeCommonKeyHash(PRUint8 * hashBuf,
+ unsigned int bufLen, SSL3Hashes *hashes,
+ PRBool bypassPKCS11);
+extern SECStatus ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms);
+extern SECStatus ssl3_AppendHandshake(sslSocket *ss, const void *void_src,
+ PRInt32 bytes);
+extern SECStatus ssl3_AppendHandshakeHeader(sslSocket *ss,
+ SSL3HandshakeType t, PRUint32 length);
+extern SECStatus ssl3_AppendHandshakeVariable( sslSocket *ss,
+ const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize);
+extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes,
+ SSL3Opaque **b, PRUint32 *length);
+extern SECStatus ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i,
+ PRInt32 bytes, SSL3Opaque **b, PRUint32 *length);
+extern SECStatus ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key,
+ SECItem *buf, PRBool isTLS);
+extern SECStatus ssl3_VerifySignedHashes(SSL3Hashes *hash,
+ CERTCertificate *cert, SECItem *buf, PRBool isTLS,
+ void *pwArg);
+
/* Construct a new NSPR socket for the app to use */
extern PRFileDesc *ssl_NewPRSocket(sslSocket *ss, PRFileDesc *fd);
extern void ssl_FreePRSocket(PRFileDesc *fd);
diff --git a/security/nss/lib/ssl/sslinfo.c b/security/nss/lib/ssl/sslinfo.c
index 218973a2a..d3a9735f0 100644
--- a/security/nss/lib/ssl/sslinfo.c
+++ b/security/nss/lib/ssl/sslinfo.c
@@ -60,24 +60,17 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
memset(&inf, 0, sizeof inf);
inf.length = PR_MIN(sizeof inf, len);
- if (ss->useSecurity && ss->firstHsDone) {
+ if (ss->opt.useSecurity && ss->firstHsDone) {
sid = ss->sec.ci.sid;
inf.protocolVersion = ss->version;
inf.authKeyBits = ss->sec.authKeyBits;
inf.keaKeyBits = ss->sec.keaKeyBits;
if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
inf.cipherSuite = ss->sec.cipherType | 0xff00;
- } else if (ss->ssl3) { /* SSL3 and TLS */
+ } else if (ss->ssl3.initialized) { /* SSL3 and TLS */
/* XXX These should come from crSpec */
- inf.cipherSuite = ss->ssl3->hs.cipher_suite;
-#if 0
- /* misc */
- inf.isFIPS = (inf.symCipher == ssl_calg_des || inf.symCipher == ssl_calg_3des)
- && (inf.macAlgorithm == ssl_mac_sha || inf.macAlgorithm == ssl_hmac_sha)
- && (inf.protocolVersion > SSL_LIBRARY_VERSION_3_0 ||
- inf.cipherSuite >= 0xfef0);
-#endif
+ inf.cipherSuite = ss->ssl3.hs.cipher_suite;
}
if (sid) {
inf.creationTime = sid->creationTime;
@@ -85,7 +78,8 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
inf.expirationTime = sid->expirationTime;
if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
inf.sessionIDLength = SSL2_SESSIONID_BYTES;
- memcpy(inf.sessionID, sid->u.ssl2.sessionID, SSL2_SESSIONID_BYTES);
+ memcpy(inf.sessionID, sid->u.ssl2.sessionID,
+ SSL2_SESSIONID_BYTES);
} else {
unsigned int sidLen = sid->u.ssl3.sessionIDLength;
sidLen = PR_MIN(sidLen, sizeof inf.sessionID);
@@ -100,8 +94,6 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
return SECSuccess;
}
-#define kt_kea kt_fortezza
-#define calg_sj calg_fortezza
#define CS(x) x, #x
#define CK(x) x | 0xff00, #x
@@ -139,34 +131,31 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
static const SSLCipherSuiteInfo suiteInfo[] = {
/* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */
-{0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_DHE, C_AES, B_256, M_SHA, 0, 0, 0, },
-{0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA), S_DSA, K_DHE, C_AES, B_256, M_SHA, 0, 0, 0, },
-{0,CS(TLS_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_RSA, C_AES, B_256, M_SHA, 0, 0, 0, },
+{0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
+{0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA), S_DSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
+{0,CS(TLS_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_RSA, C_AES, B_256, M_SHA, 1, 0, 0, },
-{0,CS(SSL_FORTEZZA_DMS_WITH_RC4_128_SHA), S_KEA, K_KEA, C_RC4, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_DHE_DSS_WITH_RC4_128_SHA), S_DSA, K_DHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
-{0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, 0, 0, 0, },
-{0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, 0, 0, 0, },
+{0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
+{0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
{0,CS(SSL_RSA_WITH_RC4_128_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0, },
{0,CS(SSL_RSA_WITH_RC4_128_SHA), S_RSA, K_RSA, C_RC4, B_128, M_SHA, 0, 0, 0, },
-{0,CS(TLS_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_RSA, C_AES, B_128, M_SHA, 0, 0, 0, },
+{0,CS(TLS_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_RSA, C_AES, B_128, M_SHA, 1, 0, 0, },
-{0,CS(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_DHE, C_3DES,B_3DES,M_SHA, 0, 0, 0, },
-{0,CS(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA), S_DSA, K_DHE, C_3DES,B_3DES,M_SHA, 0, 0, 0, },
+{0,CS(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
+{0,CS(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA), S_DSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
{0,CS(SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 1, },
{0,CS(SSL_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
-{0,CS(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA),S_KEA, K_KEA, C_SJ, B_SJ, M_SHA, 1, 0, 0, },
{0,CS(SSL_DHE_RSA_WITH_DES_CBC_SHA), S_RSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
{0,CS(SSL_DHE_DSS_WITH_DES_CBC_SHA), S_DSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
-{0,CS(SSL_RSA_FIPS_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 1, 0, 1, },
-{0,CS(SSL_RSA_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 1, 0, 0, },
+{0,CS(SSL_RSA_FIPS_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 1, },
+{0,CS(SSL_RSA_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 0, },
{0,CS(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA), S_RSA, K_RSA, C_RC4, B_56, M_SHA, 0, 1, 0, },
-{0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 1, 1, 0, },
+{0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 1, 0, },
{0,CS(SSL_RSA_EXPORT_WITH_RC4_40_MD5), S_RSA, K_RSA, C_RC4, B_40, M_MD5, 0, 1, 0, },
{0,CS(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5), S_RSA, K_RSA, C_RC2, B_40, M_MD5, 0, 1, 0, },
-{0,CS(SSL_FORTEZZA_DMS_WITH_NULL_SHA), S_KEA, K_KEA, C_NULL,B_0, M_SHA, 0, 1, 0, },
{0,CS(SSL_RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL,B_0, M_SHA, 0, 1, 0, },
{0,CS(SSL_RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL,B_0, M_MD5, 0, 1, 0, },
@@ -175,20 +164,20 @@ static const SSLCipherSuiteInfo suiteInfo[] = {
{0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_ECDSA_WITH_DES_CBC_SHA), S_ECDSA, K_ECDH, C_DES, B_DES, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, 0, 0, 0, },
+{0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
+{0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, },
+{0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, },
{0,CS(TLS_ECDH_RSA_WITH_NULL_SHA), S_RSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_ECDH_RSA_WITH_DES_CBC_SHA), S_RSA, K_ECDH, C_DES, B_DES, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDH, C_AES, B_128, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDH, C_AES, B_256, M_SHA, 0, 0, 0, },
+{0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
+{0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, },
+{0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, },
-{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 0, 0, 0, },
+{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, },
-{0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_128, M_SHA, 0, 0, 0, },
+{0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, },
#endif /* NSS_ENABLE_ECC */
/* SSL 2 table */
diff --git a/security/nss/lib/ssl/sslnonce.c b/security/nss/lib/ssl/sslnonce.c
index 1a02666e5..e2dbcf0a5 100644
--- a/security/nss/lib/ssl/sslnonce.c
+++ b/security/nss/lib/ssl/sslnonce.c
@@ -193,7 +193,7 @@ ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID,
PORT_Strcmp(sid->peerID, peerID) == 0)) &&
/* is cacheable */
(sid->version < SSL_LIBRARY_VERSION_3_0 ||
- sid->u.ssl3.resumable) &&
+ sid->u.ssl3.keys.resumable) &&
/* server hostname matches. */
(sid->urlSvrName != NULL) &&
((0 == PORT_Strcmp(urlSvrName, sid->urlSvrName)) ||
diff --git a/security/nss/lib/ssl/sslproto.h b/security/nss/lib/ssl/sslproto.h
index fa0639605..e7a998126 100644
--- a/security/nss/lib/ssl/sslproto.h
+++ b/security/nss/lib/ssl/sslproto.h
@@ -139,9 +139,9 @@
#define SSL_DH_ANON_WITH_DES_CBC_SHA 0x001a
#define SSL_DH_ANON_WITH_3DES_EDE_CBC_SHA 0x001b
-#define SSL_FORTEZZA_DMS_WITH_NULL_SHA 0x001c
-#define SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA 0x001d
-#define SSL_FORTEZZA_DMS_WITH_RC4_128_SHA 0x001e
+#define SSL_FORTEZZA_DMS_WITH_NULL_SHA 0x001c /* deprecated */
+#define SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA 0x001d /* deprecated */
+#define SSL_FORTEZZA_DMS_WITH_RC4_128_SHA 0x001e /* deprecated */
/* New TLS cipher suites */
#define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F
diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c
index 404f9a7dc..a30b062df 100644
--- a/security/nss/lib/ssl/sslsecur.c
+++ b/security/nss/lib/ssl/sslsecur.c
@@ -112,9 +112,9 @@ ssl_Do1stHandshake(sslSocket *ss)
int loopCount = 0;
do {
- PORT_Assert( ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( !ssl_HaveRecvBufLock(ss) );
- PORT_Assert( !ssl_HaveXmitBufLock(ss) );
+ PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
+ PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss));
if (ss->handshake == 0) {
/* Previous handshake finished. Switch to next one */
@@ -153,8 +153,8 @@ ssl_Do1stHandshake(sslSocket *ss)
*/
} while (rv != SECFailure); /* was (rv >= 0); XXX_1 */
- PORT_Assert( !ssl_HaveRecvBufLock(ss) );
- PORT_Assert( !ssl_HaveXmitBufLock(ss) );
+ PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss));
+ PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss));
if (rv == SECWouldBlock) {
PORT_SetError(PR_WOULD_BLOCK_ERROR);
@@ -202,7 +202,7 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool asServer)
}
/* Don't waste my time */
- if (!ss->useSecurity)
+ if (!ss->opt.useSecurity)
return SECSuccess;
SSL_LOCK_READER(ss);
@@ -231,7 +231,7 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool asServer)
** Blow away old security state and get a fresh setup.
*/
ssl_GetXmitBufLock(ss);
- ssl_ResetSecurityInfo(&ss->sec);
+ ssl_ResetSecurityInfo(&ss->sec, PR_TRUE);
status = ssl_CreateSecurityInfo(ss);
ssl_ReleaseXmitBufLock(ss);
@@ -264,7 +264,7 @@ SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache)
return SECFailure;
}
- if (!ss->useSecurity)
+ if (!ss->opt.useSecurity)
return SECSuccess;
ssl_Get1stHandshakeLock(ss);
@@ -284,6 +284,19 @@ SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache)
return rv;
}
+/*
+** Same as above, but with an I/O timeout.
+ */
+SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd,
+ PRBool flushCache,
+ PRIntervalTime timeout)
+{
+ if (SECSuccess != ssl_SetTimeout(fd, timeout)) {
+ return SECFailure;
+ }
+ return SSL_ReHandshake(fd, flushCache);
+}
+
SECStatus
SSL_RedoHandshake(PRFileDesc *fd)
{
@@ -306,7 +319,7 @@ SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb,
return SECFailure;
}
- if (!ss->useSecurity) {
+ if (!ss->opt.useSecurity) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@@ -347,7 +360,7 @@ SSL_ForceHandshake(PRFileDesc *fd)
}
/* Don't waste my time */
- if (!ss->useSecurity)
+ if (!ss->opt.useSecurity)
return SECSuccess;
ssl_Get1stHandshakeLock(ss);
@@ -378,6 +391,19 @@ SSL_ForceHandshake(PRFileDesc *fd)
return rv;
}
+/*
+ ** Same as above, but with an I/O timeout.
+ */
+SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
+ PRIntervalTime timeout)
+{
+ if (SECSuccess != ssl_SetTimeout(fd, timeout)) {
+ return SECFailure;
+ }
+ return SSL_ForceHandshake(fd);
+}
+
+
/************************************************************************/
/*
@@ -388,17 +414,20 @@ SSL_ForceHandshake(PRFileDesc *fd)
SECStatus
sslBuffer_Grow(sslBuffer *b, unsigned int newLen)
{
+ newLen = PR_MAX(newLen, MAX_FRAGMENT_LENGTH + 2048);
if (newLen > b->space) {
+ unsigned char *newBuf;
if (b->buf) {
- b->buf = (unsigned char *) PORT_Realloc(b->buf, newLen);
+ newBuf = (unsigned char *) PORT_Realloc(b->buf, newLen);
} else {
- b->buf = (unsigned char *) PORT_Alloc(newLen);
+ newBuf = (unsigned char *) PORT_Alloc(newLen);
}
- if (!b->buf) {
+ if (!newBuf) {
return SECFailure;
}
SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d",
SSL_GETPID(), b->space, newLen));
+ b->buf = newBuf;
b->space = newLen;
}
return SECSuccess;
@@ -417,7 +446,7 @@ ssl_SaveWriteData(sslSocket *ss, sslBuffer *buf, const void *data,
unsigned int newlen;
SECStatus rv;
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
newlen = buf->len + len;
if (newlen > buf->space) {
rv = sslBuffer_Grow(buf, newlen);
@@ -444,7 +473,7 @@ ssl_SendSavedWriteData(sslSocket *ss, sslBuffer *buf, sslSendFunc send)
int rv = 0;
int len = buf->len;
- PORT_Assert( ssl_HaveXmitBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
if (len != 0) {
SSL_TRC(5, ("%d: SSL[%d]: sending %d bytes of saved data",
SSL_GETPID(), ss->fd, len));
@@ -574,12 +603,7 @@ ssl_FindCertKEAType(CERTCertificate * cert)
case SEC_OID_PKCS1_RSA_ENCRYPTION:
keaType = kt_rsa;
break;
- case SEC_OID_MISSI_KEA_DSS_OLD:
- case SEC_OID_MISSI_KEA_DSS:
- case SEC_OID_MISSI_DSS_OLD:
- case SEC_OID_MISSI_DSS:
- keaType = kt_fortezza;
- break;
+
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
keaType = kt_dh;
break;
@@ -667,19 +691,47 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert,
}
/* load the private key */
- if (sc->serverKey != NULL) {
- SECKEY_DestroyPrivateKey(sc->serverKey);
- sc->serverKey = NULL;
+ if (sc->serverKeyPair != NULL) {
+ ssl3_FreeKeyPair(sc->serverKeyPair);
+ sc->serverKeyPair = NULL;
}
if (key) {
- sc->serverKey = SECKEY_CopyPrivateKey(key);
- if (sc->serverKey == NULL)
+ SECKEYPrivateKey * keyCopy = NULL;
+ CK_MECHANISM_TYPE keyMech = CKM_INVALID_MECHANISM;
+
+ if (key->pkcs11Slot) {
+ PK11SlotInfo * bestSlot;
+ bestSlot = PK11_ReferenceSlot(key->pkcs11Slot);
+ if (bestSlot) {
+ keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
+ PK11_FreeSlot(bestSlot);
+ }
+ }
+ if (keyCopy == NULL)
+ keyMech = PK11_MapSignKeyType(key->keyType);
+ if (keyMech != CKM_INVALID_MECHANISM) {
+ PK11SlotInfo * bestSlot;
+ /* XXX Maybe should be bestSlotMultiple? */
+ bestSlot = PK11_GetBestSlot(keyMech, NULL /* wincx */);
+ if (bestSlot) {
+ keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
+ PK11_FreeSlot(bestSlot);
+ }
+ }
+ if (keyCopy == NULL)
+ keyCopy = SECKEY_CopyPrivateKey(key);
+ if (keyCopy == NULL)
goto loser;
- SECKEY_CacheStaticFlags(sc->serverKey);
+ SECKEY_CacheStaticFlags(keyCopy);
+ sc->serverKeyPair = ssl3_NewKeyPair(keyCopy, NULL);
+ if (sc->serverKeyPair == NULL) {
+ SECKEY_DestroyPrivateKey(keyCopy);
+ goto loser;
+ }
}
if (kea == kt_rsa && cert && sc->serverKeyBits > 512) {
- if (ss->noStepDown) {
+ if (ss->opt.noStepDown) {
/* disable all export ciphersuites */
} else {
rv = ssl3_CreateRSAStepDownKeys(ss);
@@ -704,9 +756,9 @@ loser:
CERT_DestroyCertificateList(sc->serverCertChain);
sc->serverCertChain = NULL;
}
- if (sc->serverKey != NULL) {
- SECKEY_DestroyPrivateKey(sc->serverKey);
- sc->serverKey = NULL;
+ if (sc->serverKeyPair != NULL) {
+ ssl3_FreeKeyPair(sc->serverKeyPair);
+ sc->serverKeyPair = NULL;
}
return SECFailure;
}
@@ -791,7 +843,7 @@ loser:
** Caller holds any relevant locks.
*/
void
-ssl_ResetSecurityInfo(sslSecurityInfo *sec)
+ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset)
{
/* Destroy MAC */
if (sec->hash && sec->hashcx) {
@@ -833,7 +885,10 @@ ssl_ResetSecurityInfo(sslSecurityInfo *sec)
ssl_FreeSID(sec->ci.sid);
}
PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space);
- memset(&sec->ci, 0, sizeof sec->ci);
+ if (doMemset) {
+ memset(&sec->ci, 0, sizeof sec->ci);
+ }
+
}
/*
@@ -844,7 +899,7 @@ ssl_ResetSecurityInfo(sslSecurityInfo *sec)
void
ssl_DestroySecurityInfo(sslSecurityInfo *sec)
{
- ssl_ResetSecurityInfo(sec);
+ ssl_ResetSecurityInfo(sec, PR_FALSE);
PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space);
sec->writeBuf.buf = 0;
@@ -860,7 +915,7 @@ ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa)
PRFileDesc *osfd = ss->fd->lower;
int rv;
- if ( ss->handshakeAsServer ) {
+ if ( ss->opt.handshakeAsServer ) {
ss->securityHandshake = ssl2_BeginServerHandshake;
ss->handshaking = sslHandshakingAsServer;
} else {
@@ -895,7 +950,7 @@ ssl_SecureClose(sslSocket *ss)
ss->firstHsDone &&
!(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
!ss->recvdCloseNotify &&
- (ss->ssl3 != NULL)) {
+ ss->ssl3.initialized) {
/* We don't want the final alert to be Nagle delayed. */
if (!ss->delayDisabled) {
@@ -927,7 +982,7 @@ ssl_SecureShutdown(sslSocket *ss, int nsprHow)
(ss->version >= SSL_LIBRARY_VERSION_3_0) &&
ss->firstHsDone &&
!ss->recvdCloseNotify &&
- (ss->ssl3 != NULL)) {
+ ss->ssl3.initialized) {
(void) SSL3_SendAlert(ss, alert_warning, close_notify);
}
@@ -959,7 +1014,7 @@ ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
return PR_FAILURE;
}
- if (!ssl_SocketIsBlocking(ss) && !ss->fdx) {
+ if (!ssl_SocketIsBlocking(ss) && !ss->opt.fdx) {
ssl_GetXmitBufLock(ss);
if (ss->pendingBuf.len != 0) {
rv = ssl_SendSavedWriteData(ss, &ss->pendingBuf, ssl_DefSend);
@@ -1135,7 +1190,7 @@ SSL_DataPending(PRFileDesc *fd)
ss = ssl_FindSocket(fd);
- if (ss && ss->useSecurity) {
+ if (ss && ss->opt.useSecurity) {
ssl_Get1stHandshakeLock(ss);
ssl_GetSSL3HandshakeLock(ss);
@@ -1183,7 +1238,7 @@ SSL_GetSessionID(PRFileDesc *fd)
ssl_Get1stHandshakeLock(ss);
ssl_GetSSL3HandshakeLock(ss);
- if (ss->useSecurity && ss->firstHsDone && ss->sec.ci.sid) {
+ if (ss->opt.useSecurity && ss->firstHsDone && ss->sec.ci.sid) {
item = (SECItem *)PORT_Alloc(sizeof(SECItem));
if (item) {
sslSessionID * sid = ss->sec.ci.sid;
diff --git a/security/nss/lib/ssl/sslsnce.c b/security/nss/lib/ssl/sslsnce.c
index 345104f1f..877a5a995 100644
--- a/security/nss/lib/ssl/sslsnce.c
+++ b/security/nss/lib/ssl/sslsnce.c
@@ -146,17 +146,15 @@ struct sidCacheEntryStr {
/* 2 */ ssl3CipherSuite cipherSuite;
/* 2 */ PRUint16 compression; /* SSL3CompressionMethod */
-/*122 */ ssl3SidKeys keys; /* keys and ivs, wrapped as needed. */
-/* 1 */ PRUint8 hasFortezza;
-/* 1 */ PRUint8 resumable;
+/*100 */ ssl3SidKeys keys; /* keys and ivs, wrapped as needed. */
/* 4 */ PRUint32 masterWrapMech;
/* 4 */ SSL3KEAType exchKeyType;
/* 4 */ PRInt32 certIndex;
-/*140 */} ssl3;
-#if defined(LINUX)
+/*116 */} ssl3;
+#if defined(LINUX) /* XXX Why only on Linux ? */
struct {
- PRUint8 filler[144];
+ PRUint8 filler[144]; /* XXX why this number ? */
} forceSize;
#endif
} u;
@@ -441,8 +439,6 @@ ConvertFromSID(sidCacheEntry *to, sslSessionID *from)
to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
to->u.ssl3.compression = (uint16)from->u.ssl3.compression;
- to->u.ssl3.resumable = from->u.ssl3.resumable;
- to->u.ssl3.hasFortezza = from->u.ssl3.hasFortezza;
to->u.ssl3.keys = from->u.ssl3.keys;
to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType;
@@ -517,8 +513,6 @@ ConvertToSID(sidCacheEntry *from, certCacheEntry *pcce,
to->u.ssl3.sessionIDLength = from->sessionIDLength;
to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
to->u.ssl3.compression = (SSL3CompressionMethod)from->u.ssl3.compression;
- to->u.ssl3.resumable = from->u.ssl3.resumable;
- to->u.ssl3.hasFortezza = from->u.ssl3.hasFortezza;
to->u.ssl3.keys = from->u.ssl3.keys;
to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType;
@@ -530,7 +524,7 @@ ConvertToSID(sidCacheEntry *from, certCacheEntry *pcce,
*/
to->u.ssl3.clientWriteKey = NULL;
to->u.ssl3.serverWriteKey = NULL;
- to->u.ssl3.tek = NULL;
+
to->urlSvrName = NULL;
to->u.ssl3.masterModuleID = (SECMODModuleID)-1; /* invalid value */
@@ -544,8 +538,6 @@ ConvertToSID(sidCacheEntry *from, certCacheEntry *pcce,
to->u.ssl3.clAuthSeries = 0;
to->u.ssl3.clAuthValid = PR_FALSE;
- to->u.ssl3.clientWriteSaveLen = 0;
-
if (from->u.ssl3.certIndex != -1 && pcce) {
SECItem derCert;
@@ -929,6 +921,11 @@ InitCache(cacheDesc *cache, int maxCacheEntries, PRUint32 ssl2_timeout,
int locks_to_initialize = 0;
PRUint32 init_time;
+ if ( (!cache) || (maxCacheEntries < 0) || (!directory) ) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
if (cache->cacheMem) {
/* Already done */
return SECSuccess;
diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c
index 9803eec96..6344c99c5 100644
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -71,8 +71,6 @@ static cipherPolicy ssl_ciphers[] = { /* Export France */
{ SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, SSL_ALLOWED, SSL_ALLOWED },
{ SSL_EN_DES_64_CBC_WITH_MD5, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ SSL_EN_DES_192_EDE3_CBC_WITH_MD5, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ SSL_RSA_WITH_RC4_128_MD5, SSL_RESTRICTED, SSL_NOT_ALLOWED },
{ SSL_RSA_WITH_RC4_128_SHA, SSL_RESTRICTED, SSL_NOT_ALLOWED },
{ SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
@@ -81,7 +79,6 @@ static cipherPolicy ssl_ciphers[] = { /* Export France */
{ SSL_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_ALLOWED, SSL_ALLOWED },
{ SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_ALLOWED, SSL_ALLOWED },
- { SSL_FORTEZZA_DMS_WITH_NULL_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
@@ -164,6 +161,8 @@ static sslOptions ssl_defaults = {
PR_TRUE, /* v2CompatibleHello */
PR_TRUE, /* detectRollBack */
PR_FALSE, /* noStepDown */
+ PR_FALSE, /* bypassPKCS11 */
+ PR_FALSE, /* noLocks */
};
sslSessionIDLookupFunc ssl_sid_lookup;
@@ -173,13 +172,17 @@ sslSessionIDUncacheFunc ssl_sid_uncache;
static PRBool ssl_inited = PR_FALSE;
static PRDescIdentity ssl_layer_id;
+PRBool locksEverDisabled; /* implicitly PR_FALSE */
+PRBool ssl_force_locks; /* implicitly PR_FALSE */
int ssl_lock_readers = 1; /* default true. */
char ssl_debug;
char ssl_trace;
-
+char lockStatus[] = "Locks are ENABLED. ";
+#define LOCKSTATUS_OFFSET 10 /* offset of ENABLED */
/* forward declarations. */
-static sslSocket *ssl_NewSocket(void);
+static sslSocket *ssl_NewSocket(PRBool makeLocks);
+static SECStatus ssl_MakeLocks(sslSocket *ss);
static PRStatus ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack,
PRDescIdentity id);
@@ -230,22 +233,10 @@ ssl_DupSocket(sslSocket *os)
sslSocket *ss;
SECStatus rv;
- ss = ssl_NewSocket();
+ ss = ssl_NewSocket((PRBool)(!os->opt.noLocks));
if (ss) {
- ss->useSocks = PR_FALSE;
- ss->useSecurity = os->useSecurity;
- ss->requestCertificate = os->requestCertificate;
- ss->requireCertificate = os->requireCertificate;
- ss->handshakeAsClient = os->handshakeAsClient;
- ss->handshakeAsServer = os->handshakeAsServer;
- ss->enableSSL2 = os->enableSSL2;
- ss->enableSSL3 = os->enableSSL3;
- ss->enableTLS = os->enableTLS;
- ss->noCache = os->noCache;
- ss->fdx = os->fdx;
- ss->v2CompatibleHello = os->v2CompatibleHello;
- ss->detectRollBack = os->detectRollBack;
- ss->noStepDown = os->noStepDown;
+ ss->opt = os->opt;
+ ss->opt.useSocks = PR_FALSE;
ss->peerID = !os->peerID ? NULL : PORT_Strdup(os->peerID);
ss->url = !os->url ? NULL : PORT_Strdup(os->url);
@@ -274,7 +265,7 @@ ssl_DupSocket(sslSocket *os)
ss->sizeCipherSpecs = 0;
ss->preferredCipher = NULL;
}
- if (ss->useSecurity) {
+ if (ss->opt.useSecurity) {
/* This int should be SSLKEAType, but CC on Irix complains,
* during the for loop.
*/
@@ -292,9 +283,9 @@ ssl_DupSocket(sslSocket *os)
sc->serverCert = NULL;
sc->serverCertChain = NULL;
}
- sc->serverKey = oc->serverKey ?
- SECKEY_CopyPrivateKey(oc->serverKey) : NULL;
- if (oc->serverKey && !sc->serverKey)
+ sc->serverKeyPair = oc->serverKeyPair ?
+ ssl3_GetKeyPairRef(oc->serverKeyPair) : NULL;
+ if (oc->serverKeyPair && !sc->serverKeyPair)
goto loser;
sc->serverKeyBits = oc->serverKeyBits;
}
@@ -331,7 +322,6 @@ loser:
static void
ssl_DestroyLocks(sslSocket *ss)
{
-
/* Destroy locks. */
if (ss->firstHandshakeLock) {
PZ_DestroyMonitor(ss->firstHandshakeLock);
@@ -376,7 +366,7 @@ ssl_DestroySocketContents(sslSocket *ss)
/* Free up socket */
ssl_DestroySecurityInfo(&ss->sec);
- ssl3_DestroySSL3Info(ss->ssl3);
+ ssl3_DestroySSL3Info(ss);
PORT_Free(ss->saveBuf.buf);
PORT_Free(ss->pendingBuf.buf);
@@ -399,8 +389,8 @@ ssl_DestroySocketContents(sslSocket *ss)
CERT_DestroyCertificate(sc->serverCert);
if (sc->serverCertChain != NULL)
CERT_DestroyCertificateList(sc->serverCertChain);
- if (sc->serverKey != NULL)
- SECKEY_DestroyPrivateKey(sc->serverKey);
+ if (sc->serverKeyPair != NULL)
+ ssl3_FreeKeyPair(sc->serverKeyPair);
}
if (ss->stepDownKeyPair) {
ssl3_FreeKeyPair(ss->stepDownKeyPair);
@@ -479,7 +469,7 @@ ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled)
static void
ssl_ChooseOps(sslSocket *ss)
{
- ss->ops = ss->useSecurity ? &ssl_secure_ops : &ssl_default_ops;
+ ss->ops = ss->opt.useSecurity ? &ssl_secure_ops : &ssl_default_ops;
}
/* Called from SSL_Enable (immediately below) */
@@ -503,18 +493,20 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
{
sslSocket *ss = ssl_FindSocket(fd);
SECStatus rv = SECSuccess;
+ PRBool holdingLocks;
if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
return SECFailure;
}
+ holdingLocks = (!ss->opt.noLocks);
ssl_Get1stHandshakeLock(ss);
ssl_GetSSL3HandshakeLock(ss);
switch (which) {
case SSL_SOCKS:
- ss->useSocks = PR_FALSE;
+ ss->opt.useSocks = PR_FALSE;
rv = PrepareSocket(ss);
if (on) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -523,38 +515,38 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
break;
case SSL_SECURITY:
- ss->useSecurity = on;
+ ss->opt.useSecurity = on;
rv = PrepareSocket(ss);
break;
case SSL_REQUEST_CERTIFICATE:
- ss->requestCertificate = on;
+ ss->opt.requestCertificate = on;
break;
case SSL_REQUIRE_CERTIFICATE:
- ss->requireCertificate = on;
+ ss->opt.requireCertificate = on;
break;
case SSL_HANDSHAKE_AS_CLIENT:
- if ( ss->handshakeAsServer && on ) {
+ if ( ss->opt.handshakeAsServer && on ) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
break;
}
- ss->handshakeAsClient = on;
+ ss->opt.handshakeAsClient = on;
break;
case SSL_HANDSHAKE_AS_SERVER:
- if ( ss->handshakeAsClient && on ) {
+ if ( ss->opt.handshakeAsClient && on ) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
break;
}
- ss->handshakeAsServer = on;
+ ss->opt.handshakeAsServer = on;
break;
case SSL_ENABLE_TLS:
- ss->enableTLS = on;
+ ss->opt.enableTLS = on;
ss->preferredCipher = NULL;
if (ss->cipherSpecs) {
PORT_Free(ss->cipherSpecs);
@@ -564,7 +556,7 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
break;
case SSL_ENABLE_SSL3:
- ss->enableSSL3 = on;
+ ss->opt.enableSSL3 = on;
ss->preferredCipher = NULL;
if (ss->cipherSpecs) {
PORT_Free(ss->cipherSpecs);
@@ -574,9 +566,9 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
break;
case SSL_ENABLE_SSL2:
- ss->enableSSL2 = on;
+ ss->opt.enableSSL2 = on;
if (on) {
- ss->v2CompatibleHello = on;
+ ss->opt.v2CompatibleHello = on;
}
ss->preferredCipher = NULL;
if (ss->cipherSpecs) {
@@ -587,37 +579,76 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
break;
case SSL_NO_CACHE:
- ss->noCache = on;
+ ss->opt.noCache = on;
break;
case SSL_ENABLE_FDX:
- ss->fdx = on;
+ if (on && ss->opt.noLocks) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ }
+ ss->opt.fdx = on;
break;
case SSL_V2_COMPATIBLE_HELLO:
- ss->v2CompatibleHello = on;
+ ss->opt.v2CompatibleHello = on;
if (!on) {
- ss->enableSSL2 = on;
+ ss->opt.enableSSL2 = on;
}
break;
case SSL_ROLLBACK_DETECTION:
- ss->detectRollBack = on;
+ ss->opt.detectRollBack = on;
break;
case SSL_NO_STEP_DOWN:
- ss->noStepDown = on;
+ ss->opt.noStepDown = on;
if (on)
SSL_DisableExportCipherSuites(fd);
break;
+ case SSL_BYPASS_PKCS11:
+ if (ss->handshakeBegun) {
+ PORT_SetError(PR_INVALID_STATE_ERROR);
+ rv = SECFailure;
+ } else {
+ ss->opt.bypassPKCS11 = on;
+ }
+ break;
+
+ case SSL_NO_LOCKS:
+ if (on && ss->opt.fdx) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ }
+ if (on && ssl_force_locks)
+ on = PR_FALSE; /* silent override */
+ ss->opt.noLocks = on;
+ if (on) {
+ locksEverDisabled = PR_TRUE;
+ strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
+ } else if (!holdingLocks) {
+ rv = ssl_MakeLocks(ss);
+ if (rv != SECSuccess) {
+ ss->opt.noLocks = PR_TRUE;
+ }
+ }
+ break;
+
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
}
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
+ /* We can't use the macros for releasing the locks here,
+ * because ss->opt.noLocks might have changed just above.
+ * We must release these locks (monitors) here, if we aquired them above,
+ * regardless of the current value of ss->opt.noLocks.
+ */
+ if (holdingLocks) {
+ PZ_ExitMonitor((ss)->ssl3HandshakeLock);
+ PZ_ExitMonitor((ss)->firstHandshakeLock);
+ }
return rv;
}
@@ -644,19 +675,21 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
switch (which) {
case SSL_SOCKS: on = PR_FALSE; break;
- case SSL_SECURITY: on = ss->useSecurity; break;
- case SSL_REQUEST_CERTIFICATE: on = ss->requestCertificate; break;
- case SSL_REQUIRE_CERTIFICATE: on = ss->requireCertificate; break;
- case SSL_HANDSHAKE_AS_CLIENT: on = ss->handshakeAsClient; break;
- case SSL_HANDSHAKE_AS_SERVER: on = ss->handshakeAsServer; break;
- case SSL_ENABLE_TLS: on = ss->enableTLS; break;
- case SSL_ENABLE_SSL3: on = ss->enableSSL3; break;
- case SSL_ENABLE_SSL2: on = ss->enableSSL2; break;
- case SSL_NO_CACHE: on = ss->noCache; break;
- case SSL_ENABLE_FDX: on = ss->fdx; break;
- case SSL_V2_COMPATIBLE_HELLO: on = ss->v2CompatibleHello; break;
- case SSL_ROLLBACK_DETECTION: on = ss->detectRollBack; break;
- case SSL_NO_STEP_DOWN: on = ss->noStepDown; break;
+ case SSL_SECURITY: on = ss->opt.useSecurity; break;
+ case SSL_REQUEST_CERTIFICATE: on = ss->opt.requestCertificate; break;
+ case SSL_REQUIRE_CERTIFICATE: on = ss->opt.requireCertificate; break;
+ case SSL_HANDSHAKE_AS_CLIENT: on = ss->opt.handshakeAsClient; break;
+ case SSL_HANDSHAKE_AS_SERVER: on = ss->opt.handshakeAsServer; break;
+ case SSL_ENABLE_TLS: on = ss->opt.enableTLS; break;
+ case SSL_ENABLE_SSL3: on = ss->opt.enableSSL3; break;
+ case SSL_ENABLE_SSL2: on = ss->opt.enableSSL2; break;
+ case SSL_NO_CACHE: on = ss->opt.noCache; break;
+ case SSL_ENABLE_FDX: on = ss->opt.fdx; break;
+ case SSL_V2_COMPATIBLE_HELLO: on = ss->opt.v2CompatibleHello; break;
+ case SSL_ROLLBACK_DETECTION: on = ss->opt.detectRollBack; break;
+ case SSL_NO_STEP_DOWN: on = ss->opt.noStepDown; break;
+ case SSL_BYPASS_PKCS11: on = ss->opt.bypassPKCS11; break;
+ case SSL_NO_LOCKS: on = ss->opt.noLocks; break;
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -696,6 +729,8 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
case SSL_V2_COMPATIBLE_HELLO: on = ssl_defaults.v2CompatibleHello; break;
case SSL_ROLLBACK_DETECTION: on = ssl_defaults.detectRollBack; break;
case SSL_NO_STEP_DOWN: on = ssl_defaults.noStepDown; break;
+ case SSL_BYPASS_PKCS11: on = ssl_defaults.bypassPKCS11; break;
+ case SSL_NO_LOCKS: on = ssl_defaults.noLocks; break;
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -773,6 +808,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
break;
case SSL_ENABLE_FDX:
+ if (on && ssl_defaults.noLocks) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
ssl_defaults.fdx = on;
break;
@@ -793,6 +832,24 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
SSL_DisableDefaultExportCipherSuites();
break;
+ case SSL_BYPASS_PKCS11:
+ ssl_defaults.bypassPKCS11 = on;
+ break;
+
+ case SSL_NO_LOCKS:
+ if (on && ssl_defaults.fdx) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ if (on && ssl_force_locks)
+ on = PR_FALSE; /* silent override */
+ ssl_defaults.noLocks = on;
+ if (on) {
+ locksEverDisabled = PR_TRUE;
+ strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
+ }
+ break;
+
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@@ -800,6 +857,20 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on)
return SECSuccess;
}
+/* function tells us if the cipher suite is one that we no longer support. */
+static PRBool
+ssl_IsRemovedCipherSuite(PRInt32 suite)
+{
+ switch (suite) {
+ case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
+ case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
+ case SSL_FORTEZZA_DMS_WITH_RC4_128_SHA:
+ return PR_TRUE;
+ default:
+ return PR_FALSE;
+ }
+}
+
/* Part of the public NSS API.
* Since this is a global (not per-socket) setting, we cannot use the
* HandshakeLock to protect this. Probably want a global lock.
@@ -814,6 +885,8 @@ SSL_SetPolicy(long which, int policy)
else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
}
+ if (ssl_IsRemovedCipherSuite(which))
+ return SECSuccess;
return SSL_CipherPolicySet(which, policy);
}
@@ -822,7 +895,9 @@ SSL_CipherPolicySet(PRInt32 which, PRInt32 policy)
{
SECStatus rv;
- if (SSL_IS_SSL2_CIPHER(which)) {
+ if (ssl_IsRemovedCipherSuite(which)) {
+ rv = SECSuccess;
+ } else if (SSL_IS_SSL2_CIPHER(which)) {
rv = ssl2_SetPolicy(which, policy);
} else {
rv = ssl3_SetPolicy((ssl3CipherSuite)which, policy);
@@ -839,7 +914,10 @@ SSL_CipherPolicyGet(PRInt32 which, PRInt32 *oPolicy)
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- if (SSL_IS_SSL2_CIPHER(which)) {
+ if (ssl_IsRemovedCipherSuite(which)) {
+ *oPolicy = SSL_NOT_ALLOWED;
+ rv = SECSuccess;
+ } else if (SSL_IS_SSL2_CIPHER(which)) {
rv = ssl2_GetPolicy(which, oPolicy);
} else {
rv = ssl3_GetPolicy((ssl3CipherSuite)which, oPolicy);
@@ -862,6 +940,8 @@ SSL_EnableCipher(long which, PRBool enabled)
else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
}
+ if (ssl_IsRemovedCipherSuite(which))
+ return SECSuccess;
return SSL_CipherPrefSetDefault(which, enabled);
}
@@ -869,7 +949,9 @@ SECStatus
SSL_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
{
SECStatus rv;
-
+
+ if (ssl_IsRemovedCipherSuite(which))
+ return SECSuccess;
if (enabled && ssl_defaults.noStepDown && SSL_IsExportCipherSuite(which)) {
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
return SECFailure;
@@ -891,7 +973,10 @@ SSL_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- if (SSL_IS_SSL2_CIPHER(which)) {
+ if (ssl_IsRemovedCipherSuite(which)) {
+ *enabled = PR_FALSE;
+ rv = SECSuccess;
+ } else if (SSL_IS_SSL2_CIPHER(which)) {
rv = ssl2_CipherPrefGetDefault(which, enabled);
} else {
rv = ssl3_CipherPrefGetDefault((ssl3CipherSuite)which, enabled);
@@ -909,7 +994,9 @@ SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefSet", SSL_GETPID(), fd));
return SECFailure;
}
- if (enabled && ss->noStepDown && SSL_IsExportCipherSuite(which)) {
+ if (ssl_IsRemovedCipherSuite(which))
+ return SECSuccess;
+ if (enabled && ss->opt.noStepDown && SSL_IsExportCipherSuite(which)) {
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
return SECFailure;
}
@@ -936,7 +1023,10 @@ SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled)
*enabled = PR_FALSE;
return SECFailure;
}
- if (SSL_IS_SSL2_CIPHER(which)) {
+ if (ssl_IsRemovedCipherSuite(which)) {
+ *enabled = PR_FALSE;
+ rv = SECSuccess;
+ } else if (SSL_IS_SSL2_CIPHER(which)) {
rv = ssl2_CipherPrefGet(ss, which, enabled);
} else {
rv = ssl3_CipherPrefGet(ss, (ssl3CipherSuite)which, enabled);
@@ -1002,7 +1092,7 @@ SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
if (model == NULL) {
/* Just create a default socket if we're given NULL for the model */
- ns = ssl_NewSocket();
+ ns = ssl_NewSocket((PRBool)(!ssl_defaults.noLocks));
} else {
sslSocket * ss = ssl_FindSocket(model);
if (ss == NULL) {
@@ -1087,8 +1177,8 @@ ssl_Accept(PRFileDesc *fd, PRNetAddr *sockaddr, PRIntervalTime timeout)
/* Now start server connection handshake with client.
** Don't need locks here because nobody else has a reference to ns yet.
*/
- if ( ns->useSecurity ) {
- if ( ns->handshakeAsClient ) {
+ if ( ns->opt.useSecurity ) {
+ if ( ns->opt.handshakeAsClient ) {
ns->handshake = ssl2_BeginClientHandshake;
ss->handshaking = sslHandshakingAsClient;
} else {
@@ -1244,7 +1334,7 @@ ssl_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags,
}
SSL_LOCK_READER(ss);
ss->rTimeout = timeout;
- if (!ss->fdx)
+ if (!ss->opt.fdx)
ss->wTimeout = timeout;
rv = (*ss->ops->recv)(ss, (unsigned char*)buf, len, flags);
SSL_UNLOCK_READER(ss);
@@ -1265,7 +1355,7 @@ ssl_Send(PRFileDesc *fd, const void *buf, PRInt32 len, PRIntn flags,
}
SSL_LOCK_WRITER(ss);
ss->wTimeout = timeout;
- if (!ss->fdx)
+ if (!ss->opt.fdx)
ss->rTimeout = timeout;
rv = (*ss->ops->send)(ss, (const unsigned char*)buf, len, flags);
SSL_UNLOCK_WRITER(ss);
@@ -1285,7 +1375,7 @@ ssl_Read(PRFileDesc *fd, void *buf, PRInt32 len)
}
SSL_LOCK_READER(ss);
ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
- if (!ss->fdx)
+ if (!ss->opt.fdx)
ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
rv = (*ss->ops->read)(ss, (unsigned char*)buf, len);
SSL_UNLOCK_READER(ss);
@@ -1305,7 +1395,7 @@ ssl_Write(PRFileDesc *fd, const void *buf, PRInt32 len)
}
SSL_LOCK_WRITER(ss);
ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
- if (!ss->fdx)
+ if (!ss->opt.fdx)
ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
rv = (*ss->ops->write)(ss, (const unsigned char*)buf, len);
SSL_UNLOCK_WRITER(ss);
@@ -1384,6 +1474,29 @@ SSL_SetSockPeerID(PRFileDesc *fd, char *peerID)
return SECSuccess;
}
+SECStatus PR_CALLBACK
+ssl_SetTimeout(PRFileDesc *fd, PRIntervalTime timeout)
+{
+ sslSocket *ss;
+
+ ss = ssl_GetPrivate(fd);
+ if (!ss) {
+ SSL_DBG(("%d: SSL[%d]: bad socket in SetTimeout", SSL_GETPID(), fd));
+ return SECFailure;
+ }
+ SSL_LOCK_READER(ss);
+ ss->rTimeout = timeout;
+ if (ss->opt.fdx) {
+ SSL_LOCK_WRITER(ss);
+ }
+ ss->wTimeout = timeout;
+ if (ss->opt.fdx) {
+ SSL_UNLOCK_WRITER(ss);
+ }
+ SSL_UNLOCK_READER(ss);
+ return SECSuccess;
+}
+
#define PR_POLL_RW (PR_POLL_WRITE | PR_POLL_READ)
static PRInt16 PR_CALLBACK
@@ -1401,7 +1514,7 @@ ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags)
return 0; /* don't poll on this socket */
}
- if (ss->useSecurity &&
+ if (ss->opt.useSecurity &&
ss->handshaking != sslHandshakingUndetermined &&
!ss->firstHsDone &&
(how_flags & PR_POLL_RW)) {
@@ -1843,38 +1956,88 @@ loser:
return PR_FAILURE;
}
+/* if this fails, caller must destroy socket. */
+static SECStatus
+ssl_MakeLocks(sslSocket *ss)
+{
+ ss->firstHandshakeLock = PZ_NewMonitor(nssILockSSL);
+ if (!ss->firstHandshakeLock)
+ goto loser;
+ ss->ssl3HandshakeLock = PZ_NewMonitor(nssILockSSL);
+ if (!ss->ssl3HandshakeLock)
+ goto loser;
+ ss->specLock = NSSRWLock_New(SSL_LOCK_RANK_SPEC, NULL);
+ if (!ss->specLock)
+ goto loser;
+ ss->recvBufLock = PZ_NewMonitor(nssILockSSL);
+ if (!ss->recvBufLock)
+ goto loser;
+ ss->xmitBufLock = PZ_NewMonitor(nssILockSSL);
+ if (!ss->xmitBufLock)
+ goto loser;
+ ss->writerThread = NULL;
+ if (ssl_lock_readers) {
+ ss->recvLock = PZ_NewLock(nssILockSSL);
+ if (!ss->recvLock)
+ goto loser;
+ ss->sendLock = PZ_NewLock(nssILockSSL);
+ if (!ss->sendLock)
+ goto loser;
+ }
+ return SECSuccess;
+loser:
+ ssl_DestroyLocks(ss);
+ return SECFailure;
+}
+
+#if (defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS)) && !defined(_WIN32_WCE)
+#define NSS_HAVE_GETENV 1
+#endif
+
/*
** Create a newsocket structure for a file descriptor.
*/
static sslSocket *
-ssl_NewSocket(void)
+ssl_NewSocket(PRBool makeLocks)
{
sslSocket *ss;
-#ifdef DEBUG
-#if (defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS)) && !defined(_WIN32_WCE)
+#if defined( NSS_HAVE_GETENV )
static int firsttime = 1;
if (firsttime) {
+ char * ev;
firsttime = 0;
- {
- char *ev = getenv("SSLDEBUG");
- if (ev && ev[0]) {
- ssl_debug = atoi(ev);
- SSL_TRACE(("SSL: debugging set to %d", ssl_debug));
- }
- }
+#ifdef DEBUG
#ifdef TRACE
- {
- char *ev = getenv("SSLTRACE");
- if (ev && ev[0]) {
- ssl_trace = atoi(ev);
- SSL_TRACE(("SSL: tracing set to %d", ssl_trace));
- }
+ ev = getenv("SSLTRACE");
+ if (ev && ev[0]) {
+ ssl_trace = atoi(ev);
+ SSL_TRACE(("SSL: tracing set to %d", ssl_trace));
}
#endif /* TRACE */
- }
-#endif /* XP_UNIX || XP_WIN32 */
+ ev = getenv("SSLDEBUG");
+ if (ev && ev[0]) {
+ ssl_debug = atoi(ev);
+ SSL_TRACE(("SSL: debugging set to %d", ssl_debug));
+ }
#endif /* DEBUG */
+ ev = getenv("SSLBYPASS");
+ if (ev && ev[0]) {
+ ssl_defaults.bypassPKCS11 = (ev[0] == '1');
+ SSL_TRACE(("SSL: bypass default set to %d", \
+ ssl_defaults.bypassPKCS11));
+ }
+ ev = getenv("SSLFORCELOCKS");
+ if (ev && ev[0] == '1') {
+ ssl_force_locks = PR_TRUE;
+ ssl_defaults.noLocks = 0;
+ strcpy(lockStatus + LOCKSTATUS_OFFSET, "FORCED. ");
+ SSL_TRACE(("SSL: force_locks set to %d", ssl_force_locks));
+ }
+ }
+#endif /* NSS_HAVE_GETENV */
+ if (ssl_force_locks)
+ makeLocks = PR_TRUE;
/* Make a new socket and get it ready */
ss = (sslSocket*) PORT_ZAlloc(sizeof(sslSocket));
@@ -1885,20 +2048,10 @@ ssl_NewSocket(void)
int i;
SECStatus status;
- ss->useSecurity = ssl_defaults.useSecurity;
- ss->useSocks = PR_FALSE;
- ss->requestCertificate = ssl_defaults.requestCertificate;
- ss->requireCertificate = ssl_defaults.requireCertificate;
- ss->handshakeAsClient = ssl_defaults.handshakeAsClient;
- ss->handshakeAsServer = ssl_defaults.handshakeAsServer;
- ss->enableSSL2 = ssl_defaults.enableSSL2;
- ss->enableSSL3 = ssl_defaults.enableSSL3;
- ss->enableTLS = ssl_defaults.enableTLS ;
- ss->fdx = ssl_defaults.fdx;
- ss->v2CompatibleHello = ssl_defaults.v2CompatibleHello;
- ss->detectRollBack = ssl_defaults.detectRollBack;
- ss->noStepDown = ssl_defaults.noStepDown;
- ss->noCache = ssl_defaults.noCache;
+ ss->opt = ssl_defaults;
+ ss->opt.useSocks = PR_FALSE;
+ ss->opt.noLocks = !makeLocks;
+
ss->peerID = NULL;
ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
@@ -1912,7 +2065,7 @@ ssl_NewSocket(void)
sslServerCerts * sc = ss->serverCerts + i;
sc->serverCert = NULL;
sc->serverCertChain = NULL;
- sc->serverKey = NULL;
+ sc->serverKeyPair = NULL;
sc->serverKeyBits = 0;
}
ss->stepDownKeyPair = NULL;
@@ -1930,25 +2083,14 @@ ssl_NewSocket(void)
ssl2_InitSocketPolicy(ss);
ssl3_InitSocketPolicy(ss);
- ss->firstHandshakeLock = PZ_NewMonitor(nssILockSSL);
- if (!ss->firstHandshakeLock) goto loser;
- ss->ssl3HandshakeLock = PZ_NewMonitor(nssILockSSL);
- if (!ss->ssl3HandshakeLock) goto loser;
- ss->specLock = NSSRWLock_New(SSL_LOCK_RANK_SPEC, NULL);
- if (!ss->specLock) goto loser;
- ss->recvBufLock = PZ_NewMonitor(nssILockSSL);
- if (!ss->recvBufLock) goto loser;
- ss->xmitBufLock = PZ_NewMonitor(nssILockSSL);
- if (!ss->xmitBufLock) goto loser;
- ss->writerThread = NULL;
- if (ssl_lock_readers) {
- ss->recvLock = PZ_NewLock(nssILockSSL);
- if (!ss->recvLock) goto loser;
- ss->sendLock = PZ_NewLock(nssILockSSL);
- if (!ss->sendLock) goto loser;
+ if (makeLocks) {
+ status = ssl_MakeLocks(ss);
+ if (status != SECSuccess)
+ goto loser;
}
status = ssl_CreateSecurityInfo(ss);
- if (status != SECSuccess) goto loser;
+ if (status != SECSuccess)
+ goto loser;
status = ssl_InitGather(&ss->gs);
if (status != SECSuccess) {
loser:
diff --git a/security/nss/lib/ssl/sslt.h b/security/nss/lib/ssl/sslt.h
index 0223ee2ad..052339b7d 100644
--- a/security/nss/lib/ssl/sslt.h
+++ b/security/nss/lib/ssl/sslt.h
@@ -66,7 +66,7 @@ typedef enum {
ssl_kea_null = 0,
ssl_kea_rsa = 1,
ssl_kea_dh = 2,
- ssl_kea_fortezza = 3,
+ ssl_kea_fortezza = 3, /* deprecated, now unused */
ssl_kea_ecdh = 4,
ssl_kea_size /* number of ssl_kea_ algorithms */
} SSLKEAType;
@@ -79,7 +79,7 @@ typedef enum {
#define kt_null ssl_kea_null
#define kt_rsa ssl_kea_rsa
#define kt_dh ssl_kea_dh
-#define kt_fortezza ssl_kea_fortezza
+#define kt_fortezza ssl_kea_fortezza /* deprecated, now unused */
#define kt_ecdh ssl_kea_ecdh
#define kt_kea_size ssl_kea_size
@@ -105,7 +105,7 @@ typedef enum {
ssl_calg_des = 3,
ssl_calg_3des = 4,
ssl_calg_idea = 5,
- ssl_calg_fortezza = 6, /* skipjack */
+ ssl_calg_fortezza = 6, /* deprecated, now unused */
ssl_calg_aes = 7 /* coming soon */
} SSLCipherAlgorithm;
diff --git a/security/nss/lib/util/Makefile b/security/nss/lib/util/Makefile
index 97dfe0d7a..afe353d31 100644
--- a/security/nss/lib/util/Makefile
+++ b/security/nss/lib/util/Makefile
@@ -50,12 +50,6 @@ include manifest.mn
include $(CORE_DEPTH)/coreconf/config.mk
-ifeq ($(OS_TARGET),HP-UX)
-ifneq ($(OS_TEST),ia64)
- ASFILES += ret_cr16.s
-endif
-endif
-
#######################################################################
# (3) Include "component" configuration information. (OPTIONAL) #
#######################################################################
diff --git a/security/nss/lib/util/quickder.c b/security/nss/lib/util/quickder.c
index 33b251272..29a582147 100644
--- a/security/nss/lib/util/quickder.c
+++ b/security/nss/lib/util/quickder.c
@@ -113,12 +113,9 @@ static SECStatus GetItem(SECItem* src, SECItem* dest, PRBool includeTag)
/* reaching the end of the buffer is not an error */
dest->data = NULL;
dest->len = 0;
- dest->type = siBuffer;
-
return SECSuccess;
}
- dest->type = siBuffer;
dest->data = definite_length_decoder(src->data, src->len, &dest->len,
includeTag);
if (dest->data == NULL)
@@ -862,7 +859,12 @@ static SECStatus DecodeItem(void* dest,
SECItem* destItem = (SECItem*) ((char*)dest + templateEntry->offset);
if (destItem)
{
- *(destItem) = temp;
+ /* we leave the type alone in the destination SECItem.
+ If part of the destination was allocated by the decoder, in
+ cases of POINTER, SET OF and SEQUENCE OF, then type is set to
+ siBuffer due to the use of PORT_ArenaZAlloc*/
+ destItem->data = temp.data;
+ destItem->len = temp.len;
}
else
{
diff --git a/security/nss/lib/util/secasn1.h b/security/nss/lib/util/secasn1.h
index 5e4779d57..462aaac23 100644
--- a/security/nss/lib/util/secasn1.h
+++ b/security/nss/lib/util/secasn1.h
@@ -92,6 +92,13 @@ extern SECStatus SEC_ASN1Decode(PRArenaPool *pool, void *dest,
const SEC_ASN1Template *t,
const char *buf, long len);
+/* Both classic ASN.1 and QuickDER have a feature that removes leading zeroes
+ out of SEC_ASN1_INTEGER if the caller sets siUnsignedInteger in the type
+ field of the target SECItem prior to calling the decoder. Otherwise, the
+ type field is ignored and untouched. For SECItem that are dynamically
+ allocated (from POINTER, SET OF, SEQUENCE OF) the decoder sets the type
+ field to siBuffer. */
+
extern SECStatus SEC_ASN1DecodeItem(PRArenaPool *pool, void *dest,
const SEC_ASN1Template *t,
const SECItem *src);
diff --git a/security/nss/makefile.win b/security/nss/makefile.win
deleted file mode 100644
index 266a28162..000000000
--- a/security/nss/makefile.win
+++ /dev/null
@@ -1,104 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-#
-# An NMAKE file to set up and adjust NSS's build system for
-# Client build. Client build should invoke NMAKE on this file
-# instead of invoking gmake directly.
-#
-
-DEPTH = ..\..
-include <$(DEPTH)\config\config.mak>
-
-GMAKE = gmake.exe
-
-GMAKE_FLAGS = OBJDIR_NAME=$(OBJDIR) MOZILLA_CLIENT=1
-GMAKE_FLAGS = $(GMAKE_FLAGS) MOZILLA_INCLUDES="-I$(MOZ_SRC:\=/)/mozilla/dist/include/nspr -I$(MOZ_SRC:\=/)/mozilla/dist/include/dbm"
-
-#
-# The Client's debug build uses MSVC's debug runtime library (/MDd).
-#
-
-!ifndef MOZ_DEBUG
-GMAKE_FLAGS = $(GMAKE_FLAGS) BUILD_OPT=1
-!endif
-
-!if "$(MOZ_BITS)" == "16"
-GMAKE_FLAGS = $(GMAKE_FLAGS) OS_TARGET=WIN16
-!else
-
-GMAKE_FLAGS = $(GMAKE_FLAGS) OS_TARGET=WIN95
-!ifdef MOZ_DEBUG
-!ifndef MOZ_NO_DEBUG_RTL
-GMAKE_FLAGS = $(GMAKE_FLAGS) USE_DEBUG_RTL=1
-!endif
-!endif
-
-!endif
-
-#
-# The rules. Simply invoke gmake with the same target.
-# The default target is 'all'. For Win16, set up the
-# environment to use the Watcom compiler, Watcom headers,
-# and Watcom libs.
-#
-
-all:: export libs install
-
-install:: moz_import install_roots
-
-depend::
- $(GMAKE) -C lib $(GMAKE_FLAGS) clean
-
-export libs install clobber clobber_all clean::
-!if "$(MOZ_BITS)" == "16"
- set PATH=%WATCPATH%
- set INCLUDE=%WATC_INC%
- set LIB=%WATC_LIB%
-!endif
- $(GMAKE) -C lib $(GMAKE_FLAGS) $@
-!if "$(MOZ_BITS)" == "16"
- set PATH=%MSVCPATH%
- set INCLUDE=%MSVC_INC%
- set LIB=%MSVC_LIB%
-!endif
-
-moz_import::
- copy $(DIST)\lib\dbm32.lib $(DIST)\lib\dbm.lib
-
-install_roots::
- $(MAKE_INSTALL) $(DIST)\lib\nssckbi.dll $(DIST)\bin
diff --git a/security/nss/pkg/linux/Makefile b/security/nss/pkg/linux/Makefile
index decc20ecd..a4ecce510 100644
--- a/security/nss/pkg/linux/Makefile
+++ b/security/nss/pkg/linux/Makefile
@@ -44,7 +44,9 @@
CORE_DEPTH = ../../..
NAME = sun-nss
-RELEASE = 1
+ifndef RPM_RELEASE
+RPM_RELEASE = 1
+endif
VERSION = `grep NSS_VERSION $(CORE_DEPTH)/../dist/public/nss/nss.h \
| sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//'`
PWD = `pwd`
@@ -52,17 +54,26 @@ BUILDROOT = $(PWD)\/$(NAME)-root
include $(CORE_DEPTH)/coreconf/config.mk
+# Force i386 for non 64 bit build
+ifneq ($(USE_64),1)
+ RPMTARGET = "--target=i386"
+ RPMLIBDIR = lib
+else
+ RPMLIBDIR = lib64
+endif
+
+
publish:
$(MAKE) clean
mkdir -p SOURCES SRPMS RPMS BUILD
- mkdir -p opt/sun/private/lib
+ mkdir -p opt/sun/private/$(RPMLIBDIR)
find $(CORE_DEPTH)/../dist/$(OBJDIR)/lib -type l \
\( -name "*.so" -o -name "*.chk" \) \
- -exec cp {} opt/sun/private/lib \;
- rm -f opt/sun/private/lib/libnspr4.so \
- opt/sun/private/lib/libplc4.so \
- opt/sun/private/lib/libplds4.so \
- opt/sun/private/lib/libjss*.so
+ -exec cp {} opt/sun/private/$(RPMLIBDIR) \;
+ rm -f opt/sun/private/$(RPMLIBDIR)/libnspr4.so \
+ opt/sun/private/$(RPMLIBDIR)/libplc4.so \
+ opt/sun/private/$(RPMLIBDIR)/libplds4.so \
+ opt/sun/private/$(RPMLIBDIR)/libjss*.so
mkdir -p opt/sun/private/bin
(cd $(CORE_DEPTH)/../dist/$(OBJDIR)/bin && tar cphf - \
certutil cmsutil crlutil modutil pk12util signtool \
@@ -76,7 +87,7 @@ publish:
echo "%define _topdir `pwd`" >temp.spec
sed -e "s/NAME_REPLACE/$(NAME)/" \
-e "s/VERSION_REPLACE/$(VERSION)/" \
- -e "s/RELEASE_REPLACE/$(RELEASE)/" \
+ -e "s/RELEASE_REPLACE/$(RPM_RELEASE)/" \
<$(NAME).spec >>temp.spec
echo "" >>temp.spec
echo "%files" >>temp.spec
@@ -84,7 +95,7 @@ publish:
echo "%dir /opt" >>temp.spec
echo "%dir /opt/sun" >>temp.spec
echo "%dir /opt/sun/private" >>temp.spec
- echo "%dir /opt/sun/private/lib" >>temp.spec
+ echo "%dir /opt/sun/private/$(RPMLIBDIR)" >>temp.spec
echo "%dir /opt/sun/private/bin" >>temp.spec
find opt \( -name "*.so" -o -name "*.chk" -o -type f \
-perm u=rwx,g=rx,o=rx \) | sed -e "s-^-/-" >>temp.spec
@@ -99,7 +110,7 @@ publish:
find opt -type f \( -name "*.h" \) \
| sed -e "s-^-/-" >>temp.spec
cp $(NAME)-$(VERSION).tar.gz SOURCES
- rpm -ba temp.spec
+ rpmbuild $(RPMTARGET) -bb temp.spec
clean::
rm -rf SOURCES SRPMS RPMS BUILD
diff --git a/security/nss/pkg/linux/sun-nss.spec b/security/nss/pkg/linux/sun-nss.spec
index 5660761d4..13b5b26db 100644
--- a/security/nss/pkg/linux/sun-nss.spec
+++ b/security/nss/pkg/linux/sun-nss.spec
@@ -62,6 +62,8 @@ Summary: Development Libraries for Network Security Services
Group: Development/Libraries
Requires: %{name} = %{version}-%{release}
+%define _unpackaged_files_terminate_build 0
+
%description devel
Header files for doing development with Network Security Services.
diff --git a/security/nss/pkg/solaris/SUNWtls/prototype_i386 b/security/nss/pkg/solaris/SUNWtls/prototype_i386
index 8febcbc41..0b55f3009 100644
--- a/security/nss/pkg/solaris/SUNWtls/prototype_i386
+++ b/security/nss/pkg/solaris/SUNWtls/prototype_i386
@@ -64,6 +64,10 @@
#
# SUNWtls
#
+f none usr/lib/mps/libfreebl3.chk 755 root bin
+f none usr/lib/mps/libfreebl3.so 755 root bin
+s none usr/lib/mps/secv1/libfreebl3.chk=../libfreebl3.chk
+s none usr/lib/mps/secv1/libfreebl3.so=../libfreebl3.so
#64#s none usr/lib/mps/64=amd64
#64#s none usr/lib/mps/secv1/64=amd64
#64#d none usr/lib/mps/amd64 755 root bin
@@ -74,9 +78,13 @@
#64#f none usr/lib/mps/amd64/libnssckbi.so 755 root bin
#64#f none usr/lib/mps/amd64/libsoftokn3.chk 755 root bin
#64#f none usr/lib/mps/amd64/libsoftokn3.so 755 root bin
+#64#f none usr/lib/mps/amd64/libfreebl3.chk 755 root bin
+#64#f none usr/lib/mps/amd64/libfreebl3.so 755 root bin
#64#s none usr/lib/mps/secv1/amd64/libnss3.so=../../amd64/libnss3.so
#64#s none usr/lib/mps/secv1/amd64/libsmime3.so=../../amd64/libsmime3.so
#64#s none usr/lib/mps/secv1/amd64/libssl3.so=../../amd64/libssl3.so
#64#s none usr/lib/mps/secv1/amd64/libnssckbi.so=../../amd64/libnssckbi.so
#64#s none usr/lib/mps/secv1/amd64/libsoftokn3.chk=../../amd64/libsoftokn3.chk
#64#s none usr/lib/mps/secv1/amd64/libsoftokn3.so=../../amd64/libsoftokn3.so
+#64#s none usr/lib/mps/secv1/amd64/libfreebl3.chk=../../amd64/libfreebl3.chk
+#64#s none usr/lib/mps/secv1/amd64/libfreebl3.so=../../amd64/libfreebl3.so
diff --git a/security/nss/pkg/solaris/SUNWtls/prototype_sparc b/security/nss/pkg/solaris/SUNWtls/prototype_sparc
index 1a9b9c845..e7b487ac0 100644
--- a/security/nss/pkg/solaris/SUNWtls/prototype_sparc
+++ b/security/nss/pkg/solaris/SUNWtls/prototype_sparc
@@ -64,14 +64,18 @@
#
# SUNWtls
#
-f none usr/lib/mps/libfreebl_hybrid_3.chk 755 root bin
-f none usr/lib/mps/libfreebl_hybrid_3.so 755 root bin
-f none usr/lib/mps/libfreebl_pure32_3.chk 755 root bin
-f none usr/lib/mps/libfreebl_pure32_3.so 755 root bin
-s none usr/lib/mps/secv1/libfreebl_hybrid_3.chk=../libfreebl_hybrid_3.chk
-s none usr/lib/mps/secv1/libfreebl_hybrid_3.so=../libfreebl_hybrid_3.so
-s none usr/lib/mps/secv1/libfreebl_pure32_3.chk=../libfreebl_pure32_3.chk
-s none usr/lib/mps/secv1/libfreebl_pure32_3.so=../libfreebl_pure32_3.so
+f none usr/lib/mps/libfreebl_32fpu_3.chk 755 root bin
+f none usr/lib/mps/libfreebl_32fpu_3.so 755 root bin
+f none usr/lib/mps/libfreebl_32int64_3.chk 755 root bin
+f none usr/lib/mps/libfreebl_32int64_3.so 755 root bin
+f none usr/lib/mps/libfreebl_32int_3.chk 755 root bin
+f none usr/lib/mps/libfreebl_32int_3.so 755 root bin
+s none usr/lib/mps/secv1/libfreebl_32fpu_3.chk=../libfreebl_32fpu_3.chk
+s none usr/lib/mps/secv1/libfreebl_32fpu_3.so=../libfreebl_32fpu_3.so
+s none usr/lib/mps/secv1/libfreebl_32int64_3.chk=../libfreebl_32int64_3.chk
+s none usr/lib/mps/secv1/libfreebl_32int64_3.so=../libfreebl_32int64_3.so
+s none usr/lib/mps/secv1/libfreebl_32int_3.chk=../libfreebl_32int_3.chk
+s none usr/lib/mps/secv1/libfreebl_32int_3.so=../libfreebl_32int_3.so
#64#s none usr/lib/mps/64=sparcv9
#64#s none usr/lib/mps/secv1/64=sparcv9
#64#d none usr/lib/mps/sparcv9 755 root bin
@@ -82,10 +86,18 @@ s none usr/lib/mps/secv1/libfreebl_pure32_3.so=../libfreebl_pure32_3.so
#64#f none usr/lib/mps/sparcv9/libnssckbi.so 755 root bin
#64#f none usr/lib/mps/sparcv9/libsoftokn3.chk 755 root bin
#64#f none usr/lib/mps/sparcv9/libsoftokn3.so 755 root bin
+#64#f none usr/lib/mps/sparcv9/libfreebl_64fpu_3.chk 755 root bin
+#64#f none usr/lib/mps/sparcv9/libfreebl_64fpu_3.so 755 root bin
+#64#f none usr/lib/mps/sparcv9/libfreebl_64int_3.chk 755 root bin
+#64#f none usr/lib/mps/sparcv9/libfreebl_64int_3.so 755 root bin
#64#s none usr/lib/mps/secv1/sparcv9/libnss3.so=../../sparcv9/libnss3.so
#64#s none usr/lib/mps/secv1/sparcv9/libsmime3.so=../../sparcv9/libsmime3.so
#64#s none usr/lib/mps/secv1/sparcv9/libssl3.so=../../sparcv9/libssl3.so
#64#s none usr/lib/mps/secv1/sparcv9/libnssckbi.so=../../sparcv9/libnssckbi.so
#64#s none usr/lib/mps/secv1/sparcv9/libsoftokn3.chk=../../sparcv9/libsoftokn3.chk
#64#s none usr/lib/mps/secv1/sparcv9/libsoftokn3.so=../../sparcv9/libsoftokn3.so
+#64#s none usr/lib/mps/secv1/sparcv9/libfreebl_64fpu_3.chk=../../sparcv9/libfreebl_64fpu_3.chk
+#64#s none usr/lib/mps/secv1/sparcv9/libfreebl_64fpu_3.so=../../sparcv9/libfreebl_64fpu_3.so
+#64#s none usr/lib/mps/secv1/sparcv9/libfreebl_64int_3.chk=../../sparcv9/libfreebl_64int_3.chk
+#64#s none usr/lib/mps/secv1/sparcv9/libfreebl_64int_3.so=../../sparcv9/libfreebl_64int_3.so
diff --git a/security/nss/pkg/solaris/SUNWtlsd/prototype b/security/nss/pkg/solaris/SUNWtlsd/prototype
index 6581f32f1..b742d2f9e 100755
--- a/security/nss/pkg/solaris/SUNWtlsd/prototype
+++ b/security/nss/pkg/solaris/SUNWtlsd/prototype
@@ -160,6 +160,4 @@ f none usr/include/mps/ssl.h 0644 root bin
f none usr/include/mps/sslerr.h 0644 root bin
f none usr/include/mps/sslproto.h 0644 root bin
f none usr/include/mps/sslt.h 0644 root bin
-f none usr/include/mps/swfort.h 0644 root bin
-f none usr/include/mps/swfortt.h 0644 root bin
f none usr/include/mps/watcomfx.h 0644 root bin
diff --git a/security/nss/tests/all.sh b/security/nss/tests/all.sh
index cb9121a28..f664ed488 100755
--- a/security/nss/tests/all.sh
+++ b/security/nss/tests/all.sh
@@ -52,6 +52,7 @@
# other tests
# ssl.sh - tests SSL V2 SSL V3 and TLS
# smime.sh - S/MIME testing
+# crmf.sh - CRMF/CMMF testing
# sdr.sh - test NSS SDR
# cipher.sh - test NSS ciphers
# perf.sh - Nightly performance measurments
@@ -77,7 +78,7 @@
#
########################################################################
-TESTS="cert ssl sdr cipher smime perf tools fips dbtests"
+TESTS="cert ssl sdr cipher smime crmf perf tools fips dbtests"
SCRIPTNAME=all.sh
CLEANUP="${SCRIPTNAME}"
cd `dirname $0` # will cause problems if sourced
diff --git a/security/nss/tests/cert/cert.sh b/security/nss/tests/cert/cert.sh
index 9feeb76d7..3956a3b23 100755
--- a/security/nss/tests/cert/cert.sh
+++ b/security/nss/tests/cert/cert.sh
@@ -436,10 +436,6 @@ cert_smime_client()
################# 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
diff --git a/security/nss/tests/cert/eccert.sh b/security/nss/tests/cert/eccert.sh
index 996c48d4d..e1a172455 100644
--- a/security/nss/tests/cert/eccert.sh
+++ b/security/nss/tests/cert/eccert.sh
@@ -568,7 +568,7 @@ cert_smime_client()
echo "$SCRIPTNAME: Creating Client CA Issued Certificates =============="
cert_create_certs ${ALICEDIR} "Alice" 30 ${D_ALICE}
- cert_create_cert ${BOBDIR} "Bob" 40 ${D_BOB}
+ cert_create_certs ${BOBDIR} "Bob" 40 ${D_BOB}
echo "$SCRIPTNAME: Creating Dave's Certificate -------------------------"
cert_create_cert "${DAVEDIR}" Dave 50 ${D_DAVE}
@@ -595,10 +595,6 @@ cert_smime_client()
################# 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
diff --git a/security/nss/tests/cert/noeccert.sh b/security/nss/tests/cert/noeccert.sh
deleted file mode 100755
index 21ff388d7..000000000
--- a/security/nss/tests/cert/noeccert.sh
+++ /dev/null
@@ -1,658 +0,0 @@
-#! /bin/sh
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-########################################################################
-#
-# 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/crmf/crmf.sh b/security/nss/tests/crmf/crmf.sh
new file mode 100644
index 000000000..251f1021a
--- /dev/null
+++ b/security/nss/tests/crmf/crmf.sh
@@ -0,0 +1,121 @@
+#! /bin/sh
+#
+# ***** BEGIN LICENSE BLOCK *****
+# 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 Netscape security libraries.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1994-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# 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.
+#
+# ***** END LICENSE BLOCK *****
+
+########################################################################
+#
+# mozilla/security/nss/tests/crmf/crmf.sh
+#
+# Script to test NSS crmf library (a static library)
+#
+# needs to work on all Unix and Windows platforms
+#
+# special strings
+# ---------------
+# FIXME ... known problems, search for this string
+# NOTE .... unexpected behavior
+#
+########################################################################
+
+############################## smime_init ##############################
+# local shell function to initialize this script
+########################################################################
+crmf_init()
+{
+ SCRIPTNAME=crmf.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
+ html_head "CRMF/CMMF Tests"
+
+ # cmrf uses the S/MIME certs to test with
+ grep "SUCCESS: SMIME passed" $CERT_LOG_FILE >/dev/null || {
+ Exit 11 "Fatal - S/MIME of cert.sh needs to pass first"
+ }
+
+ CRMFDIR=${HOSTDIR}/crmf
+ R_CRMFDIR=../crmf
+ mkdir -p ${CRMFDIR}
+ cd ${CRMFDIR}
+}
+
+############################## crmf_main ##############################
+# local shell function to test basic CRMF request and CMMF responses
+# from 1 --> 2"
+########################################################################
+crmf_main()
+{
+ echo "$SCRIPTNAME: CRMF/CMMF Tests ------------------------------"
+ echo "crmftest -d ${P_R_BOBDIR} -p Bob -e dave@bogus.com -s TestCA -P nss crmf decode"
+ crmftest -d ${P_R_BOBDIR} -p Bob -e dave@bogus.com -s TestCA -P nss crmf decode
+ html_msg $? 0 "CRMF test" "."
+
+ echo "crmftest -d ${P_R_BOBDIR} -p Bob -e dave@bogus.com -s TestCA -P nss cmmf"
+ crmftest -d ${P_R_BOBDIR} -p Bob -e dave@bogus.com -s TestCA -P nss cmmf
+ html_msg $? 0 "CMMF test" "."
+
+# Add tests for key recovery and challange as crmftest's capabilities increase
+
+}
+
+############################## crmf_cleanup ###########################
+# local shell function to finish this script (no exit since it might be
+# sourced)
+########################################################################
+crmf_cleanup()
+{
+ html "</TABLE><BR>"
+ cd ${QADIR}
+ . common/cleanup.sh
+}
+
+################## main #################################################
+
+crmf_init
+crmf_main
+crmf_cleanup
+
diff --git a/security/nss/tests/fixtests.sh b/security/nss/tests/fixtests.sh
index 8994a1ea0..42cbdf8ee 100755
--- a/security/nss/tests/fixtests.sh
+++ b/security/nss/tests/fixtests.sh
@@ -48,6 +48,8 @@ fix_test_scripts()
FLAG=$1
CERT_DIR=cert
CERT_SCRIPT=cert.sh
+ SMIME_DIR=smime
+ SMIME_SCRIPT=smime.sh
SSL_DIR=ssl
SSLAUTH=sslauth.txt
SSLCOV=sslcov.txt
@@ -60,6 +62,7 @@ fix_test_scripts()
if [ xx$FLAG = xx"enable_ecc" ]; then
if [ -f $CERT_DIR/$NOEC_PREFIX$CERT_SCRIPT -a \
+ -f $SMIME_DIR/$NOEC_PREFIX$SMIME_SCRIPT -a \
-f $SSL_DIR/$NOEC_PREFIX$SSLAUTH -a \
-f $SSL_DIR/$NOEC_PREFIX$SSLCOV -a \
-f $SSL_DIR/$NOEC_PREFIX$SSL_SCRIPT -a \
@@ -70,6 +73,7 @@ fix_test_scripts()
echo "noecc files are missing"
echo "Saving files as noec"
cp $CERT_DIR/$CERT_SCRIPT $CERT_DIR/$NOEC_PREFIX$CERT_SCRIPT
+ cp $SMIME_DIR/$SMIME_SCRIPT $SMIME_DIR/$NOEC_PREFIX$SMIME_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
@@ -78,6 +82,7 @@ fix_test_scripts()
fi
echo "Overwriting with ec versions"
cp $CERT_DIR/$EC_PREFIX$CERT_SCRIPT $CERT_DIR/$CERT_SCRIPT
+ cp $SMIME_DIR/$EC_PREFIX$SMIME_SCRIPT $SMIME_DIR/$SMIME_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
@@ -85,6 +90,7 @@ fix_test_scripts()
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 $SMIME_DIR/$NOEC_PREFIX$SMIME_SCRIPT -a \
-f $SSL_DIR/$NOEC_PREFIX$SSLAUTH -a \
-f $SSL_DIR/$NOEC_PREFIX$SSLCOV -a \
-f $SSL_DIR/$NOEC_PREFIX$SSL_SCRIPT -a \
@@ -93,6 +99,7 @@ fix_test_scripts()
echo "noecc files exist"
echo "Overwriting with noec versions"
cp $CERT_DIR/$NOEC_PREFIX$CERT_SCRIPT $CERT_DIR/$CERT_SCRIPT
+ cp $SMIME_DIR/$NOEC_PREFIX$SMIME_SCRIPT $SMIME_DIR/$SMIME_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
diff --git a/security/nss/tests/smime/ecsmime.sh b/security/nss/tests/smime/ecsmime.sh
new file mode 100644
index 000000000..e94000bfa
--- /dev/null
+++ b/security/nss/tests/smime/ecsmime.sh
@@ -0,0 +1,260 @@
+#! /bin/sh
+#
+# ***** BEGIN LICENSE BLOCK *****
+# 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 Netscape security libraries.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1994-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# 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.
+#
+# ***** END LICENSE BLOCK *****
+
+########################################################################
+#
+# mozilla/security/nss/tests/smime/smime.sh
+#
+# Script to test NSS smime
+#
+# needs to work on all Unix and Windows platforms
+#
+# special strings
+# ---------------
+# FIXME ... known problems, search for this string
+# NOTE .... unexpected behavior
+#
+########################################################################
+
+############################## smime_init ##############################
+# local shell function to initialize this script
+########################################################################
+smime_init()
+{
+ SCRIPTNAME=smime.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=smime.sh
+ html_head "S/MIME Tests"
+
+ grep "SUCCESS: SMIME passed" $CERT_LOG_FILE >/dev/null || {
+ Exit 11 "Fatal - S/MIME of cert.sh needs to pass first"
+ }
+
+ SMIMEDIR=${HOSTDIR}/smime
+ R_SMIMEDIR=../smime
+ mkdir -p ${SMIMEDIR}
+ cd ${SMIMEDIR}
+ cp ${QADIR}/smime/alice.txt ${SMIMEDIR}
+}
+
+
+############################## smime_main ##############################
+# local shell function to test basic signed and enveloped messages
+# from 1 --> 2"
+########################################################################
+smime_main()
+{
+
+ echo "$SCRIPTNAME: Signing Attached Message (ECDSA SHA1) ------------------"
+ echo "cmsutil -S -N Alice-ec -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.sig"
+ cmsutil -S -N Alice-ec -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.sig
+ html_msg $? 0 "Create Signature Alice (ECDSA SHA1)" "."
+
+ echo "cmsutil -D -i alice-ec.sig -d ${P_R_BOBDIR} -o alice-ec.data1"
+ cmsutil -D -i alice-ec.sig -d ${P_R_BOBDIR} -o alice-ec.data1
+ html_msg $? 0 "Decode Alice's Signature (ECDSA SHA1)" "."
+
+ echo "diff alice.txt alice-ec.data1"
+ diff alice.txt alice-ec.data1
+ html_msg $? 0 "Compare Decoded Signature and Original (ECDSA SHA1)" "."
+
+ echo "$SCRIPTNAME: Signing Attached Message (SHA1) ------------------"
+ echo "cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig"
+ cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig
+ html_msg $? 0 "Create Signature Alice (SHA1)" "."
+
+ echo "cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1"
+ cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1
+ html_msg $? 0 "Decode Alice's Signature (SHA1)" "."
+
+ echo "diff alice.txt alice.data1"
+ diff alice.txt alice.data1
+ html_msg $? 0 "Compare Decoded Signature and Original (SHA1)" "."
+
+ echo "$SCRIPTNAME: Signing Attached Message (SHA256) ------------------"
+ echo "cmsutil -S -N Alice -H SHA256 -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig"
+ cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig
+ html_msg $? 0 "Create Signature Alice (SHA256)" "."
+
+ echo "cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1"
+ cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1
+ html_msg $? 0 "Decode Alice's Signature (SHA256)" "."
+
+ echo "diff alice.txt alice.data1"
+ diff alice.txt alice.data1
+ html_msg $? 0 "Compare Decoded Signature and Original (SHA256)" "."
+
+ echo "$SCRIPTNAME: Signing Attached Message (SHA384) ------------------"
+ echo "cmsutil -S -N Alice -H SHA384 -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig"
+ cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig
+ html_msg $? 0 "Create Signature Alice (SHA384)" "."
+
+ echo "cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1"
+ cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1
+ html_msg $? 0 "Decode Alice's Signature (SHA384)" "."
+
+ echo "diff alice.txt alice.data1"
+ diff alice.txt alice.data1
+ html_msg $? 0 "Compare Decoded Signature and Original (SHA384)" "."
+
+ echo "$SCRIPTNAME: Signing Attached Message (SHA512) ------------------"
+ echo "cmsutil -S -N Alice -H SHA512 -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig"
+ cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig
+ html_msg $? 0 "Create Signature Alice (SHA512)" "."
+
+ echo "cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1"
+ cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1
+ html_msg $? 0 "Decode Alice's Signature (SHA512)" "."
+
+ echo "diff alice.txt alice.data1"
+ diff alice.txt alice.data1
+ html_msg $? 0 "Compare Decoded Signature and Original (SHA512)" "."
+
+ echo "$SCRIPTNAME: Enveloped Data Tests ------------------------------"
+ echo "cmsutil -E -r bob@bogus.com -i alice.txt -d ${P_R_ALICEDIR} -p nss \\"
+ echo " -o alice.env"
+ cmsutil -E -r bob@bogus.com -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.env
+ html_msg $? 0 "Create Enveloped Data Alice" "."
+
+ echo "cmsutil -D -i alice.env -d ${P_R_BOBDIR} -p nss -o alice.data1"
+ cmsutil -D -i alice.env -d ${P_R_BOBDIR} -p nss -o alice.data1
+ html_msg $? 0 "Decode Enveloped Data Alice" "."
+
+ echo "diff alice.txt alice.data1"
+ diff alice.txt alice.data1
+ html_msg $? 0 "Compare Decoded Enveloped Data and Original" "."
+
+ # multiple recip
+ echo "$SCRIPTNAME: Testing multiple recipients ------------------------------"
+ echo "cmsutil -E -i alicecc.txt -d ${P_R_ALICEDIR} -o alicecc.env \\"
+ echo " -r bob@bogus.com,dave@bogus.com"
+ cmsutil -E -i alice.txt -d ${P_R_ALICEDIR} -o alicecc.env \
+ -r bob@bogus.com,dave@bogus.com
+ ret=$?
+ html_msg $ret 0 "Create Multiple Recipients Enveloped Data Alice" "."
+ if [ $ret != 0 ] ; then
+ echo "certutil -L -d ${P_R_ALICEDIR}"
+ certutil -L -d ${P_R_ALICEDIR}
+ echo "certutil -L -d ${P_R_ALICEDIR} -n dave@bogus.com"
+ certutil -L -d ${P_R_ALICEDIR} -n dave@bogus.com
+ fi
+
+ echo "$SCRIPTNAME: Testing multiple email addrs ------------------------------"
+ echo "cmsutil -E -i alicecc.txt -d ${P_R_ALICEDIR} -o aliceve.env \\"
+ echo " -r eve@bogus.net"
+ cmsutil -E -i alice.txt -d ${P_R_ALICEDIR} -o aliceve.env \
+ -r eve@bogus.net
+ ret=$?
+ html_msg $ret 0 "Encrypt to a Multiple Email cert" "."
+
+ echo "cmsutil -D -i alicecc.env -d ${P_R_BOBDIR} -p nss -o alice.data2"
+ cmsutil -D -i alicecc.env -d ${P_R_BOBDIR} -p nss -o alice.data2
+ html_msg $? 0 "Decode Multiple Recipients Enveloped Data Alice by Bob" "."
+
+ echo "cmsutil -D -i alicecc.env -d ${P_R_DAVEDIR} -p nss -o alice.data3"
+ cmsutil -D -i alicecc.env -d ${P_R_DAVEDIR} -p nss -o alice.data3
+ html_msg $? 0 "Decode Multiple Recipients Enveloped Data Alice by Dave" "."
+
+ echo "cmsutil -D -i aliceve.env -d ${P_R_EVEDIR} -p nss -o alice.data4"
+ cmsutil -D -i aliceve.env -d ${P_R_EVEDIR} -p nss -o alice.data4
+ html_msg $? 0 "Decrypt with a Multiple Email cert" "."
+
+ diff alice.txt alice.data2
+ html_msg $? 0 "Compare Decoded Mult. Recipients Enveloped Data Alice/Bob" "."
+
+ diff alice.txt alice.data3
+ html_msg $? 0 "Compare Decoded Mult. Recipients Enveloped Data Alice/Dave" "."
+
+ diff alice.txt alice.data4
+ html_msg $? 0 "Compare Decoded with Multiple Email cert" "."
+
+ echo "$SCRIPTNAME: Sending CERTS-ONLY Message ------------------------------"
+ echo "cmsutil -O -r \"Alice,bob@bogus.com,dave@bogus.com\" \\"
+ echo " -d ${P_R_ALICEDIR} > co.der"
+ cmsutil -O -r "Alice,bob@bogus.com,dave@bogus.com" -d ${P_R_ALICEDIR} > co.der
+ html_msg $? 0 "Create Certs-Only Alice" "."
+
+ echo "cmsutil -D -i co.der -d ${P_R_BOBDIR}"
+ cmsutil -D -i co.der -d ${P_R_BOBDIR}
+ html_msg $? 0 "Verify Certs-Only by CA" "."
+
+ echo "$SCRIPTNAME: Encrypted-Data Message ---------------------------------"
+ echo "cmsutil -C -i alice.txt -e alicehello.env -d ${P_R_ALICEDIR} \\"
+ echo " -r \"bob@bogus.com\" > alice.enc"
+ cmsutil -C -i alice.txt -e alicehello.env -d ${P_R_ALICEDIR} \
+ -r "bob@bogus.com" > alice.enc
+ html_msg $? 0 "Create Encrypted-Data" "."
+
+ echo "cmsutil -D -i alice.enc -d ${P_R_BOBDIR} -e alicehello.env -p nss \\"
+ echo " -o alice.data2"
+ cmsutil -D -i alice.enc -d ${P_R_BOBDIR} -e alicehello.env -p nss -o alice.data2
+ html_msg $? 0 "Decode Encrypted-Data" "."
+
+ diff alice.txt alice.data2
+ html_msg $? 0 "Compare Decoded and Original Data" "."
+}
+
+############################## smime_cleanup ###########################
+# local shell function to finish this script (no exit since it might be
+# sourced)
+########################################################################
+smime_cleanup()
+{
+ html "</TABLE><BR>"
+ cd ${QADIR}
+ . common/cleanup.sh
+}
+
+################## main #################################################
+
+smime_init
+smime_main
+smime_cleanup
+
diff --git a/security/nss/tests/smime/smime.sh b/security/nss/tests/smime/smime.sh
index a66c81dd0..f8e2e6c8c 100755
--- a/security/nss/tests/smime/smime.sh
+++ b/security/nss/tests/smime/smime.sh
@@ -84,6 +84,35 @@ smime_init()
cp ${QADIR}/smime/alice.txt ${SMIMEDIR}
}
+smime_sign()
+{
+ HASH_CMD=-H ${HASH}
+ SIG=sig.${HASH}
+
+ echo "$SCRIPTNAME: Signing Detached Message {$HASH} ------------------"
+ echo "cmsutil -S -T -N Alice ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.d${SIG}"
+ cmsutil -S -T -N Alice ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.d${SIG}
+ html_msg $? 0 "Create Detached Signature Alice (${HASH})" "."
+
+ echo "cmsutil -D -i alice.d${SIG} -c alice.txt -d ${P_R_BOBDIR} "
+ cmsutil -D -i alice.d${SIG} -c alice.txt -d ${P_R_BOBDIR}
+ html_msg $? 0 "Verifying Alice's Detached Signature (${HASH})" "."
+
+ echo "$SCRIPTNAME: Signing Attached Message (${HASH}) ------------------"
+ echo "cmsutil -S -N Alice ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.${SIG}"
+ cmsutil -S -N Alice ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.${SIG}
+ html_msg $? 0 "Create Attached Signature Alice (${HASH})" "."
+
+ echo "cmsutil -D -i alice.${SIG} -d ${P_R_BOBDIR} -o alice.data.${HASH}"
+ cmsutil -D -i alice.${SIG} -d ${P_R_BOBDIR} -o alice.data.${HASH}
+ html_msg $? 0 "Decode Alice's Attached Signature (${HASH})" "."
+
+ echo "diff alice.txt alice.data.${HASH}"
+ diff alice.txt alice.data.${HASH}
+ html_msg $? 0 "Compare Attached Signed Data and Original (${HASH})" "."
+}
+
+
############################## smime_main ##############################
# local shell function to test basic signed and enveloped messages
@@ -92,57 +121,14 @@ smime_init()
smime_main()
{
- echo "$SCRIPTNAME: Signing Attached Message (SHA1) ------------------"
- echo "cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig"
- cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig
- html_msg $? 0 "Create Signature Alice (SHA1)" "."
-
- echo "cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1"
- cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1
- html_msg $? 0 "Decode Alice's Signature (SHA1)" "."
-
- echo "diff alice.txt alice.data1"
- diff alice.txt alice.data1
- html_msg $? 0 "Compare Decoded Signature and Original (SHA1)" "."
-
- echo "$SCRIPTNAME: Signing Attached Message (SHA256) ------------------"
- echo "cmsutil -S -N Alice -H SHA256 -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig"
- cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig
- html_msg $? 0 "Create Signature Alice (SHA256)" "."
-
- echo "cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1"
- cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1
- html_msg $? 0 "Decode Alice's Signature (SHA256)" "."
-
- echo "diff alice.txt alice.data1"
- diff alice.txt alice.data1
- html_msg $? 0 "Compare Decoded Signature and Original (SHA256)" "."
-
- echo "$SCRIPTNAME: Signing Attached Message (SHA384) ------------------"
- echo "cmsutil -S -N Alice -H SHA384 -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig"
- cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig
- html_msg $? 0 "Create Signature Alice (SHA384)" "."
-
- echo "cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1"
- cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1
- html_msg $? 0 "Decode Alice's Signature (SHA384)" "."
-
- echo "diff alice.txt alice.data1"
- diff alice.txt alice.data1
- html_msg $? 0 "Compare Decoded Signature and Original (SHA384)" "."
-
- echo "$SCRIPTNAME: Signing Attached Message (SHA512) ------------------"
- echo "cmsutil -S -N Alice -H SHA512 -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig"
- cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig
- html_msg $? 0 "Create Signature Alice (SHA512)" "."
-
- echo "cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1"
- cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1
- html_msg $? 0 "Decode Alice's Signature (SHA512)" "."
-
- echo "diff alice.txt alice.data1"
- diff alice.txt alice.data1
- html_msg $? 0 "Compare Decoded Signature and Original (SHA512)" "."
+ HASH=SHA1
+ smime_sign
+ HASH=SHA256
+ smime_sign
+ HASH=SHA384
+ smime_sign
+ HASH=SHA512
+ smime_sign
echo "$SCRIPTNAME: Enveloped Data Tests ------------------------------"
echo "cmsutil -E -r bob@bogus.com -i alice.txt -d ${P_R_ALICEDIR} -p nss \\"
diff --git a/security/nss/tests/ssl/ssl.sh b/security/nss/tests/ssl/ssl.sh
index 9ee3632f2..1ad1ca843 100755
--- a/security/nss/tests/ssl/ssl.sh
+++ b/security/nss/tests/ssl/ssl.sh
@@ -136,15 +136,17 @@ is_selfserv_alive()
########################################################################
wait_for_selfserv()
{
- echo "tstclnt -p ${PORT} -h ${HOSTADDR} -q \\"
+ echo "tstclnt -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \\"
echo " -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}"
#echo "tstclnt -q started at `date`"
- tstclnt -p ${PORT} -h ${HOSTADDR} -q -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}
+ tstclnt -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \
+ -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}
if [ $? -ne 0 ]; then
html_failed "<TR><TD> Wait for Server "
- echo "RETRY: tstclnt -p ${PORT} -h ${HOSTADDR} -q \\"
+ echo "RETRY: tstclnt -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \\"
echo " -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}"
- tstclnt -p ${PORT} -h ${HOSTADDR} -q -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}
+ tstclnt -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \
+ -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}
elif [ sparam = "-c ABCDEFabcdefghijklmnvy" ] ; then # "$1" = "cov" ] ; then
html_passed "<TR><TD> Wait for Server"
fi
@@ -187,15 +189,15 @@ start_selfserv()
echo "$SCRIPTNAME: $testname ----"
fi
sparam=`echo $sparam | sed -e 's;_; ;g'`
- echo "selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} \\"
+ echo "selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} ${SERVER_OPTIONS} \\"
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} \
+ selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} ${SERVER_OPTIONS} \
-w nss ${sparam} -i ${R_SERVERPID} $verbose \
> ${SERVEROUTFILE} 2>&1 &
else
- selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} \
+ selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} ${SERVER_OPTIONS} \
-w nss ${sparam} -i ${R_SERVERPID} $verbose &
fi
# The PID $! returned by the MKS or Cygwin shell is not the PID of
@@ -219,7 +221,7 @@ start_selfserv()
########################################################################
ssl_cov()
{
- html_head "SSL Cipher Coverage $NORM_EXT"
+ html_head "SSL Cipher Coverage $NORM_EXT - $BYPASS_STRING"
testname=""
sparam="-c ABCDEFabcdefghijklmnvyz"
@@ -231,7 +233,7 @@ ssl_cov()
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
+ if [ "$p" = "SSL2" -a "$NORM_EXT" = "Extended Test" ] ; then
echo "$SCRIPTNAME: skipping $testname for $NORM_EXT"
elif [ "$tls" != "#" ] ; then
echo "$SCRIPTNAME: running $testname ----------------------------"
@@ -241,11 +243,11 @@ ssl_cov()
fi
is_selfserv_alive
- echo "tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} ${TLS_FLAG} \\"
+ echo "tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} ${TLS_FLAG} ${CLIENT_OPTIONS} \\"
echo " -f -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}"
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
- tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} ${TLS_FLAG} -f \
+ tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} ${TLS_FLAG} ${CLIENT_OPTIONS} -f \
-d ${P_R_CLIENTDIR} < ${REQUEST_FILE} \
>${TMP}/$HOST.tmp.$$ 2>&1
ret=$?
@@ -264,7 +266,7 @@ ssl_cov()
########################################################################
ssl_auth()
{
- html_head "SSL Client Authentication $NORM_EXT"
+ html_head "SSL Client Authentication $NORM_EXT - $BYPASS_STRING"
while read value sparam cparam testname
do
@@ -272,10 +274,10 @@ ssl_auth()
cparam=`echo $cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" `
start_selfserv
- echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} \\"
+ echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} ${CLIENT_OPTIONS} \\"
echo " ${cparam} < ${REQUEST_FILE}"
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
- tstclnt -p ${PORT} -h ${HOSTADDR} -f ${cparam} \
+ tstclnt -p ${PORT} -h ${HOSTADDR} -f ${cparam} ${CLIENT_OPTIONS} \
-d ${P_R_CLIENTDIR} < ${REQUEST_FILE} \
>${TMP}/$HOST.tmp.$$ 2>&1
ret=$?
@@ -297,12 +299,12 @@ ssl_auth()
########################################################################
ssl_stress()
{
- html_head "SSL Stress Test $NORM_EXT"
+ html_head "SSL Stress Test $NORM_EXT - $BYPASS_STRING"
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
+ 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'`
@@ -312,10 +314,10 @@ ssl_stress()
ps -ef | grep selfserv
fi
- echo "strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} -w nss $cparam \\"
+ echo "strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} ${CLIENT_OPTIONS} -w nss $cparam \\"
echo " $verbose ${HOSTADDR}"
echo "strsclnt started at `date`"
- strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} -w nss $cparam \
+ strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} ${CLIENT_OPTIONS} -w nss $cparam \
$verbose ${HOSTADDR}
ret=$?
echo "strsclnt completed at `date`"
@@ -610,16 +612,16 @@ ssl_cleanup()
. 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_run ### #############################
+# local shell function to run both standard and extended ssl tests
+########################################################################
+ssl_run()
+{
ssl_init
+
ssl_cov
ssl_auth
- ssl_crl_ssl
- ssl_crl_cache
ssl_stress
SERVERDIR=$EXT_SERVERDIR
@@ -629,10 +631,53 @@ if [ -z "$DO_REM_ST" -a -z "$DO_DIST_ST" ] ; then
P_R_SERVERDIR=$P_R_EXT_SERVERDIR
P_R_CLIENTDIR=$P_R_EXT_CLIENTDIR
USER_NICKNAME=ExtendedSSLUser
- NORM_EXT="Extended test"
+ NORM_EXT="Extended Test"
cd ${CLIENTDIR}
ssl_cov
ssl_auth
ssl_stress
+
+ # the next round off ssl tests will only run if these vars are reset
+ SERVERDIR=$ORIG_SERVERDIR
+ CLIENTDIR=$ORIG_CLIENTDIR
+ R_SERVERDIR=$ORIG_R_SERVERDIR
+ R_CLIENTDIR=$ORIG_R_CLIENTDIR
+ P_R_SERVERDIR=$ORIG_P_R_SERVERDIR
+ P_R_CLIENTDIR=$ORIG_P_R_CLIENTDIR
+ USER_NICKNAME=TestUser
+ NORM_EXT=
+ cd ${QADIR}/ssl
ssl_cleanup
+}
+
+################## 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
+
+ # save the directories as setup by init.sh
+ ORIG_SERVERDIR=$SERVERDIR
+ ORIG_CLIENTDIR=$CLIENTDIR
+ ORIG_R_SERVERDIR=$R_SERVERDIR
+ ORIG_R_CLIENTDIR=$R_CLIENTDIR
+ ORIG_P_R_SERVERDIR=$P_R_SERVERDIR
+ ORIG_P_R_CLIENTDIR=$P_R_CLIENTDIR
+
+ ssl_crl_ssl
+ ssl_crl_cache
+ ssl_cleanup
+
+ # Test all combinations of server bypass and client bypass
+ CLIENT_OPTIONS="-B -s"
+ SERVER_OPTIONS=""
+ BYPASS_STRING="Client Bypass"
+ ssl_run
+ SERVER_OPTIONS="-B -s"
+ CLIENT_OPTIONS=""
+ BYPASS_STRING="Server Bypass"
+ ssl_run
+
fi
diff --git a/security/nss/tests/tools/noectools.sh b/security/nss/tests/tools/noectools.sh
deleted file mode 100644
index 3a2c8dbda..000000000
--- a/security/nss/tests/tools/noectools.sh
+++ /dev/null
@@ -1,193 +0,0 @@
-#! /bin/sh
-#
-# ***** BEGIN LICENSE BLOCK *****
-# 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 Netscape security libraries.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1994-2000
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# 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.
-#
-# ***** END LICENSE BLOCK *****
-
-########################################################################
-#
-# mozilla/security/nss/tests/tools/noectools.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
-
-