Compare commits

..

1 Commits

Author SHA1 Message Date
cvs2svn
a372f9bf25 This commit was manufactured by cvs2svn to create tag 'STATE_after_zlib'. 2002-12-08 09:31:42 +00:00
321 changed files with 32037 additions and 7695 deletions

368
CHANGES
View File

@@ -2,36 +2,356 @@
OpenSSL CHANGES
_______________
Changes between 0.9.6h and 0.9.7 [31 Dec 2002]
Changes between 0.9.7 and 0.9.8 [xx XXX 2002]
*) Fix session ID handling in SSLv2 client code: the SERVER FINISHED
code (06) was taken as the first octet of the session ID and the last
octet was ignored consequently. As a result SSLv2 client side session
caching could not have worked due to the session ID mismatch between
client and server.
Behaviour observed by Crispin Flowerday <crispin@flowerday.cx> as
PR #377.
[Lutz Jaenicke]
*) Change the "progress" mechanism used in key-generation and
primality testing to functions that take a new BN_GENCB pointer in
place of callback/argument pairs. The new API functions have "_ex"
postfixes and the older functions are reimplemented as wrappers for
the new ones. The OPENSSL_NO_DEPRECATED symbol can be used to hide
declarations of the old functions to help (graceful) attempts to
migrate to the new functions. Also, the new key-generation API
functions operate on a caller-supplied key-structure and return
success/failure rather than returning a key or NULL - this is to
help make "keygen" another member function of RSA_METHOD etc.
[Geoff Thorpe]
*) Change the declaration of needed Kerberos libraries to use EX_LIBS
instead of the special (and badly supported) LIBKRB5. LIBKRB5 is
removed entirely.
*) Change the ZLIB compression method to be stateful, and make it
available to TLS with the number defined in
draft-ietf-tls-compression-04.txt.
[Richard Levitte]
*) The hw_ncipher.c engine requires dynamic locks. Unfortunately, it
seems that in spite of existing for more than a year, many application
author have done nothing to provide the necessary callbacks, which
means that this particular engine will not work properly anywhere.
This is a very unfortunate situation which forces us, in the name
of usability, to give the hw_ncipher.c a static lock, which is part
of libcrypto.
NOTE: This is for the 0.9.7 series ONLY. This hack will never
appear in 0.9.8 or later. We EXPECT application authors to have
dealt properly with this when 0.9.8 is released (unless we actually
make such changes in the libcrypto locking code that changes will
have to be made anyway).
*) Add the ASN.1 structures and functions for CertificatePair, which
is defined as follows (according to X.509_4thEditionDraftV6.pdf):
CertificatePair ::= SEQUENCE {
forward [0] Certificate OPTIONAL,
reverse [1] Certificate OPTIONAL,
-- at least one of the pair shall be present -- }
Also implement the PEM functions to read and write certificate
pairs, and defined the PEM tag as "CERTIFICATE PAIR".
This needed to be defined, mostly for the sake of the LDAP
attribute crossCertificatePair, but may prove useful elsewhere as
well.
[Richard Levitte]
*) Make it possible to inhibit symlinking of shared libraries in
Makefile.shared, for Cygwin's sake.
[Richard Levitte]
*) Extend the BIGNUM API by creating new macros that behave like
functions
void BN_set_sign(BIGNUM *a, int neg);
int BN_get_sign(const BIGNUM *a);
and avoid the need to access 'a->neg' directly in applications.
[Nils Larsch <nla@trustcenter.de>]
*) Implement fast modular reduction for pseudo-Mersenne primes
used in NIST curves (crypto/bn/bn_nist.c, crypto/ec/ecp_nist.c).
EC_GROUP_new_curve_GFp() will now automatically use this
if applicable.
[Nils Larsch <nla@trustcenter.de>]
*) Add new lock type (CRYPTO_LOCK_BN).
[Bodo Moeller]
*) Change the ENGINE framework to automatically load engines
dynamically from specific directories unless they could be
found to already be built in or loaded. Move all the
current engines except for the cryptodev one to a new
directory engines/.
The engines in engines/ are built as shared libraries if
the "shared" options was given to ./Configure or ./config.
Otherwise, they are inserted in libcrypto.a.
/usr/local/ssl/engines is the default directory for dynamic
engines, but that can be overriden at configure time through
the usual use of --prefix and/or --openssldir, and at run
time with the environment variable OPENSSL_ENGINES.
[Geoff Thorpe and Richard Levitte]
*) Add Makefile.shared, a helper makefile to build shared
libraries. Addapt Makefile.org.
[Richard Levitte]
*) Add version info to Win32 DLLs.
[Peter 'Luna' Runestig" <peter@runestig.com>]
*) Add new 'medium level' PKCS#12 API. Certificates and keys
can be added using this API to created arbitrary PKCS#12
files while avoiding the low level API.
New options to PKCS12_create(), key or cert can be NULL and
will then be omitted from the output file. The encryption
algorithm NIDs can be set to -1 for no encryption, the mac
iteration count can be set to 0 to omit the mac.
Enhance pkcs12 utility by making the -nokeys and -nocerts
options work when creating a PKCS#12 file. New option -nomac
to omit the mac, NONE can be set for an encryption algorithm.
New code is modified to use the enhanced PKCS12_create()
instead of the low level API.
[Steve Henson]
*) Extend ASN1 encoder to support indefinite length constructed
encoding. This can output sequences tags and octet strings in
this form. Modify pk7_asn1.c to support indefinite length
encoding. This is experimental and needs additional code to
be useful, such as an ASN1 bio and some enhanced streaming
PKCS#7 code.
Extend template encode functionality so that tagging is passed
down to the template encoder.
[Steve Henson]
*) Let 'openssl req' fail if an argument to '-newkey' is not
recognized instead of using RSA as a default.
[Bodo Moeller]
*) Add support for ECC-based ciphersuites from draft-ietf-tls-ecc-01.txt.
As these are not official, they are not included in "ALL";
the "ECCdraft" ciphersuite group alias can be used to select them.
[Vipul Gupta and Sumit Gupta (Sun Microsystems Laboratories)]
*) Add ECDH engine support.
[Nils Gura and Douglas Stebila (Sun Microsystems Laboratories)]
*) Add ECDH in new directory crypto/ecdh/.
TODO: more general interface (return x coordinate, not its hash)
TODO: bug: pad x with leading zeros if necessary
[Douglas Stebila (Sun Microsystems Laboratories)]
*) Let BN_rand_range() abort with an error after 100 iterations
without success (which indicates a broken PRNG).
[Bodo Moeller]
*) Change BN_mod_sqrt() so that it verifies that the input value
is really the square of the return value. (Previously,
BN_mod_sqrt would show GIGO behaviour.)
[Bodo Moeller]
*) Add named elliptic curves over binary fields from X9.62, SECG,
and WAP/WTLS; add OIDs that were still missing.
[Sheueling Chang Shantz and Douglas Stebila
(Sun Microsystems Laboratories)]
*) Extend the EC library for elliptic curves over binary fields
(new files ec2_smpl.c, ec2_smpt.c, ec2_mult.c in crypto/ec/).
New EC_METHOD:
EC_GF2m_simple_method
New API functions:
EC_GROUP_new_curve_GF2m
EC_GROUP_set_curve_GF2m
EC_GROUP_get_curve_GF2m
EC_POINT_set_affine_coordinates_GF2m
EC_POINT_get_affine_coordinates_GF2m
EC_POINT_set_compressed_coordinates_GF2m
Point compression for binary fields is disabled by default for
patent reasons (compile with OPENSSL_EC_BIN_PT_COMP defined to
enable it).
As binary polynomials are represented as BIGNUMs, various members
of the EC_GROUP and EC_POINT data structures can be shared
between the implementations for prime fields and binary fields;
the above ..._GF2m functions (except for EX_GROUP_new_curve_GF2m)
are essentially identical to their ..._GFp counterparts.
(For simplicity, the '..._GFp' prefix has been dropped from
various internal method names.)
An internal 'field_div' method (similar to 'field_mul' and
'field_sqr') has been added; this is used only for binary fields.
[Sheueling Chang Shantz and Douglas Stebila
(Sun Microsystems Laboratories)]
*) Optionally dispatch EC_POINT_mul(), EC_POINT_precompute_mult()
through methods ('mul', 'precompute_mult').
The generic implementations (now internally called 'ec_wNAF_mul'
and 'ec_wNAF_precomputed_mult') remain the default if these
methods are undefined.
[Sheueling Chang Shantz and Douglas Stebila
(Sun Microsystems Laboratories)]
*) New function EC_GROUP_get_degree, which is defined through
EC_METHOD. For curves over prime fields, this returns the bit
length of the modulus.
[Sheueling Chang Shantz and Douglas Stebila
(Sun Microsystems Laboratories)]
*) New functions EC_GROUP_dup, EC_POINT_dup.
(These simply call ..._new and ..._copy).
[Sheueling Chang Shantz and Douglas Stebila
(Sun Microsystems Laboratories)]
*) Add binary polynomial arithmetic software in crypto/bn/bn_gf2m.c.
Polynomials are represented as BIGNUMs (where the sign bit is not
used) in the following functions [macros]:
BN_GF2m_add
BN_GF2m_sub [= BN_GF2m_add]
BN_GF2m_mod [wrapper for BN_GF2m_mod_arr]
BN_GF2m_mod_mul [wrapper for BN_GF2m_mod_mul_arr]
BN_GF2m_mod_sqr [wrapper for BN_GF2m_mod_sqr_arr]
BN_GF2m_mod_inv
BN_GF2m_mod_exp [wrapper for BN_GF2m_mod_exp_arr]
BN_GF2m_mod_sqrt [wrapper for BN_GF2m_mod_sqrt_arr]
BN_GF2m_mod_solve_quad [wrapper for BN_GF2m_mod_solve_quad_arr]
BN_GF2m_cmp [= BN_ucmp]
(Note that only the 'mod' functions are actually for fields GF(2^m).
BN_GF2m_add() is misnomer, but this is for the sake of consistency.)
For some functions, an the irreducible polynomial defining a
field can be given as an 'unsigned int[]' with strictly
decreasing elements giving the indices of those bits that are set;
i.e., p[] represents the polynomial
f(t) = t^p[0] + t^p[1] + ... + t^p[k]
where
p[0] > p[1] > ... > p[k] = 0.
This applies to the following functions:
BN_GF2m_mod_arr
BN_GF2m_mod_mul_arr
BN_GF2m_mod_sqr_arr
BN_GF2m_mod_inv_arr [wrapper for BN_GF2m_mod_inv]
BN_GF2m_mod_div_arr [wrapper for BN_GF2m_mod_div]
BN_GF2m_mod_exp_arr
BN_GF2m_mod_sqrt_arr
BN_GF2m_mod_solve_quad_arr
BN_GF2m_poly2arr
BN_GF2m_arr2poly
Conversion can be performed by the following functions:
BN_GF2m_poly2arr
BN_GF2m_arr2poly
bntest.c has additional tests for binary polynomial arithmetic.
Two implementations for BN_GF2m_mod_div() are available.
The default algorithm simply uses BN_GF2m_mod_inv() and
BN_GF2m_mod_mul(). The alternative algorithm is compiled in only
if OPENSSL_SUN_GF2M_DIV is defined (patent pending; read the
copyright notice in crypto/bn/bn_gf2m.c before enabling it).
[Sheueling Chang Shantz and Douglas Stebila
(Sun Microsystems Laboratories)]
*) Add new error code 'ERR_R_DISABLED' that can be used when some
functionality is disabled at compile-time.
[Douglas Stebila <douglas.stebila@sun.com>]
*) Change default behaviour of 'openssl asn1parse' so that more
information is visible when viewing, e.g., a certificate:
Modify asn1_parse2 (crypto/asn1/asn1_par.c) so that in non-'dump'
mode the content of non-printable OCTET STRINGs is output in a
style similar to INTEGERs, but with '[HEX DUMP]' prepended to
avoid the appearance of a printable string.
[Nils Larsch <nla@trustcenter.de>]
*) Add 'asn1_flag' and 'asn1_form' member to EC_GROUP with access
functions
EC_GROUP_set_asn1_flag()
EC_GROUP_get_asn1_flag()
EC_GROUP_set_point_conversion_form()
EC_GROUP_get_point_conversion_form()
These control ASN1 encoding details:
- Curves (i.e., groups) are encoded explicitly unless asn1_flag
has been set to OPENSSL_EC_NAMED_CURVE.
- Points are encoded in uncompressed form by default; options for
asn1_for are as for point2oct, namely
POINT_CONVERSION_COMPRESSED
POINT_CONVERSION_UNCOMPRESSED
POINT_CONVERSION_HYBRID
Also add 'seed' and 'seed_len' members to EC_GROUP with access
functions
EC_GROUP_set_seed()
EC_GROUP_get0_seed()
EC_GROUP_get_seed_len()
This is used only for ASN1 purposes (so far).
[Nils Larsch <nla@trustcenter.de>]
*) Add 'field_type' member to EC_METHOD, which holds the NID
of the appropriate field type OID. The new function
EC_METHOD_get_field_type() returns this value.
[Nils Larsch <nla@trustcenter.de>]
*) Add functions
EC_POINT_point2bn()
EC_POINT_bn2point()
EC_POINT_point2hex()
EC_POINT_hex2point()
providing useful interfaces to EC_POINT_point2oct() and
EC_POINT_oct2point().
[Nils Larsch <nla@trustcenter.de>]
*) Change internals of the EC library so that the functions
EC_GROUP_set_generator()
EC_GROUP_get_generator()
EC_GROUP_get_order()
EC_GROUP_get_cofactor()
are implemented directly in crypto/ec/ec_lib.c and not dispatched
to methods, which would lead to unnecessary code duplication when
adding different types of curves.
[Nils Larsch <nla@trustcenter.de> with input by Bodo Moeller]
*) Implement compute_wNAF (crypto/ec/ec_mult.c) without BIGNUM
arithmetic, and such that modified wNAFs are generated
(which avoid length expansion in many cases).
[Bodo Moeller]
*) Add a function EC_GROUP_check_discriminant() (defined via
EC_METHOD) that verifies that the curve discriminant is non-zero.
Add a function EC_GROUP_check() that makes some sanity tests
on a EC_GROUP, its generator and order. This includes
EC_GROUP_check_discriminant().
[Nils Larsch <nla@trustcenter.de>]
*) Add ECDSA in new directory crypto/ecdsa/.
Add applications 'openssl ecparam' and 'openssl ecdsa'
(these are based on 'openssl dsaparam' and 'openssl dsa').
ECDSA support is also included in various other files across the
library. Most notably,
- 'openssl req' now has a '-newkey ecdsa:file' option;
- EVP_PKCS82PKEY (crypto/evp/evp_pkey.c) now can handle ECDSA;
- X509_PUBKEY_get (crypto/asn1/x_pubkey.c) and
d2i_PublicKey (crypto/asn1/d2i_pu.c) have been modified to make
them suitable for ECDSA where domain parameters must be
extracted before the specific public key;
- ECDSA engine support has been added.
[Nils Larsch <nla@trustcenter.de>]
*) Include some named elliptic curves, and add OIDs from X9.62,
SECG, and WAP/WTLS. Each curve can be obtained from the new
function
EC_GROUP_new_by_nid(),
and the list of available named curves can be obtained with
EC_get_builtin_curves().
Also add a 'curve_name' member to EC_GROUP objects, which can be
accessed via
EC_GROUP_set_nid()
EC_GROUP_get_nid()
[Nils Larsch <nla@trustcenter.de, Bodo Moeller]
Changes between 0.9.6h and 0.9.7 [XX xxx 2002]
*) In asn1_d2i_read_bio() repeatedly call BIO_read() until all content
octets have been read, EOF or an error occurs. Without this change
some truncated ASN1 structures will not produce an error.

148
Configure
View File

@@ -161,25 +161,25 @@ my %table=(
# surrounds it with #APP #NO_APP comment pair which (at least Solaris
# 7_x86) /usr/ccs/bin/as fails to assemble with "Illegal mnemonic"
# error message.
"solaris-x86-gcc","gcc:-O3 -fomit-frame-pointer -m486 -Wall -DL_ENDIAN -DOPENSSL_NO_INLINE_ASM::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_sol_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"solaris-x86-gcc","gcc:-O3 -fomit-frame-pointer -m486 -Wall -DL_ENDIAN -DOPENSSL_NO_INLINE_ASM::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_sol_asm}:dlfcn:solaris-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
#### Solaris x86 with Sun C setups
"solaris-x86-cc","cc:-fast -O -Xa::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_UNROLL BF_PTR::::::::::dlfcn:solaris-shared:-KPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
#### SPARC Solaris with GNU C setups
"solaris-sparcv7-gcc","gcc:-O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR::::::::::dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"solaris-sparcv8-gcc","gcc:-mv8 -O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8.o:::::::::dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"solaris-sparcv7-gcc","gcc:-O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR::::::::::dlfcn:solaris-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"solaris-sparcv8-gcc","gcc:-mv8 -O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8.o:::::::::dlfcn:solaris-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
# -m32 should be safe to add as long as driver recognizes -mcpu=ultrasparc
"solaris-sparcv9-gcc","gcc:-m32 -mcpu=ultrasparc -O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8plus.o:::asm/md5-sparcv8plus.o::::::dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"solaris64-sparcv9-gcc31","gcc:-mcpu=ultrasparc -m64 -O3 -fomit-frame-pointer -Wall -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR::::asm/md5-sparcv9.o::::::dlfcn:solaris-shared:-fPIC:-m64 -shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"solaris-sparcv9-gcc","gcc:-m32 -mcpu=ultrasparc -O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8plus.o:::asm/md5-sparcv8plus.o::::::dlfcn:solaris-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"solaris64-sparcv9-gcc31","gcc:-mcpu=ultrasparc -m64 -O3 -fomit-frame-pointer -Wall -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR::::asm/md5-sparcv9.o::::::dlfcn:solaris-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
# gcc pre-2.8 doesn't understand -mcpu=ultrasparc, so fall down to -mv8
# but keep the assembler modules.
"solaris-sparcv9-gcc27","gcc:-mv8 -O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8plus-gcc27.o:::asm/md5-sparcv8plus-gcc27.o::::::dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"solaris64-sparcv9-gcc","gcc:-m64 -mcpu=ultrasparc -O3 -Wall -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR::::asm/md5-sparcv9.o::::::dlfcn:solaris-shared:-fPIC:-m64 -shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"solaris-sparcv9-gcc27","gcc:-mv8 -O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8plus-gcc27.o:::asm/md5-sparcv8plus-gcc27.o::::::dlfcn:solaris-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"solaris64-sparcv9-gcc","gcc:-m64 -mcpu=ultrasparc -O3 -Wall -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR::::asm/md5-sparcv9.o::::::dlfcn:solaris-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
####
"debug-solaris-sparcv8-gcc","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -O -g -mv8 -Wall -DB_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8.o:::::::::dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-solaris-sparcv9-gcc","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -O -g -mcpu=ultrasparc -Wall -DB_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8plus.o:::::::::dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-solaris-sparcv8-gcc","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -O -g -mv8 -Wall -DB_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8.o:::::::::dlfcn:solaris-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"debug-solaris-sparcv9-gcc","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -O -g -mcpu=ultrasparc -Wall -DB_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8plus.o:::::::::dlfcn:solaris-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
#### SPARC Solaris with Sun C setups
# DO NOT use /xO[34] on sparc with SC3.0. It is broken, and will not pass the tests
@@ -391,7 +391,7 @@ my %table=(
"linux-s390", "gcc:-DB_ENDIAN -DTERMIO -DNO_ASM -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"linux-s390x", "gcc:-DB_ENDIAN -DTERMIO -DNO_ASM -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"linux-ia64", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK RC4_CHAR:asm/ia64.o:::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"linux-x86_64", "gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK RC4_CHAR BF_PTR2 DES_INT DES_UNROLL:asm/x86_64-gcc.o:::::::::dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"linux-x86_64", "gcc:-DL_ENDIAN -DNO_ASM ::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"NetBSD-sparc", "gcc:-DTERMIOS -O3 -fomit-frame-pointer -mv8 -Wall -DB_ENDIAN::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX DES_UNROLL::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"NetBSD-m68", "gcc:-DTERMIOS -O3 -fomit-frame-pointer -Wall -DB_ENDIAN::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX DES_UNROLL::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"NetBSD-x86", "gcc:-DTERMIOS -O3 -fomit-frame-pointer -m486 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
@@ -480,7 +480,7 @@ my %table=(
# SCO cc.
"sco5-cc", "cc:-belf::(unknown)::-lsocket -lresolv -lnsl:${x86_gcc_des} ${x86_gcc_opts}::::::::::dlfcn:svr3-shared:-Kpic", # des options?
"sco5-cc-pentium", "cc:-Kpentium::(unknown)::-lsocket:${x86_gcc_des} ${x86_gcc_opts}:::", # des options?
"sco5-gcc", "gcc:-O3 -fomit-frame-pointer::(unknown)::-lsocket -lresolv -lnsl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}::::::::::dlfcn:svr3-shared:-fPIC",
"sco5-gcc", "gcc:-O3 -fomit-frame-pointer::(unknown)::-lsocket -lresolv -lnsl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:svr3-shared:-fPIC", # the SCO assembler doesn't seem to like our assembler files ...
# Sinix/ReliantUNIX RM400
# NOTE: The CDS++ Compiler up to V2.0Bsomething has the IRIX_CC_BUG optimizer problem. Better use -g */
@@ -527,7 +527,7 @@ my %table=(
"DJGPP", "gcc:-I/dev/env/WATT_ROOT/inc -DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O2 -Wall:::MSDOS:-L/dev/env/WATT_ROOT/lib -lwatt:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}::::::::::",
# Ultrix from Bernhard Simon <simon@zid.tuwien.ac.at>
"ultrix-cc","cc:-std1 -O -Olimit 2500 -DL_ENDIAN::(unknown):::::::",
"ultrix-cc","cc:-std1 -O -Olimit 1000 -DL_ENDIAN::(unknown):::::::",
"ultrix-gcc","gcc:-O3 -DL_ENDIAN::(unknown):::::::",
# K&R C is no longer supported; you need gcc on old Ultrix installations
##"ultrix","cc:-O2 -DNOPROTO -DNOCONST -DL_ENDIAN::(unknown):::::::",
@@ -759,6 +759,27 @@ PROCESS_ARGS:
$depflags .= "-DOPENSSL_NO_MDC2 ";
$openssl_algorithm_defines .= "#define OPENSSL_NO_MDC2\n";
}
if ($algo eq "EC")
{
push @skip, "ecdsa";
push @skip, "ecdh";
$options .= " no-ecdsa";
$options .= " no-ecdh";
$flags .= "-DOPENSSL_NO_ECDSA ";
$flags .= "-DOPENSSL_NO_ECDH ";
$depflags .= "-DOPENSSL_NO_ECDSA ";
$depflags .= "-DOPENSSL_NO_ECDH ";
$openssl_algorithm_defines .= "#define OPENSSL_NO_ECDSA\n";
$openssl_algorithm_defines .= "#define OPENSSL_NO_ECDH\n";
}
if ($algo eq "SHA" || $algo eq "SHA1")
{
push @skip, "ecdsa";
$options .= " no-ecdsa";
$flags .= "-DOPENSSL_NO_ECDSA ";
$depflags .= "-DOPENSSL_NO_ECDSA ";
$openssl_algorithm_defines .= "#define OPENSSL_NO_ECDSA\n";
}
if ($algo eq "MD5")
{
$no_md5 = 1;
@@ -1016,12 +1037,10 @@ else
}
}
$withargs{"krb5-lib"} .= " -lresolv"
if ("$lresolv" ne "");
if ("$lresolv");
$withargs{"krb5-include"} = "-I".$withargs{"krb5-dir"}."/include"
if $withargs{"krb5-include"} eq "" &&
$withargs{"krb5-dir"} ne "";
$libs.=$withargs{"krb5-lib"}." " if $withargs{"krb5-lib"} ne "";
}
# The DSO code currently always implements all functions so that no
@@ -1077,7 +1096,7 @@ else
# }
}
$lflags="$libs$lflags" if ($libs ne "");
$lflags="$libs$lflags"if ($libs ne "");
if ($no_asm)
{
@@ -1085,11 +1104,6 @@ if ($no_asm)
$sha1_obj=$md5_obj=$rmd160_obj="";
}
if (!$no_shared)
{
$cast_obj=""; # CAST assembler is not PIC
}
if ($threads)
{
$cflags=$thread_cflags;
@@ -1105,16 +1119,31 @@ if ($zlib)
# You will find shlib_mark1 and shlib_mark2 explained in Makefile.org
my $shared_mark = "";
if ($shared_target eq "")
{
$no_shared = 1;
}
if (!$no_shared)
if ($shared_target ne "")
{
if ($shared_cflag ne "")
{
$cflags = "$shared_cflag $cflags";
}
if (!$no_shared)
{
#$shared_mark = "\$(SHARED_LIBS)";
}
}
else
{
$no_shared = 1;
}
if ($no_shared)
{
$cflags="-DOPENSSL_NO_DYNAMIC_ENGINE $cflags";
$openssl_other_defines.="#define OPENSSL_NO_DYNAMIC_ENGINE\n";
}
else
{
$cflags="-DOPENSSL_NO_STATIC_ENGINE $cflags";
$openssl_other_defines.="#define OPENSSL_NO_STATIC_ENGINE\n";
}
if ($sys_id ne "")
@@ -1161,6 +1190,7 @@ if ($rmd160_obj =~ /\.o$/)
$cflags =~ s/([\\\"])/\\\1/g;
my $version = "unknown";
my $version_num = "unknown";
my $major = "unknown";
my $minor = "unknown";
my $shlib_version_number = "unknown";
@@ -1172,6 +1202,7 @@ open(IN,'<crypto/opensslv.h') || die "unable to read opensslv.h:$!\n";
while (<IN>)
{
$version=$1 if /OPENSSL.VERSION.TEXT.*OpenSSL (\S+) /;
$version_num=$1 if /OPENSSL.VERSION.NUMBER.*0x(\S+)/;
$shlib_version_number=$1 if /SHLIB_VERSION_NUMBER *"([^"]+)"/;
$shlib_version_history=$1 if /SHLIB_VERSION_HISTORY *"([^"]*)"/;
}
@@ -1240,6 +1271,7 @@ while (<IN>)
s/^ARFLAGS=.*/ARFLAGS= $arflags/;
s/^PERL=.*/PERL= $perl/;
s/^KRB5_INCLUDES=.*/KRB5_INCLUDES=$withargs{"krb5-include"}/;
s/^LIBKRB5=.*/LIBKRB5=$withargs{"krb5-lib"}/;
s/^SHLIB_TARGET=.*/SHLIB_TARGET=$shared_target/;
s/^SHLIB_MARK=.*/SHLIB_MARK=$shared_mark/;
s/^SHARED_LIBS=.*/SHARED_LIBS=\$(SHARED_CRYPTO) \$(SHARED_SSL)/ if (!$no_shared);
@@ -1287,6 +1319,8 @@ print "ARFLAGS =$arflags\n";
print "PERL =$perl\n";
print "KRB5_INCLUDES =",$withargs{"krb5-include"},"\n"
if $withargs{"krb5-include"} ne "";
print "LIBKRB5 =",$withargs{"krb5-lib"},"\n"
if $withargs{"krb5-lib"} ne "";
my $des_ptr=0;
my $des_risc1=0;
@@ -1501,6 +1535,68 @@ EOF
}
}
# create the ms/version32.rc file if needed
if ($IsWindows) {
my ($v1, $v2, $v3, $v4);
if ($version_num =~ /(^[0-9a-f]{1})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/i) {
$v1=hex $1;
$v2=hex $2;
$v3=hex $3;
$v4=hex $4;
}
open (OUT,">ms/version32.rc") || die "Can't open ms/version32.rc";
print OUT <<EOF;
#include <winver.h>
LANGUAGE 0x09,0x01
1 VERSIONINFO
FILEVERSION $v1,$v2,$v3,$v4
PRODUCTVERSION $v1,$v2,$v3,$v4
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x01L
#else
FILEFLAGS 0x00L
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
// Required:
VALUE "CompanyName", "The OpenSSL Project, http://www.openssl.org/\\0"
VALUE "FileDescription", "OpenSSL Shared Library\\0"
VALUE "FileVersion", "$version\\0"
#if defined(CRYPTO)
VALUE "InternalName", "libeay32\\0"
VALUE "OriginalFilename", "libeay32.dll\\0"
#elif defined(SSL)
VALUE "InternalName", "ssleay32\\0"
VALUE "OriginalFilename", "ssleay32.dll\\0"
#endif
VALUE "ProductName", "The OpenSSL Toolkit\\0"
VALUE "ProductVersion", "$version\\0"
// Optional:
//VALUE "Comments", "\\0"
VALUE "LegalCopyright", "Copyright <20> 1998-2002 The OpenSSL Project. Copyright <20> 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
//VALUE "LegalTrademarks", "\\0"
//VALUE "PrivateBuild", "\\0"
//VALUE "SpecialBuild", "\\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 0x4b0
END
END
EOF
close(OUT);
}
print <<EOF;
Configured for $target.

32
FAQ
View File

@@ -44,8 +44,6 @@ OpenSSL - Frequently Asked Questions
* What is special about OpenSSL on Redhat?
* Why does the OpenSSL compilation fail on MacOS X?
* Why does the OpenSSL test suite fail on MacOS X?
* Why does the OpenSSL test suite fail in BN_sqr test [on a 64-bit platform]?
* Why does OpenBSD-i386 build fail on des-586.s with "Unimplemented segment type"?
[PROG] Questions about programming with OpenSSL
@@ -68,7 +66,7 @@ OpenSSL - Frequently Asked Questions
* Which is the current version of OpenSSL?
The current version is available from <URL: http://www.openssl.org>.
OpenSSL 0.9.7 was released on December 31, 2002.
OpenSSL 0.9.6h was released on December 5, 2002.
In addition to the current stable release, you can also access daily
snapshots of the OpenSSL development version at <URL:
@@ -554,34 +552,6 @@ libraries you just built.
Look in the file PROBLEMS for a more detailed explanation and for possible
solutions.
* Why does the OpenSSL test suite fail in BN_sqr test [on a 64-bit platform]?
Failure in BN_sqr test is most likely caused by a failure to configure the
toolkit for current platform or lack of support for the platform in question.
Run './config -t' and './apps/openssl version -p'. Do these platform
identifiers match? If they don't, then you most likely failed to run
./config and you're hereby advised to do so before filing a bug report.
If ./config itself fails to run, then it's most likely problem with your
local environment and you should turn to your system administrator (or
similar). If identifiers match (and/or no alternative identifier is
suggested by ./config script), then the platform is unsupported. There might
or might not be a workaround. Most notably on SPARC64 platforms with GNU
C compiler you should be able to produce a working build by running
'./config -m32'. I understand that -m32 might not be what you want/need,
but the build should be operational. For further details turn to
<openssl-dev@openssl.org>.
* Why does OpenBSD-i386 build fail on des-586.s with "Unimplemented segment type"?
As of 0.9.7 assembler routines were overhauled for position independence
of the machine code, which is essential for shared library support. For
some reason OpenBSD is equipped with an out-of-date GNU assembler which
finds the new code offensive. To work around the problem, configure with
no-asm (and sacrifice a great deal of performance) or upgrade /usr/bin/as.
For your convenience a pre-compiled replacement binary is provided at
http://www.openssl.org/~appro/i386-openbsd3-as, which is compiled from
binutils-2.8 released in 1997.
[PROG] ========================================================================
* Is OpenSSL thread-safe?

View File

@@ -140,8 +140,8 @@
standard headers). If it is a problem with OpenSSL itself, please
report the problem to <openssl-bugs@openssl.org> (note that your
message will be recorded in the request tracker publicly readable
via http://www.openssl.org/support/rt2.html and will be forwarded to a
public mailing list). Include the output of "make report" in your message.
via http://www.openssl.org/rt2.html and will be forwarded to a public
mailing list). Include the output of "make report" in your message.
Please check out the request tracker. Maybe the bug was already
reported or has already been fixed.
@@ -162,7 +162,7 @@
in Makefile.ssl and run "make clean; make". Please send a bug
report to <openssl-bugs@openssl.org>, including the output of
"make report" in order to be added to the request tracker at
http://www.openssl.org/support/rt2.html.
http://www.openssl.org/rt2.html.
4. If everything tests ok, install OpenSSL with

View File

@@ -15,11 +15,6 @@ OPTIONS=
CONFIGURE_ARGS=
SHLIB_TARGET=
# HERE indicates where this Makefile lives. This can be used to indicate
# where sub-Makefiles are expected to be. Currently has very limited usage,
# and should probably not be bothered with at all.
HERE=.
# INSTALL_PREFIX is for package builders so that they can configure
# for, say, /usr/ and yet have everything installed to /tmp/somedir/usr/.
# Normally it is left empty.
@@ -159,19 +154,16 @@ RMD160_ASM_OBJ= asm/rm86-out.o
# KRB5 stuff
KRB5_INCLUDES=
LIBKRB5=
# When we're prepared to use shared libraries in the programs we link here
# we might set SHLIB_MARK to '$(SHARED_LIBS)'.
SHLIB_MARK=
DIRS= crypto ssl $(SHLIB_MARK) apps test tools
DIRS= crypto ssl engines apps test tools
SHLIBDIRS= crypto ssl
# dirs in crypto to build
SDIRS= \
md2 md4 md5 sha mdc2 hmac ripemd \
des rc2 rc4 rc5 idea bf cast \
bn ec rsa dsa dh dso engine aes \
bn ec rsa dsa ecdsa dh ecdh dso engine aes \
buffer bio stack lhash rand err objects \
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5
@@ -180,7 +172,8 @@ SDIRS= \
TESTS = alltests
MAKEFILE= Makefile.ssl
MAKE= make -f Makefile.ssl
NEWMAKE= make
MAKE= $(NEWMAKE) -f Makefile.ssl
MANDIR=$(OPENSSLDIR)/man
MAN1=1
@@ -206,21 +199,33 @@ WTARFILE= $(NAME)-win.tar
EXHEADER= e_os2.h
HEADER= e_os.h
# When we're prepared to use shared libraries in the programs we link here
# we might remove 'clean-shared' from the targets to perform at this stage
all: Makefile.ssl build_all openssl.pc
all: Makefile.ssl sub_all openssl.pc
sub_all:
@for i in $(DIRS); \
do \
BUILD_CMD=if echo " $(DIRS) " | grep " $$i " >/dev/null 2>/dev/null; then \
if [ -d "$$i" ]; then \
(cd $$i && echo "making all in $$i..." && \
$(MAKE) CC='${CC}' PLATFORM='${PLATFORM}' CFLAG='${CFLAG}' SDIRS='$(SDIRS)' INSTALLTOP='${INSTALLTOP}' PEX_LIBS='${PEX_LIBS}' EX_LIBS='${EX_LIBS}' BN_ASM='${BN_ASM}' DES_ENC='${DES_ENC}' BF_ENC='${BF_ENC}' CAST_ENC='${CAST_ENC}' RC4_ENC='${RC4_ENC}' RC5_ENC='${RC5_ENC}' SHA1_ASM_OBJ='${SHA1_ASM_OBJ}' MD5_ASM_OBJ='${MD5_ASM_OBJ}' RMD160_ASM_OBJ='${RMD160_ASM_OBJ}' AR='${AR}' PROCESSOR='${PROCESSOR}' PERL='${PERL}' RANLIB='${RANLIB}' KRB5_INCLUDES='${KRB5_INCLUDES}' LIBKRB5='${LIBKRB5}' EXE_EXT='${EXE_EXT}' SHARED_LIBS='${SHARED_LIBS}' SHLIB_EXT='${SHLIB_EXT}' SHLIB_TARGET='${SHLIB_TARGET}' all ) || exit 1; \
else \
$(MAKE) $$i; \
fi; \
done;
fi; fi
sub_all: build_all
build_all: build_libs build_apps build_tests build_tools
build_libs: build_crypto build_ssl build_engines
build_crypto:
@i=crypto; $(BUILD_CMD)
build_ssl:
@i=ssl; $(BUILD_CMD)
build_engines:
@i=engines; $(BUILD_CMD)
build_apps:
@i=apps; $(BUILD_CMD)
build_tests:
@i=test; $(BUILD_CMD)
build_tools:
@i=tools; $(BUILD_CMD)
libcrypto$(SHLIB_EXT): libcrypto.a
@if [ "$(SHLIB_TARGET)" != "" ]; then \
@@ -246,279 +251,34 @@ clean-shared:
fi; \
( set -x; rm -f lib$$i$(SHLIB_EXT) ); \
if [ "$(PLATFORM)" = "Cygwin" ]; then \
( set -x; rm -f cyg$$i-$(SHLIB_VERSION_NUMBER)$(SHLIB_EXT) lib$$i$(SHLIB_EXT).a ); \
( set -x; rm -f cyg$$i$(SHLIB_EXT) lib$$i$(SHLIB_EXT).a ); \
fi; \
done
link-shared:
@if [ -n "$(SHARED_LIBS_LINK_EXTS)" ]; then \
tmp="$(SHARED_LIBS_LINK_EXTS)"; \
for i in $(SHLIBDIRS); do \
prev=lib$$i$(SHLIB_EXT); \
for j in $${tmp:-x}; do \
( set -x; \
rm -f lib$$i$$j; ln -s $$prev lib$$i$$j ); \
prev=lib$$i$$j; \
done; \
done; \
fi
build-shared: clean-shared do_$(SHLIB_TARGET) link-shared
do_bsd-gcc-shared: do_gnu-shared
do_linux-shared: do_gnu-shared
do_gnu-shared:
libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \
( set -x; ${CC} ${SHARED_LDFLAGS} \
-shared -o lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
-Wl,-soname=lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
-Wl,-Bsymbolic \
-Wl,--whole-archive lib$$i.a \
-Wl,--no-whole-archive $$libs ${EX_LIBS} -lc ) || exit 1; \
libs="$$libs -l$$i"; \
@ for i in ${SHLIBDIRS}; do \
$(NEWMAKE) -f Makefile.shared \
LIBNAME=$$i LIBVERSION=${SHLIB_MAJOR}.${SHLIB_MINOR} \
LIBCOMPATVERSIONS=";${SHLIB_VERSION_HISTORY}" \
symlink.$(SHLIB_TARGET); \
libs="$$libs -l$$i"; \
done
DETECT_GNU_LD=(${CC} -Wl,-V /dev/null 2>&1 | grep '^GNU ld' )>/dev/null
build-shared: do_$(SHLIB_TARGET) link-shared
# For Darwin AKA Mac OS/X (dyld)
do_darwin-shared:
libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \
( set -x ; ${CC} --verbose -dynamiclib -o lib$$i${SHLIB_EXT} \
lib$$i.a $$libs -all_load -current_version ${SHLIB_MAJOR}.${SHLIB_MINOR} \
-compatibility_version ${SHLIB_MAJOR}.`echo ${SHLIB_MINOR} | cut -d. -f1` \
-install_name ${INSTALLTOP}/lib/lib$$i${SHLIB_EXT} ) || exit 1; \
libs="$$libs -l`basename $$i${SHLIB_EXT} .dylib`"; \
echo "" ; \
do_$(SHLIB_TARGET):
@ libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \
$(NEWMAKE) -f Makefile.shared \
CC="$(CC)" LDFLAGS="$(LDFLAGS)" \
SHARED_LDFLAGS="$(SHARED_LDFLAGS)" \
LIBNAME=$$i LIBVERSION=${SHLIB_MAJOR}.${SHLIB_MINOR} \
LIBCOMPATVERSIONS=";${SHLIB_VERSION_HISTORY}" \
LIBDEPS="$$libs $(EX_LIBS)" \
link_a.$(SHLIB_TARGET); \
libs="$$libs -l$$i"; \
done
do_cygwin-shared:
libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \
( set -x; ${CC} -shared -o cyg$$i-$(SHLIB_VERSION_NUMBER).dll \
-Wl,-Bsymbolic \
-Wl,--whole-archive lib$$i.a \
-Wl,--out-implib,lib$$i.dll.a \
-Wl,--no-whole-archive $$libs ) || exit 1; \
libs="$$libs -l$$i"; \
done
# This assumes that GNU utilities are *not* used
do_alpha-osf1-shared:
if ${DETECT_GNU_LD}; then \
$(MAKE) do_gnu-shared; \
else \
libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \
( set -x; ${CC} ${SHARED_LDFLAGS} \
-shared -o lib$$i.so \
-set_version "${SHLIB_VERSION_HISTORY}${SHLIB_VERSION_NUMBER}" \
-all lib$$i.a -none $$libs ${EX_LIBS} -lc ) || exit 1; \
libs="$$libs -l$$i"; \
done; \
fi
# This assumes that GNU utilities are *not* used
# The difference between alpha-osf1-shared and tru64-shared is the `-msym'
# option passed to the linker.
do_tru64-shared:
if ${DETECT_GNU_LD}; then \
$(MAKE) do_gnu-shared; \
else \
libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \
( set -x; ${CC} ${SHARED_LDFLAGS} \
-shared -msym -o lib$$i.so \
-set_version "${SHLIB_VERSION_HISTORY}${SHLIB_VERSION_NUMBER}" \
-all lib$$i.a -none $$libs ${EX_LIBS} -lc ) || exit 1; \
libs="$$libs -l$$i"; \
done; \
fi
# This assumes that GNU utilities are *not* used
# The difference between tru64-shared and tru64-shared-rpath is the
# -rpath ${INSTALLTOP}/lib passed to the linker.
do_tru64-shared-rpath:
if ${DETECT_GNU_LD}; then \
$(MAKE) do_gnu-shared; \
else \
libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \
( set -x; ${CC} ${SHARED_LDFLAGS} \
-shared -msym -o lib$$i.so \
-rpath ${INSTALLTOP}/lib \
-set_version "${SHLIB_VERSION_HISTORY}${SHLIB_VERSION_NUMBER}" \
-all lib$$i.a -none $$libs ${EX_LIBS} -lc ) || exit 1; \
libs="$$libs -l$$i"; \
done; \
fi
# This assumes that GNU utilities are *not* used
do_solaris-shared:
if ${DETECT_GNU_LD}; then \
$(MAKE) do_gnu-shared; \
else \
libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \
( PATH=/usr/ccs/bin:$$PATH ; export PATH; \
MINUSZ='-z '; \
(${CC} -v 2>&1 | grep gcc) > /dev/null && MINUSZ='-Wl,-z,'; \
set -x; ${CC} ${SHARED_LDFLAGS} -G -dy -z text \
-o lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
-h lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
$${MINUSZ}allextract lib$$i.a $${MINUSZ}defaultextract \
$$libs ${EX_LIBS} -lc ) || exit 1; \
libs="$$libs -l$$i"; \
done; \
fi
# OpenServer 5 native compilers used
do_svr3-shared:
if ${DETECT_GNU_LD}; then \
$(MAKE) do_gnu-shared; \
else \
libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \
( PATH=/usr/ccs/bin:$$PATH ; export PATH; \
find . -name "*.o" -print > allobjs ; \
OBJS= ; export OBJS ; \
for obj in `ar t lib$$i.a` ; do \
OBJS="$${OBJS} `grep $$obj allobjs`" ; \
done ; \
set -x; ${CC} -G -o lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
-h lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
$${OBJS} $$libs ${EX_LIBS} ) || exit 1; \
libs="$$libs -l$$i"; \
done; \
fi
# UnixWare 7 and OpenUNIX 8 native compilers used
do_svr5-shared:
if ${DETECT_GNU_LD}; then \
$(MAKE) do_gnu-shared; \
else \
libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \
( PATH=/usr/ccs/bin:$$PATH ; export PATH; \
find . -name "*.o" -print > allobjs ; \
OBJS= ; export OBJS ; \
for obj in `ar t lib$$i.a` ; do \
OBJS="$${OBJS} `grep $$obj allobjs`" ; \
done ; \
set -x; ${CC} ${SHARED_LDFLAGS} \
-G -o lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
-h lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
$${OBJS} $$libs ${EX_LIBS} ) || exit 1; \
libs="$$libs -l$$i"; \
done; \
fi
# This assumes that GNU utilities are *not* used
do_irix-shared:
if ${DETECT_GNU_LD}; then \
$(MAKE) do_gnu-shared; \
else \
libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \
( set -x; ${CC} ${SHARED_LDFLAGS} \
-shared -o lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
-Wl,-soname,lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR} \
-all lib$$i.a $$libs ${EX_LIBS} -lc) || exit 1; \
libs="$$libs -l$$i"; \
done; \
fi
# This assumes that GNU utilities are *not* used
# HP-UX includes the full pathname of libs we depend on, so we would get
# ./libcrypto (with ./ as path information) compiled into libssl, hence
# we omit the SHLIBDEPS. Applications must be linked with -lssl -lcrypto
# anyway.
# The object modules are loaded from lib$i.a using the undocumented -Fl
# option.
#
# WARNING: Until DSO is fixed to support a search path, we support SHLIB_PATH
# by temporarily specifying "+s"!
#
do_hpux-shared:
for i in ${SHLIBDIRS}; do \
( set -x; /usr/ccs/bin/ld ${SHARED_LDFLAGS} \
+vnocompatwarnings \
-b -z +s \
-o lib$$i.sl.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+h lib$$i.sl.${SHLIB_MAJOR}.${SHLIB_MINOR} \
-Fl lib$$i.a -ldld -lc ) || exit 1; \
chmod a=rx lib$$i.sl.${SHLIB_MAJOR}.${SHLIB_MINOR}; \
done
# This assumes that GNU utilities are *not* used
# HP-UX includes the full pathname of libs we depend on, so we would get
# ./libcrypto (with ./ as path information) compiled into libssl, hence
# we omit the SHLIBDEPS. Applications must be linked with -lssl -lcrypto
# anyway.
#
# HP-UX in 64bit mode has "+s" enabled by default; it will search for
# shared libraries along LD_LIBRARY_PATH _and_ SHLIB_PATH.
#
do_hpux64-shared:
for i in ${SHLIBDIRS}; do \
( set -x; /usr/ccs/bin/ld ${SHARED_LDFLAGS} \
-b -z \
-o lib$$i.sl.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+h lib$$i.sl.${SHLIB_MAJOR}.${SHLIB_MINOR} \
+forceload lib$$i.a -ldl -lc ) || exit 1; \
chmod a=rx lib$$i.sl.${SHLIB_MAJOR}.${SHLIB_MINOR}; \
done
# The following method is said to work on all platforms. Tests will
# determine if that's how it's gong to be used.
# This assumes that for all but GNU systems, GNU utilities are *not* used.
# ALLSYMSFLAGS would be:
# GNU systems: --whole-archive
# Tru64 Unix: -all
# Solaris: -z allextract
# Irix: -all
# HP/UX-32bit: -Fl
# HP/UX-64bit: +forceload
# AIX: -bnogc
# SHAREDFLAGS would be:
# GNU systems: -shared -Wl,-soname=lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
# Tru64 Unix: -shared \
# -set_version "${SHLIB_VERSION_HISTORY}${SHLIB_VERSION_NUMBER}"
# Solaris: -G -h lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
# Irix: -shared -Wl,-soname,lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
# HP/UX-32bit: +vnocompatwarnings -b -z +s \
# +h lib$$i.sl.${SHLIB_MAJOR}.${SHLIB_MINOR}
# HP/UX-64bit: -b -z +h lib$$i.sl.${SHLIB_MAJOR}.${SHLIB_MINOR}
# AIX: -G -bE:lib$$i.exp -bM:SRE
# SHAREDCMD would be:
# GNU systems: $(CC)
# Tru64 Unix: $(CC)
# Solaris: $(CC)
# Irix: $(CC)
# HP/UX-32bit: /usr/ccs/bin/ld
# HP/UX-64bit: /usr/ccs/bin/ld
# AIX: $(CC)
ALLSYMSFLAG=-bnogc
SHAREDFLAGS=${SHARED_LDFLAGS} -G -bE:lib$$i.exp -bM:SRE
SHAREDCMD=$(CC)
do_aix-shared:
libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \
( set -x; \
ld -r -o $$i.o $(ALLSYMSFLAG) lib$$i.a && \
( nm -Pg lib$$i.o | grep ' [BD] ' | cut -f1 -d' ' > lib$$i.exp; \
$(SHAREDCMD) $(SHAREDFLAG) -o lib$$i.so lib$$i.o \
$$libs ${EX_LIBS} ) ) \
|| exit 1; \
libs="$$libs -l$$i"; \
done
do_reliantunix-shared:
libs='-L. ${SHLIBDEPS}'; for i in ${SHLIBDIRS}; do \
tmpdir=/tmp/openssl.$$$$ ; rm -rf $$tmpdir ; \
( set -x; \
( Opwd=`pwd` ; mkdir $$tmpdir || exit 1; \
cd $$tmpdir || exit 1 ; ar x $$Opwd/lib$$i.a ; \
${CC} -G -o lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR} *.o \
) || exit 1; \
cp $$tmpdir/lib$$i.so.${SHLIB_MAJOR}.${SHLIB_MINOR} . ; \
) || exit 1; \
rm -rf $$tmpdir ; \
libs="$$libs -l$$i"; \
done
openssl.pc: Makefile.ssl
openssl.pc:
@ ( echo 'prefix=$(INSTALLTOP)'; \
echo 'exec_prefix=$${prefix}'; \
echo 'libdir=$${exec_prefix}/lib'; \
@@ -529,7 +289,7 @@ openssl.pc: Makefile.ssl
echo 'Version: '$(VERSION); \
echo 'Requires: '; \
echo 'Libs: -L$${libdir} -lssl -lcrypto $(EX_LIBS)'; \
echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > openssl.pc
echo 'Cflags: -I$${includedir}' ) > openssl.pc
Makefile.ssl: Makefile.org
@echo "Makefile.ssl is older than Makefile.org."
@@ -537,7 +297,7 @@ Makefile.ssl: Makefile.org
@false
libclean:
rm -f *.a */lib */*/lib
rm -f *.so *.so.* engines/*.so *.a */lib */*/lib
clean:
rm -f shlib/*.o *.o core a.out fluff *.map rehash.time testlog make.log cctest cctest.c
@@ -602,7 +362,7 @@ rehash.time: certs
export OPENSSL OPENSSL_DEBUG_MEMORY; \
LD_LIBRARY_PATH="`pwd`"; DYLD_LIBRARY_PATH="`pwd`"; SHLIB_PATH="`pwd`"; LIBPATH="`pwd`"; \
if [ "$(PLATFORM)" = "DJGPP" ]; then PATH="`pwd`\;$$PATH"; \
elif [ "$(PLATFORM)" = "Cygwin" ]; then PATH="`pwd`:$$PATH"; fi; \
elif [ "$(PLATFORM)" != "Cygwin" ]; then PATH="`pwd`:$$PATH"; fi; \
export LD_LIBRARY_PATH DYLD_LIBRARY_PATH SHLIB_PATH LIBPATH PATH; \
$(PERL) tools/c_rehash certs)
touch rehash.time
@@ -614,7 +374,7 @@ tests: rehash
$(MAKE) CC='${CC}' PLATFORM='${PLATFORM}' CFLAG='${CFLAG}' SDIRS='$(SDIRS)' INSTALLTOP='${INSTALLTOP}' PEX_LIBS='${PEX_LIBS}' EX_LIBS='${EX_LIBS}' BN_ASM='${BN_ASM}' DES_ENC='${DES_ENC}' BF_ENC='${BF_ENC}' CAST_ENC='${CAST_ENC}' RC4_ENC='${RC4_ENC}' RC5_ENC='${RC5_ENC}' SHA1_ASM_OBJ='${SHA1_ASM_OBJ}' MD5_ASM_OBJ='${MD5_ASM_OBJ}' RMD160_ASM_OBJ='${RMD160_ASM_OBJ}' AR='${AR}' PROCESSOR='${PROCESSOR}' PERL='${PERL}' RANLIB='${RANLIB}' TESTS='${TESTS}' KRB5_INCLUDES='${KRB5_INCLUDES}' LIBKRB5='${LIBKRB5}' EXE_EXT='${EXE_EXT}' SHARED_LIBS='${SHARED_LIBS}' SHLIB_EXT='${SHLIB_EXT}' SHLIB_TARGET='${SHLIB_TARGET}' TESTS='${TESTS}' OPENSSL_DEBUG_MEMORY=on tests );
@LD_LIBRARY_PATH="`pwd`"; DYLD_LIBRARY_PATH="`pwd`"; SHLIB_PATH="`pwd`"; LIBPATH="`pwd`"; \
if [ "$(PLATFORM)" = "DJGPP" ]; then PATH="`pwd`\;$$PATH"; \
elif [ "$(PLATFORM)" = "Cygwin" ]; then PATH="`pwd`:$$PATH"; fi; \
elif [ "$(PLATFORM)" != "Cygwin" ]; then PATH="`pwd`:$$PATH"; fi; \
export LD_LIBRARY_PATH DYLD_LIBRARY_PATH SHLIB_PATH LIBPATH PATH; \
apps/openssl version -a
@@ -650,7 +410,7 @@ tags:
errors:
$(PERL) util/mkerr.pl -recurse -write
(cd crypto/engine; $(MAKE) PERL=$(PERL) errors)
(cd engines; $(MAKE) PERL=$(PERL) errors)
stacks:
$(PERL) util/mkstack.pl -write
@@ -710,8 +470,9 @@ dist_pem_h:
install: all install_docs
@$(PERL) $(TOP)/util/mkdir-p.pl $(INSTALL_PREFIX)$(INSTALLTOP)/bin \
$(INSTALL_PREFIX)$(INSTALLTOP)/lib \
$(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig \
$(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkginfo \
$(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl \
$(INSTALL_PREFIX)$(OPENSSLDIR)/engines \
$(INSTALL_PREFIX)$(OPENSSLDIR)/misc \
$(INSTALL_PREFIX)$(OPENSSLDIR)/certs \
$(INSTALL_PREFIX)$(OPENSSLDIR)/private \
@@ -725,7 +486,7 @@ install: all install_docs
do \
if [ -d "$$i" ]; then \
(cd $$i; echo "installing $$i..."; \
$(MAKE) CC='${CC}' CFLAG='${CFLAG}' INSTALL_PREFIX='${INSTALL_PREFIX}' INSTALLTOP='${INSTALLTOP}' OPENSSLDIR='${OPENSSLDIR}' EX_LIBS='${EX_LIBS}' SDIRS='${SDIRS}' RANLIB='${RANLIB}' EXE_EXT='${EXE_EXT}' install ); \
$(MAKE) CC='${CC}' CFLAG='${CFLAG}' INSTALL_PREFIX='${INSTALL_PREFIX}' INSTALLTOP='${INSTALLTOP}' OPENSSLDIR='${OPENSSLDIR}' EX_LIBS='${EX_LIBS}' SDIRS='${SDIRS}' RANLIB='${RANLIB}' EXE_EXT='${EXE_EXT}' SHARED_LIBS='${SHARED_LIBS}' install ); \
fi; \
done
@for i in $(LIBS) ;\
@@ -735,7 +496,7 @@ install: all install_docs
cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
$(RANLIB) $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i ); \
mv $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i ); \
fi; \
done;
@if [ -n "$(SHARED_LIBS)" ]; then \
@@ -747,24 +508,23 @@ install: all install_docs
if [ "$(PLATFORM)" != "Cygwin" ]; then \
cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new; \
mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i; \
mv $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i; \
else \
c=`echo $$i | sed 's/^lib\(.*\)/cyg\1-$(SHLIB_VERSION_NUMBER)/'`; \
c=`echo $$i | sed 's/^lib/cyg/'`; \
cp $$c $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c; \
mv $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c; \
cp $$i.a $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.a.new; \
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.a.new; \
mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.a.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.a; \
mv $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.a.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/$$i.a; \
fi ); \
fi; \
done; \
( here="`pwd`"; \
cd $(INSTALL_PREFIX)$(INSTALLTOP)/lib; \
set $(MAKE); \
$$1 -f $$here/Makefile link-shared ); \
$(NEWMAKE) -f $$here/Makefile link-shared ); \
fi
cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkgconfig
cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/lib/pkginfo
install_docs:
@$(PERL) $(TOP)/util/mkdir-p.pl \
@@ -773,11 +533,6 @@ install_docs:
$(INSTALL_PREFIX)$(MANDIR)/man5 \
$(INSTALL_PREFIX)$(MANDIR)/man7
@pod2man="`cd util; ./pod2mantest $(PERL)`"; \
here="`pwd`"; \
filecase=; \
if [ "$(PLATFORM)" = "DJGPP" -o "$(PLATFORM)" = "Cygwin" ]; then \
filecase=-i; \
fi; \
for i in doc/apps/*.pod; do \
fn=`basename $$i .pod`; \
if [ "$$fn" = "config" ]; then sec=5; else sec=1; fi; \
@@ -787,12 +542,10 @@ install_docs:
--section=$$sec --center=OpenSSL \
--release=$(VERSION) `basename $$i`") \
> $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$$sec; \
$(PERL) util/extract-names.pl < $$i | \
grep -v $$filecase "^$$fn\$$" | \
(cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \
while read n; do \
$$here/util/point.sh $$fn.$$sec $$n.$$sec; \
done); \
$(PERL) util/extract-names.pl < $$i | grep -v "^$$fn" | \
while read n; do \
util/point.sh $$fn.$$sec $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$n.$$sec; \
done; \
done; \
for i in doc/crypto/*.pod doc/ssl/*.pod; do \
fn=`basename $$i .pod`; \
@@ -803,12 +556,10 @@ install_docs:
--section=$$sec --center=OpenSSL \
--release=$(VERSION) `basename $$i`") \
> $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$$sec; \
$(PERL) util/extract-names.pl < $$i | \
grep -v $$filecase "^$$fn\$$" | \
(cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \
while read n; do \
$$here/util/point.sh $$fn.$$sec $$n.$$sec; \
done); \
$(PERL) util/extract-names.pl < $$i | grep -v "^$$fn" | \
while read n; do \
util/point.sh $$fn.$$sec $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$n.$$sec; \
done; \
done
# DO NOT DELETE THIS LINE -- make depend depends on it.

584
Makefile.shared Normal file
View File

@@ -0,0 +1,584 @@
#
# Helper makefile to link shared libraries in a portable way.
# This is much simpler than libtool, and hopefully not too error-prone.
#
# The following variables need to be set on the command line to build
# properly
# CC contains the current compiler. This one MUST be defined
CC=cc
# LDFLAGS contains flags to be used when the temporary object file is
# created. SHARED_LDFLAGS contains flags to be used when the shared
# library is created.
LDFLAGS=
SHARED_LDFLAGS=
# LIBNAME contains just the name of thhe library, without prefix ("lib"
# on Unix, "cyg" for certain forms under Cygwin...) or suffix (.a, .so,
# .dll, ...). This one MUST have a value when using this makefile.
# For example, to build libfoo.so, you need to do the following:
#LIBNAME=foo
LIBNAME=
# LIBEXTRAS contains extra modules to link together with the library.
# For example, if a second library, say libbar.a needs to be linked into
# libfoo.so, you need to do the following:
#LIBEXTRAS=libbar.a
# Note that this MUST be used when using the link_o targets, to hold the
# names of all object files that go into the target library.
LIBEXTRAS=
# LIBVERSION contains the current version of the library.
# For example, to build libfoo.so.1.2, you need to do the following:
#LIBVERSION=1.2
LIBVERSION=
# LIBCOMPATVERSIONS contains the compatibility versions (a list) of
# the library. They MUST be in decreasing order.
# For example, if libfoo.so.1.2.1 is backward compatible with libfoo.so.1.2
# and libfoo.so.1, you need to do the following:
#LIBCOMPATVERSIONS=1.2 1
# Note that on systems that use sonames, the last number will appear as
# part of it.
# It's also possible, for systems that support it (Tru64, for example),
# to add extra compatibility info with more precision, by adding a second
# list of versions, separated from the first with a semicolon, like this:
#LIBCOMPATVERSIONS=1.2 1;1.2.0 1.1.2 1.1.1 1.1.0 1.0.0
LIBCOMPATVERSIONS=
# LIBDEPS contains all the flags necessary to cover all necessary
# dependencies to other libraries.
LIBDEPS=
#------------------------------------------------------------------------------
# The rest is private to this makefile.
#DEBUG=:
DEBUG=set -x
top:
echo "Trying to use this makefile interactively? Don't."
CALC_VERSIONS= \
SHLIB_COMPAT=; SHLIB_SOVER=; \
if [ -n "$(LIBVERSION)$(LIBCOMPATVERSIONS)" ]; then \
prev=""; \
for v in `echo "$(LIBVERSION) $(LIBCOMPATVERSIONS)" | cut -d';' -f1`; do \
SHLIB_SOVER_NODOT=$$v \
SHLIB_SOVER=.$$v; \
if [ -n "$$prev" ]; then \
SHLIB_COMPAT="$$SHLIB_COMPAT .$$prev"; \
fi; \
prev=$$v; \
done; \
fi
LINK_SO= \
( $(DEBUG); \
nm -Pg $$SHOBJECTS | grep ' [BDT] ' | cut -f1 -d' ' > lib$(LIBNAME).exp; \
$$SHAREDCMD $(SHARED_LDFLAGS) $$SHAREDFLAGS -o $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX \
$$ALLSYMSFLAGS $$SHOBJECTS $$NOALLSYMSFLAGS $$LIBDEPS ) && \
$(SYMLINK_SO); ( $(DEBUG); rm -f lib$(LIBNAME).exp )
SYMLINK_SO= \
if [ -n "$$INHIBIT_SYMLINKS" ]; then :; else \
prev=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX; \
if [ -n "$$SHLIB_COMPAT" ]; then \
for x in $$SHLIB_COMPAT; do \
( $(DEBUG); rm -f $$SHLIB$$x$$SHLIB_SUFFIX; \
ln -s $$prev $$SHLIB$$x$$SHLIB_SUFFIX ); \
prev=$$SHLIB$$x$$SHLIB_SUFFIX; \
done; \
fi; \
if [ -n "$$SHLIB_SOVER" ]; then \
( $(DEBUG); rm -f $$SHLIB$$SHLIB_SUFFIX; \
ln -s $$prev $$SHLIB$$SHLIB_SUFFIX ); \
fi; \
fi
LINK_SO_A= SHOBJECTS="lib$(LIBNAME).a $(LIBEXTRAS)"; $(LINK_SO)
LINK_SO_O= SHOBJECTS="$(LIBEXTRAS)"; $(LINK_SO)
LINK_SO_A_VIA_O= \
SHOBJECTS=lib$(LIBNAME).o ALL=$$ALLSYMSFLAGS ALLSYMSFLAGS= NOALLSYMSFLAGS=; \
( $(DEBUG); \
ld $(LDFLAGS) -r -o lib$(LIBNAME).o $$ALL lib$(LIBNAME).a $(LIBEXTRAS) ); \
$(LINK_SO) && rm -f $(LIBNAME).o
LINK_SO_A_UNPACKED= \
UNPACKDIR=link_tmp.$$$$; rm -rf $$UNPACKDIR; mkdir $$UNPACKDIR; \
(cd $$UNPACKDIR; ar x ../lib$(LIBNAME).a) && cp $(LIBEXTRAS) $$UNPACKDIR && \
SHOBJECTS=$$UNPACKDIR/*.o; \
$(LINK_SO) && rm -rf $$UNPACKDIR
DETECT_GNU_LD=${CC} -v 2>&1 | grep '^gcc' >/dev/null 2>&1 && \
my_ld=`${CC} -print-prog-name=ld 2>&1` && \
[ -n "$$my_ld" ] && \
$$my_ld -v 2>&1 | grep 'GNU ld' >/dev/null 2>&1
DO_GNU=$(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='-Wl,--whole-archive' \
NOALLSYMSFLAGS='-Wl,--no-whole-archive' \
SHAREDFLAGS="-shared -Wl,-Bsymbolic -Wl,-soname=$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX" \
SHAREDCMD='$(CC)'
link_o.gnu:
@ $(DO_GNU); $(LINK_SO_O)
link_a.gnu:
@ $(DO_GNU); $(LINK_SO_A)
# For Darwin AKA Mac OS/X (dyld)
link_o.darwin:
@ $(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME) \
SHLIB_SUFFIX=.dylib \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='-all_load' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS="-dynamiclib" \
SHAREDCMD='$(CC)'; \
if [ -n "$(LIBVERSION)" ]; then \
SHAREDFLAGS="$SHAREDFLAGS -current_version $(LIBVERSION)"; \
fi; \
if [ -n "$$SHLIB_SOVER_NODOT" ]; then \
SHAREDFLAGS="$SHAREDFLAGS -compatibility_version $$SHLIB_SOVER_NODOT"; \
fi; \
$(LINK_SO_O)
link_a.darwin:
@ $(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME) \
SHLIB_SUFFIX=.dylib \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='-all_load' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS="-dynamiclib" \
SHAREDCMD='$(CC)'; \
if [ -n "$(LIBVERSION)" ]; then \
SHAREDFLAGS="$SHAREDFLAGS -current_version $(LIBVERSION)"; \
fi; \
if [ -n "$$SHLIB_SOVER_NODOT" ]; then \
SHAREDFLAGS="$SHAREDFLAGS -compatibility_version $$SHLIB_SOVER_NODOT"; \
fi; \
$(LINK_SO_A)
link_o.cygwin:
@ $(CALC_VERSIONS); \
INHIBIT_SYMLINKS=yes; \
SHLIB=cyg$(LIBNAME) \
SHLIB_SUFFIX=.dll \
LIBDEPS="$(LIBDEPS) -lc" \
SHLIB_SOVER=-$(LIBVERSION) \
ALLSYMSFLAGS='-Wl,--whole-archive' \
NOALLSYMSFLAGS='-Wl,--no-whole-archive' \
SHAREDFLAGS="-shared -Wl,-Bsymbolic -Wl,--out-implib,lib$(LIBNAME).dll.a" \
SHAREDCMD='${CC}'; \
$(LINK_SO_O)
link_a.cygwin:
@ $(CALC_VERSIONS); \
INHIBIT_SYMLINKS=yes; \
SHLIB=cyg$(LIBNAME) \
SHLIB_SUFFIX=.dll \
LIBDEPS="$(LIBDEPS) -lc" \
SHLIB_SOVER= \
ALLSYMSFLAGS='-Wl,--whole-archive' \
NOALLSYMSFLAGS='-Wl,--no-whole-archive' \
SHAREDFLAGS="-shared -Wl,-Bsymbolic -Wl,--out-implib,lib$(LIBNAME).dll.a" \
SHAREDCMD='${CC}'; \
$(LINK_SO_A)
link_o.alpha-osf1:
@ if ${DETECT_GNU_LD}; then \
$(DO_GNU); \
else \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
SHLIB_HIST=`echo "$(LIBCOMPATVERSIONS)" | cut -d';' -f2 | sed -e 's/ */:/'`; \
if [ -n "$$SHLIB_HIST" ]; then \
SHLIB_HIST="$${SHLIB_HIST}:$(LIBVERSION)"; \
else \
SHLIB_HIST="$(LIBVERSION)"; \
fi
SHLIB_SOVER= \
ALLSYMSFLAGS='-all' \
NOALLSYMSFLAGS='-none' \
SHAREDFLAGS="-shared" \
SHAREDCMD='$(CC)'; \
if [ -n "$$SHLIB_HIST" ]; then \
SHAREDFLAGS="$SHAREDFLAGS -set_version \"$$SHLIB_HIST\""; \
fi; \
fi; \
$(LINK_SO_O)
link_a.alpha-osf1:
@ if ${DETECT_GNU_LD}; then \
$(DO_GNU); \
else \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
SHLIB_HIST=`echo "$(LIBCOMPATVERSIONS)" | cut -d';' -f2 | sed -e 's/ */:/'`; \
if [ -n "$$SHLIB_HIST" ]; then \
SHLIB_HIST="$${SHLIB_HIST}:$(LIBVERSION)"; \
else \
SHLIB_HIST="$(LIBVERSION)"; \
fi
SHLIB_SOVER= \
ALLSYMSFLAGS='-all' \
NOALLSYMSFLAGS='-none' \
SHAREDFLAGS="-shared" \
SHAREDCMD='$(CC)'; \
if [ -n "$$SHLIB_HIST" ]; then \
SHAREDFLAGS="$SHAREDFLAGS -set_version \"$$SHLIB_HIST\""; \
fi; \
fi; \
$(LINK_SO_A)
# The difference between alpha-osf1-shared and tru64-shared is the `-msym'
# option passed to the linker.
link_o.tru64:
@ if ${DETECT_GNU_LD}; then \
$(DO_GNU); \
else \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
SHLIB_HIST=`echo "$(LIBCOMPATVERSIONS)" | cut -d';' -f2 | sed -e 's/ */:/'`; \
if [ -n "$$SHLIB_HIST" ]; then \
SHLIB_HIST="$${SHLIB_HIST}:$(LIBVERSION)"; \
else \
SHLIB_HIST="$(LIBVERSION)"; \
fi
SHLIB_SOVER= \
ALLSYMSFLAGS='-all' \
NOALLSYMSFLAGS='-none' \
SHAREDFLAGS="-shared -msym" \
SHAREDCMD='$(CC)'; \
if [ -n "$$SHLIB_HIST" ]; then \
SHAREDFLAGS="$SHAREDFLAGS -set_version \"$$SHLIB_HIST\""; \
fi; \
fi; \
$(LINK_SO_O)
link_a.tru64:
@ if ${DETECT_GNU_LD}; then \
$(DO_GNU); \
else \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
SHLIB_HIST=`echo "$(LIBCOMPATVERSIONS)" | cut -d';' -f2 | sed -e 's/ */:/'`; \
if [ -n "$$SHLIB_HIST" ]; then \
SHLIB_HIST="$${SHLIB_HIST}:$(LIBVERSION)"; \
else \
SHLIB_HIST="$(LIBVERSION)"; \
fi
SHLIB_SOVER= \
ALLSYMSFLAGS='-all' \
NOALLSYMSFLAGS='-none' \
SHAREDFLAGS="-shared -msym" \
SHAREDCMD='$(CC)'; \
if [ -n "$$SHLIB_HIST" ]; then \
SHAREDFLAGS="$SHAREDFLAGS -set_version \"$$SHLIB_HIST\""; \
fi; \
fi; \
$(LINK_SO_A)
# The difference between tru64-shared and tru64-shared-rpath is the
# -rpath ${LIBRPATH} passed to the linker.
link_o.tru64-rpath:
@ if ${DETECT_GNU_LD}; then \
$(DO_GNU); \
else \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
SHLIB_HIST=`echo "$(LIBCOMPATVERSIONS)" | cut -d';' -f2 | sed -e 's/ */:/'`; \
if [ -n "$$SHLIB_HIST" ]; then \
SHLIB_HIST="$${SHLIB_HIST}:$(LIBVERSION)"; \
else \
SHLIB_HIST="$(LIBVERSION)"; \
fi
SHLIB_SOVER= \
ALLSYMSFLAGS='-all' \
NOALLSYMSFLAGS='-none' \
SHAREDFLAGS="-shared -msym -rpath $(LIBRPATH)" \
SHAREDCMD='$(CC)'; \
if [ -n "$$SHLIB_HIST" ]; then \
SHAREDFLAGS="$SHAREDFLAGS -set_version \"$$SHLIB_HIST\""; \
fi; \
fi; \
$(LINK_SO_O)
link_a.tru64-rpath:
@ if ${DETECT_GNU_LD}; then \
$(DO_GNU); \
else \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
SHLIB_HIST=`echo "$(LIBCOMPATVERSIONS)" | cut -d';' -f2 | sed -e 's/ */:/'`; \
if [ -n "$$SHLIB_HIST" ]; then \
SHLIB_HIST="$${SHLIB_HIST}:$(LIBVERSION)"; \
else \
SHLIB_HIST="$(LIBVERSION)"; \
fi
SHLIB_SOVER= \
ALLSYMSFLAGS='-all' \
NOALLSYMSFLAGS='-none' \
SHAREDFLAGS="-shared -msym -rpath $(LIBRPATH)" \
SHAREDCMD='$(CC)'; \
if [ -n "$$SHLIB_HIST" ]; then \
SHAREDFLAGS="$SHAREDFLAGS -set_version \"$$SHLIB_HIST\""; \
fi; \
fi; \
$(LINK_SO_A)
link_o.solaris:
@ if ${DETECT_GNU_LD}; then \
$(DO_GNU); \
else \
$(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='-z allextract' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='-G -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX' \
SHAREDCMD='$(CC)'; \
fi; \
$(LINK_SO_O)
link_a.solaris:
@ if ${DETECT_GNU_LD}; then \
$(DO_GNU); \
else \
$(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='-z allextract' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='-G -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX' \
SHAREDCMD='$(CC)'; \
fi; \
$(LINK_SO_A)
# OpenServer 5 native compilers used
# UnixWare 7 and OpenUNIX 8 native compilers used
link_o.svr3:
@ if ${DETECT_GNU_LD}; then \
$(DO_GNU); \
else \
$(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='-z allextract' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='-G -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX' \
SHAREDCMD='$(CC)'; \
fi; \
$(LINK_SO_O)
link_a.svr3:
@ if ${DETECT_GNU_LD}; then \
$(DO_GNU); \
else \
$(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='-z allextract' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='-G -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX' \
SHAREDCMD='$(CC)'; \
fi; \
$(LINK_SO_A_UNPACKED)
link_o.irix:
@ if ${DETECT_GNU_LD}; then \
$(DO_GNU); \
else \
$(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='-all' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='-shared -Wl,-soname,$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX' \
SHAREDCMD='$(CC)'; \
fi; \
$(LINK_SO_O)
link_a.irix:
@ if ${DETECT_GNU_LD}; then \
$(DO_GNU); \
else \
$(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='-all' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='-shared -Wl,-soname,$$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX' \
SHAREDCMD='$(CC)'; \
fi; \
$(LINK_SO_A)
# HP-UX includes the full pathname of libs we depend on, so we would get
# ./libcrypto (with ./ as path information) compiled into libssl, hence
# we omit the SHLIBDEPS. Applications must be linked with -lssl -lcrypto
# anyway.
# The object modules are loaded from lib$i.a using the undocumented -Fl
# option.
#
# WARNING: Until DSO is fixed to support a search path, we support SHLIB_PATH
# by temporarily specifying "+s"!
#
link_o.hpux32:
@ $(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).sl \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='-Fl' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='+vnocompatwarnings -b -z +s +h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX' \
SHAREDCMD='/usr/ccs/bin/ld'; \
$(LINK_SO_O) && chmod a=rx $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX
link_a.hpux32:
@ $(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).sl \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='-Fl' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='+vnocompatwarnings -b -z +s +h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX' \
SHAREDCMD='/usr/ccs/bin/ld'; \
$(LINK_SO_A) && chmod a=rx $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX
# HP-UX includes the full pathname of libs we depend on, so we would get
# ./libcrypto (with ./ as path information) compiled into libssl, hence
# we omit the SHLIBDEPS. Applications must be linked with -lssl -lcrypto
# anyway.
#
# HP-UX in 64bit mode has "+s" enabled by default; it will search for
# shared libraries along LD_LIBRARY_PATH _and_ SHLIB_PATH.
#
link_o.hpux64:
@ $(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).sl \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='+forceload' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='-b -z +h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX' \
SHAREDCMD='/usr/ccs/bin/ld'; \
$(LINK_SO_O) && chmod a=rx $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX
link_a.hpux64:
@ $(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).sl \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='+forceload' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='-b -z +h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX' \
SHAREDCMD='/usr/ccs/bin/ld'; \
$(LINK_SO_A) && chmod a=rx $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX
link_o.aix:
@ $(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='-bnogc' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='-G -bE:lib$(LIBNAME).exp -bM:SRE' \
SHAREDCMD='$(CC)'; \
$(LINK_SO_O)
link_a.aix:
@ $(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS='-bnogc' \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='-G -bE:lib$(LIBNAME).exp -bM:SRE' \
SHAREDCMD='$(CC)'; \
$(LINK_SO_A_VIA_O)
link_o.reliantunix:
@ $(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS= \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='-G' \
SHAREDCMD='$(CC)'; \
$(LINK_SO_O)
link_a.reliantunix:
@ $(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).so \
SHLIB_SUFFIX= \
LIBDEPS="$(LIBDEPS) -lc" \
ALLSYMSFLAGS= \
NOALLSYMSFLAGS='' \
SHAREDFLAGS='-G' \
SHAREDCMD='$(CC)'; \
$(LINK_SO_A_UNPACKED)
# Targets to build symbolic links when needed
symlink.gnu symlink.solaris symlink.svr3 symlink.irix \
symlink.aix symlink.reliantunix:
@ $(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).so; \
$(SYMLINK_SO)
symlink.darwin:
@ $(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME) \
SHLIB_SUFFIX=.dylib; \
$(SYMLINK_SO)
symlink.hpux32 symlink.hpux64:
@ $(CALC_VERSIONS); \
SHLIB=lib$(LIBNAME).sl; \
$(SYMLINK_SO)
# The following lines means those specific architectures do no symlinks
symlink.cygwin symlib.alpha-osf1 symlink.tru64 symlink.tru64-rpath:
# Compatibility targets
link_o.bsd-gcc-shared link_o.linux-shared link_o.gnu-shared: link_o.gnu
link_a.bsd-gcc-shared link_a.linux-shared link_a.gnu-shared: link_a.gnu
symlink.bsd-gcc-shared symlink.linux-shared symlink.gnu-shared: symlink.gnu
link_o.darwin-shared: link_o.darwin
link_a.darwin-shared: link_a.darwin
symlink.darwin-shared: symlink.darwin
link_o.cygwin-shared: link_o.cygwin
link_a.cygwin-shared: link_a.cygwin
symlink.cygwin-shared: symlink.cygwin
link_o.alpha-osf1-shared: link_o.alpha-osf1
link_a.alpha-osf1-shared: link_a.alpha-osf1
symlink.alpha-osf1-shared: symlink.alpha-osf1
link_o.tru64-shared: link_o.tru64
link_a.tru64-shared: link_a.tru64
symlink.tru64-shared: symlink.tru64
link_o.tru64-shared-rpath: link_o.tru64-rpath
link_a.tru64-shared-rpath: link_a.tru64-rpath
symlink.tru64-shared-rpath: symlink.tru64-rpath
link_o.solaris-shared: link_o.solaris
link_a.solaris-shared: link_a.solaris
symlink.solaris-shared: symlink.solaris
link_o.svr3-shared: link_o.svr3
link_a.svr3-shared: link_a.svr3
symlink.svr3-shared: symlink.svr3
link_o.svr5-shared: link_o.svr3
link_a.svr5-shared: link_a.svr3
symlink.svr5-shared: symlink.svr3
link_o.irix-shared: link_o.irix
link_a.irix-shared: link_a.irix
symlink.irix-shared: symlink.irix
link_o.hpux-shared: link_o.hpux32
link_a.hpux-shared: link_a.hpux32
symlink.hpux-shared: symlink.hpux32
link_o.hpux64-shared: link_o.hpux64
link_a.hpux64-shared: link_a.hpux64
symlink.hpux64-shared: symlink.hpux64
link_o.aix-shared: link_o.aix
link_a.aix-shared: link_a.aix
symlink.aix-shared: symlink.aix
link_o.reliantunix-shared: link_o.reliantunix
link_a.reliantunix-shared: link_a.reliantunix
symlink.reliantunix-shared: symlink.reliantunix

5
NEWS
View File

@@ -18,14 +18,11 @@
o New elliptic curve library section.
o New AES (Rijndael) library section.
o Support for new platforms: Windows CE, Tandem OSS, A/UX, AIX 64-bit,
Linux x86_64, Linux 64-bit on Sparc v9
Linux x86_64
o Extended support for some platforms: VxWorks
o Enhanced support for shared libraries.
o Now only builds PIC code when shared library support is requested.
o Support for pkg-config.
o Lots of new manuals.
o Makes symbolic links to or copies of manuals to cover all described
functions.
o Change DES API to clean up the namespace (some applications link also
against libdes providing similar functions having the same name).
Provide macros for backward compatibility (will be removed in the

View File

@@ -62,11 +62,3 @@ What happens is that gcc might optimize a little too agressively, and
you end up with an extra incrementation when *header != '4'.
We recommend that you upgrade gcc to as high a 3.x version as you can.
* solaris64-sparcv9-cc SHA-1 performance with WorkShop 6 compiler.
As subject suggests SHA-1 might perform poorly (4 times slower)
if compiled with WorkShop 6 compiler and -xarch=v9. The cause for
this seems to be the fact that compiler emits multiplication to
perform shift operations:-( To work the problem around configure
with './Configure solaris64-sparcv9-cc -DMD32_REG_T=int'.

4
README
View File

@@ -1,5 +1,5 @@
OpenSSL 0.9.7 31 Dec 2002
OpenSSL 0.9.8-dev XX xxx XXXX
Copyright (c) 1998-2002 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
@@ -154,7 +154,7 @@
- Stack Traceback (if the application dumps core)
Report the bug to the OpenSSL project via the Request Tracker
(http://www.openssl.org/support/rt2.html) by mail to:
(http://www.openssl.org/rt2.html) by mail to:
openssl-bugs@openssl.org

19
STATUS
View File

@@ -1,11 +1,16 @@
OpenSSL STATUS Last modified at
______________ $Date: 2002/12/30 23:54:11 $
______________ $Date: 2002/12/07 20:03:42 $
DEVELOPMENT STATE
o OpenSSL 0.9.8: Under development...
o OpenSSL 0.9.7: Released on December 31st, 2002
o OpenSSL 0.9.7-beta5: Released on December 5th, 2002
o OpenSSL 0.9.7-beta4: Released on November 19th, 2002
Debian GNU/Linux (kernel version 2.4.19, gcc 2.95.4) - PASSED
o OpenSSL 0.9.7-beta3: Released on July 30th, 2002
o OpenSSL 0.9.7-beta2: Released on June 16th, 2002
o OpenSSL 0.9.7-beta1: Released on June 1st, 2002
o OpenSSL 0.9.6h: Released on December 5th, 2002
o OpenSSL 0.9.6g: Released on August 9th, 2002
o OpenSSL 0.9.6f: Released on August 8th, 2002
@@ -27,6 +32,9 @@
RELEASE SHOWSTOPPERS
o BN_mod_mul verification fails for mips3-sgi-irix
unless configured with no-asm
o [2002-11-21]
PR 343 mentions that scrubbing memory with 'memset(ptr, 0, n)' may
be optimized away in modern compilers. This is definitely not good
@@ -62,9 +70,16 @@
Shared library support for VMS.
Kerberos 5 authentication (Heimdal)
Constification
Compression
Attribute Certificate support
Certificate Pair support
Storage Engines (primarly an LDAP storage engine)
NEEDS PATCH
o 0.9.8-dev: COMPLEMENTOFALL and COMPLEMENTOFDEFAULT do not
handle ECCdraft cipher suites correctly.
o apps/ca.c: "Sign the certificate?" - "n" creates empty certificate file
o "OpenSSL STATUS" is never up-to-date.

46
TABLE
View File

@@ -1945,7 +1945,7 @@ $rc5_obj =
$dso_scheme = dlfcn
$shared_target= solaris-shared
$shared_cflag = -fPIC
$shared_ldflag = -shared
$shared_ldflag =
$shared_extension = .so.$(SHLIB_MAJOR).$(SHLIB_MINOR)
$ranlib =
$arflags =
@@ -1995,7 +1995,7 @@ $rc5_obj =
$dso_scheme = dlfcn
$shared_target= solaris-shared
$shared_cflag = -fPIC
$shared_ldflag = -shared
$shared_ldflag =
$shared_extension = .so.$(SHLIB_MAJOR).$(SHLIB_MINOR)
$ranlib =
$arflags =
@@ -3377,13 +3377,13 @@ $arflags =
*** linux-x86_64
$cc = gcc
$cflags = -m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int
$cflags = -DL_ENDIAN -DNO_ASM
$unistd =
$thread_cflag = -D_REENTRANT
$sys_id =
$lflags = -ldl
$bn_ops = SIXTY_FOUR_BIT_LONG RC4_CHUNK RC4_CHAR BF_PTR2 DES_INT DES_UNROLL
$bn_obj = asm/x86_64-gcc.o
$bn_ops = SIXTY_FOUR_BIT_LONG
$bn_obj =
$des_obj =
$bf_obj =
$md5_obj =
@@ -3395,7 +3395,7 @@ $rc5_obj =
$dso_scheme = dlfcn
$shared_target= linux-shared
$shared_cflag = -fPIC
$shared_ldflag = -m64
$shared_ldflag =
$shared_extension = .so.$(SHLIB_MAJOR).$(SHLIB_MINOR)
$ranlib =
$arflags =
@@ -3708,15 +3708,15 @@ $thread_cflag = (unknown)
$sys_id =
$lflags = -lsocket -lresolv -lnsl
$bn_ops = BN_LLONG DES_PTR DES_RISC1 DES_UNROLL RC4_INDEX MD2_INT
$bn_obj =
$des_obj =
$bf_obj =
$md5_obj =
$sha1_obj =
$cast_obj =
$rc4_obj =
$rmd160_obj =
$rc5_obj =
$bn_obj = asm/bn86-elf.o asm/co86-elf.o
$des_obj = asm/dx86-elf.o asm/yx86-elf.o
$bf_obj = asm/bx86-elf.o
$md5_obj = asm/mx86-elf.o
$sha1_obj = asm/sx86-elf.o
$cast_obj = asm/cx86-elf.o
$rc4_obj = asm/rx86-elf.o
$rmd160_obj = asm/rm86-elf.o
$rc5_obj = asm/r586-elf.o
$dso_scheme = dlfcn
$shared_target= svr3-shared
$shared_cflag = -fPIC
@@ -3795,7 +3795,7 @@ $rc5_obj =
$dso_scheme = dlfcn
$shared_target= solaris-shared
$shared_cflag = -fPIC
$shared_ldflag = -shared
$shared_ldflag =
$shared_extension = .so.$(SHLIB_MAJOR).$(SHLIB_MINOR)
$ranlib =
$arflags =
@@ -3845,7 +3845,7 @@ $rc5_obj =
$dso_scheme = dlfcn
$shared_target= solaris-shared
$shared_cflag = -fPIC
$shared_ldflag = -shared
$shared_ldflag =
$shared_extension = .so.$(SHLIB_MAJOR).$(SHLIB_MINOR)
$ranlib =
$arflags =
@@ -3895,7 +3895,7 @@ $rc5_obj =
$dso_scheme = dlfcn
$shared_target= solaris-shared
$shared_cflag = -fPIC
$shared_ldflag = -shared
$shared_ldflag =
$shared_extension = .so.$(SHLIB_MAJOR).$(SHLIB_MINOR)
$ranlib =
$arflags =
@@ -3920,7 +3920,7 @@ $rc5_obj =
$dso_scheme = dlfcn
$shared_target= solaris-shared
$shared_cflag = -fPIC
$shared_ldflag = -shared
$shared_ldflag =
$shared_extension = .so.$(SHLIB_MAJOR).$(SHLIB_MINOR)
$ranlib =
$arflags =
@@ -3970,7 +3970,7 @@ $rc5_obj = asm/r586-sol.o
$dso_scheme = dlfcn
$shared_target= solaris-shared
$shared_cflag = -fPIC
$shared_ldflag = -shared
$shared_ldflag =
$shared_extension = .so.$(SHLIB_MAJOR).$(SHLIB_MINOR)
$ranlib =
$arflags =
@@ -4020,7 +4020,7 @@ $rc5_obj =
$dso_scheme = dlfcn
$shared_target= solaris-shared
$shared_cflag = -fPIC
$shared_ldflag = -m64 -shared
$shared_ldflag = -m64
$shared_extension = .so.$(SHLIB_MAJOR).$(SHLIB_MINOR)
$ranlib =
$arflags =
@@ -4045,7 +4045,7 @@ $rc5_obj =
$dso_scheme = dlfcn
$shared_target= solaris-shared
$shared_cflag = -fPIC
$shared_ldflag = -m64 -shared
$shared_ldflag = -m64
$shared_extension = .so.$(SHLIB_MAJOR).$(SHLIB_MINOR)
$ranlib =
$arflags =
@@ -4102,7 +4102,7 @@ $arflags =
*** ultrix-cc
$cc = cc
$cflags = -std1 -O -Olimit 2500 -DL_ENDIAN
$cflags = -std1 -O -Olimit 1000 -DL_ENDIAN
$unistd =
$thread_cflag = (unknown)
$sys_id =

View File

@@ -285,6 +285,7 @@ $ if alg_entry .eqs. "" then goto loop2
$ if alg_entry .nes. ","
$ then
$ if alg_entry .eqs. "KRB5" then goto loop ! Special for now
$ if alg_entry .eqs. "STATIC_ENGINE" then goto loop ! Special for now
$ if f$trnlnm("OPENSSL_NO_"+alg_entry) .nes. "" then goto loop
$ goto loop2
$ endif

View File

@@ -1 +0,0 @@
sys$share:tcpip$ipc_shr.exe/share

File diff suppressed because it is too large Load Diff

View File

@@ -82,6 +82,8 @@
int MAIN(int, char **);
static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf);
int MAIN(int argc, char **argv)
{
int i,badops=0,offset=0,ret=1,j;
@@ -90,6 +92,7 @@ int MAIN(int argc, char **argv)
BIO *in=NULL,*out=NULL,*b64=NULL, *derout = NULL;
int informat,indent=0, noout = 0, dump = 0;
char *infile=NULL,*str=NULL,*prog,*oidfile=NULL, *derfile=NULL;
char *genstr=NULL, *genconf=NULL;
unsigned char *tmpbuf;
BUF_MEM *buf=NULL;
STACK *osk=NULL;
@@ -167,6 +170,16 @@ int MAIN(int argc, char **argv)
if (--argc < 1) goto bad;
sk_push(osk,*(++argv));
}
else if (strcmp(*argv,"-genstr") == 0)
{
if (--argc < 1) goto bad;
genstr= *(++argv);
}
else if (strcmp(*argv,"-genconf") == 0)
{
if (--argc < 1) goto bad;
genconf= *(++argv);
}
else
{
BIO_printf(bio_err,"unknown option %s\n",*argv);
@@ -195,6 +208,8 @@ bad:
BIO_printf(bio_err," -strparse offset\n");
BIO_printf(bio_err," a series of these can be used to 'dig' into multiple\n");
BIO_printf(bio_err," ASN1 blob wrappings\n");
BIO_printf(bio_err," -genstr str string to generate ASN1 structure from\n");
BIO_printf(bio_err," -genconf file file to generate ASN1 structure from\n");
goto end;
}
@@ -248,25 +263,39 @@ bad:
if ((buf=BUF_MEM_new()) == NULL) goto end;
if (!BUF_MEM_grow(buf,BUFSIZ*8)) goto end; /* Pre-allocate :-) */
if (informat == FORMAT_PEM)
if (genstr || genconf)
{
BIO *tmp;
if ((b64=BIO_new(BIO_f_base64())) == NULL)
num = do_generate(bio_err, genstr, genconf, buf);
if (num < 0)
{
ERR_print_errors(bio_err);
goto end;
BIO_push(b64,in);
tmp=in;
in=b64;
b64=tmp;
}
}
num=0;
for (;;)
else
{
if (!BUF_MEM_grow(buf,(int)num+BUFSIZ)) goto end;
i=BIO_read(in,&(buf->data[num]),BUFSIZ);
if (i <= 0) break;
num+=i;
if (informat == FORMAT_PEM)
{
BIO *tmp;
if ((b64=BIO_new(BIO_f_base64())) == NULL)
goto end;
BIO_push(b64,in);
tmp=in;
in=b64;
b64=tmp;
}
num=0;
for (;;)
{
if (!BUF_MEM_grow(buf,(int)num+BUFSIZ)) goto end;
i=BIO_read(in,&(buf->data[num]),BUFSIZ);
if (i <= 0) break;
num+=i;
}
}
str=buf->data;
@@ -335,3 +364,61 @@ end:
OPENSSL_EXIT(ret);
}
static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf)
{
CONF *cnf = NULL;
int len;
long errline;
unsigned char *p;
ASN1_TYPE *atyp = NULL;
if (genconf)
{
cnf = NCONF_new(NULL);
if (!NCONF_load(cnf, genconf, &errline))
goto conferr;
if (!genstr)
genstr = NCONF_get_string(cnf, "default", "asn1");
if (!genstr)
{
BIO_printf(bio, "Can't find 'asn1' in '%s'\n", genconf);
goto err;
}
}
atyp = ASN1_generate_nconf(genstr, cnf);
NCONF_free(cnf);
if (!atyp)
return -1;
len = i2d_ASN1_TYPE(atyp, NULL);
if (len <= 0)
goto err;
if (!BUF_MEM_grow(buf,len))
goto err;
p=(unsigned char *)buf->data;
i2d_ASN1_TYPE(atyp, &p);
ASN1_TYPE_free(atyp);
return len;
conferr:
if (errline > 0)
BIO_printf(bio, "Error on line %ld of config file '%s'\n",
errline, genconf);
else
BIO_printf(bio, "Error loading config file '%s'\n", genconf);
err:
NCONF_free(cnf);
ASN1_TYPE_free(atyp);
return -1;
}

View File

@@ -1021,7 +1021,7 @@ bad:
}
if (verbose)
BIO_printf(bio_err, "Successfully loaded extensions file %s\n", extfile);
BIO_printf(bio_err, "Succesfully loaded extensions file %s\n", extfile);
/* We can have sections in the ext file */
if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions")))
@@ -1532,6 +1532,11 @@ bad:
if (pkey->type == EVP_PKEY_DSA)
dgst=EVP_dss1();
else
#endif
#ifndef OPENSSL_NO_ECDSA
if (pkey->type == EVP_PKEY_EC)
dgst=EVP_ecdsa();
else
#endif
dgst=EVP_md5();
}
@@ -1596,10 +1601,6 @@ bad:
}
j=TXT_DB_write(out,db);
if (j <= 0) goto err;
BIO_free_all(out);
out = NULL;
BIO_free_all(in);
in = NULL;
strncpy(buf[1],dbfile,BSIZE-4);
buf[1][BSIZE-4]='\0';
#ifndef OPENSSL_SYS_VMS
@@ -1607,6 +1608,10 @@ bad:
#else
strcat(buf[1],"-old");
#endif
BIO_free(in);
in = NULL;
BIO_free(out);
out = NULL;
if (rename(dbfile,buf[1]) < 0)
{
BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]);
@@ -2316,6 +2321,16 @@ again2:
EVP_PKEY_copy_parameters(pktmp,pkey);
EVP_PKEY_free(pktmp);
#endif
#ifndef OPENSSL_NO_ECDSA
if (pkey->type == EVP_PKEY_EC)
dgst = EVP_ecdsa();
pktmp = X509_get_pubkey(ret);
if (EVP_PKEY_missing_parameters(pktmp) &&
!EVP_PKEY_missing_parameters(pkey))
EVP_PKEY_copy_parameters(pktmp, pkey);
EVP_PKEY_free(pktmp);
#endif
if (!X509_sign(ret,pkey,dgst))
goto err;
@@ -3061,16 +3076,16 @@ X509_NAME *do_subject(char *subject, long chtype)
int nid;
if (!buf || !ne_types || !ne_values)
{
{
BIO_printf(bio_err, "malloc error\n");
goto error;
}
}
if (*subject != '/')
{
{
BIO_printf(bio_err, "Subject does not start with '/'.\n");
goto error;
}
}
sp++; /* skip leading / */
while (*sp)
@@ -3083,12 +3098,12 @@ X509_NAME *do_subject(char *subject, long chtype)
{
if (*++sp)
*bp++ = *sp++;
else
else
{
BIO_printf(bio_err, "escape character at end of string\n");
goto error;
}
}
}
else if (*sp == '=')
{
sp++;
@@ -3126,7 +3141,7 @@ X509_NAME *do_subject(char *subject, long chtype)
}
*bp++ = '\0';
ne_num++;
}
}
if (!(n = X509_NAME_new()))
goto error;

395
apps/ec.c Normal file
View File

@@ -0,0 +1,395 @@
/* apps/ec.c */
/*
* Written by Nils Larsch for the OpenSSL project.
*/
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#ifndef OPENSSL_NO_EC
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#undef PROG
#define PROG ec_main
/* -inform arg - input format - default PEM (one of DER, NET or PEM)
* -outform arg - output format - default PEM
* -in arg - input file - default stdin
* -out arg - output file - default stdout
* -des - encrypt output if PEM format with DES in cbc mode
* -text - print a text version
* -param_out - print the elliptic curve parameters
* -conv_form arg - specifies the point encoding form
* -param_enc arg - specifies the parameter encoding
*/
int MAIN(int, char **);
int MAIN(int argc, char **argv)
{
ENGINE *e = NULL;
int ret = 1;
EC_KEY *eckey = NULL;
int i, badops = 0;
const EVP_CIPHER *enc = NULL;
BIO *in = NULL, *out = NULL;
int informat, outformat, text=0, noout=0;
int pubin = 0, pubout = 0, param_out = 0;
char *infile, *outfile, *prog, *engine;
char *passargin = NULL, *passargout = NULL;
char *passin = NULL, *passout = NULL;
point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
int new_form = 0;
int asn1_flag = OPENSSL_EC_NAMED_CURVE;
int new_asn1_flag = 0;
apps_startup();
if (bio_err == NULL)
if ((bio_err=BIO_new(BIO_s_file())) != NULL)
BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
if (!load_config(bio_err, NULL))
goto end;
engine = NULL;
infile = NULL;
outfile = NULL;
informat = FORMAT_PEM;
outformat = FORMAT_PEM;
prog = argv[0];
argc--;
argv++;
while (argc >= 1)
{
if (strcmp(*argv,"-inform") == 0)
{
if (--argc < 1) goto bad;
informat=str2fmt(*(++argv));
}
else if (strcmp(*argv,"-outform") == 0)
{
if (--argc < 1) goto bad;
outformat=str2fmt(*(++argv));
}
else if (strcmp(*argv,"-in") == 0)
{
if (--argc < 1) goto bad;
infile= *(++argv);
}
else if (strcmp(*argv,"-out") == 0)
{
if (--argc < 1) goto bad;
outfile= *(++argv);
}
else if (strcmp(*argv,"-passin") == 0)
{
if (--argc < 1) goto bad;
passargin= *(++argv);
}
else if (strcmp(*argv,"-passout") == 0)
{
if (--argc < 1) goto bad;
passargout= *(++argv);
}
else if (strcmp(*argv, "-engine") == 0)
{
if (--argc < 1) goto bad;
engine= *(++argv);
}
else if (strcmp(*argv, "-noout") == 0)
noout = 1;
else if (strcmp(*argv, "-text") == 0)
text = 1;
else if (strcmp(*argv, "-conv_form") == 0)
{
if (--argc < 1)
goto bad;
++argv;
new_form = 1;
if (strcmp(*argv, "compressed") == 0)
form = POINT_CONVERSION_COMPRESSED;
else if (strcmp(*argv, "uncompressed") == 0)
form = POINT_CONVERSION_UNCOMPRESSED;
else if (strcmp(*argv, "hybrid") == 0)
form = POINT_CONVERSION_HYBRID;
else
goto bad;
}
else if (strcmp(*argv, "-param_enc") == 0)
{
if (--argc < 1)
goto bad;
++argv;
new_asn1_flag = 1;
if (strcmp(*argv, "named_curve") == 0)
asn1_flag = OPENSSL_EC_NAMED_CURVE;
else if (strcmp(*argv, "explicit") == 0)
asn1_flag = 0;
else
goto bad;
}
else if (strcmp(*argv, "-param_out") == 0)
param_out = 1;
else if (strcmp(*argv, "-pubin") == 0)
pubin=1;
else if (strcmp(*argv, "-pubout") == 0)
pubout=1;
else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
{
BIO_printf(bio_err, "unknown option %s\n", *argv);
badops=1;
break;
}
argc--;
argv++;
}
if (badops)
{
bad:
BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
BIO_printf(bio_err, "where options are\n");
BIO_printf(bio_err, " -inform arg input format - "
"DER or PEM\n");
BIO_printf(bio_err, " -outform arg output format - "
"DER or PEM\n");
BIO_printf(bio_err, " -in arg input file\n");
BIO_printf(bio_err, " -passin arg input file pass "
"phrase source\n");
BIO_printf(bio_err, " -out arg output file\n");
BIO_printf(bio_err, " -passout arg output file pass "
"phrase source\n");
BIO_printf(bio_err, " -engine e use engine e, "
"possibly a hardware device.\n");
BIO_printf(bio_err, " -des encrypt PEM output, "
"instead of 'des' every other \n"
" cipher "
"supported by OpenSSL can be used\n");
BIO_printf(bio_err, " -text print the key\n");
BIO_printf(bio_err, " -noout don't print key out\n");
BIO_printf(bio_err, " -param_out print the elliptic "
"curve parameters\n");
BIO_printf(bio_err, " -conv_form arg specifies the "
"point conversion form \n");
BIO_printf(bio_err, " possible values:"
" compressed\n");
BIO_printf(bio_err, " "
" uncompressed (default)\n");
BIO_printf(bio_err, " "
" hybrid\n");
BIO_printf(bio_err, " -param_enc arg specifies the way"
" the ec parameters are encoded\n");
BIO_printf(bio_err, " in the asn1 der "
"encoding\n");
BIO_printf(bio_err, " possilbe values:"
" named_curve (default)\n");
BIO_printf(bio_err," "
"explicit\n");
goto end;
}
ERR_load_crypto_strings();
e = setup_engine(bio_err, engine, 0);
if(!app_passwd(bio_err, passargin, passargout, &passin, &passout))
{
BIO_printf(bio_err, "Error getting passwords\n");
goto end;
}
in = BIO_new(BIO_s_file());
out = BIO_new(BIO_s_file());
if ((in == NULL) || (out == NULL))
{
ERR_print_errors(bio_err);
goto end;
}
if (infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else
{
if (BIO_read_filename(in, infile) <= 0)
{
perror(infile);
goto end;
}
}
BIO_printf(bio_err, "read EC key\n");
if (informat == FORMAT_ASN1)
{
if (pubin)
eckey = d2i_EC_PUBKEY_bio(in, NULL);
else
eckey = d2i_ECPrivateKey_bio(in, NULL);
}
else if (informat == FORMAT_PEM)
{
if (pubin)
eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL,
NULL);
else
eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL,
passin);
}
else
{
BIO_printf(bio_err, "bad input format specified for key\n");
goto end;
}
if (eckey == NULL)
{
BIO_printf(bio_err,"unable to load Key\n");
ERR_print_errors(bio_err);
goto end;
}
if (outfile == NULL)
{
BIO_set_fp(out, stdout, BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
{
BIO *tmpbio = BIO_new(BIO_f_linebuffer());
out = BIO_push(tmpbio, out);
}
#endif
}
else
{
if (BIO_write_filename(out, outfile) <= 0)
{
perror(outfile);
goto end;
}
}
if (new_form)
{
EC_GROUP_set_point_conversion_form(eckey->group, form);
eckey->conv_form = form;
}
if (new_asn1_flag)
EC_GROUP_set_asn1_flag(eckey->group, asn1_flag);
if (text)
if (!EC_KEY_print(out, eckey, 0))
{
perror(outfile);
ERR_print_errors(bio_err);
goto end;
}
if (noout)
goto end;
BIO_printf(bio_err, "writing EC key\n");
if (outformat == FORMAT_ASN1)
{
if (param_out)
i = i2d_ECPKParameters_bio(out, eckey->group);
else if (pubin || pubout)
i = i2d_EC_PUBKEY_bio(out, eckey);
else
i = i2d_ECPrivateKey_bio(out, eckey);
}
else if (outformat == FORMAT_PEM)
{
if (param_out)
i = PEM_write_bio_ECPKParameters(out, eckey->group);
else if (pubin || pubout)
i = PEM_write_bio_EC_PUBKEY(out, eckey);
else
i = PEM_write_bio_ECPrivateKey(out, eckey, enc,
NULL, 0, NULL, passout);
}
else
{
BIO_printf(bio_err, "bad output format specified for "
"outfile\n");
goto end;
}
if (!i)
{
BIO_printf(bio_err, "unable to write private key\n");
ERR_print_errors(bio_err);
}
else
ret=0;
end:
if (in)
BIO_free(in);
if (out)
BIO_free_all(out);
if (eckey)
EC_KEY_free(eckey);
if (passin)
OPENSSL_free(passin);
if (passout)
OPENSSL_free(passout);
apps_shutdown();
OPENSSL_EXIT(ret);
}
#endif

709
apps/ecparam.c Normal file
View File

@@ -0,0 +1,709 @@
/* apps/ecparam.c */
/*
* Written by Nils Larsch for the OpenSSL project.
*/
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the OpenSSL open source
* license provided above.
*
* The elliptic curve binary polynomial software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
*
*/
#ifndef OPENSSL_NO_EC
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#undef PROG
#define PROG ecparam_main
/* -inform arg - input format - default PEM (DER or PEM)
* -outform arg - output format - default PEM
* -in arg - input file - default stdin
* -out arg - output file - default stdout
* -noout - do not print the ec parameter
* -text - print the ec parameters in text form
* -check - validate the ec parameters
* -C - print a 'C' function creating the parameters
* -name arg - use the ec parameters with 'short name' name
* -list_curves - prints a list of all currently available curve 'short names'
* -conv_form arg - specifies the point conversion form
* - possible values: compressed
* uncompressed (default)
* hybrid
* -param_enc arg - specifies the way the ec parameters are encoded
* in the asn1 der encoding
* possible values: named_curve (default)
* explicit
* -no_seed - if 'explicit' parameters are choosen do not use the seed
* -genkey - generate ec key
* -rand file - files to use for random number input
* -engine e - use engine e, possibly a hardware device
*/
static int ecparam_print_var(BIO *,BIGNUM *,const char *,int,unsigned char *);
int MAIN(int, char **);
int MAIN(int argc, char **argv)
{
EC_GROUP *group = NULL;
point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
int new_form = 0;
int asn1_flag = OPENSSL_EC_NAMED_CURVE;
int new_asn1_flag = 0;
char *curve_name = NULL, *inrand = NULL;
int list_curves = 0, no_seed = 0, check = 0,
badops = 0, text = 0, i, need_rand = 0, genkey = 0;
char *infile = NULL, *outfile = NULL, *prog;
BIO *in = NULL, *out = NULL;
int informat, outformat, noout = 0, C = 0, ret = 1;
ENGINE *e = NULL;
char *engine = NULL;
BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL,
*ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL;
unsigned char *buffer = NULL;
apps_startup();
if (bio_err == NULL)
if ((bio_err=BIO_new(BIO_s_file())) != NULL)
BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
if (!load_config(bio_err, NULL))
goto end;
informat=FORMAT_PEM;
outformat=FORMAT_PEM;
prog=argv[0];
argc--;
argv++;
while (argc >= 1)
{
if (strcmp(*argv,"-inform") == 0)
{
if (--argc < 1) goto bad;
informat=str2fmt(*(++argv));
}
else if (strcmp(*argv,"-outform") == 0)
{
if (--argc < 1) goto bad;
outformat=str2fmt(*(++argv));
}
else if (strcmp(*argv,"-in") == 0)
{
if (--argc < 1) goto bad;
infile= *(++argv);
}
else if (strcmp(*argv,"-out") == 0)
{
if (--argc < 1) goto bad;
outfile= *(++argv);
}
else if (strcmp(*argv,"-text") == 0)
text = 1;
else if (strcmp(*argv,"-C") == 0)
C = 1;
else if (strcmp(*argv,"-check") == 0)
check = 1;
else if (strcmp (*argv, "-name") == 0)
{
if (--argc < 1)
goto bad;
curve_name = *(++argv);
}
else if (strcmp(*argv, "-list_curves") == 0)
list_curves = 1;
else if (strcmp(*argv, "-conv_form") == 0)
{
if (--argc < 1)
goto bad;
++argv;
new_form = 1;
if (strcmp(*argv, "compressed") == 0)
form = POINT_CONVERSION_COMPRESSED;
else if (strcmp(*argv, "uncompressed") == 0)
form = POINT_CONVERSION_UNCOMPRESSED;
else if (strcmp(*argv, "hybrid") == 0)
form = POINT_CONVERSION_HYBRID;
else
goto bad;
}
else if (strcmp(*argv, "-param_enc") == 0)
{
if (--argc < 1)
goto bad;
++argv;
new_asn1_flag = 1;
if (strcmp(*argv, "named_curve") == 0)
asn1_flag = OPENSSL_EC_NAMED_CURVE;
else if (strcmp(*argv, "explicit") == 0)
asn1_flag = 0;
else
goto bad;
}
else if (strcmp(*argv, "-no_seed") == 0)
no_seed = 1;
else if (strcmp(*argv, "-noout") == 0)
noout=1;
else if (strcmp(*argv,"-genkey") == 0)
{
genkey=1;
need_rand=1;
}
else if (strcmp(*argv, "-rand") == 0)
{
if (--argc < 1) goto bad;
inrand= *(++argv);
need_rand=1;
}
else if(strcmp(*argv, "-engine") == 0)
{
if (--argc < 1) goto bad;
engine = *(++argv);
}
else
{
BIO_printf(bio_err,"unknown option %s\n",*argv);
badops=1;
break;
}
argc--;
argv++;
}
if (badops)
{
bad:
BIO_printf(bio_err, "%s [options] <infile >outfile\n",prog);
BIO_printf(bio_err, "where options are\n");
BIO_printf(bio_err, " -inform arg input format - "
"default PEM (DER or PEM)\n");
BIO_printf(bio_err, " -outform arg output format - "
"default PEM\n");
BIO_printf(bio_err, " -in arg input file - "
"default stdin\n");
BIO_printf(bio_err, " -out arg output file - "
"default stdout\n");
BIO_printf(bio_err, " -noout do not print the "
"ec parameter\n");
BIO_printf(bio_err, " -text print the ec "
"parameters in text form\n");
BIO_printf(bio_err, " -check validate the ec "
"parameters\n");
BIO_printf(bio_err, " -C print a 'C' "
"function creating the parameters\n");
BIO_printf(bio_err, " -name arg use the "
"ec parameters with 'short name' name\n");
BIO_printf(bio_err, " -list_curves prints a list of "
"all currently available curve 'short names'\n");
BIO_printf(bio_err, " -conv_form arg specifies the "
"point conversion form \n");
BIO_printf(bio_err, " possible values:"
" compressed\n");
BIO_printf(bio_err, " "
" uncompressed (default)\n");
BIO_printf(bio_err, " "
" hybrid\n");
BIO_printf(bio_err, " -param_enc arg specifies the way"
" the ec parameters are encoded\n");
BIO_printf(bio_err, " in the asn1 der "
"encoding\n");
BIO_printf(bio_err, " possible values:"
" named_curve (default)\n");
BIO_printf(bio_err, " "
" explicit\n");
BIO_printf(bio_err, " -no_seed if 'explicit'"
" parameters are choosen do not"
" use the seed\n");
BIO_printf(bio_err, " -genkey generate ec"
" key\n");
BIO_printf(bio_err, " -rand file files to use for"
" random number input\n");
BIO_printf(bio_err, " -engine e use engine e, "
"possibly a hardware device\n");
goto end;
}
ERR_load_crypto_strings();
in=BIO_new(BIO_s_file());
out=BIO_new(BIO_s_file());
if ((in == NULL) || (out == NULL))
{
ERR_print_errors(bio_err);
goto end;
}
if (infile == NULL)
BIO_set_fp(in,stdin,BIO_NOCLOSE);
else
{
if (BIO_read_filename(in,infile) <= 0)
{
perror(infile);
goto end;
}
}
if (outfile == NULL)
{
BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
{
BIO *tmpbio = BIO_new(BIO_f_linebuffer());
out = BIO_push(tmpbio, out);
}
#endif
}
else
{
if (BIO_write_filename(out,outfile) <= 0)
{
perror(outfile);
goto end;
}
}
e = setup_engine(bio_err, engine, 0);
if (list_curves)
{
EC_builtin_curve *curves = NULL;
size_t crv_len = 0;
size_t n = 0;
size_t len;
crv_len = EC_get_builtin_curves(NULL, 0);
curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
if (curves == NULL)
goto end;
if (!EC_get_builtin_curves(curves, crv_len))
{
OPENSSL_free(curves);
goto end;
}
for (n = 0; n < crv_len; n++)
{
const char *comment;
const char *sname;
comment = curves[n].comment;
sname = OBJ_nid2sn(curves[n].nid);
if (comment == NULL)
comment = "CURVE DESCRIPTION NOT AVAILABLE";
if (sname == NULL)
sname = "";
len = BIO_printf(out, " %-10s: ", sname);
if (len + strlen(comment) > 80)
BIO_printf(out, "\n%80s\n", comment);
else
BIO_printf(out, "%s\n", comment);
}
OPENSSL_free(curves);
ret = 0;
goto end;
}
if (curve_name != NULL)
{
int nid = OBJ_sn2nid(curve_name);
if (nid == 0)
{
BIO_printf(bio_err, "unknown curve name (%s)\n",
curve_name);
goto end;
}
group = EC_GROUP_new_by_nid(nid);
if (group == NULL)
{
BIO_printf(bio_err, "unable to create curve (%s)\n",
curve_name);
goto end;
}
EC_GROUP_set_asn1_flag(group, asn1_flag);
EC_GROUP_set_point_conversion_form(group, form);
}
else if (informat == FORMAT_ASN1)
{
group = d2i_ECPKParameters_bio(in, NULL);
}
else if (informat == FORMAT_PEM)
{
group = PEM_read_bio_ECPKParameters(in,NULL,NULL,NULL);
}
else
{
BIO_printf(bio_err, "bad input format specified\n");
goto end;
}
if (group == NULL)
{
BIO_printf(bio_err,
"unable to load elliptic curve parameters\n");
ERR_print_errors(bio_err);
goto end;
}
if (new_form)
EC_GROUP_set_point_conversion_form(group, form);
if (new_asn1_flag)
EC_GROUP_set_asn1_flag(group, asn1_flag);
if (no_seed)
{
EC_GROUP_set_seed(group, NULL, 0);
}
if (text)
{
if (!ECPKParameters_print(out, group, 0))
goto end;
}
if (check)
{
if (group == NULL)
BIO_printf(bio_err, "no elliptic curve parameters\n");
BIO_printf(bio_err, "checking elliptic curve parameters: ");
if (!EC_GROUP_check(group, NULL))
{
BIO_printf(bio_err, "failed\n");
ERR_print_errors(bio_err);
}
else
BIO_printf(bio_err, "ok\n");
}
if (C)
{
size_t buf_len = 0, tmp_len = 0;
const EC_POINT *point;
int is_prime, len = 0;
const EC_METHOD *meth = EC_GROUP_method_of(group);
if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL ||
(ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL ||
(ec_order = BN_new()) == NULL ||
(ec_cofactor = BN_new()) == NULL )
{
perror("OPENSSL_malloc");
goto end;
}
is_prime = (EC_METHOD_get_field_type(meth) ==
NID_X9_62_prime_field);
if (is_prime)
{
if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a,
ec_b, NULL))
goto end;
}
else
{
/* TODO */
goto end;
}
if ((point = EC_GROUP_get0_generator(group)) == NULL)
goto end;
if (!EC_POINT_point2bn(group, point,
EC_GROUP_get_point_conversion_form(group), ec_gen,
NULL))
goto end;
if (!EC_GROUP_get_order(group, ec_order, NULL))
goto end;
if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
goto end;
if (!ec_p || !ec_a || !ec_b || !ec_gen ||
!ec_order || !ec_cofactor)
goto end;
len = BN_num_bits(ec_order);
if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len)
buf_len = tmp_len;
if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len)
buf_len = tmp_len;
if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len)
buf_len = tmp_len;
if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len)
buf_len = tmp_len;
if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len)
buf_len = tmp_len;
if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len)
buf_len = tmp_len;
buffer = (unsigned char *)OPENSSL_malloc(buf_len);
if (buffer == NULL)
{
perror("OPENSSL_malloc");
goto end;
}
ecparam_print_var(out, ec_p, "ec_p", len, buffer);
ecparam_print_var(out, ec_a, "ec_a", len, buffer);
ecparam_print_var(out, ec_b, "ec_b", len, buffer);
ecparam_print_var(out, ec_gen, "ec_gen", len, buffer);
ecparam_print_var(out, ec_order, "ec_order", len, buffer);
ecparam_print_var(out, ec_cofactor, "ec_cofactor", len,
buffer);
BIO_printf(out, "\n\n");
BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len);
BIO_printf(out, "\tint ok=0;\n");
BIO_printf(out, "\tEC_GROUP *group = NULL;\n");
BIO_printf(out, "\tEC_POINT *point = NULL;\n");
BIO_printf(out, "\tBIGNUM *tmp_1 = NULL, *tmp_2 = NULL, "
"*tmp_3 = NULL;\n\n");
BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, "
"sizeof(ec_p_%d), NULL)) == NULL)\n\t\t"
"goto err;\n", len, len);
BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, "
"sizeof(ec_a_%d), NULL)) == NULL)\n\t\t"
"goto err;\n", len, len);
BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, "
"sizeof(ec_b_%d), NULL)) == NULL)\n\t\t"
"goto err;\n", len, len);
if (is_prime)
{
BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
"GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
"\n\t\tgoto err;\n\n");
}
else
{
/* TODO */
goto end;
}
BIO_printf(out, "\t/* build generator */\n");
BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, "
"sizeof(ec_gen_%d), tmp_1)) == NULL)"
"\n\t\tgoto err;\n", len, len);
BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, "
"NULL, NULL);\n");
BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n");
BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, "
"sizeof(ec_order_%d), tmp_2)) == NULL)"
"\n\t\tgoto err;\n", len, len);
BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, "
"sizeof(ec_cofactor_%d), tmp_3)) == NULL)"
"\n\t\tgoto err;\n", len, len);
BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point,"
" tmp_2, tmp_3))\n\t\tgoto err;\n");
BIO_printf(out, "\n\tok=1;\n");
BIO_printf(out, "err:\n");
BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n");
BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n");
BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n");
BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n");
BIO_printf(out, "\tif (!ok)\n");
BIO_printf(out, "\t\t{\n");
BIO_printf(out, "\t\tEC_GROUP_free(group);\n");
BIO_printf(out, "\t\tgroup = NULL;\n");
BIO_printf(out, "\t\t}\n");
BIO_printf(out, "\treturn(group);\n\t}\n");
}
if (!noout)
{
if (outformat == FORMAT_ASN1)
i = i2d_ECPKParameters_bio(out, group);
else if (outformat == FORMAT_PEM)
i = PEM_write_bio_ECPKParameters(out, group);
else
{
BIO_printf(bio_err,"bad output format specified for"
" outfile\n");
goto end;
}
if (!i)
{
BIO_printf(bio_err, "unable to write elliptic "
"curve parameters\n");
ERR_print_errors(bio_err);
goto end;
}
}
if (need_rand)
{
app_RAND_load_file(NULL, bio_err, (inrand != NULL));
if (inrand != NULL)
BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
}
if (genkey)
{
EC_KEY *eckey = EC_KEY_new();
if (eckey == NULL)
goto end;
assert(need_rand);
eckey->group = group;
if (!EC_KEY_generate_key(eckey))
{
eckey->group = NULL;
EC_KEY_free(eckey);
goto end;
}
if (outformat == FORMAT_ASN1)
i = i2d_ECPrivateKey_bio(out, eckey);
else if (outformat == FORMAT_PEM)
i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
NULL, 0, NULL, NULL);
else
{
BIO_printf(bio_err, "bad output format specified "
"for outfile\n");
eckey->group = NULL;
EC_KEY_free(eckey);
goto end;
}
eckey->group = NULL;
EC_KEY_free(eckey);
}
if (need_rand)
app_RAND_write_file(NULL, bio_err);
ret=0;
end:
if (ec_p)
BN_free(ec_p);
if (ec_a)
BN_free(ec_a);
if (ec_b)
BN_free(ec_b);
if (ec_gen)
BN_free(ec_gen);
if (ec_order)
BN_free(ec_order);
if (ec_cofactor)
BN_free(ec_cofactor);
if (buffer)
OPENSSL_free(buffer);
if (in != NULL)
BIO_free(in);
if (out != NULL)
BIO_free_all(out);
if (group != NULL)
EC_GROUP_free(group);
apps_shutdown();
OPENSSL_EXIT(ret);
}
int ecparam_print_var(BIO *out, BIGNUM *in, const char *var,
int len, unsigned char *buffer)
{
BIO_printf(out, "static unsigned char %s_%d[] = {", var, len);
if (BN_is_zero(in))
BIO_printf(out, "\n\t0x00");
else
{
int i, l;
l = BN_bn2bin(in, buffer);
for (i=0; i<l-1; i++)
{
if ((i%12) == 0)
BIO_printf(out, "\n\t");
BIO_printf(out, "0x%02X,", buffer[i]);
}
if ((i%12) == 0)
BIO_printf(out, "\n\t");
BIO_printf(out, "0x%02X", buffer[i]);
}
BIO_printf(out, "\n\t};\n\n");
return 1;
}
#endif

View File

@@ -139,13 +139,13 @@ $! Define The Application Files.
$!
$ LIB_FILES = "VERIFY;ASN1PARS;REQ;DGST;DH;DHPARAM;ENC;PASSWD;GENDH;ERRSTR;"+-
"CA;PKCS7;CRL2P7;CRL;"+-
"RSA;RSAUTL;DSA;DSAPARAM;"+-
"RSA;RSAUTL;DSA;DSAPARAM;EC;ECPARAM;"+-
"X509;GENRSA;GENDSA;S_SERVER;S_CLIENT;SPEED;"+-
"S_TIME;APPS;S_CB;S_SOCKET;APP_RAND;VERSION;SESS_ID;"+-
"CIPHERS;NSEQ;PKCS12;PKCS8;SPKAC;SMIME;RAND;ENGINE;OCSP"
$ APP_FILES := OPENSSL,'OBJ_DIR'VERIFY.OBJ,ASN1PARS.OBJ,REQ.OBJ,DGST.OBJ,DH.OBJ,DHPARAM.OBJ,ENC.OBJ,PASSWD.OBJ,GENDH.OBJ,ERRSTR.OBJ,-
CA.OBJ,PKCS7.OBJ,CRL2P7.OBJ,CRL.OBJ,-
RSA.OBJ,RSAUTL.OBJ,DSA.OBJ,DSAPARAM.OBJ,-
RSA.OBJ,RSAUTL.OBJ,DSA.OBJ,DSAPARAM.OBJ,EC.OBJ,ECPARAM.OBJ,-
X509.OBJ,GENRSA.OBJ,GENDSA.OBJ,S_SERVER.OBJ,S_CLIENT.OBJ,SPEED.OBJ,-
S_TIME.OBJ,APPS.OBJ,S_CB.OBJ,S_SOCKET.OBJ,APP_RAND.OBJ,VERSION.OBJ,SESS_ID.OBJ,-
CIPHERS.OBJ,NSEQ.OBJ,PKCS12.OBJ,PKCS8.OBJ,SPKAC.OBJ,SMIME.OBJ,RAND.OBJ,ENGINE.OBJ,OCSP.OBJ
@@ -166,7 +166,7 @@ $! TCPIP_PROGRAMS = ",S_SERVER,S_CLIENT,SESS_ID,CIPHERS,S_TIME,"
$!
$! Setup exceptional compilations
$!
$ COMPILEWITH_CC2 = ",S_SERVER,S_CLIENT,"
$ COMPILEWITH_CC2 = ",S_SOCKET,S_SERVER,S_CLIENT,"
$!
$ PHASE := LIB
$!

View File

@@ -2,10 +2,10 @@
#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
* project 1999.
* project.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
* Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -164,10 +164,14 @@ int MAIN(int argc, char **argv)
maciter = PKCS12_DEFAULT_ITER;
else if (!strcmp (*args, "-nomaciter"))
maciter = 1;
else if (!strcmp (*args, "-nomac"))
maciter = -1;
else if (!strcmp (*args, "-nodes")) enc=NULL;
else if (!strcmp (*args, "-certpbe")) {
if (args[1]) {
args++;
if (!strcmp(*args, "NONE"))
cert_pbe = -1;
cert_pbe=OBJ_txt2nid(*args);
if(cert_pbe == NID_undef) {
BIO_printf(bio_err,
@@ -178,7 +182,10 @@ int MAIN(int argc, char **argv)
} else if (!strcmp (*args, "-keypbe")) {
if (args[1]) {
args++;
key_pbe=OBJ_txt2nid(*args);
if (!strcmp(*args, "NONE"))
key_pbe = -1;
else
key_pbe=OBJ_txt2nid(*args);
if(key_pbe == NID_undef) {
BIO_printf(bio_err,
"Unknown PBE algorithm %s\n", *args);
@@ -357,24 +364,6 @@ int MAIN(int argc, char **argv)
goto end;
}
#if 0
if (certfile) {
if(!(certsin = BIO_new_file(certfile, "r"))) {
BIO_printf(bio_err, "Can't open certificate file %s\n", certfile);
perror (certfile);
goto end;
}
}
if (keyname) {
if(!(inkey = BIO_new_file(keyname, "r"))) {
BIO_printf(bio_err, "Can't key certificate file %s\n", keyname);
perror (keyname);
goto end;
}
}
#endif
#ifdef CRYPTO_MDEBUG
CRYPTO_pop_info();
CRYPTO_push_info("write files");
@@ -411,27 +400,31 @@ int MAIN(int argc, char **argv)
if (export_cert) {
EVP_PKEY *key = NULL;
STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
STACK_OF(PKCS7) *safes = NULL;
PKCS12_SAFEBAG *bag = NULL;
PKCS8_PRIV_KEY_INFO *p8 = NULL;
PKCS7 *authsafe = NULL;
X509 *ucert = NULL;
X509 *ucert = NULL, *x = NULL;
STACK_OF(X509) *certs=NULL;
char *catmp = NULL;
unsigned char *catmp = NULL;
int i;
unsigned char keyid[EVP_MAX_MD_SIZE];
unsigned int keyidlen = 0;
if ((options & (NOCERTS|NOKEYS)) == (NOCERTS|NOKEYS))
{
BIO_printf(bio_err, "Nothing to do!\n");
goto export_end;
}
if (options & NOCERTS)
chain = 0;
#ifdef CRYPTO_MDEBUG
CRYPTO_push_info("process -export_cert");
CRYPTO_push_info("reading private key");
#endif
key = load_key(bio_err, keyname ? keyname : infile, FORMAT_PEM, 1,
passin, e, "private key");
if (!key) {
goto export_end;
}
if (!(options & NOKEYS))
{
key = load_key(bio_err, keyname ? keyname : infile,
FORMAT_PEM, 1, passin, e, "private key");
if (!key)
goto export_end;
}
#ifdef CRYPTO_MDEBUG
CRYPTO_pop_info();
@@ -439,50 +432,62 @@ int MAIN(int argc, char **argv)
#endif
/* Load in all certs in input file */
if(!(certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
"certificates"))) {
goto export_end;
}
if(!(options & NOCERTS))
{
certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
"certificates");
if (!certs)
goto export_end;
if (key)
{
/* Look for matching private key */
for(i = 0; i < sk_X509_num(certs); i++)
{
x = sk_X509_value(certs, i);
if(X509_check_private_key(x, key))
{
ucert = x;
/* Zero keyid and alias */
X509_keyid_set1(ucert, NULL, 0);
X509_alias_set1(ucert, NULL, 0);
/* Remove from list */
sk_X509_delete(certs, i);
break;
}
}
if (!ucert)
{
BIO_printf(bio_err, "No certificate matches private key\n");
goto export_end;
}
}
}
#ifdef CRYPTO_MDEBUG
CRYPTO_pop_info();
CRYPTO_push_info("reading certs from input 2");
#endif
for(i = 0; i < sk_X509_num(certs); i++) {
ucert = sk_X509_value(certs, i);
if(X509_check_private_key(ucert, key)) {
X509_digest(ucert, EVP_sha1(), keyid, &keyidlen);
break;
}
}
if(!keyidlen) {
ucert = NULL;
BIO_printf(bio_err, "No certificate matches private key\n");
goto export_end;
}
/* Add any more certificates asked for */
if(certfile)
{
STACK_OF(X509) *morecerts=NULL;
if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
NULL, e,
"certificates from certfile")))
goto export_end;
while(sk_X509_num(morecerts) > 0)
sk_X509_push(certs, sk_X509_shift(morecerts));
sk_X509_free(morecerts);
}
#ifdef CRYPTO_MDEBUG
CRYPTO_pop_info();
CRYPTO_push_info("reading certs from certfile");
#endif
bags = sk_PKCS12_SAFEBAG_new_null ();
/* Add any more certificates asked for */
if (certfile) {
STACK_OF(X509) *morecerts=NULL;
if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
NULL, e,
"certificates from certfile"))) {
goto export_end;
}
while(sk_X509_num(morecerts) > 0) {
sk_X509_push(certs, sk_X509_shift(morecerts));
}
sk_X509_free(morecerts);
}
#ifdef CRYPTO_MDEBUG
CRYPTO_pop_info();
CRYPTO_push_info("building chain");
@@ -518,100 +523,51 @@ int MAIN(int argc, char **argv)
}
}
#ifdef CRYPTO_MDEBUG
CRYPTO_pop_info();
CRYPTO_push_info("building bags");
#endif
/* Add any CA names */
/* We now have loads of certificates: include them all */
for(i = 0; i < sk_X509_num(certs); i++) {
X509 *cert = NULL;
cert = sk_X509_value(certs, i);
bag = PKCS12_x5092certbag(cert);
/* If it matches private key set id */
if(cert == ucert) {
if(name) PKCS12_add_friendlyname(bag, name, -1);
PKCS12_add_localkeyid(bag, keyid, keyidlen);
} else if((catmp = sk_shift(canames)))
PKCS12_add_friendlyname(bag, catmp, -1);
sk_PKCS12_SAFEBAG_push(bags, bag);
}
sk_X509_pop_free(certs, X509_free);
certs = NULL;
for (i = 0; i < sk_num(canames); i++)
{
catmp = (unsigned char *)sk_value(canames, i);
X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
}
#ifdef CRYPTO_MDEBUG
CRYPTO_pop_info();
CRYPTO_push_info("encrypting bags");
CRYPTO_push_info("reading password");
#endif
if(!noprompt &&
EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1)) {
BIO_printf (bio_err, "Can't read Password\n");
goto export_end;
}
EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", 1))
{
BIO_printf (bio_err, "Can't read Password\n");
goto export_end;
}
if (!twopass) strcpy(macpass, pass);
/* Turn certbags into encrypted authsafe */
authsafe = PKCS12_pack_p7encdata(cert_pbe, cpass, -1, NULL, 0,
iter, bags);
sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
bags = NULL;
if (!authsafe) {
ERR_print_errors (bio_err);
#ifdef CRYPTO_MDEBUG
CRYPTO_pop_info();
CRYPTO_push_info("creating PKCS#12 structure");
#endif
p12 = PKCS12_create(pass, name, key, ucert, certs,
key_pbe, cert_pbe, iter, -1, keytype);
if (!p12)
{
ERR_print_errors (bio_err);
goto export_end;
}
}
safes = sk_PKCS7_new_null ();
sk_PKCS7_push (safes, authsafe);
#ifdef CRYPTO_MDEBUG
CRYPTO_pop_info();
CRYPTO_push_info("building shrouded key bag");
#endif
/* Make a shrouded key bag */
p8 = EVP_PKEY2PKCS8 (key);
if(keytype) PKCS8_add_keyusage(p8, keytype);
bag = PKCS12_MAKE_SHKEYBAG(key_pbe, cpass, -1, NULL, 0, iter, p8);
PKCS8_PRIV_KEY_INFO_free(p8);
p8 = NULL;
if (name) PKCS12_add_friendlyname (bag, name, -1);
if(csp_name) PKCS12_add_CSPName_asc(bag, csp_name, -1);
PKCS12_add_localkeyid (bag, keyid, keyidlen);
bags = sk_PKCS12_SAFEBAG_new_null();
sk_PKCS12_SAFEBAG_push (bags, bag);
#ifdef CRYPTO_MDEBUG
CRYPTO_pop_info();
CRYPTO_push_info("encrypting shrouded key bag");
#endif
/* Turn it into unencrypted safe bag */
authsafe = PKCS12_pack_p7data (bags);
sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
bags = NULL;
sk_PKCS7_push (safes, authsafe);
#ifdef CRYPTO_MDEBUG
CRYPTO_pop_info();
CRYPTO_push_info("building pkcs12");
#endif
p12 = PKCS12_init(NID_pkcs7_data);
PKCS12_pack_authsafes(p12, safes);
sk_PKCS7_pop_free(safes, PKCS7_free);
safes = NULL;
PKCS12_set_mac (p12, mpass, -1, NULL, 0, maciter, NULL);
if (maciter != -1)
PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, NULL);
#ifdef CRYPTO_MDEBUG
CRYPTO_pop_info();
CRYPTO_push_info("writing pkcs12");
#endif
i2d_PKCS12_bio (out, p12);
i2d_PKCS12_bio(out, p12);
ret = 0;
@@ -624,8 +580,7 @@ int MAIN(int argc, char **argv)
if (key) EVP_PKEY_free(key);
if (certs) sk_X509_pop_free(certs, X509_free);
if (safes) sk_PKCS7_pop_free(safes, PKCS7_free);
if (bags) sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
if (ucert) X509_free(ucert);
#ifdef CRYPTO_MDEBUG
CRYPTO_pop_info();

View File

@@ -17,6 +17,8 @@ extern int rsa_main(int argc,char *argv[]);
extern int rsautl_main(int argc,char *argv[]);
extern int dsa_main(int argc,char *argv[]);
extern int dsaparam_main(int argc,char *argv[]);
extern int ec_main(int argc,char *argv[]);
extern int ecparam_main(int argc,char *argv[]);
extern int x509_main(int argc,char *argv[]);
extern int genrsa_main(int argc,char *argv[]);
extern int gendsa_main(int argc,char *argv[]);
@@ -78,6 +80,12 @@ FUNCTION functions[] = {
#endif
#ifndef OPENSSL_NO_DSA
{FUNC_TYPE_GENERAL,"dsaparam",dsaparam_main},
#endif
#ifndef OPENSSL_NO_EC
{FUNC_TYPE_GENERAL,"ec",ec_main},
#endif
#ifndef OPENSSL_NO_EC
{FUNC_TYPE_GENERAL,"ecparam",ecparam_main},
#endif
{FUNC_TYPE_GENERAL,"x509",x509_main},
#ifndef OPENSSL_NO_RSA

View File

@@ -33,6 +33,8 @@ foreach (@ARGV)
{ print "#ifndef OPENSSL_NO_RSA\n${str}#endif\n"; }
elsif ( ($_ =~ /^dsa$/) || ($_ =~ /^gendsa$/) || ($_ =~ /^dsaparam$/))
{ print "#ifndef OPENSSL_NO_DSA\n${str}#endif\n"; }
elsif ( ($_ =~ /^ec$/) || ($_ =~ /^ecparam$/))
{ print "#ifndef OPENSSL_NO_EC\n${str}#endif\n";}
elsif ( ($_ =~ /^dh$/) || ($_ =~ /^gendh$/) || ($_ =~ /^dhparam$/))
{ print "#ifndef OPENSSL_NO_DH\n${str}#endif\n"; }
elsif ( ($_ =~ /^pkcs12$/))

View File

@@ -135,6 +135,7 @@ static int req_check_len(int len,int n_min,int n_max);
static int check_end(char *str, char *end);
#ifndef MONOLITH
static char *default_config_file=NULL;
static CONF *config=NULL;
#endif
static CONF *req_conf=NULL;
static int batch=0;
@@ -142,6 +143,7 @@ static int batch=0;
#define TYPE_RSA 1
#define TYPE_DSA 2
#define TYPE_DH 3
#define TYPE_EC 4
int MAIN(int, char **);
@@ -150,6 +152,9 @@ int MAIN(int argc, char **argv)
ENGINE *e = NULL;
#ifndef OPENSSL_NO_DSA
DSA *dsa_params=NULL;
#endif
#ifndef OPENSSL_NO_ECDSA
EC_KEY *ec_params = NULL;
#endif
unsigned long nmflag = 0, reqflag = 0;
int ex=1,x509=0,days=30;
@@ -318,11 +323,59 @@ int MAIN(int argc, char **argv)
}
}
BIO_free(in);
newkey=BN_num_bits(dsa_params->p);
in=NULL;
newkey=BN_num_bits(dsa_params->p);
}
else
#endif
#ifndef OPENSSL_NO_ECDSA
if (strncmp("ec:",p,3) == 0)
{
X509 *xtmp=NULL;
EVP_PKEY *dtmp;
pkey_type=TYPE_EC;
p+=3;
if ((in=BIO_new_file(p,"r")) == NULL)
{
perror(p);
goto end;
}
if ((ec_params = EC_KEY_new()) == NULL)
goto end;
if ((ec_params->group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL)) == NULL)
{
if (ec_params)
EC_KEY_free(ec_params);
ERR_clear_error();
(void)BIO_reset(in);
if ((xtmp=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
{
BIO_printf(bio_err,"unable to load EC parameters from file\n");
goto end;
}
if ((dtmp=X509_get_pubkey(xtmp))==NULL)
goto end;
if (dtmp->type == EVP_PKEY_EC)
ec_params = ECParameters_dup(dtmp->pkey.eckey);
EVP_PKEY_free(dtmp);
X509_free(xtmp);
if (ec_params == NULL)
{
BIO_printf(bio_err,"Certificate does not contain EC parameters\n");
goto end;
}
}
BIO_free(in);
in=NULL;
newkey = EC_GROUP_get_degree(ec_params->group);
}
else
#endif
#ifndef OPENSSL_NO_DH
if (strncmp("dh:",p,4) == 0)
{
@@ -331,7 +384,9 @@ int MAIN(int argc, char **argv)
}
else
#endif
pkey_type=TYPE_RSA;
{
goto bad;
}
newreq=1;
}
@@ -439,6 +494,9 @@ bad:
BIO_printf(bio_err," the random number generator\n");
BIO_printf(bio_err," -newkey rsa:bits generate a new RSA key of 'bits' in size\n");
BIO_printf(bio_err," -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n");
#ifndef OPENSSL_NO_ECDSA
BIO_printf(bio_err," -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n");
#endif
BIO_printf(bio_err," -[digest] Digest to sign with (md5, sha1, md2, mdc2, md4)\n");
BIO_printf(bio_err," -config file request template file.\n");
BIO_printf(bio_err," -subj arg set or modify request subject\n");
@@ -629,7 +687,8 @@ bad:
message */
goto end;
}
if (EVP_PKEY_type(pkey->type) == EVP_PKEY_DSA)
if (EVP_PKEY_type(pkey->type) == EVP_PKEY_DSA ||
EVP_PKEY_type(pkey->type) == EVP_PKEY_EC)
{
char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE");
if (randfile == NULL)
@@ -653,14 +712,15 @@ bad:
newkey=DEFAULT_KEY_LENGTH;
}
if (newkey < MIN_KEY_LENGTH)
if (newkey < MIN_KEY_LENGTH && (pkey_type == TYPE_RSA || pkey_type == TYPE_DSA))
{
BIO_printf(bio_err,"private key length is too short,\n");
BIO_printf(bio_err,"it needs to be at least %d bits, not %d\n",MIN_KEY_LENGTH,newkey);
goto end;
}
BIO_printf(bio_err,"Generating a %d bit %s private key\n",
newkey,(pkey_type == TYPE_RSA)?"RSA":"DSA");
newkey,(pkey_type == TYPE_RSA)?"RSA":
(pkey_type == TYPE_DSA)?"DSA":"EC");
if ((pkey=EVP_PKEY_new()) == NULL) goto end;
@@ -682,6 +742,15 @@ bad:
dsa_params=NULL;
}
#endif
#ifndef OPENSSL_NO_ECDSA
if (pkey_type == TYPE_EC)
{
if (!EC_KEY_generate_key(ec_params)) goto end;
if (!EVP_PKEY_assign_EC_KEY(pkey, ec_params))
goto end;
ec_params = NULL;
}
#endif
app_RAND_write_file(randfile, bio_err);
@@ -787,6 +856,10 @@ loop:
#ifndef OPENSSL_NO_DSA
if (pkey->type == EVP_PKEY_DSA)
digest=EVP_dss1();
#endif
#ifndef OPENSSL_NO_ECDSA
if (pkey->type == EVP_PKEY_EC)
digest=EVP_ecdsa();
#endif
if (req == NULL)
{
@@ -1072,6 +1145,9 @@ end:
OBJ_cleanup();
#ifndef OPENSSL_NO_DSA
if (dsa_params != NULL) DSA_free(dsa_params);
#endif
#ifndef OPENSSL_NO_ECDSA
if (ec_params != NULL) EC_KEY_free(ec_params);
#endif
apps_shutdown();
OPENSSL_EXIT(ex);

View File

@@ -108,6 +108,11 @@
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* ECC cipher suite support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
#include <assert.h>
#include <stdio.h>
@@ -172,6 +177,7 @@ static int generate_session_id(const SSL *ssl, unsigned char *id,
static DH *load_dh_param(char *dhfile);
static DH *get_dh512(void);
#endif
#ifdef MONOLITH
static void s_server_init(void);
#endif
@@ -210,6 +216,7 @@ static DH *get_dh512(void)
}
#endif
/* static int load_CA(SSL_CTX *ctx, char *file);*/
#undef BUFSIZZ
@@ -287,6 +294,11 @@ static void sv_usage(void)
BIO_printf(bio_err," -dkey arg - second private key file to use (usually for DSA)\n");
BIO_printf(bio_err," -dhparam arg - DH parameter file to use, in cert file if not specified\n");
BIO_printf(bio_err," or a default set of parameters is used\n");
#ifndef OPENSSL_NO_ECDH
BIO_printf(bio_err," -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \
" Use \"openssl ecparam -list_curves\" for all names\n" \
" (default is sect163r2).\n");
#endif
#ifdef FIONBIO
BIO_printf(bio_err," -nbio - Run with non-blocking IO\n");
#endif
@@ -310,6 +322,9 @@ static void sv_usage(void)
BIO_printf(bio_err," -no_tls1 - Just disable TLSv1\n");
#ifndef OPENSSL_NO_DH
BIO_printf(bio_err," -no_dhe - Disable ephemeral DH\n");
#endif
#ifndef OPENSSL_NO_ECDH
BIO_printf(bio_err," -no_ecdhe - Disable ephemeral ECDH\n");
#endif
BIO_printf(bio_err," -bugs - Turn on SSL bug compatibility\n");
BIO_printf(bio_err," -www - Respond to a 'GET /' with a status page\n");
@@ -484,10 +499,11 @@ int MAIN(int argc, char *argv[])
char *CApath=NULL,*CAfile=NULL;
char *context = NULL;
char *dhfile = NULL;
char *named_curve = NULL;
int badop=0,bugs=0;
int ret=1;
int off=0;
int no_tmp_rsa=0,no_dhe=0,nocert=0;
int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
int state=0;
SSL_METHOD *meth=NULL;
ENGINE *e=NULL;
@@ -568,6 +584,13 @@ int MAIN(int argc, char *argv[])
if (--argc < 1) goto bad;
dhfile = *(++argv);
}
#ifndef OPENSSL_NO_ECDH
else if (strcmp(*argv,"-named_curve") == 0)
{
if (--argc < 1) goto bad;
named_curve = *(++argv);
}
#endif
else if (strcmp(*argv,"-dcert") == 0)
{
if (--argc < 1) goto bad;
@@ -636,6 +659,8 @@ int MAIN(int argc, char *argv[])
{ no_tmp_rsa=1; }
else if (strcmp(*argv,"-no_dhe") == 0)
{ no_dhe=1; }
else if (strcmp(*argv,"-no_ecdhe") == 0)
{ no_ecdhe=1; }
else if (strcmp(*argv,"-www") == 0)
{ www=1; }
else if (strcmp(*argv,"-WWW") == 0)
@@ -718,7 +743,7 @@ bad:
}
}
#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA)
#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
if (nocert)
#endif
{
@@ -806,6 +831,59 @@ bad:
DH_free(dh);
}
#endif
#ifndef OPENSSL_NO_ECDH
if (!no_ecdhe)
{
EC_KEY *ecdh=NULL;
ecdh = EC_KEY_new();
if (ecdh == NULL)
{
BIO_printf(bio_err,"Could not create ECDH struct.\n");
goto end;
}
if (named_curve)
{
int nid = OBJ_sn2nid(named_curve);
if (nid == 0)
{
BIO_printf(bio_err, "unknown curve name (%s)\n",
named_curve);
goto end;
}
ecdh->group = EC_GROUP_new_by_nid(nid);
if (ecdh->group == NULL)
{
BIO_printf(bio_err, "unable to create curve (%s)\n",
named_curve);
goto end;
}
}
if (ecdh->group != NULL)
{
BIO_printf(bio_s_out,"Setting temp ECDH parameters\n");
}
else
{
BIO_printf(bio_s_out,"Using default temp ECDH parameters\n");
ecdh->group=EC_GROUP_new_by_nid(NID_sect163r2);
if (ecdh->group == NULL)
{
BIO_printf(bio_err, "unable to create curve (sect163r2)\n");
goto end;
}
}
(void)BIO_flush(bio_s_out);
SSL_CTX_set_tmp_ecdh(ctx,ecdh);
EC_KEY_free(ecdh);
}
#endif
if (!set_cert_stuff(ctx,s_cert_file,s_key_file))
goto end;

View File

@@ -62,8 +62,6 @@
#include <errno.h>
#include <signal.h>
#include <openssl/e_os2.h>
/* With IPv6, it looks like Digital has mixed up the proper order of
recursive header file inclusion, resulting in the compiler complaining
that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
@@ -81,6 +79,14 @@ typedef unsigned int u_int;
#include "s_apps.h"
#include <openssl/ssl.h>
#ifdef FLAT_INC
#include "e_os.h"
#else
#include "../e_os.h"
#endif
#ifndef OPENSSL_NO_SOCK
static struct hostent *GetHostByName(char *name);
#ifdef OPENSSL_SYS_WINDOWS
static void ssl_sock_cleanup(void);
@@ -553,3 +559,5 @@ static struct hostent *GetHostByName(char *name)
return(ret);
}
}
#endif

View File

@@ -55,6 +55,19 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the OpenSSL open source
* license provided above.
*
* The ECDH and ECDSA speed test software is originally written by
* Sumit Gupta of Sun Microsystems Laboratories.
*
*/
/* most of this code has been pilfered from my libdes speed.c program */
@@ -62,6 +75,8 @@
#define SECONDS 3
#define RSA_SECONDS 10
#define DSA_SECONDS 10
#define ECDSA_SECONDS 10
#define ECDH_SECONDS 10
/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */
/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */
@@ -184,6 +199,12 @@
#ifndef OPENSSL_NO_DSA
#include "./testdsa.h"
#endif
#ifndef OPENSSL_NO_ECDSA
#include <openssl/ecdsa.h>
#endif
#ifndef OPENSSL_NO_ECDH
#include <openssl/ecdh.h>
#endif
/* The following if from times(3) man page. It may need to be changed */
#ifndef HZ
@@ -227,6 +248,10 @@ static int do_multi(int multi);
#define SIZE_NUM 5
#define RSA_NUM 4
#define DSA_NUM 3
#define EC_NUM 16
#define MAX_ECDH_SIZE 256
static const char *names[ALGOR_NUM]={
"md2","mdc2","md4","md5","hmac(md5)","sha1","rmd160","rc4",
"des cbc","des ede3","idea cbc",
@@ -236,6 +261,9 @@ static double results[ALGOR_NUM][SIZE_NUM];
static int lengths[SIZE_NUM]={16,64,256,1024,8*1024};
static double rsa_results[RSA_NUM][2];
static double dsa_results[DSA_NUM][2];
static double ecdsa_results[EC_NUM][2];
static double ecdh_results[EC_NUM][1];
#ifdef SIGALRM
#if defined(__STDC__) || defined(sgi) || defined(_AIX)
@@ -478,6 +506,24 @@ int MAIN(int argc, char **argv)
#define R_RSA_1024 1
#define R_RSA_2048 2
#define R_RSA_4096 3
#define R_EC_P160 0
#define R_EC_P192 1
#define R_EC_P224 2
#define R_EC_P256 3
#define R_EC_P384 4
#define R_EC_P521 5
#define R_EC_K163 6
#define R_EC_K233 7
#define R_EC_K283 8
#define R_EC_K409 9
#define R_EC_K571 10
#define R_EC_B163 11
#define R_EC_B233 12
#define R_EC_B283 13
#define R_EC_B409 14
#define R_EC_B571 15
#ifndef OPENSSL_NO_RSA
RSA *rsa_key[RSA_NUM];
long rsa_c[RSA_NUM][2];
@@ -493,8 +539,83 @@ int MAIN(int argc, char **argv)
long dsa_c[DSA_NUM][2];
static unsigned int dsa_bits[DSA_NUM]={512,1024,2048};
#endif
#ifndef OPENSSL_NO_EC
/* We only test over the following curves as they are representative,
* To add tests over more curves, simply add the curve NID
* and curve name to the following arrays and increase the
* EC_NUM value accordingly.
*/
static unsigned int test_curves[EC_NUM] =
{
/* Prime Curves */
NID_secp160r1,
NID_X9_62_prime192v1,
NID_secp224r1,
NID_X9_62_prime256v1,
NID_secp384r1,
NID_secp521r1,
/* Binary Curves */
NID_sect163k1,
NID_sect233k1,
NID_sect283k1,
NID_sect409k1,
NID_sect571k1,
NID_sect163r2,
NID_sect233r1,
NID_sect283r1,
NID_sect409r1,
NID_sect571r1
};
static char * test_curves_names[EC_NUM] =
{
/* Prime Curves */
"secp160r1",
"nistp192",
"nistp224",
"nistp256",
"nistp384",
"nistp521",
/* Binary Curves */
"nistk163",
"nistk233",
"nistk283",
"nistk409",
"nistk571",
"nistb163",
"nistb233",
"nistb283",
"nistb409",
"nistb571"
};
static int test_curves_bits[EC_NUM] =
{
160, 192, 224, 256, 384, 521,
163, 233, 283, 409, 571,
163, 233, 283, 409, 571
};
#endif
#ifndef OPENSSL_NO_ECDSA
unsigned char ecdsasig[256];
unsigned int ecdsasiglen;
EC_KEY *ecdsa[EC_NUM];
long ecdsa_c[EC_NUM][2];
#endif
#ifndef OPENSSL_NO_ECDH
EC_KEY *ecdh_a[EC_NUM], *ecdh_b[EC_NUM];
unsigned char secret_a[MAX_ECDH_SIZE], secret_b[MAX_ECDH_SIZE];
int secret_size_a, secret_size_b;
int ecdh_checks = 0;
int secret_idx = 0;
long ecdh_c[EC_NUM][2];
#endif
int rsa_doit[RSA_NUM];
int dsa_doit[DSA_NUM];
int ecdsa_doit[EC_NUM];
int ecdh_doit[EC_NUM];
int doit[ALGOR_NUM];
int pr_header=0;
const EVP_CIPHER *evp_cipher=NULL;
@@ -513,6 +634,17 @@ int MAIN(int argc, char **argv)
#ifndef OPENSSL_NO_DSA
memset(dsa_key,0,sizeof(dsa_key));
#endif
#ifndef OPENSSL_NO_ECDSA
for (i=0; i<EC_NUM; i++) ecdsa[i] = NULL;
#endif
#ifndef OPENSSL_NO_ECDH
for (i=0; i<EC_NUM; i++)
{
ecdh_a[i] = NULL;
ecdh_b[i] = NULL;
}
#endif
if (bio_err == NULL)
if ((bio_err=BIO_new(BIO_s_file())) != NULL)
@@ -551,6 +683,15 @@ int MAIN(int argc, char **argv)
rsa_doit[i]=0;
for (i=0; i<DSA_NUM; i++)
dsa_doit[i]=0;
#ifndef OPENSSL_NO_ECDSA
for (i=0; i<EC_NUM; i++)
ecdsa_doit[i]=0;
#endif
#ifndef OPENSSL_NO_ECDH
for (i=0; i<EC_NUM; i++)
ecdh_doit[i]=0;
#endif
j=0;
argc--;
@@ -769,6 +910,52 @@ int MAIN(int argc, char **argv)
dsa_doit[R_DSA_1024]=1;
}
else
#endif
#ifndef OPENSSL_NO_ECDSA
if (strcmp(*argv,"ecdsap160") == 0) ecdsa_doit[R_EC_P160]=2;
else if (strcmp(*argv,"ecdsap224") == 0) ecdsa_doit[R_EC_P224]=2;
else if (strcmp(*argv,"ecdsap256") == 0) ecdsa_doit[R_EC_P256]=2;
else if (strcmp(*argv,"ecdsap384") == 0) ecdsa_doit[R_EC_P384]=2;
else if (strcmp(*argv,"ecdsap521") == 0) ecdsa_doit[R_EC_P521]=2;
else if (strcmp(*argv,"ecdsak163") == 0) ecdsa_doit[R_EC_K163]=2;
else if (strcmp(*argv,"ecdsak233") == 0) ecdsa_doit[R_EC_K233]=2;
else if (strcmp(*argv,"ecdsak283") == 0) ecdsa_doit[R_EC_K283]=2;
else if (strcmp(*argv,"ecdsak409") == 0) ecdsa_doit[R_EC_K409]=2;
else if (strcmp(*argv,"ecdsak571") == 0) ecdsa_doit[R_EC_K571]=2;
else if (strcmp(*argv,"ecdsab163") == 0) ecdsa_doit[R_EC_B163]=2;
else if (strcmp(*argv,"ecdsab233") == 0) ecdsa_doit[R_EC_B233]=2;
else if (strcmp(*argv,"ecdsab283") == 0) ecdsa_doit[R_EC_B283]=2;
else if (strcmp(*argv,"ecdsab409") == 0) ecdsa_doit[R_EC_B409]=2;
else if (strcmp(*argv,"ecdsab571") == 0) ecdsa_doit[R_EC_B571]=2;
else if (strcmp(*argv,"ecdsa") == 0)
{
for (i=0; i < EC_NUM; i++)
ecdsa_doit[i]=1;
}
else
#endif
#ifndef OPENSSL_NO_ECDH
if (strcmp(*argv,"ecdhp160") == 0) ecdh_doit[R_EC_P160]=2;
else if (strcmp(*argv,"ecdhp224") == 0) ecdh_doit[R_EC_P224]=2;
else if (strcmp(*argv,"ecdhp256") == 0) ecdh_doit[R_EC_P256]=2;
else if (strcmp(*argv,"ecdhp384") == 0) ecdh_doit[R_EC_P384]=2;
else if (strcmp(*argv,"ecdhp521") == 0) ecdh_doit[R_EC_P521]=2;
else if (strcmp(*argv,"ecdhk163") == 0) ecdh_doit[R_EC_K163]=2;
else if (strcmp(*argv,"ecdhk233") == 0) ecdh_doit[R_EC_K233]=2;
else if (strcmp(*argv,"ecdhk283") == 0) ecdh_doit[R_EC_K283]=2;
else if (strcmp(*argv,"ecdhk409") == 0) ecdh_doit[R_EC_K409]=2;
else if (strcmp(*argv,"ecdhk571") == 0) ecdh_doit[R_EC_K571]=2;
else if (strcmp(*argv,"ecdhb163") == 0) ecdh_doit[R_EC_B163]=2;
else if (strcmp(*argv,"ecdhb233") == 0) ecdh_doit[R_EC_B233]=2;
else if (strcmp(*argv,"ecdhb283") == 0) ecdh_doit[R_EC_B283]=2;
else if (strcmp(*argv,"ecdhb409") == 0) ecdh_doit[R_EC_B409]=2;
else if (strcmp(*argv,"ecdhb571") == 0) ecdh_doit[R_EC_B571]=2;
else if (strcmp(*argv,"ecdh") == 0)
{
for (i=0; i < EC_NUM; i++)
ecdh_doit[i]=1;
}
else
#endif
{
BIO_printf(bio_err,"Error: bad option or value\n");
@@ -835,6 +1022,18 @@ int MAIN(int argc, char **argv)
#ifndef OPENSSL_NO_DSA
BIO_printf(bio_err,"dsa512 dsa1024 dsa2048\n");
#endif
#ifndef OPENSSL_NO_ECDSA
BIO_printf(bio_err,"ecdsap160 ecdsap224 ecdsap256 ecdsap384 ecdsap521\n");
BIO_printf(bio_err,"ecdsak163 ecdsak233 ecdsak283 ecdsak409 ecdsak571\n");
BIO_printf(bio_err,"ecdsab163 ecdsab233 ecdsab283 ecdsab409 ecdsab571\n");
BIO_printf(bio_err,"ecdsa\n");
#endif
#ifndef OPENSSL_NO_ECDH
BIO_printf(bio_err,"ecdhp160 ecdhp224 ecdhp256 ecdhp384 ecdhp521\n");
BIO_printf(bio_err,"ecdhk163 ecdhk233 ecdhk283 ecdhk409 ecdhk571\n");
BIO_printf(bio_err,"ecdhb163 ecdhb233 ecdhb283 ecdhb409 ecdhb571\n");
BIO_printf(bio_err,"ecdh\n");
#endif
#ifndef OPENSSL_NO_IDEA
BIO_printf(bio_err,"idea ");
@@ -1064,6 +1263,114 @@ int MAIN(int argc, char **argv)
}
#endif
#ifndef OPENSSL_NO_ECDSA
ecdsa_c[R_EC_P160][0]=count/1000;
ecdsa_c[R_EC_P160][1]=count/1000/2;
for (i=R_EC_P224; i<=R_EC_P521; i++)
{
ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
ecdsa_doit[i]=0;
else
{
if (ecdsa_c[i] == 0)
{
ecdsa_c[i][0]=1;
ecdsa_c[i][1]=1;
}
}
}
ecdsa_c[R_EC_K163][0]=count/1000;
ecdsa_c[R_EC_K163][1]=count/1000/2;
for (i=R_EC_K233; i<=R_EC_K571; i++)
{
ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
ecdsa_doit[i]=0;
else
{
if (ecdsa_c[i] == 0)
{
ecdsa_c[i][0]=1;
ecdsa_c[i][1]=1;
}
}
}
ecdsa_c[R_EC_B163][0]=count/1000;
ecdsa_c[R_EC_B163][1]=count/1000/2;
for (i=R_EC_B233; i<=R_EC_B571; i++)
{
ecdsa_c[i][0]=ecdsa_c[i-1][0]/2;
ecdsa_c[i][1]=ecdsa_c[i-1][1]/2;
if ((ecdsa_doit[i] <= 1) && (ecdsa_c[i][0] == 0))
ecdsa_doit[i]=0;
else
{
if (ecdsa_c[i] == 0)
{
ecdsa_c[i][0]=1;
ecdsa_c[i][1]=1;
}
}
}
#endif
#ifndef OPENSSL_NO_ECDH
ecdh_c[R_EC_P160][0]=count/1000;
ecdh_c[R_EC_P160][1]=count/1000;
for (i=R_EC_P224; i<=R_EC_P521; i++)
{
ecdh_c[i][0]=ecdh_c[i-1][0]/2;
ecdh_c[i][1]=ecdh_c[i-1][1]/2;
if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
ecdh_doit[i]=0;
else
{
if (ecdh_c[i] == 0)
{
ecdh_c[i][0]=1;
ecdh_c[i][1]=1;
}
}
}
ecdh_c[R_EC_K163][0]=count/1000;
ecdh_c[R_EC_K163][1]=count/1000;
for (i=R_EC_K233; i<=R_EC_K571; i++)
{
ecdh_c[i][0]=ecdh_c[i-1][0]/2;
ecdh_c[i][1]=ecdh_c[i-1][1]/2;
if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
ecdh_doit[i]=0;
else
{
if (ecdh_c[i] == 0)
{
ecdh_c[i][0]=1;
ecdh_c[i][1]=1;
}
}
}
ecdh_c[R_EC_B163][0]=count/1000;
ecdh_c[R_EC_B163][1]=count/1000;
for (i=R_EC_B233; i<=R_EC_B571; i++)
{
ecdh_c[i][0]=ecdh_c[i-1][0]/2;
ecdh_c[i][1]=ecdh_c[i-1][1]/2;
if ((ecdh_doit[i] <= 1) && (ecdh_c[i][0] == 0))
ecdh_doit[i]=0;
else
{
if (ecdh_c[i] == 0)
{
ecdh_c[i][0]=1;
ecdh_c[i][1]=1;
}
}
}
#endif
#define COND(d) (count < (d))
#define COUNT(d) (d)
#else
@@ -1588,6 +1895,220 @@ int MAIN(int argc, char **argv)
}
if (rnd_fake) RAND_cleanup();
#endif
#ifndef OPENSSL_NO_ECDSA
if (RAND_status() != 1)
{
RAND_seed(rnd_seed, sizeof rnd_seed);
rnd_fake = 1;
}
for (j=0; j<EC_NUM; j++)
{
int ret;
if (!ecdsa_doit[j]) continue; /* Ignore Curve */
ecdsa[j] = EC_KEY_new();
if (ecdsa[j] == NULL)
{
BIO_printf(bio_err,"ECDSA failure.\n");
ERR_print_errors(bio_err);
rsa_count=1;
}
else
{
ecdsa[j]->group = EC_GROUP_new_by_nid(test_curves[j]);
/* Could not obtain group information */
if (ecdsa[j]->group == NULL)
{
BIO_printf(bio_err,"ECDSA failure.Could not obtain group information\n");
ERR_print_errors(bio_err);
rsa_count=1;
}
else
{
/* Perform ECDSA signature test */
EC_KEY_generate_key(ecdsa[j]);
ret = ECDSA_sign(0, buf, 20, ecdsasig,
&ecdsasiglen, ecdsa[j]);
if (ret == 0)
{
BIO_printf(bio_err,"ECDSA sign failure. No ECDSA sign will be done.\n");
ERR_print_errors(bio_err);
rsa_count=1;
}
else
{
pkey_print_message("sign","ecdsa",
ecdsa_c[j][0],
test_curves_bits[j],
ECDSA_SECONDS);
Time_F(START);
for (count=0,run=1; COND(ecdsa_c[j][0]);
count++)
{
ret=ECDSA_sign(0, buf, 20,
ecdsasig, &ecdsasiglen,
ecdsa[j]);
if (ret == 0)
{
BIO_printf(bio_err, "ECDSA sign failure\n");
ERR_print_errors(bio_err);
count=1;
break;
}
}
d=Time_F(STOP);
BIO_printf(bio_err, mr ? "+R5:%ld:%d:%.2f\n" :
"%ld %d bit ECDSA signs in %.2fs \n",
count, test_curves_bits[j], d);
ecdsa_results[j][0]=d/(double)count;
rsa_count=count;
}
/* Perform ECDSA verification test */
ret=ECDSA_verify(0, buf, 20, ecdsasig,
ecdsasiglen, ecdsa[j]);
if (ret != 1)
{
BIO_printf(bio_err,"ECDSA verify failure. No ECDSA verify will be done.\n");
ERR_print_errors(bio_err);
ecdsa_doit[j] = 0;
}
else
{
pkey_print_message("verify","ecdsa",
ecdsa_c[j][1],
test_curves_bits[j],
ECDSA_SECONDS);
Time_F(START);
for (count=0,run=1; COND(ecdsa_c[j][1]); count++)
{
ret=ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[j]);
if (ret != 1)
{
BIO_printf(bio_err, "ECDSA verify failure\n");
ERR_print_errors(bio_err);
count=1;
break;
}
}
d=Time_F(STOP);
BIO_printf(bio_err, mr? "+R6:%ld:%d:%.2f\n"
: "%ld %d bit ECDSA verify in %.2fs\n",
count, test_curves_bits[j], d);
ecdsa_results[j][1]=d/(double)count;
}
if (rsa_count <= 1)
{
/* if longer than 10s, don't do any more */
for (j++; j<EC_NUM; j++)
ecdsa_doit[j]=0;
}
}
}
}
if (rnd_fake) RAND_cleanup();
#endif
#ifndef OPENSSL_NO_ECDH
if (RAND_status() != 1)
{
RAND_seed(rnd_seed, sizeof rnd_seed);
rnd_fake = 1;
}
for (j=0; j<EC_NUM; j++)
{
if (!ecdh_doit[j]) continue;
ecdh_a[j] = EC_KEY_new();
ecdh_b[j] = EC_KEY_new();
if ((ecdh_a[j] == NULL) || (ecdh_b[j] == NULL))
{
BIO_printf(bio_err,"ECDH failure.\n");
ERR_print_errors(bio_err);
rsa_count=1;
}
else
{
ecdh_a[j]->group = EC_GROUP_new_by_nid(test_curves[j]);
if (ecdh_a[j]->group == NULL)
{
BIO_printf(bio_err,"ECDH failure.\n");
ERR_print_errors(bio_err);
rsa_count=1;
}
else
{
ecdh_b[j]->group = ecdh_a[j]->group;
/* generate two ECDH key pairs */
if (!EC_KEY_generate_key(ecdh_a[j]) ||
!EC_KEY_generate_key(ecdh_b[j]))
{
BIO_printf(bio_err,"ECDH key generation failure.\n");
ERR_print_errors(bio_err);
rsa_count=1;
}
else
{
secret_size_a = ECDH_compute_key(secret_a,
ecdh_b[j]->pub_key,
ecdh_a[j]);
secret_size_b = ECDH_compute_key(secret_b,
ecdh_a[j]->pub_key,
ecdh_b[j]);
if (secret_size_a != secret_size_b)
ecdh_checks = 0;
else
ecdh_checks = 1;
for (secret_idx = 0;
(secret_idx < secret_size_a)
&& (ecdh_checks == 1);
secret_idx++)
{
if (secret_a[secret_idx] != secret_b[secret_idx])
ecdh_checks = 0;
}
if (ecdh_checks == 0)
{
BIO_printf(bio_err,"ECDH computations don't match.\n");
ERR_print_errors(bio_err);
rsa_count=1;
}
pkey_print_message("","ecdh",
ecdh_c[j][0],
test_curves_bits[j],
ECDH_SECONDS);
Time_F(START);
for (count=0,run=1; COND(ecdh_c[j][0]); count++)
{
ECDH_compute_key(secret_a,
ecdh_b[j]->pub_key,
ecdh_a[j]);
}
d=Time_F(STOP);
BIO_printf(bio_err, mr ? "+R7:%ld:%d:%.2f\n" :"%ld %d-bit ECDH ops in %.2fs\n",
count, test_curves_bits[j], d);
ecdh_results[j][0]=d/(double)count;
rsa_count=count;
}
}
}
if (rsa_count <= 1)
{
/* if longer than 10s, don't do any more */
for (j++; j<EC_NUM; j++)
ecdh_doit[j]=0;
}
}
if (rnd_fake) RAND_cleanup();
#endif
#ifdef HAVE_FORK
show_res:
#endif
@@ -1713,7 +2234,57 @@ show_res:
1.0/dsa_results[k][0],1.0/dsa_results[k][1]);
}
#endif
#ifndef OPENSSL_NO_ECDSA
j=1;
for (k=0; k<EC_NUM; k++)
{
if (!ecdsa_doit[k]) continue;
if (j && !mr)
{
printf("%30ssign verify sign/s verify/s\n"," ");
j=0;
}
if (mr)
fprintf(stdout,"+F4:%u:%u:%f:%f\n",
k, test_curves_bits[k],
ecdsa_results[k][0],ecdsa_results[k][1]);
else
fprintf(stdout,
"%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
test_curves_bits[k],
test_curves_names[k],
ecdsa_results[k][0],ecdsa_results[k][1],
1.0/ecdsa_results[k][0],1.0/ecdsa_results[k][1]);
}
#endif
#ifndef OPENSSL_NO_ECDH
j=1;
for (k=0; k<EC_NUM; k++)
{
if (!ecdh_doit[k]) continue;
if (j && !mr)
{
printf("%30sop op/s\n"," ");
j=0;
}
if (mr)
fprintf(stdout,"+F5:%u:%u:%f:%f\n",
k, test_curves_bits[k],
ecdh_results[k][0], 1.0/ecdh_results[k][0]);
else
fprintf(stdout,"%4u bit ecdh (%s) %8.4fs %8.1f\n",
test_curves_bits[k],
test_curves_names[k],
ecdh_results[k][0], 1.0/ecdh_results[k][0]);
}
#endif
mret=0;
end:
ERR_print_errors(bio_err);
if (buf != NULL) OPENSSL_free(buf);
@@ -1728,6 +2299,22 @@ end:
if (dsa_key[i] != NULL)
DSA_free(dsa_key[i]);
#endif
#ifndef OPENSSL_NO_ECDSA
for (i=0; i<EC_NUM; i++)
if (ecdsa[i] != NULL)
EC_KEY_free(ecdsa[i]);
#endif
#ifndef OPENSSL_NO_ECDH
for (i=0; i<EC_NUM; i++)
{
if (ecdh_a[i] != NULL)
EC_KEY_free(ecdh_a[i]);
if (ecdh_b[i] != NULL)
EC_KEY_free(ecdh_b[i]);
}
#endif
apps_shutdown();
OPENSSL_EXIT(mret);
}
@@ -1929,6 +2516,49 @@ static int do_multi(int multi)
else
dsa_results[k][1]=d;
}
#ifndef OPENSSL_NO_ECDSA
else if(!strncmp(buf,"+F4:",4))
{
int k;
double d;
p=buf+4;
k=atoi(sstrsep(&p,sep));
sstrsep(&p,sep);
d=atof(sstrsep(&p,sep));
if(n)
ecdsa_results[k][0]=1/(1/ecdsa_results[k][0]+1/d);
else
ecdsa_results[k][0]=d;
d=atof(sstrsep(&p,sep));
if(n)
ecdsa_results[k][1]=1/(1/ecdsa_results[k][1]+1/d);
else
ecdsa_results[k][1]=d;
}
#endif
#ifndef OPENSSL_NO_ECDH
else if(!strncmp(buf,"+F5:",4))
{
int k;
double d;
p=buf+4;
k=atoi(sstrsep(&p,sep));
sstrsep(&p,sep);
d=atof(sstrsep(&p,sep));
if(n)
ecdh_results[k][0]=1/(1/ecdh_results[k][0]+1/d);
else
ecdh_results[k][0]=d;
}
#endif
else if(!strncmp(buf,"+H:",3))
{
}

View File

@@ -172,7 +172,19 @@ int MAIN(int argc, char **argv)
}
}
if (version) printf("%s\n",SSLeay_version(SSLEAY_VERSION));
if (version)
{
if (SSLeay() == SSLEAY_VERSION_NUMBER)
{
printf("%s\n",SSLeay_version(SSLEAY_VERSION));
}
else
{
printf("%s (Library: %s)\n",
OPENSSL_VERSION_TEXT,
SSLeay_version(SSLEAY_VERSION));
}
}
if (date) printf("%s\n",SSLeay_version(SSLEAY_BUILT_ON));
if (platform) printf("%s\n",SSLeay_version(SSLEAY_PLATFORM));
if (options)

View File

@@ -870,6 +870,10 @@ bad:
if (Upkey->type == EVP_PKEY_DSA)
digest=EVP_dss1();
#endif
#ifndef OPENSSL_NO_ECDSA
if (Upkey->type == EVP_PKEY_EC)
digest=EVP_ecdsa();
#endif
assert(need_rand);
if (!sign(x,Upkey,days,clrext,digest,
@@ -890,6 +894,10 @@ bad:
if (CApkey->type == EVP_PKEY_DSA)
digest=EVP_dss1();
#endif
#ifndef OPENSSL_NO_ECDSA
if (CApkey->type == EVP_PKEY_EC)
digest = EVP_ecdsa();
#endif
assert(need_rand);
if (!x509_certify(ctx,CAfile,digest,x,xca,
@@ -921,6 +929,10 @@ bad:
if (pk->type == EVP_PKEY_DSA)
digest=EVP_dss1();
#endif
#ifndef OPENSSL_NO_ECDSA
if (pk->type == EVP_PKEY_EC)
digest=EVP_ecdsa();
#endif
rq=X509_to_X509_REQ(x,pk,digest);
EVP_PKEY_free(pk);

View File

@@ -28,7 +28,7 @@ LIBS=
SDIRS= md2 md5 sha mdc2 hmac ripemd \
des rc2 rc4 rc5 idea bf cast \
bn ec rsa dsa dh dso engine aes \
bn ec rsa dsa ecdsa ecdh dh dso engine aes \
buffer bio stack lhash rand err objects \
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5
@@ -141,7 +141,7 @@ depend:
@for i in $(SDIRS) ;\
do \
(cd $$i && echo "making depend in crypto/$$i..." && \
$(MAKE) MAKEFILE='${MAKEFILE}' INCLUDES='${INCLUDES}' CFLAG='${CFLAG}' DEPFLAG='${DEPFLAG}' MAKEDEPPROG='${MAKEDEPPROG}' KRB5_INCLUDES='${KRB5_INCLUDES}' PERL='${PERL}' depend ); \
$(MAKE) MAKEFILE='${MAKEFILE}' INCLUDES='${INCLUDES}' CFLAG='${CFLAG}' DEPFLAG='${DEPFLAG}' PERL='${PERL}' depend ); \
done;
clean:

View File

@@ -56,9 +56,8 @@
#error AES is disabled.
#endif
#define AES_ENCRYPT 1
#define AES_DECRYPT 0
static const int AES_DECRYPT = 0;
static const int AES_ENCRYPT = 1;
/* Because array size can't be a const in C, the following two are macros.
Both sizes are in bytes. */
#define AES_MAXNR 14

View File

@@ -72,7 +72,7 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
if (AES_ENCRYPT == enc) {
while (len >= AES_BLOCK_SIZE) {
for(n=0; n < sizeof tmp; ++n)
for(n=0; n < AES_BLOCK_SIZE; ++n)
tmp[n] = in[n] ^ ivec[n];
AES_encrypt(tmp, out, key);
memcpy(ivec, out, AES_BLOCK_SIZE);
@@ -87,11 +87,11 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
tmp[n] = ivec[n];
AES_encrypt(tmp, tmp, key);
memcpy(out, tmp, len);
memcpy(ivec, tmp, sizeof tmp);
memcpy(ivec, tmp, AES_BLOCK_SIZE);
}
} else {
while (len >= AES_BLOCK_SIZE) {
memcpy(tmp, in, sizeof tmp);
memcpy(tmp, in, AES_BLOCK_SIZE);
AES_decrypt(in, out, key);
for(n=0; n < AES_BLOCK_SIZE; ++n)
out[n] ^= ivec[n];
@@ -101,11 +101,11 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
out += AES_BLOCK_SIZE;
}
if (len) {
memcpy(tmp, in, sizeof tmp);
memcpy(tmp, in, AES_BLOCK_SIZE);
AES_decrypt(tmp, tmp, key);
for(n=0; n < len; ++n)
out[n] ^= ivec[n];
memcpy(ivec, tmp, sizeof tmp);
memcpy(ivec, tmp, AES_BLOCK_SIZE);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -147,7 +147,7 @@ ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_NESTED_ASN1_ERROR);
goto err;
}
if(bn->neg) ret->type = V_ASN1_NEG_ENUMERATED;
if(BN_get_sign(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
else ret->type=V_ASN1_ENUMERATED;
j=BN_num_bits(bn);
len=((j == 0)?0:((j/8)+1));
@@ -175,6 +175,6 @@ BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN,ASN1_R_BN_LIB);
else if(ai->type == V_ASN1_NEG_ENUMERATED) ret->neg = 1;
else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_sign(ret,1);
return(ret);
}

View File

@@ -393,7 +393,8 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai)
ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_NESTED_ASN1_ERROR);
goto err;
}
if(bn->neg) ret->type = V_ASN1_NEG_INTEGER;
if (BN_get_sign(bn))
ret->type = V_ASN1_NEG_INTEGER;
else ret->type=V_ASN1_INTEGER;
j=BN_num_bits(bn);
len=((j == 0)?0:((j/8)+1));
@@ -426,7 +427,8 @@ BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai, BIGNUM *bn)
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
ASN1err(ASN1_F_ASN1_INTEGER_TO_BN,ASN1_R_BN_LIB);
else if(ai->type == V_ASN1_NEG_INTEGER) ret->neg = 1;
else if(ai->type == V_ASN1_NEG_INTEGER)
BN_set_sign(ret, 1);
return(ret);
}

View File

@@ -191,6 +191,11 @@ typedef struct asn1_object_st
} ASN1_OBJECT;
#define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */
/* This indicates that the ASN1_STRING is not a real value but just a place
* holder for the location where indefinite length constructed data should
* be inserted in the memory buffer
*/
#define ASN1_STRING_FLAG_NDEF 0x010
/* This is the base type that holds just about everything :-) */
typedef struct asn1_string_st
{
@@ -279,6 +284,9 @@ typedef struct ASN1_VALUE_st ASN1_VALUE;
int i2d_##name(const type *a, unsigned char **out); \
DECLARE_ASN1_ITEM(name)
#define DECLARE_ASN1_NDEF_FUNCTION(name) \
int i2d_##name##_NDEF(name *a, unsigned char **out);
#define DECLARE_ASN1_FUNCTIONS_const(name) \
name *name##_new(void); \
void name##_free(name *a);
@@ -792,6 +800,8 @@ DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
int ASN1_TIME_check(ASN1_TIME *t);
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
@@ -848,6 +858,7 @@ int ASN1_get_object(unsigned char **pp, long *plength, int *ptag,
int ASN1_check_infinite_end(unsigned char **p,long len);
void ASN1_put_object(unsigned char **pp, int constructed, int length,
int tag, int xclass);
int ASN1_put_eoc(unsigned char **pp);
int ASN1_object_size(int constructed, int length, int tag);
/* Used to implement other functions */
@@ -934,9 +945,13 @@ ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_ITEM *it);
int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
void ASN1_add_oid_module(void);
ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
@@ -950,6 +965,8 @@ void ERR_load_ASN1_strings(void);
#define ASN1_F_A2I_ASN1_ENUMERATED 101
#define ASN1_F_A2I_ASN1_INTEGER 102
#define ASN1_F_A2I_ASN1_STRING 103
#define ASN1_F_APPEND_TAG 177
#define ASN1_F_ASN1_CB 178
#define ASN1_F_ASN1_CHECK_TLEN 104
#define ASN1_F_ASN1_COLLATE_PRIMITIVE 105
#define ASN1_F_ASN1_COLLECT 106
@@ -960,6 +977,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_F_ASN1_DUP 111
#define ASN1_F_ASN1_ENUMERATED_SET 112
#define ASN1_F_ASN1_ENUMERATED_TO_BN 113
#define ASN1_F_ASN1_GENERATE_V3 182
#define ASN1_F_ASN1_GET_OBJECT 114
#define ASN1_F_ASN1_HEADER_NEW 115
#define ASN1_F_ASN1_I2D_BIO 116
@@ -975,6 +993,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_F_ASN1_SEQ_PACK 126
#define ASN1_F_ASN1_SEQ_UNPACK 127
#define ASN1_F_ASN1_SIGN 128
#define ASN1_F_ASN1_STR2TYPE 179
#define ASN1_F_ASN1_STRING_TABLE_ADD 129
#define ASN1_F_ASN1_STRING_TYPE_NEW 130
#define ASN1_F_ASN1_TEMPLATE_D2I 131
@@ -984,6 +1003,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135
#define ASN1_F_ASN1_UNPACK_STRING 136
#define ASN1_F_ASN1_VERIFY 137
#define ASN1_F_BITSTR_CB 180
#define ASN1_F_BN_TO_ASN1_ENUMERATED 138
#define ASN1_F_BN_TO_ASN1_INTEGER 139
#define ASN1_F_COLLECT_DATA 140
@@ -1008,12 +1028,15 @@ void ERR_load_ASN1_strings(void);
#define ASN1_F_D2I_X509_PKEY 159
#define ASN1_F_I2D_ASN1_TIME 160
#define ASN1_F_I2D_DSA_PUBKEY 161
#define ASN1_F_I2D_ECDSA_PUBKEY 174
#define ASN1_F_I2D_EC_PUBKEY 176
#define ASN1_F_I2D_NETSCAPE_RSA 162
#define ASN1_F_I2D_PRIVATEKEY 163
#define ASN1_F_I2D_PUBLICKEY 164
#define ASN1_F_I2D_RSA_PUBKEY 165
#define ASN1_F_LONG_C2I 166
#define ASN1_F_OID_MODULE_INIT 174
#define ASN1_F_OID_MODULE_INIT 175
#define ASN1_F_PARSE_TAGGING 181
#define ASN1_F_PKCS5_PBE2_SET 167
#define ASN1_F_X509_CINF_NEW 168
#define ASN1_F_X509_CRL_ADD0_REVOKED 169
@@ -1036,6 +1059,7 @@ void ERR_load_ASN1_strings(void);
#define ASN1_R_DATA_IS_WRONG 109
#define ASN1_R_DECODE_ERROR 110
#define ASN1_R_DECODING_ERROR 111
#define ASN1_R_DEPTH_EXCEEDED 173
#define ASN1_R_ENCODE_ERROR 112
#define ASN1_R_ERROR_LOADING_SECTION 172
#define ASN1_R_ERROR_PARSING_SET_ELEMENT 113
@@ -1049,38 +1073,57 @@ void ERR_load_ASN1_strings(void);
#define ASN1_R_FIELD_MISSING 121
#define ASN1_R_FIRST_NUM_TOO_LARGE 122
#define ASN1_R_HEADER_TOO_LONG 123
#define ASN1_R_ILLEGAL_BITSTRING_FORMAT 174
#define ASN1_R_ILLEGAL_BOOLEAN 175
#define ASN1_R_ILLEGAL_CHARACTERS 124
#define ASN1_R_ILLEGAL_FORMAT 176
#define ASN1_R_ILLEGAL_HEX 177
#define ASN1_R_ILLEGAL_IMPLICIT_TAG 178
#define ASN1_R_ILLEGAL_INTEGER 179
#define ASN1_R_ILLEGAL_NESTED_TAGGING 180
#define ASN1_R_ILLEGAL_NULL 125
#define ASN1_R_ILLEGAL_NULL_VALUE 181
#define ASN1_R_ILLEGAL_OBJECT 182
#define ASN1_R_ILLEGAL_OPTIONAL_ANY 126
#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170
#define ASN1_R_ILLEGAL_TAGGED_ANY 127
#define ASN1_R_ILLEGAL_TIME_VALUE 183
#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 184
#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
#define ASN1_R_INVALID_BMPSTRING_LENGTH 129
#define ASN1_R_INVALID_DIGIT 130
#define ASN1_R_INVALID_MODIFIER 185
#define ASN1_R_INVALID_NUMBER 186
#define ASN1_R_INVALID_SEPARATOR 131
#define ASN1_R_INVALID_TIME_FORMAT 132
#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133
#define ASN1_R_INVALID_UTF8STRING 134
#define ASN1_R_IV_TOO_LARGE 135
#define ASN1_R_LENGTH_ERROR 136
#define ASN1_R_LIST_ERROR 187
#define ASN1_R_MISSING_EOC 137
#define ASN1_R_MISSING_SECOND_NUMBER 138
#define ASN1_R_MISSING_VALUE 188
#define ASN1_R_MSTRING_NOT_UNIVERSAL 139
#define ASN1_R_MSTRING_WRONG_TAG 140
#define ASN1_R_NON_HEX_CHARACTERS 141
#define ASN1_R_NOT_ASCII_FORMAT 189
#define ASN1_R_NOT_ENOUGH_DATA 142
#define ASN1_R_NO_MATCHING_CHOICE_TYPE 143
#define ASN1_R_NULL_IS_WRONG_LENGTH 144
#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 190
#define ASN1_R_ODD_NUMBER_OF_CHARS 145
#define ASN1_R_PRIVATE_KEY_HEADER_MISSING 146
#define ASN1_R_SECOND_NUMBER_TOO_LARGE 147
#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148
#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149
#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 195
#define ASN1_R_SHORT_LINE 150
#define ASN1_R_STRING_TOO_LONG 151
#define ASN1_R_STRING_TOO_SHORT 152
#define ASN1_R_TAG_VALUE_TOO_HIGH 153
#define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154
#define ASN1_R_TIME_NOT_ASCII_FORMAT 191
#define ASN1_R_TOO_LONG 155
#define ASN1_R_TYPE_NOT_CONSTRUCTED 156
#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157
@@ -1090,10 +1133,13 @@ void ERR_load_ASN1_strings(void);
#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161
#define ASN1_R_UNKNOWN_OBJECT_TYPE 162
#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163
#define ASN1_R_UNKNOWN_TAG 192
#define ASN1_R_UNKOWN_FORMAT 193
#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164
#define ASN1_R_UNSUPPORTED_CIPHER 165
#define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166
#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167
#define ASN1_R_UNSUPPORTED_TYPE 194
#define ASN1_R_WRONG_TAG 168
#define ASN1_R_WRONG_TYPE 169

View File

@@ -1,6 +1,6 @@
/* crypto/asn1/asn1_err.c */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
* Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -70,6 +70,8 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_PACK(0,ASN1_F_A2I_ASN1_ENUMERATED,0), "a2i_ASN1_ENUMERATED"},
{ERR_PACK(0,ASN1_F_A2I_ASN1_INTEGER,0), "a2i_ASN1_INTEGER"},
{ERR_PACK(0,ASN1_F_A2I_ASN1_STRING,0), "a2i_ASN1_STRING"},
{ERR_PACK(0,ASN1_F_APPEND_TAG,0), "APPEND_TAG"},
{ERR_PACK(0,ASN1_F_ASN1_CB,0), "ASN1_CB"},
{ERR_PACK(0,ASN1_F_ASN1_CHECK_TLEN,0), "ASN1_CHECK_TLEN"},
{ERR_PACK(0,ASN1_F_ASN1_COLLATE_PRIMITIVE,0), "ASN1_COLLATE_PRIMITIVE"},
{ERR_PACK(0,ASN1_F_ASN1_COLLECT,0), "ASN1_COLLECT"},
@@ -80,6 +82,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_PACK(0,ASN1_F_ASN1_DUP,0), "ASN1_dup"},
{ERR_PACK(0,ASN1_F_ASN1_ENUMERATED_SET,0), "ASN1_ENUMERATED_set"},
{ERR_PACK(0,ASN1_F_ASN1_ENUMERATED_TO_BN,0), "ASN1_ENUMERATED_to_BN"},
{ERR_PACK(0,ASN1_F_ASN1_GENERATE_V3,0), "ASN1_generate_v3"},
{ERR_PACK(0,ASN1_F_ASN1_GET_OBJECT,0), "ASN1_get_object"},
{ERR_PACK(0,ASN1_F_ASN1_HEADER_NEW,0), "ASN1_HEADER_new"},
{ERR_PACK(0,ASN1_F_ASN1_I2D_BIO,0), "ASN1_i2d_bio"},
@@ -95,6 +98,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_PACK(0,ASN1_F_ASN1_SEQ_PACK,0), "ASN1_seq_pack"},
{ERR_PACK(0,ASN1_F_ASN1_SEQ_UNPACK,0), "ASN1_seq_unpack"},
{ERR_PACK(0,ASN1_F_ASN1_SIGN,0), "ASN1_sign"},
{ERR_PACK(0,ASN1_F_ASN1_STR2TYPE,0), "ASN1_STR2TYPE"},
{ERR_PACK(0,ASN1_F_ASN1_STRING_TABLE_ADD,0), "ASN1_STRING_TABLE_add"},
{ERR_PACK(0,ASN1_F_ASN1_STRING_TYPE_NEW,0), "ASN1_STRING_type_new"},
{ERR_PACK(0,ASN1_F_ASN1_TEMPLATE_D2I,0), "ASN1_TEMPLATE_D2I"},
@@ -104,6 +108,7 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_PACK(0,ASN1_F_ASN1_TYPE_GET_OCTETSTRING,0), "ASN1_TYPE_get_octetstring"},
{ERR_PACK(0,ASN1_F_ASN1_UNPACK_STRING,0), "ASN1_unpack_string"},
{ERR_PACK(0,ASN1_F_ASN1_VERIFY,0), "ASN1_verify"},
{ERR_PACK(0,ASN1_F_BITSTR_CB,0), "BITSTR_CB"},
{ERR_PACK(0,ASN1_F_BN_TO_ASN1_ENUMERATED,0), "BN_to_ASN1_ENUMERATED"},
{ERR_PACK(0,ASN1_F_BN_TO_ASN1_INTEGER,0), "BN_to_ASN1_INTEGER"},
{ERR_PACK(0,ASN1_F_COLLECT_DATA,0), "COLLECT_DATA"},
@@ -128,12 +133,15 @@ static ERR_STRING_DATA ASN1_str_functs[]=
{ERR_PACK(0,ASN1_F_D2I_X509_PKEY,0), "d2i_X509_PKEY"},
{ERR_PACK(0,ASN1_F_I2D_ASN1_TIME,0), "I2D_ASN1_TIME"},
{ERR_PACK(0,ASN1_F_I2D_DSA_PUBKEY,0), "i2d_DSA_PUBKEY"},
{ERR_PACK(0,ASN1_F_I2D_ECDSA_PUBKEY,0), "I2D_ECDSA_PUBKEY"},
{ERR_PACK(0,ASN1_F_I2D_EC_PUBKEY,0), "i2d_EC_PUBKEY"},
{ERR_PACK(0,ASN1_F_I2D_NETSCAPE_RSA,0), "i2d_Netscape_RSA"},
{ERR_PACK(0,ASN1_F_I2D_PRIVATEKEY,0), "i2d_PrivateKey"},
{ERR_PACK(0,ASN1_F_I2D_PUBLICKEY,0), "i2d_PublicKey"},
{ERR_PACK(0,ASN1_F_I2D_RSA_PUBKEY,0), "i2d_RSA_PUBKEY"},
{ERR_PACK(0,ASN1_F_LONG_C2I,0), "LONG_C2I"},
{ERR_PACK(0,ASN1_F_OID_MODULE_INIT,0), "OID_MODULE_INIT"},
{ERR_PACK(0,ASN1_F_PARSE_TAGGING,0), "PARSE_TAGGING"},
{ERR_PACK(0,ASN1_F_PKCS5_PBE2_SET,0), "PKCS5_pbe2_set"},
{ERR_PACK(0,ASN1_F_X509_CINF_NEW,0), "X509_CINF_NEW"},
{ERR_PACK(0,ASN1_F_X509_CRL_ADD0_REVOKED,0), "X509_CRL_add0_revoked"},
@@ -159,6 +167,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ASN1_R_DATA_IS_WRONG ,"data is wrong"},
{ASN1_R_DECODE_ERROR ,"decode error"},
{ASN1_R_DECODING_ERROR ,"decoding error"},
{ASN1_R_DEPTH_EXCEEDED ,"depth exceeded"},
{ASN1_R_ENCODE_ERROR ,"encode error"},
{ASN1_R_ERROR_LOADING_SECTION ,"error loading section"},
{ASN1_R_ERROR_PARSING_SET_ELEMENT ,"error parsing set element"},
@@ -172,38 +181,57 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ASN1_R_FIELD_MISSING ,"field missing"},
{ASN1_R_FIRST_NUM_TOO_LARGE ,"first num too large"},
{ASN1_R_HEADER_TOO_LONG ,"header too long"},
{ASN1_R_ILLEGAL_BITSTRING_FORMAT ,"illegal bitstring format"},
{ASN1_R_ILLEGAL_BOOLEAN ,"illegal boolean"},
{ASN1_R_ILLEGAL_CHARACTERS ,"illegal characters"},
{ASN1_R_ILLEGAL_FORMAT ,"illegal format"},
{ASN1_R_ILLEGAL_HEX ,"illegal hex"},
{ASN1_R_ILLEGAL_IMPLICIT_TAG ,"illegal implicit tag"},
{ASN1_R_ILLEGAL_INTEGER ,"illegal integer"},
{ASN1_R_ILLEGAL_NESTED_TAGGING ,"illegal nested tagging"},
{ASN1_R_ILLEGAL_NULL ,"illegal null"},
{ASN1_R_ILLEGAL_NULL_VALUE ,"illegal null value"},
{ASN1_R_ILLEGAL_OBJECT ,"illegal object"},
{ASN1_R_ILLEGAL_OPTIONAL_ANY ,"illegal optional any"},
{ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE ,"illegal options on item template"},
{ASN1_R_ILLEGAL_TAGGED_ANY ,"illegal tagged any"},
{ASN1_R_ILLEGAL_TIME_VALUE ,"illegal time value"},
{ASN1_R_INTEGER_NOT_ASCII_FORMAT ,"integer not ascii format"},
{ASN1_R_INTEGER_TOO_LARGE_FOR_LONG ,"integer too large for long"},
{ASN1_R_INVALID_BMPSTRING_LENGTH ,"invalid bmpstring length"},
{ASN1_R_INVALID_DIGIT ,"invalid digit"},
{ASN1_R_INVALID_MODIFIER ,"invalid modifier"},
{ASN1_R_INVALID_NUMBER ,"invalid number"},
{ASN1_R_INVALID_SEPARATOR ,"invalid separator"},
{ASN1_R_INVALID_TIME_FORMAT ,"invalid time format"},
{ASN1_R_INVALID_UNIVERSALSTRING_LENGTH ,"invalid universalstring length"},
{ASN1_R_INVALID_UTF8STRING ,"invalid utf8string"},
{ASN1_R_IV_TOO_LARGE ,"iv too large"},
{ASN1_R_LENGTH_ERROR ,"length error"},
{ASN1_R_LIST_ERROR ,"list error"},
{ASN1_R_MISSING_EOC ,"missing eoc"},
{ASN1_R_MISSING_SECOND_NUMBER ,"missing second number"},
{ASN1_R_MISSING_VALUE ,"missing value"},
{ASN1_R_MSTRING_NOT_UNIVERSAL ,"mstring not universal"},
{ASN1_R_MSTRING_WRONG_TAG ,"mstring wrong tag"},
{ASN1_R_NON_HEX_CHARACTERS ,"non hex characters"},
{ASN1_R_NOT_ASCII_FORMAT ,"not ascii format"},
{ASN1_R_NOT_ENOUGH_DATA ,"not enough data"},
{ASN1_R_NO_MATCHING_CHOICE_TYPE ,"no matching choice type"},
{ASN1_R_NULL_IS_WRONG_LENGTH ,"null is wrong length"},
{ASN1_R_OBJECT_NOT_ASCII_FORMAT ,"object not ascii format"},
{ASN1_R_ODD_NUMBER_OF_CHARS ,"odd number of chars"},
{ASN1_R_PRIVATE_KEY_HEADER_MISSING ,"private key header missing"},
{ASN1_R_SECOND_NUMBER_TOO_LARGE ,"second number too large"},
{ASN1_R_SEQUENCE_LENGTH_MISMATCH ,"sequence length mismatch"},
{ASN1_R_SEQUENCE_NOT_CONSTRUCTED ,"sequence not constructed"},
{ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG ,"sequence or set needs config"},
{ASN1_R_SHORT_LINE ,"short line"},
{ASN1_R_STRING_TOO_LONG ,"string too long"},
{ASN1_R_STRING_TOO_SHORT ,"string too short"},
{ASN1_R_TAG_VALUE_TOO_HIGH ,"tag value too high"},
{ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD,"the asn1 object identifier is not known for this md"},
{ASN1_R_TIME_NOT_ASCII_FORMAT ,"time not ascii format"},
{ASN1_R_TOO_LONG ,"too long"},
{ASN1_R_TYPE_NOT_CONSTRUCTED ,"type not constructed"},
{ASN1_R_UNABLE_TO_DECODE_RSA_KEY ,"unable to decode rsa key"},
@@ -213,10 +241,13 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
{ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM ,"unknown message digest algorithm"},
{ASN1_R_UNKNOWN_OBJECT_TYPE ,"unknown object type"},
{ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE ,"unknown public key type"},
{ASN1_R_UNKNOWN_TAG ,"unknown tag"},
{ASN1_R_UNKOWN_FORMAT ,"unkown format"},
{ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE ,"unsupported any defined by type"},
{ASN1_R_UNSUPPORTED_CIPHER ,"unsupported cipher"},
{ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM ,"unsupported encryption algorithm"},
{ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE ,"unsupported public key type"},
{ASN1_R_UNSUPPORTED_TYPE ,"unsupported type"},
{ASN1_R_WRONG_TAG ,"wrong tag"},
{ASN1_R_WRONG_TYPE ,"wrong type"},
{0,NULL}

839
crypto/asn1/asn1_gen.c Normal file
View File

@@ -0,0 +1,839 @@
/* asn1_gen.c */
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
* project 2002.
*/
/* ====================================================================
* Copyright (c) 2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/x509v3.h>
#define ASN1_GEN_FLAG 0x10000
#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1)
#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2)
#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3)
#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4)
#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5)
#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6)
#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7)
#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8)
#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val}
#define ASN1_FLAG_EXP_MAX 20
/* Input formats */
/* ASCII: default */
#define ASN1_GEN_FORMAT_ASCII 1
/* UTF8 */
#define ASN1_GEN_FORMAT_UTF8 2
/* Hex */
#define ASN1_GEN_FORMAT_HEX 3
/* List of bits */
#define ASN1_GEN_FORMAT_BITLIST 4
struct tag_name_st
{
char *strnam;
int len;
int tag;
};
typedef struct
{
int exp_tag;
int exp_class;
int exp_constructed;
int exp_pad;
long exp_len;
} tag_exp_type;
typedef struct
{
int imp_tag;
int imp_class;
int utype;
int format;
const char *str;
tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
int exp_count;
} tag_exp_arg;
static int bitstr_cb(const char *elem, int len, void *bitstr);
static int asn1_cb(const char *elem, int len, void *bitstr);
static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok);
static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass);
static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf);
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
static int asn1_str2tag(const char *tagstr, int len);
ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
{
X509V3_CTX cnf;
if (!nconf)
return ASN1_generate_v3(str, NULL);
X509V3_set_nconf(&cnf, nconf);
return ASN1_generate_v3(str, &cnf);
}
ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
{
ASN1_TYPE *ret;
tag_exp_arg asn1_tags;
tag_exp_type *etmp;
int i, len;
unsigned char *orig_der = NULL, *new_der = NULL;
unsigned char *cpy_start, *p;
int cpy_len;
long hdr_len;
int hdr_constructed = 0, hdr_tag, hdr_class;
int r;
asn1_tags.imp_tag = -1;
asn1_tags.imp_class = -1;
asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
asn1_tags.exp_count = 0;
if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
return NULL;
if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET))
{
if (!cnf)
{
ASN1err(ASN1_F_ASN1_GENERATE_V3, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
return NULL;
}
ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
}
else
ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
if (!ret)
return NULL;
/* If no tagging return base type */
if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
return ret;
/* Generate the encoding */
cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
ASN1_TYPE_free(ret);
ret = NULL;
/* Set point to start copying for modified encoding */
cpy_start = orig_der;
/* Do we need IMPLICIT tagging? */
if (asn1_tags.imp_tag != -1)
{
/* If IMPLICIT we will replace the underlying tag */
/* Skip existing tag+len */
r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, cpy_len);
if (r & 0x80)
goto err;
/* Update copy length */
cpy_len -= cpy_start - orig_der;
/* For IMPLICIT tagging the length should match the
* original length and constructed flag should be
* consistent.
*/
if (r & 0x1)
{
/* Indefinite length constructed */
hdr_constructed = 2;
hdr_len = 0;
}
else
/* Just retain constructed flag */
hdr_constructed = r & V_ASN1_CONSTRUCTED;
/* Work out new length with IMPLICIT tag: ignore constructed
* because it will mess up if indefinite length
*/
len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
}
else
len = cpy_len;
/* Work out length in any EXPLICIT, starting from end */
for(i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; i < asn1_tags.exp_count; i++, etmp--)
{
/* Content length: number of content octets + any padding */
len += etmp->exp_pad;
etmp->exp_len = len;
/* Total object length: length including new header */
len = ASN1_object_size(0, len, etmp->exp_tag);
}
/* Allocate buffer for new encoding */
new_der = OPENSSL_malloc(len);
/* Generate tagged encoding */
p = new_der;
/* Output explicit tags first */
for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; i++, etmp++)
{
ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
etmp->exp_tag, etmp->exp_class);
if (etmp->exp_pad)
*p++ = 0;
}
/* If IMPLICIT, output tag */
if (asn1_tags.imp_tag != -1)
ASN1_put_object(&p, hdr_constructed, hdr_len,
asn1_tags.imp_tag, asn1_tags.imp_class);
/* Copy across original encoding */
memcpy(p, cpy_start, cpy_len);
p = new_der;
/* Obtain new ASN1_TYPE structure */
ret = d2i_ASN1_TYPE(NULL, &p, len);
err:
if (orig_der)
OPENSSL_free(orig_der);
if (new_der)
OPENSSL_free(new_der);
return ret;
}
static int asn1_cb(const char *elem, int len, void *bitstr)
{
tag_exp_arg *arg = bitstr;
int i;
int utype;
int vlen = 0;
const char *p, *vstart = NULL;
int tmp_tag, tmp_class;
for(i = 0, p = elem; i < len; p++, i++)
{
/* Look for the ':' in name value pairs */
if (*p == ':')
{
vstart = p + 1;
vlen = len - (vstart - elem);
len = p - elem;
break;
}
}
utype = asn1_str2tag(elem, len);
if (utype == -1)
{
ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG);
ERR_add_error_data(2, "tag=", elem);
return -1;
}
/* If this is not a modifier mark end of string and exit */
if (!(utype & ASN1_GEN_FLAG))
{
arg->utype = utype;
arg->str = vstart;
/* If no value and not end of string, error */
if (!vstart && elem[len])
{
ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE);
return -1;
}
return 0;
}
switch(utype)
{
case ASN1_GEN_FLAG_IMP:
/* Check for illegal multiple IMPLICIT tagging */
if (arg->imp_tag != -1)
{
ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING);
return -1;
}
if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
return -1;
break;
case ASN1_GEN_FLAG_EXP:
if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
return -1;
if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
return -1;
break;
case ASN1_GEN_FLAG_SEQWRAP:
if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
return -1;
break;
case ASN1_GEN_FLAG_SETWRAP:
if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
return -1;
break;
case ASN1_GEN_FLAG_BITWRAP:
if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
return -1;
break;
case ASN1_GEN_FLAG_OCTWRAP:
if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
return -1;
break;
case ASN1_GEN_FLAG_FORMAT:
if (!strncmp(vstart, "ASCII", 5))
arg->format = ASN1_GEN_FORMAT_ASCII;
else if (!strncmp(vstart, "UTF8", 4))
arg->format = ASN1_GEN_FORMAT_UTF8;
else if (!strncmp(vstart, "HEX", 3))
arg->format = ASN1_GEN_FORMAT_HEX;
else if (!strncmp(vstart, "BITLIST", 3))
arg->format = ASN1_GEN_FORMAT_BITLIST;
else
{
ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT);
return -1;
}
break;
}
return 1;
}
static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
{
char erch[2];
long tag_num;
char *eptr;
if (!vstart)
return 0;
tag_num = strtoul(vstart, &eptr, 10);
/* Check we haven't gone past max length: should be impossible */
if (eptr && *eptr && (eptr > vstart + vlen))
return 0;
if (tag_num < 0)
{
ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER);
return 0;
}
*ptag = tag_num;
/* If we have non numeric characters, parse them */
if (eptr)
vlen -= eptr - vstart;
else
vlen = 0;
if (vlen)
{
switch (*eptr)
{
case 'U':
*pclass = V_ASN1_UNIVERSAL;
break;
case 'A':
*pclass = V_ASN1_APPLICATION;
break;
case 'P':
*pclass = V_ASN1_PRIVATE;
break;
case 'C':
*pclass = V_ASN1_CONTEXT_SPECIFIC;
break;
default:
erch[0] = *eptr;
erch[1] = 0;
ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER);
ERR_add_error_data(2, "Char=", erch);
return 0;
break;
}
}
else
*pclass = V_ASN1_CONTEXT_SPECIFIC;
return 1;
}
/* Handle multiple types: SET and SEQUENCE */
static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
{
ASN1_TYPE *ret = NULL, *typ = NULL;
STACK_OF(ASN1_TYPE) *sk = NULL;
STACK_OF(CONF_VALUE) *sect = NULL;
unsigned char *der = NULL, *p;
int derlen;
int i, is_set;
sk = sk_ASN1_TYPE_new_null();
if (section)
{
if (!cnf)
goto bad;
sect = X509V3_get_section(cnf, (char *)section);
if (!sect)
goto bad;
for (i = 0; i < sk_CONF_VALUE_num(sect); i++)
{
typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
if (!typ)
goto bad;
sk_ASN1_TYPE_push(sk, typ);
typ = NULL;
}
}
/* Now we has a STACK of the components, convert to the correct form */
if (utype == V_ASN1_SET)
is_set = 1;
else
is_set = 0;
derlen = i2d_ASN1_SET((STACK *)sk, NULL, i2d_ASN1_TYPE, utype, V_ASN1_UNIVERSAL, is_set);
der = OPENSSL_malloc(derlen);
p = der;
i2d_ASN1_SET((STACK *)sk, &p, i2d_ASN1_TYPE, utype, V_ASN1_UNIVERSAL, is_set);
if (!(ret = ASN1_TYPE_new()))
goto bad;
if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype)))
goto bad;
ret->type = utype;
ret->value.asn1_string->data = der;
ret->value.asn1_string->length = derlen;
der = NULL;
bad:
if (der)
OPENSSL_free(der);
if (sk)
sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
if (typ)
ASN1_TYPE_free(typ);
if (sect)
X509V3_section_free(cnf, sect);
return ret;
}
static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok)
{
tag_exp_type *exp_tmp;
/* Can only have IMPLICIT if permitted */
if ((arg->imp_tag != -1) && !imp_ok)
{
ASN1err(ASN1_F_APPEND_TAG, ASN1_R_ILLEGAL_IMPLICIT_TAG);
return 0;
}
if (arg->exp_count == ASN1_FLAG_EXP_MAX)
{
ASN1err(ASN1_F_APPEND_TAG, ASN1_R_DEPTH_EXCEEDED);
return 0;
}
exp_tmp = &arg->exp_list[arg->exp_count++];
/* If IMPLICIT set tag to implicit value then
* reset implicit tag since it has been used.
*/
if (arg->imp_tag != -1)
{
exp_tmp->exp_tag = arg->imp_tag;
exp_tmp->exp_class = arg->imp_class;
arg->imp_tag = -1;
arg->imp_class = -1;
}
else
{
exp_tmp->exp_tag = exp_tag;
exp_tmp->exp_class = exp_class;
}
exp_tmp->exp_constructed = exp_constructed;
exp_tmp->exp_pad = exp_pad;
return 1;
}
static int asn1_str2tag(const char *tagstr, int len)
{
int i;
static struct tag_name_st *tntmp, tnst [] = {
ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
ASN1_GEN_STR("NULL", V_ASN1_NULL),
ASN1_GEN_STR("INT", V_ASN1_INTEGER),
ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
ASN1_GEN_STR("OID", V_ASN1_OBJECT),
ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
ASN1_GEN_STR("T61", V_ASN1_T61STRING),
ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
/* Special cases */
ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
ASN1_GEN_STR("SET", V_ASN1_SET),
/* type modifiers */
/* Explicit tag */
ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
/* Implicit tag */
ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
/* OCTET STRING wrapper */
ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
/* SEQUENCE wrapper */
ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
/* SET wrapper */
ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SEQWRAP),
/* BIT STRING wrapper */
ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
};
if (len == -1)
len = strlen(tagstr);
tntmp = tnst;
for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++)
{
if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len))
return tntmp->tag;
}
return -1;
}
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
{
ASN1_TYPE *atmp = NULL;
CONF_VALUE vtmp;
unsigned char *rdata;
long rdlen;
int no_unused = 1;
if (!(atmp = ASN1_TYPE_new()))
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (!str)
str = "";
switch(utype)
{
case V_ASN1_NULL:
if (str && *str)
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE);
goto bad_form;
}
break;
case V_ASN1_BOOLEAN:
if (format != ASN1_GEN_FORMAT_ASCII)
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
goto bad_form;
}
vtmp.value = (char *)str;
if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean))
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
goto bad_str;
}
break;
case V_ASN1_INTEGER:
case V_ASN1_ENUMERATED:
if (format != ASN1_GEN_FORMAT_ASCII)
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
goto bad_form;
}
if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str)))
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
goto bad_str;
}
break;
case V_ASN1_OBJECT:
if (format != ASN1_GEN_FORMAT_ASCII)
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
goto bad_form;
}
if (!(atmp->value.object = OBJ_txt2obj(str, 0)))
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
goto bad_str;
}
break;
case V_ASN1_UTCTIME:
case V_ASN1_GENERALIZEDTIME:
if (format != ASN1_GEN_FORMAT_ASCII)
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT);
goto bad_form;
}
if (!(atmp->value.asn1_string = ASN1_STRING_new()))
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
goto bad_str;
}
if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1))
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
goto bad_str;
}
atmp->value.asn1_string->type = utype;
if (!ASN1_TIME_check(atmp->value.asn1_string))
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE);
goto bad_str;
}
break;
case V_ASN1_BMPSTRING:
case V_ASN1_PRINTABLESTRING:
case V_ASN1_IA5STRING:
case V_ASN1_T61STRING:
case V_ASN1_UTF8STRING:
case V_ASN1_VISIBLESTRING:
case V_ASN1_UNIVERSALSTRING:
if (format == ASN1_GEN_FORMAT_ASCII)
format = MBSTRING_ASC;
else if (format == ASN1_GEN_FORMAT_UTF8)
format = MBSTRING_UTF8;
else
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT);
goto bad_form;
}
if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
-1, format, ASN1_tag2bit(utype)) <= 0)
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
goto bad_str;
}
break;
case V_ASN1_BIT_STRING:
case V_ASN1_OCTET_STRING:
if (!(atmp->value.asn1_string = ASN1_STRING_new()))
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
goto bad_form;
}
if (format == ASN1_GEN_FORMAT_HEX)
{
if (!(rdata = string_to_hex((char *)str, &rdlen)))
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX);
goto bad_str;
}
atmp->value.asn1_string->data = rdata;
atmp->value.asn1_string->length = rdlen;
atmp->value.asn1_string->type = utype;
}
else if (format == ASN1_GEN_FORMAT_ASCII)
ASN1_STRING_set(atmp->value.asn1_string, str, -1);
else if ((format == ASN1_GEN_FORMAT_BITLIST) && (utype == V_ASN1_BIT_STRING))
{
if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string))
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR);
goto bad_str;
}
no_unused = 0;
}
else
{
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
goto bad_form;
}
if ((utype == V_ASN1_BIT_STRING) && no_unused)
{
atmp->value.asn1_string->flags
&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
atmp->value.asn1_string->flags
|= ASN1_STRING_FLAG_BITS_LEFT;
}
break;
default:
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
goto bad_str;
break;
}
atmp->type = utype;
return atmp;
bad_str:
ERR_add_error_data(2, "string=", str);
bad_form:
ASN1_TYPE_free(atmp);
return NULL;
}
static int bitstr_cb(const char *elem, int len, void *bitstr)
{
long bitnum;
char *eptr;
if (!elem)
return 0;
bitnum = strtoul(elem, &eptr, 10);
if (eptr && *eptr && (eptr != elem + len))
return 0;
if (bitnum < 0)
{
ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER);
return 0;
}
if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1))
{
ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
}

View File

@@ -203,13 +203,22 @@ void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
}
p += ttag;
}
if ((constructed == 2) && (length == 0))
*(p++)=0x80; /* der_put_length would output 0 instead */
if (constructed == 2)
*(p++)=0x80;
else
asn1_put_length(&p,length);
*pp=p;
}
int ASN1_put_eoc(unsigned char **pp)
{
unsigned char *p = *pp;
*p++ = 0;
*p++ = 0;
*pp = p;
return 2;
}
static void asn1_put_length(unsigned char **pp, int length)
{
unsigned char *p= *pp;
@@ -247,8 +256,8 @@ int ASN1_object_size(int constructed, int length, int tag)
ret++;
}
}
if ((length == 0) && (constructed == 2))
ret+=2;
if (constructed == 2)
return ret + 3;
ret++;
if (length > 127)
{

View File

@@ -256,9 +256,11 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset,
opp=op;
os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
if (os != NULL)
if (os != NULL && os->length > 0)
{
opp=os->data;
opp = os->data;
/* testing whether the octet string is
* printable */
for (i=0; i<os->length; i++)
{
if (( (opp[i] < ' ') &&
@@ -271,7 +273,8 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset,
break;
}
}
if (printable && (os->length > 0))
if (printable)
/* printable string */
{
if (BIO_write(bp,":",1) <= 0)
goto end;
@@ -279,8 +282,21 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset,
os->length) <= 0)
goto end;
}
if (!printable && (os->length > 0)
&& dump)
else if (!dump)
/* not printable => print octet string
* as hex dump */
{
if (BIO_write(bp,"[HEX DUMP]:",11) <= 0)
goto end;
for (i=0; i<os->length; i++)
{
if (BIO_printf(bp,"%02X"
, opp[i]) <= 0)
goto end;
}
}
else
/* print the normal dump */
{
if (!nl)
{
@@ -288,11 +304,15 @@ static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset,
goto end;
}
if (BIO_dump_indent(bp,(char *)opp,
((dump == -1 || dump > os->length)?os->length:dump),
((dump == -1 || dump >
os->length)?os->length:dump),
dump_indent) <= 0)
goto end;
nl=1;
}
}
if (os != NULL)
{
M_ASN1_OCTET_STRING_free(os);
os=NULL;
}

View File

@@ -112,7 +112,7 @@ extern "C" {
/* Macros to aid ASN1 template writing */
#define ASN1_ITEM_TEMPLATE(tname) \
const static ASN1_TEMPLATE tname##_item_tt
static const ASN1_TEMPLATE tname##_item_tt
#define ASN1_ITEM_TEMPLATE_END(tname) \
;\
@@ -150,7 +150,7 @@ extern "C" {
*/
#define ASN1_SEQUENCE(tname) \
const static ASN1_TEMPLATE tname##_seq_tt[]
static const ASN1_TEMPLATE tname##_seq_tt[]
#define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
@@ -166,22 +166,37 @@ extern "C" {
#stname \
ASN1_ITEM_end(tname)
#define ASN1_NDEF_SEQUENCE(tname) \
ASN1_SEQUENCE(tname)
#define ASN1_SEQUENCE_cb(tname, cb) \
const static ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
ASN1_SEQUENCE(tname)
#define ASN1_BROKEN_SEQUENCE(tname) \
const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
ASN1_SEQUENCE(tname)
#define ASN1_SEQUENCE_ref(tname, cb, lck) \
const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
ASN1_SEQUENCE(tname)
#define ASN1_SEQUENCE_enc(tname, enc, cb) \
const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
ASN1_SEQUENCE(tname)
#define ASN1_NDEF_SEQUENCE_END(tname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_NDEF_SEQUENCE,\
V_ASN1_SEQUENCE,\
tname##_seq_tt,\
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
NULL,\
sizeof(tname),\
#tname \
ASN1_ITEM_end(tname)
#define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
@@ -224,10 +239,10 @@ extern "C" {
*/
#define ASN1_CHOICE(tname) \
const static ASN1_TEMPLATE tname##_ch_tt[]
static const ASN1_TEMPLATE tname##_ch_tt[]
#define ASN1_CHOICE_cb(tname, cb) \
const static ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
ASN1_CHOICE(tname)
#define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
@@ -353,16 +368,20 @@ extern "C" {
#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
/* EXPLICIT OPTIONAL using indefinite length constructed form */
#define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
/* Macros for the ASN1_ADB structure */
#define ASN1_ADB(name) \
const static ASN1_ADB_TABLE name##_adbtbl[]
static const ASN1_ADB_TABLE name##_adbtbl[]
#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
#define ASN1_ADB_END(name, flags, field, app_table, def, none) \
;\
const static ASN1_ADB name##_adb = {\
static const ASN1_ADB name##_adb = {\
flags,\
offsetof(name, field),\
app_table,\
@@ -376,9 +395,9 @@ extern "C" {
#define ASN1_ADB_END(name, flags, field, app_table, def, none) \
;\
const static ASN1_ITEM *name##_adb(void) \
static const ASN1_ITEM *name##_adb(void) \
{ \
const static ASN1_ADB internal_adb = \
static const ASN1_ADB internal_adb = \
{\
flags,\
offsetof(name, field),\
@@ -397,7 +416,7 @@ extern "C" {
#define ADB_ENTRY(val, template) {val, template}
#define ASN1_ADB_TEMPLATE(name) \
const static ASN1_TEMPLATE name##_tt
static const ASN1_TEMPLATE name##_tt
/* This is the ASN1 template structure that defines
* a wrapper round the actual type. It determines the
@@ -518,6 +537,13 @@ struct ASN1_ADB_TABLE_st {
#define ASN1_TFLG_COMBINE (0x1<<10)
/* This flag when present in a SEQUENCE OF, SET OF
* or EXPLICIT causes indefinite length constructed
* encoding to be used if required.
*/
#define ASN1_TFLG_NDEF (0x1<<11)
/* This is the actual ASN1 item itself */
struct ASN1_ITEM_st {
@@ -570,19 +596,25 @@ const char *sname; /* Structure name */
* has a special meaning, it is used as a mask
* of acceptable types using the B_ASN1 constants.
*
* NDEF_SEQUENCE is the same as SEQUENCE except
* that it will use indefinite length constructed
* encoding if requested.
*
*/
#define ASN1_ITYPE_PRIMITIVE 0x0
#define ASN1_ITYPE_PRIMITIVE 0x0
#define ASN1_ITYPE_SEQUENCE 0x1
#define ASN1_ITYPE_SEQUENCE 0x1
#define ASN1_ITYPE_CHOICE 0x2
#define ASN1_ITYPE_CHOICE 0x2
#define ASN1_ITYPE_COMPAT 0x3
#define ASN1_ITYPE_COMPAT 0x3
#define ASN1_ITYPE_EXTERN 0x4
#define ASN1_ITYPE_EXTERN 0x4
#define ASN1_ITYPE_MSTRING 0x5
#define ASN1_ITYPE_MSTRING 0x5
#define ASN1_ITYPE_NDEF_SEQUENCE 0x6
/* Cache for ASN1 tag and length, so we
* don't keep re-reading it for things
@@ -767,6 +799,12 @@ typedef struct ASN1_AUX_st {
return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
}
#define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
{ \
return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
}
/* This includes evil casts to remove const: they will go away when full
* ASN1 constification is done.
*/

View File

@@ -68,6 +68,9 @@
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, unsigned char **pp,
long length)
@@ -107,6 +110,16 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, unsigned char **pp,
goto err;
}
break;
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
if ((ret->pkey.eckey = d2i_ECPrivateKey(NULL,
(const unsigned char **)pp, length)) == NULL)
{
ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
goto err;
}
break;
#endif
default:
ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
@@ -138,7 +151,10 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, unsigned char **pp,
/* Since we only need to discern "traditional format" RSA and DSA
* keys we can just count the elements.
*/
if(sk_ASN1_TYPE_num(inkey) == 6) keytype = EVP_PKEY_DSA;
if(sk_ASN1_TYPE_num(inkey) == 6)
keytype = EVP_PKEY_DSA;
else if (sk_ASN1_TYPE_num(inkey) == 4)
keytype = EVP_PKEY_EC;
else keytype = EVP_PKEY_RSA;
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
return d2i_PrivateKey(keytype, a, pp, length);

View File

@@ -68,6 +68,9 @@
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif
EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, unsigned char **pp,
long length)
@@ -100,13 +103,24 @@ EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, unsigned char **pp,
#endif
#ifndef OPENSSL_NO_DSA
case EVP_PKEY_DSA:
if ((ret->pkey.dsa=d2i_DSAPublicKey(NULL,
if ((ret->pkey.dsa=d2i_DSAPublicKey(&(ret->pkey.dsa),
(const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
{
ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB);
goto err;
}
break;
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
if ((ret->pkey.eckey = ECPublicKey_set_octet_string(
&(ret->pkey.eckey), (const unsigned char **)pp,
length)) == NULL)
{
ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
goto err;
}
break;
#endif
default:
ASN1err(ASN1_F_D2I_PUBLICKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);

View File

@@ -67,6 +67,9 @@
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif
int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
{
@@ -83,6 +86,12 @@ int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
return(i2d_DSAPrivateKey(a->pkey.dsa,pp));
}
#endif
#ifndef OPENSSL_NO_EC
if (a->type == EVP_PKEY_EC)
{
return(i2d_ECPrivateKey(a->pkey.eckey, pp));
}
#endif
ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return(-1);

View File

@@ -67,6 +67,9 @@
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif
int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
{
@@ -79,6 +82,10 @@ int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
#ifndef OPENSSL_NO_DSA
case EVP_PKEY_DSA:
return(i2d_DSAPublicKey(a->pkey.dsa,pp));
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
return(ECPublicKey_get_octet_string(a->pkey.eckey, pp));
#endif
default:
ASN1err(ASN1_F_I2D_PUBLICKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);

View File

@@ -55,9 +55,15 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* Binary polynomial ECC support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include <openssl/bn.h>
#ifndef OPENSSL_NO_RSA
@@ -69,26 +75,31 @@
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif
static int print(BIO *fp,const char *str,BIGNUM *num,
unsigned char *buf,int off);
static int print_bin(BIO *fp, const char *str, const unsigned char *num,
size_t len, int off);
#ifndef OPENSSL_NO_RSA
#ifndef OPENSSL_NO_FP_API
int RSA_print_fp(FILE *fp, const RSA *x, int off)
{
BIO *b;
int ret;
{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB);
return(0);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
ret=RSA_print(b,x,off);
BIO_free(b);
return(ret);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
ret=RSA_print(b,x,off);
BIO_free(b);
return(ret);
}
#endif
int RSA_print(BIO *bp, const RSA *x, int off)
@@ -227,6 +238,313 @@ err:
}
#endif /* !OPENSSL_NO_DSA */
#ifndef OPENSSL_NO_EC
#ifndef OPENSSL_NO_FP_API
int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
{
ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
ret = ECPKParameters_print(b, x, off);
BIO_free(b);
return(ret);
}
int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
{
ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
return(0);
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
ret = EC_KEY_print(b, x, off);
BIO_free(b);
return(ret);
}
#endif
int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
{
unsigned char *buffer=NULL;
size_t buf_len=0, i;
int ret=0, reason=ERR_R_BIO_LIB;
BN_CTX *ctx=NULL;
EC_POINT *point=NULL;
BIGNUM *p=NULL, *a=NULL, *b=NULL, *gen=NULL,
*order=NULL, *cofactor=NULL;
const unsigned char *seed;
size_t seed_len=0;
static const char *gen_compressed = "Generator (compressed):";
static const char *gen_uncompressed = "Generator (uncompressed):";
static const char *gen_hybrid = "Generator (hybrid):";
if (!x)
{
reason = ERR_R_PASSED_NULL_PARAMETER;
goto err;
}
if (EC_GROUP_get_asn1_flag(x))
{
/* the curve parameter are given by an asn1 OID */
int nid;
if (!BIO_indent(bp, off, 128))
goto err;
nid = EC_GROUP_get_nid(x);
if (nid == 0)
goto err;
if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
goto err;
if (BIO_printf(bp, "\n") <= 0)
goto err;
}
else
{
/* explicit parameters */
int is_char_two = 0;
point_conversion_form_t form;
int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
if (tmp_nid == NID_X9_62_characteristic_two_field)
is_char_two = 1;
if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
(b = BN_new()) == NULL || (order = BN_new()) == NULL ||
(cofactor = BN_new()) == NULL)
{
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
if (is_char_two)
{
if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx))
{
reason = ERR_R_EC_LIB;
goto err;
}
}
else /* prime field */
{
if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
{
reason = ERR_R_EC_LIB;
goto err;
}
}
if ((point = EC_GROUP_get0_generator(x)) == NULL)
{
reason = ERR_R_EC_LIB;
goto err;
}
if (!EC_GROUP_get_order(x, order, NULL) ||
!EC_GROUP_get_cofactor(x, cofactor, NULL))
{
reason = ERR_R_EC_LIB;
goto err;
}
form = EC_GROUP_get_point_conversion_form(x);
if ((gen = EC_POINT_point2bn(x, point,
form, NULL, ctx)) == NULL)
{
reason = ERR_R_EC_LIB;
goto err;
}
buf_len = (size_t)BN_num_bytes(p);
if (buf_len < (i = (size_t)BN_num_bytes(a)))
buf_len = i;
if (buf_len < (i = (size_t)BN_num_bytes(b)))
buf_len = i;
if (buf_len < (i = (size_t)BN_num_bytes(gen)))
buf_len = i;
if (buf_len < (i = (size_t)BN_num_bytes(order)))
buf_len = i;
if (buf_len < (i = (size_t)BN_num_bytes(cofactor)))
buf_len = i;
if ((seed = EC_GROUP_get0_seed(x)) != NULL)
seed_len = EC_GROUP_get_seed_len(x);
buf_len += 10;
if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
{
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
if (!BIO_indent(bp, off, 128))
goto err;
/* print the 'short name' of the field type */
if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
<= 0)
goto err;
if (is_char_two)
{
/* print the 'short name' of the base type OID */
int basis_type = EC_GROUP_get_basis_type(x);
if (basis_type == 0)
goto err;
if (!BIO_indent(bp, off, 128))
goto err;
if (BIO_printf(bp, "Basis Type: %s\n",
OBJ_nid2sn(basis_type)) <= 0)
goto err;
/* print the polynomial */
if ((p != NULL) && !print(bp, "Polynomial:", p, buffer,
off))
goto err;
}
else
{
if ((p != NULL) && !print(bp, "Prime:", p, buffer,off))
goto err;
}
if ((a != NULL) && !print(bp, "A: ", a, buffer, off))
goto err;
if ((b != NULL) && !print(bp, "B: ", b, buffer, off))
goto err;
if (form == POINT_CONVERSION_COMPRESSED)
{
if ((gen != NULL) && !print(bp, gen_compressed, gen,
buffer, off))
goto err;
}
else if (form == POINT_CONVERSION_UNCOMPRESSED)
{
if ((gen != NULL) && !print(bp, gen_uncompressed, gen,
buffer, off))
goto err;
}
else /* form == POINT_CONVERSION_HYBRID */
{
if ((gen != NULL) && !print(bp, gen_hybrid, gen,
buffer, off))
goto err;
}
if ((order != NULL) && !print(bp, "Order: ", order,
buffer, off)) goto err;
if ((cofactor != NULL) && !print(bp, "Cofactor: ", cofactor,
buffer, off)) goto err;
if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
goto err;
}
ret=1;
err:
if (!ret)
ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
if (p)
BN_free(p);
if (a)
BN_free(a);
if (b)
BN_free(b);
if (gen)
BN_free(gen);
if (order)
BN_free(order);
if (cofactor)
BN_free(cofactor);
if (ctx)
BN_CTX_free(ctx);
if (buffer != NULL)
OPENSSL_free(buffer);
return(ret);
}
int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
{
unsigned char *buffer=NULL;
size_t buf_len=0, i;
int ret=0, reason=ERR_R_BIO_LIB;
BIGNUM *pub_key=NULL, *order=NULL;
BN_CTX *ctx=NULL;
if (!x || !x->group)
{
reason = ERR_R_PASSED_NULL_PARAMETER;
goto err;
}
if ((pub_key = EC_POINT_point2bn(x->group, x->pub_key,
x->conv_form, NULL, ctx)) == NULL)
{
reason = ERR_R_EC_LIB;
goto err;
}
buf_len = (size_t)BN_num_bytes(pub_key);
if (x->priv_key)
{
if ((i = (size_t)BN_num_bytes(x->priv_key)) > buf_len)
buf_len = i;
}
buf_len += 10;
if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
{
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
if (x->priv_key != NULL)
{
if (!BIO_indent(bp, off, 128))
goto err;
if ((order = BN_new()) == NULL)
goto err;
if (!EC_GROUP_get_order(x->group, order, NULL))
goto err;
if (BIO_printf(bp, "Private-Key: (%d bit)\n",
BN_num_bits(order)) <= 0) goto err;
}
if ((x->priv_key != NULL) && !print(bp, "priv:", x->priv_key,
buffer, off))
goto err;
if ((pub_key != NULL) && !print(bp, "pub: ", pub_key,
buffer, off))
goto err;
if (!ECPKParameters_print(bp, x->group, off))
goto err;
ret=1;
err:
if (!ret)
ECerr(EC_F_EC_KEY_PRINT, reason);
if (pub_key)
BN_free(pub_key);
if (order)
BN_free(order);
if (ctx)
BN_CTX_free(ctx);
if (buffer != NULL)
OPENSSL_free(buffer);
return(ret);
}
#endif /* OPENSSL_NO_EC */
static int print(BIO *bp, const char *number, BIGNUM *num, unsigned char *buf,
int off)
{
@@ -234,9 +552,15 @@ static int print(BIO *bp, const char *number, BIGNUM *num, unsigned char *buf,
const char *neg;
if (num == NULL) return(1);
neg=(num->neg)?"-":"";
neg = (BN_get_sign(num))?"-":"";
if(!BIO_indent(bp,off,128))
return 0;
if (BN_is_zero(num))
{
if (BIO_printf(bp, "%s 0\n", number) <= 0)
return 0;
return 1;
}
if (BN_num_bytes(num) <= BN_BYTES)
{
@@ -272,23 +596,61 @@ static int print(BIO *bp, const char *number, BIGNUM *num, unsigned char *buf,
return(1);
}
static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
size_t len, int off)
{
size_t i;
char str[128];
if (buf == NULL)
return 1;
if (off)
{
if (off > 128)
off=128;
memset(str,' ',off);
if (BIO_write(fp, str, off) <= 0)
return 0;
}
if (BIO_printf(fp,"%s", name) <= 0)
return 0;
for (i=0; i<len; i++)
{
if ((i%15) == 0)
{
str[0]='\n';
memset(&(str[1]),' ',off+4);
if (BIO_write(fp, str, off+1+4) <= 0)
return 0;
}
if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0)
return 0;
}
if (BIO_write(fp,"\n",1) <= 0)
return 0;
return 1;
}
#ifndef OPENSSL_NO_DH
#ifndef OPENSSL_NO_FP_API
int DHparams_print_fp(FILE *fp, const DH *x)
{
BIO *b;
int ret;
{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
DHerr(DH_F_DHPARAMS_PRINT_FP,ERR_R_BUF_LIB);
return(0);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
ret=DHparams_print(b, x);
BIO_free(b);
return(ret);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
ret=DHparams_print(b, x);
BIO_free(b);
return(ret);
}
#endif
int DHparams_print(BIO *bp, const DH *x)
@@ -333,20 +695,20 @@ err:
#ifndef OPENSSL_NO_DSA
#ifndef OPENSSL_NO_FP_API
int DSAparams_print_fp(FILE *fp, const DSA *x)
{
BIO *b;
int ret;
{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB);
return(0);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
ret=DSAparams_print(b, x);
BIO_free(b);
return(ret);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
ret=DSAparams_print(b, x);
BIO_free(b);
return(ret);
}
#endif
int DSAparams_print(BIO *bp, const DSA *x)
@@ -385,3 +747,59 @@ err:
#endif /* !OPENSSL_NO_DSA */
#ifndef OPENSSL_NO_EC
#ifndef OPENSSL_NO_FP_API
int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
{
ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
return(0);
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
ret = ECParameters_print(b, x);
BIO_free(b);
return(ret);
}
#endif
int ECParameters_print(BIO *bp, const EC_KEY *x)
{
int reason=ERR_R_EC_LIB, ret=0;
BIGNUM *order=NULL;
if (!x || !x->group)
{
reason = ERR_R_PASSED_NULL_PARAMETER;;
goto err;
}
if ((order = BN_new()) == NULL)
{
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
if (!EC_GROUP_get_order(x->group, order, NULL))
{
reason = ERR_R_EC_LIB;
goto err;
}
if (BIO_printf(bp, "ECDSA-Parameters: (%d bit)\n",
BN_num_bits(order)) <= 0)
goto err;
if (!ECPKParameters_print(bp, x->group, 4))
goto err;
ret=1;
err:
if (order)
BN_free(order);
ECerr(EC_F_ECPARAMETERS_PRINT, reason);
return(ret);
}
#endif

View File

@@ -159,6 +159,14 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long
DSA_print(bp,pkey->pkey.dsa,16);
}
else
#endif
#ifndef OPENSSL_NO_EC
if (pkey->type == EVP_PKEY_EC)
{
BIO_printf(bp, "%12sEC Public Key: \n","");
EC_KEY_print(bp, pkey->pkey.eckey, 16);
}
else
#endif
BIO_printf(bp,"%12sUnknown Public Key:\n","");

View File

@@ -93,6 +93,15 @@ int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
}
else
#endif
#ifndef OPENSSL_NO_EC
if (pkey->type == EVP_PKEY_EC)
{
BIO_printf(out, " EC Public Key:\n");
EC_KEY_print(out, pkey->pkey.eckey,2);
}
else
#endif
BIO_printf(out," Unknown Public Key:\n");
EVP_PKEY_free(pkey);
}

View File

@@ -66,6 +66,9 @@
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
@@ -228,6 +231,14 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
DSA_print(bp,pkey->pkey.dsa,16);
}
else
#endif
#ifndef OPENSSL_NO_EC
if (pkey->type == EVP_PKEY_EC)
{
BIO_printf(bp, "%12sEC Public Key:\n","");
EC_KEY_print(bp, pkey->pkey.eckey, 16);
}
else
#endif
BIO_printf(bp,"%12sUnknown Public Key:\n","");

View File

@@ -289,6 +289,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1
goto auxerr;
return 1;
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
p = *in;
tmplen = len;

View File

@@ -3,7 +3,7 @@
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
* Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -63,38 +63,57 @@
#include <openssl/asn1t.h>
#include <openssl/objects.h>
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *seq, unsigned char **out, int skcontlen, const ASN1_ITEM *item, int isset);
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it,
int tag, int aclass);
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
int skcontlen, const ASN1_ITEM *item,
int do_sort, int iclass);
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
const ASN1_TEMPLATE *tt,
int tag, int aclass);
static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
const ASN1_ITEM *it, int flags);
/* Encode an ASN1 item, this is compatible with the
/* Top level i2d equivalents: the 'ndef' variant instructs the encoder
* to use indefinite length constructed encoding, where appropriate
*/
int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
{
return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
}
int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
{
return asn1_item_flags_i2d(val, out, it, 0);
}
/* Encode an ASN1 item, this is use by the
* standard 'i2d' function. 'out' points to
* a buffer to output the data to, in future we will
* have more advanced versions that can output data
* a piece at a time and this will simply be a special
* case.
* a buffer to output the data to.
*
* The new i2d has one additional feature. If the output
* buffer is NULL (i.e. *out == NULL) then a buffer is
* allocated and populated with the encoding.
*/
int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it, int flags)
{
if(out && !*out) {
unsigned char *p, *buf;
int len;
len = ASN1_item_ex_i2d(&val, NULL, it, -1, 0);
len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
if(len <= 0) return len;
buf = OPENSSL_malloc(len);
if(!buf) return -1;
p = buf;
ASN1_item_ex_i2d(&val, &p, it, -1, 0);
ASN1_item_ex_i2d(&val, &p, it, -1, flags);
*out = buf;
return len;
}
return ASN1_item_ex_i2d(&val, out, it, -1, 0);
return ASN1_item_ex_i2d(&val, out, it, -1, flags);
}
/* Encode an item, taking care of IMPLICIT tagging (if any).
@@ -102,31 +121,34 @@ int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
* used in external types.
*/
int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass)
int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it, int tag, int aclass)
{
const ASN1_TEMPLATE *tt = NULL;
unsigned char *p = NULL;
int i, seqcontlen, seqlen;
ASN1_STRING *strtmp;
int i, seqcontlen, seqlen, ndef = 1;
const ASN1_COMPAT_FUNCS *cf;
const ASN1_EXTERN_FUNCS *ef;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb;
if((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) return 0;
if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb;
else asn1_cb = 0;
ASN1_aux_cb *asn1_cb = 0;
if((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
return 0;
if(aux && aux->asn1_cb)
asn1_cb = aux->asn1_cb;
switch(it->itype) {
case ASN1_ITYPE_PRIMITIVE:
if(it->templates)
return ASN1_template_i2d(pval, out, it->templates);
return asn1_template_ex_i2d(pval, out, it->templates,
tag, aclass);
return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
break;
case ASN1_ITYPE_MSTRING:
strtmp = (ASN1_STRING *)*pval;
return asn1_i2d_ex_primitive(pval, out, it, -1, 0);
return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
case ASN1_ITYPE_CHOICE:
if(asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it))
@@ -137,7 +159,8 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it
const ASN1_TEMPLATE *chtt;
chtt = it->templates + i;
pchval = asn1_get_field_ptr(pval, chtt);
return ASN1_template_i2d(pchval, out, chtt);
return asn1_template_ex_i2d(pchval, out, chtt,
-1, aclass);
}
/* Fixme: error condition if selector out of range */
if(asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it))
@@ -161,6 +184,11 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it
*p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
return i;
case ASN1_ITYPE_NDEF_SEQUENCE:
/* Use indefinite length constructed if requested */
if (aclass & ASN1_TFLG_NDEF) ndef = 2;
/* fall through */
case ASN1_ITYPE_SEQUENCE:
i = asn1_enc_restore(&seqcontlen, out, pval, it);
/* An error occurred */
@@ -172,7 +200,9 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it
/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
if(tag == -1) {
tag = V_ASN1_SEQUENCE;
aclass = V_ASN1_UNIVERSAL;
/* Retain any other flags in aclass */
aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
| V_ASN1_UNIVERSAL;
}
if(asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it))
return 0;
@@ -184,13 +214,13 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it
if(!seqtt) return 0;
pseqval = asn1_get_field_ptr(pval, seqtt);
/* FIXME: check for errors in enhanced version */
/* FIXME: special handling of indefinite length encoding */
seqcontlen += ASN1_template_i2d(pseqval, NULL, seqtt);
seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
-1, aclass);
}
seqlen = ASN1_object_size(1, seqcontlen, tag);
seqlen = ASN1_object_size(ndef, seqcontlen, tag);
if(!out) return seqlen;
/* Output SEQUENCE header */
ASN1_put_object(out, 1, seqcontlen, tag, aclass);
ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
@@ -198,8 +228,9 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it
if(!seqtt) return 0;
pseqval = asn1_get_field_ptr(pval, seqtt);
/* FIXME: check for errors in enhanced version */
ASN1_template_i2d(pseqval, out, seqtt);
asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
}
if (ndef == 2) ASN1_put_eoc(out);
if(asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it))
return 0;
return seqlen;
@@ -211,41 +242,95 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it
}
int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt)
{
return asn1_template_ex_i2d(pval, out, tt, -1, 0);
}
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt, int tag, int iclass)
{
int i, ret, flags, aclass;
int i, ret, flags, ttag, tclass, ndef;
flags = tt->flags;
aclass = flags & ASN1_TFLG_TAG_CLASS;
/* Work out tag and class to use: tagging may come
* either from the template or the arguments, not both
* because this would create ambiguity. Additionally
* the iclass argument may contain some additional flags
* which should be noted and passed down to other levels.
*/
if (flags & ASN1_TFLG_TAG_MASK)
{
/* Error if argument and template tagging */
if (tag != -1)
/* FIXME: error code here */
return -1;
/* Get tagging from template */
ttag = tt->tag;
tclass = flags & ASN1_TFLG_TAG_CLASS;
}
else if (tag != -1)
{
/* No template tagging, get from arguments */
ttag = tag;
tclass = iclass & ASN1_TFLG_TAG_CLASS;
}
else
{
ttag = -1;
tclass = 0;
}
/*
* Remove any class mask from iflag.
*/
iclass &= ~ASN1_TFLG_TAG_CLASS;
/* At this point 'ttag' contains the outer tag to use,
* 'tclass' is the class and iclass is any flags passed
* to this function.
*/
/* if template and arguments require ndef, use it */
if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
ndef = 2;
else ndef = 1;
if(flags & ASN1_TFLG_SK_MASK) {
/* SET OF, SEQUENCE OF */
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
int isset, sktag, skaclass;
int skcontlen, sklen;
ASN1_VALUE *skitem;
if(!*pval) return 0;
if(flags & ASN1_TFLG_SET_OF) {
isset = 1;
/* 2 means we reorder */
if(flags & ASN1_TFLG_SEQUENCE_OF) isset = 2;
} else isset = 0;
/* First work out inner tag value */
if(flags & ASN1_TFLG_IMPTAG) {
sktag = tt->tag;
skaclass = aclass;
/* Work out inner tag value: if EXPLICIT
* or no tagging use underlying type.
*/
if((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
sktag = ttag;
skaclass = tclass;
} else {
skaclass = V_ASN1_UNIVERSAL;
if(isset) sktag = V_ASN1_SET;
else sktag = V_ASN1_SEQUENCE;
}
/* Now work out length of items */
/* Determine total length of items */
skcontlen = 0;
for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
skitem = sk_ASN1_VALUE_value(sk, i);
skcontlen += ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), -1, 0);
skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
ASN1_ITEM_ptr(tt->item),
-1, iclass);
}
sklen = ASN1_object_size(1, skcontlen, sktag);
sklen = ASN1_object_size(ndef, skcontlen, sktag);
/* If EXPLICIT need length of surrounding tag */
if(flags & ASN1_TFLG_EXPTAG)
ret = ASN1_object_size(1, sklen, tt->tag);
ret = ASN1_object_size(ndef, sklen, ttag);
else ret = sklen;
if(!out) return ret;
@@ -253,35 +338,43 @@ int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLAT
/* Now encode this lot... */
/* EXPLICIT tag */
if(flags & ASN1_TFLG_EXPTAG)
ASN1_put_object(out, 1, sklen, tt->tag, aclass);
ASN1_put_object(out, ndef, sklen, ttag, tclass);
/* SET or SEQUENCE and IMPLICIT tag */
ASN1_put_object(out, 1, skcontlen, sktag, skaclass);
/* And finally the stuff itself */
asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), isset);
ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
/* And the stuff itself */
asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
isset, iclass);
if (ndef == 2) {
ASN1_put_eoc(out);
if(flags & ASN1_TFLG_EXPTAG)
ASN1_put_eoc(out);
}
return ret;
}
if(flags & ASN1_TFLG_EXPTAG) {
/* EXPLICIT tagging */
/* Find length of tagged item */
i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, 0);
i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item),
-1, iclass);
if(!i) return 0;
/* Find length of EXPLICIT tag */
ret = ASN1_object_size(1, i, tt->tag);
ret = ASN1_object_size(ndef, i, ttag);
if(out) {
/* Output tag and item */
ASN1_put_object(out, 1, i, tt->tag, aclass);
ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, 0);
ASN1_put_object(out, ndef, i, ttag, tclass);
ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
-1, iclass);
if (ndef == 2) ASN1_put_eoc(out);
}
return ret;
}
if(flags & ASN1_TFLG_IMPTAG) {
/* IMPLICIT tagging */
return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), tt->tag, aclass);
}
/* Nothing special: treat as normal */
return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, 0);
/* Either normal or IMPLICIT tagging: combine class and flags */
return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
ttag, tclass | iclass);
}
/* Temporary structure used to hold DER encoding of items for SET OF */
@@ -304,7 +397,9 @@ static int der_cmp(const void *a, const void *b)
/* Output the content octets of SET OF or SEQUENCE OF */
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int skcontlen, const ASN1_ITEM *item, int do_sort)
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
int skcontlen, const ASN1_ITEM *item,
int do_sort, int iclass)
{
int i;
ASN1_VALUE *skitem;
@@ -323,7 +418,7 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int s
if(!do_sort) {
for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
skitem = sk_ASN1_VALUE_value(sk, i);
ASN1_item_i2d(skitem, out, item);
ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
}
return 1;
}
@@ -332,7 +427,7 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int s
for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
skitem = sk_ASN1_VALUE_value(sk, i);
tder->data = p;
tder->length = ASN1_item_i2d(skitem, &p, item);
tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
tder->field = skitem;
}
/* Now sort them */
@@ -359,6 +454,7 @@ static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const A
int len;
int utype;
int usetag;
int ndef = 0;
utype = it->utype;
@@ -381,19 +477,27 @@ static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const A
/* -1 means omit type */
if(len == -1) return 0;
if(len == -1)
return 0;
/* -2 return is special meaning use ndef */
if (len == -2)
{
ndef = 2;
len = 0;
}
/* If not implicitly tagged get tag from underlying type */
if(tag == -1) tag = utype;
/* Output tag+length followed by content octets */
if(out) {
if(usetag) ASN1_put_object(out, 0, len, tag, aclass);
if(usetag) ASN1_put_object(out, ndef, len, tag, aclass);
asn1_ex_i2c(pval, *out, &utype, it);
*out += len;
}
if(usetag) return ASN1_object_size(0, len, tag);
if(usetag) return ASN1_object_size(ndef, len, tag);
return len;
}
@@ -486,6 +590,19 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_
default:
/* All based on ASN1_STRING and handled the same */
strtmp = (ASN1_STRING *)*pval;
/* Special handling for NDEF */
if ((it->size == ASN1_TFLG_NDEF)
&& (strtmp->flags & ASN1_STRING_FLAG_NDEF))
{
if (cout)
{
strtmp->data = cout;
strtmp->length = 0;
ASN1_put_eoc(&cout);
}
/* Special return code */
return -2;
}
cont = strtmp->data;
len = strtmp->length;

View File

@@ -130,6 +130,7 @@ static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int c
if(ef && ef->asn1_ex_free) ef->asn1_ex_free(pval, it);
break;
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
if(asn1_do_lock(pval, -1, it) > 0) return;
if(asn1_cb) {

View File

@@ -155,6 +155,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int
goto auxerr;
break;
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
if(asn1_cb) {
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it);
@@ -231,6 +232,7 @@ static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
case ASN1_ITYPE_COMPAT:
case ASN1_ITYPE_CHOICE:
case ASN1_ITYPE_SEQUENCE:
case ASN1_ITYPE_NDEF_SEQUENCE:
*pval = NULL;
break;
}

View File

@@ -131,3 +131,7 @@ IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1)
IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1)
IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
/* Special, OCTET STRING with indefinite length constructed support */
IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF)

View File

@@ -102,7 +102,8 @@ int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
{
const ASN1_AUX *aux;
int *lck, ret;
if(it->itype != ASN1_ITYPE_SEQUENCE) return 0;
if((it->itype != ASN1_ITYPE_SEQUENCE)
&& (it->itype != ASN1_ITYPE_NDEF_SEQUENCE)) return 0;
aux = it->funcs;
if(!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) return 0;
lck = offset2ptr(*pval, aux->ref_offset);

View File

@@ -63,13 +63,14 @@
/* Minor tweak to operation: free up EVP_PKEY */
static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
{
if(operation == ASN1_OP_FREE_POST) {
{
if (operation == ASN1_OP_FREE_POST)
{
X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
EVP_PKEY_free(pubkey->pkey);
}
}
return 1;
}
}
ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
@@ -108,13 +109,12 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
a->parameter->type=V_ASN1_NULL;
}
}
else
#ifndef OPENSSL_NO_DSA
if (pkey->type == EVP_PKEY_DSA)
else if (pkey->type == EVP_PKEY_DSA)
{
unsigned char *pp;
DSA *dsa;
dsa=pkey->pkey.dsa;
dsa->write_params=0;
ASN1_TYPE_free(a->parameter);
@@ -128,8 +128,62 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
ASN1_STRING_set(a->parameter->value.sequence,p,i);
OPENSSL_free(p);
}
else
#endif
#ifndef OPENSSL_NO_EC
else if (pkey->type == EVP_PKEY_EC)
{
int nid=0;
unsigned char *pp;
EC_KEY *eckey;
eckey = pkey->pkey.eckey;
ASN1_TYPE_free(a->parameter);
if ((a->parameter = ASN1_TYPE_new()) == NULL)
{
X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
goto err;
}
if (EC_GROUP_get_asn1_flag(eckey->group)
&& (nid = EC_GROUP_get_nid(eckey->group)))
{
/* just set the OID */
a->parameter->type = V_ASN1_OBJECT;
a->parameter->value.object = OBJ_nid2obj(nid);
}
else /* explicit parameters */
{
if ((i = i2d_ECParameters(eckey, NULL)) == 0)
{
X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
goto err;
}
if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
{
X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
goto err;
}
pp = p;
if (!i2d_ECParameters(eckey, &pp))
{
X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
OPENSSL_free(p);
goto err;
}
a->parameter->type = V_ASN1_SEQUENCE;
if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL)
{
X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
OPENSSL_free(p);
goto err;
}
ASN1_STRING_set(a->parameter->value.sequence, p, i);
OPENSSL_free(p);
}
}
#endif
else if (1)
{
X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
goto err;
@@ -173,7 +227,7 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
long j;
int type;
unsigned char *p;
#ifndef OPENSSL_NO_DSA
#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
const unsigned char *cp;
X509_ALGOR *a;
#endif
@@ -181,40 +235,102 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
if (key == NULL) goto err;
if (key->pkey != NULL)
{
CRYPTO_add(&key->pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
return(key->pkey);
}
{
CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
return(key->pkey);
}
if (key->public_key == NULL) goto err;
type=OBJ_obj2nid(key->algor->algorithm);
p=key->public_key->data;
j=key->public_key->length;
if ((ret=d2i_PublicKey(type,NULL,&p,(long)j)) == NULL)
if ((ret = EVP_PKEY_new()) == NULL)
{
X509err(X509_F_X509_PUBKEY_GET,X509_R_ERR_ASN1_LIB);
X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->save_parameters=0;
ret->type = EVP_PKEY_type(type);
#ifndef OPENSSL_NO_DSA
/* the parameters must be extracted before the public key (ECDSA!) */
#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
a=key->algor;
if (ret->type == EVP_PKEY_DSA)
#endif
if (0)
;
#ifndef OPENSSL_NO_DSA
else if (ret->type == EVP_PKEY_DSA)
{
if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
{
if ((ret->pkey.dsa = DSA_new()) == NULL)
{
X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->pkey.dsa->write_params=0;
cp=p=a->parameter->value.sequence->data;
j=a->parameter->value.sequence->length;
if (!d2i_DSAparams(&ret->pkey.dsa,&cp,(long)j))
if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j))
goto err;
}
ret->save_parameters=1;
}
#endif
key->pkey=ret;
CRYPTO_add(&ret->references,1,CRYPTO_LOCK_EVP_PKEY);
#ifndef OPENSSL_NO_EC
else if (ret->type == EVP_PKEY_EC)
{
if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
{
/* type == V_ASN1_SEQUENCE => we have explicit parameters
* (e.g. parameters in the X9_62_EC_PARAMETERS-structure )
*/
if ((ret->pkey.eckey= EC_KEY_new()) == NULL)
{
X509err(X509_F_X509_PUBKEY_GET,
ERR_R_MALLOC_FAILURE);
goto err;
}
cp = p = a->parameter->value.sequence->data;
j = a->parameter->value.sequence->length;
if (!d2i_ECParameters(&ret->pkey.eckey, &cp, (long)j))
{
X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB);
goto err;
}
}
else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT))
{
/* type == V_ASN1_OBJECT => the parameters are given
* by an asn1 OID
*/
EC_KEY *eckey;
if (ret->pkey.eckey == NULL)
ret->pkey.eckey = EC_KEY_new();
eckey = ret->pkey.eckey;
if (eckey->group)
EC_GROUP_free(eckey->group);
if ((eckey->group = EC_GROUP_new_by_nid(
OBJ_obj2nid(a->parameter->value.object))) == NULL)
goto err;
EC_GROUP_set_asn1_flag(eckey->group,
OPENSSL_EC_NAMED_CURVE);
}
/* the case implicitlyCA is currently not implemented */
ret->save_parameters = 1;
}
#endif
p=key->public_key->data;
j=key->public_key->length;
if ((ret = d2i_PublicKey(type, &ret, &p, (long)j)) == NULL)
{
X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB);
goto err;
}
key->pkey = ret;
CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
return(ret);
err:
if (ret != NULL)
@@ -228,7 +344,7 @@ err:
EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, unsigned char **pp,
long length)
{
{
X509_PUBKEY *xpk;
EVP_PKEY *pktmp;
xpk = d2i_X509_PUBKEY(NULL, pp, length);
@@ -236,15 +352,16 @@ EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, unsigned char **pp,
pktmp = X509_PUBKEY_get(xpk);
X509_PUBKEY_free(xpk);
if(!pktmp) return NULL;
if(a) {
if(a)
{
EVP_PKEY_free(*a);
*a = pktmp;
}
}
return pktmp;
}
}
int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
{
{
X509_PUBKEY *xpk=NULL;
int ret;
if(!a) return 0;
@@ -252,7 +369,7 @@ int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
ret = i2d_X509_PUBKEY(xpk, pp);
X509_PUBKEY_free(xpk);
return ret;
}
}
/* The following are equivalents but which return RSA and DSA
* keys
@@ -260,75 +377,117 @@ int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
#ifndef OPENSSL_NO_RSA
RSA *d2i_RSA_PUBKEY(RSA **a, unsigned char **pp,
long length)
{
{
EVP_PKEY *pkey;
RSA *key;
unsigned char *q;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if(!pkey) return NULL;
if (!pkey) return NULL;
key = EVP_PKEY_get1_RSA(pkey);
EVP_PKEY_free(pkey);
if(!key) return NULL;
if (!key) return NULL;
*pp = q;
if(a) {
if (a)
{
RSA_free(*a);
*a = key;
}
}
return key;
}
}
int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
{
{
EVP_PKEY *pktmp;
int ret;
if(!a) return 0;
if (!a) return 0;
pktmp = EVP_PKEY_new();
if(!pktmp) {
if (!pktmp)
{
ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
return 0;
}
}
EVP_PKEY_set1_RSA(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return ret;
}
}
#endif
#ifndef OPENSSL_NO_DSA
DSA *d2i_DSA_PUBKEY(DSA **a, unsigned char **pp,
long length)
{
{
EVP_PKEY *pkey;
DSA *key;
unsigned char *q;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if(!pkey) return NULL;
if (!pkey) return NULL;
key = EVP_PKEY_get1_DSA(pkey);
EVP_PKEY_free(pkey);
if(!key) return NULL;
if (!key) return NULL;
*pp = q;
if(a) {
if (a)
{
DSA_free(*a);
*a = key;
}
}
return key;
}
}
int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
{
{
EVP_PKEY *pktmp;
int ret;
if(!a) return 0;
pktmp = EVP_PKEY_new();
if(!pktmp) {
if(!pktmp)
{
ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
return 0;
}
}
EVP_PKEY_set1_DSA(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return ret;
}
}
#endif
#ifndef OPENSSL_NO_EC
EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, unsigned char **pp, long length)
{
EVP_PKEY *pkey;
EC_KEY *key;
unsigned char *q;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if (!pkey) return(NULL);
key = EVP_PKEY_get1_EC_KEY(pkey);
EVP_PKEY_free(pkey);
if (!key) return(NULL);
*pp = q;
if (a)
{
EC_KEY_free(*a);
*a = key;
}
return(key);
}
int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
{
EVP_PKEY *pktmp;
int ret;
if (!a) return(0);
if ((pktmp = EVP_PKEY_new()) == NULL)
{
ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
return(0);
}
EVP_PKEY_set1_EC_KEY(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return(ret);
}
#endif

View File

@@ -91,6 +91,14 @@ static X509_CERT_AUX *aux_get(X509 *x)
int X509_alias_set1(X509 *x, unsigned char *name, int len)
{
X509_CERT_AUX *aux;
if (!name)
{
if (!x || !x->aux || !x->aux->alias)
return 1;
ASN1_UTF8STRING_free(x->aux->alias);
x->aux->alias = NULL;
return 1;
}
if(!(aux = aux_get(x))) return 0;
if(!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) return 0;
return ASN1_STRING_set(aux->alias, name, len);
@@ -99,6 +107,14 @@ int X509_alias_set1(X509 *x, unsigned char *name, int len)
int X509_keyid_set1(X509 *x, unsigned char *id, int len)
{
X509_CERT_AUX *aux;
if (!id)
{
if (!x || !x->aux || !x->aux->keyid)
return 1;
ASN1_OCTET_STRING_free(x->aux->keyid);
x->aux->keyid = NULL;
return 1;
}
if(!(aux = aux_get(x))) return 0;
if(!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) return 0;
return ASN1_STRING_set(aux->keyid, id, len);
@@ -111,6 +127,13 @@ unsigned char *X509_alias_get0(X509 *x, int *len)
return x->aux->alias->data;
}
unsigned char *X509_keyid_get0(X509 *x, int *len)
{
if(!x->aux || !x->aux->keyid) return NULL;
if(len) *len = x->aux->keyid->length;
return x->aux->keyid->data;
}
int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj)
{
X509_CERT_AUX *aux;
@@ -149,3 +172,9 @@ void X509_reject_clear(X509 *x)
}
}
ASN1_SEQUENCE(X509_CERT_PAIR) = {
ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0),
ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1)
} ASN1_SEQUENCE_END(X509_CERT_PAIR)
IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_PAIR)

View File

@@ -247,7 +247,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
ret=0;
break;
}
#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2)
#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS)
if (!(num & BIO_FP_TEXT))
strcat(p,"b");
else

View File

@@ -39,12 +39,12 @@ LIB=$(TOP)/libcrypto.a
LIBSRC= bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c bn_mod.c \
bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \
bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c bn_asm.c \
bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c
bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c
LIBOBJ= bn_add.o bn_div.o bn_exp.o bn_lib.o bn_ctx.o bn_mul.o bn_mod.o \
bn_print.o bn_rand.o bn_shift.o bn_word.o bn_blind.o \
bn_kron.o bn_sqrt.o bn_gcd.o bn_prime.o bn_err.o bn_sqr.o $(BN_ASM) \
bn_recp.o bn_mont.o bn_mpi.o bn_exp2.o
bn_recp.o bn_mont.o bn_mpi.o bn_exp2.o bn_gf2m.o bn_nist.o
SRC= $(LIBSRC)
@@ -136,8 +136,6 @@ asm/ia64-cpp.o: asm/ia64.S
$(CC) $(ASFLAGS) -c -o asm/ia64-cpp.o /tmp/ia64.$$$$.s; \
rm -f /tmp/ia64.$$$$.s
asm/x86_64-gcc.o: asm/x86_64-gcc.c
files:
$(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO
@@ -244,6 +242,13 @@ bn_gcd.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
bn_gcd.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
bn_gcd.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
bn_gcd.o: ../cryptlib.h bn_gcd.c bn_lcl.h
bn_gf2m.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
bn_gf2m.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
bn_gf2m.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
bn_gf2m.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
bn_gf2m.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
bn_gf2m.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
bn_gf2m.o: ../cryptlib.h bn_gf2m.c bn_lcl.h
bn_kron.o: ../../include/openssl/bn.h ../../include/openssl/e_os2.h
bn_kron.o: ../../include/openssl/opensslconf.h bn_kron.c bn_lcl.h
bn_lib.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
@@ -281,6 +286,13 @@ bn_mul.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
bn_mul.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
bn_mul.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
bn_mul.o: ../cryptlib.h bn_lcl.h bn_mul.c
bn_nist.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
bn_nist.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
bn_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
bn_nist.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
bn_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
bn_nist.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
bn_nist.o: ../cryptlib.h bn_lcl.h bn_nist.c
bn_prime.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
bn_prime.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
bn_prime.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h

View File

@@ -172,7 +172,7 @@ n=12 ;(AP) n by value (input)
; }
;
; Using EDIV would be very easy, if it didn't do signed calculations.
; Any time any of the input numbers are signed, there are problems,
; Any time, any of the input numbers are signed, there are problems,
; usually with integer overflow, at which point it returns useless
; data (the quotient gets the value of l, and the remainder becomes 0).
;
@@ -180,26 +180,21 @@ n=12 ;(AP) n by value (input)
; it by 2 (unsigned), do the division, multiply the resulting quotient
; and remainder by 2, add the bit that was dropped when dividing by 2
; to the remainder, and do some adjustment so the remainder doesn't
; end up larger than the divisor. For some cases when the divisor is
; negative (from EDIV's point of view, i.e. when the highest bit is set),
; dividing the dividend by 2 isn't enough, and since some operations
; might generate integer overflows even when the dividend is divided by
; 4 (when the high part of the shifted down dividend ends up being exactly
; half of the divisor, the result is the quotient 0x80000000, which is
; negative...) it needs to be divided by 8. Furthermore, the divisor needs
; to be divided by 2 (unsigned) as well, to avoid more problems with the sign.
; In this case, a little extra fiddling with the remainder is required.
; end up larger than the divisor. This method works as long as the
; divisor is positive, so we'll keep that (with a small adjustment)
; as the main method.
; For some cases when the divisor is negative (from EDIV's point of
; view, i.e. when the highest bit is set), dividing the dividend by
; 2 isn't enough, it needs to be divided by 4. Furthermore, the
; divisor needs to be divided by 2 (unsigned) as well, to avoid more
; problems with the sign. In this case, a little extra fiddling with
; the remainder is required.
;
; So, the simplest way to handle this is always to divide the dividend
; by 8, and to divide the divisor by 2 if it's highest bit is set.
; After EDIV has been used, the quotient gets multiplied by 8 if the
; original divisor was positive, otherwise 4. The remainder, oddly
; enough, is *always* multiplied by 8.
; NOTE: in the case mentioned above, where the high part of the shifted
; down dividend ends up being exactly half the shifted down divisor, we
; end up with a 33 bit quotient. That's no problem however, it usually
; means we have ended up with a too large remainder as well, and the
; problem is fixed by the last part of the algorithm (next paragraph).
; by 4, and to divide the divisor by 2 if it's highest bit is set.
; After EDIV has been used, the quotient gets multiplied by 4 if the
; original divisor was positive, otherwise 2. The remainder, oddly
; enough, is *always* multiplied by 4.
;
; The routine ends with comparing the resulting remainder with the
; original divisor and if the remainder is larger, subtract the
@@ -209,19 +204,15 @@ n=12 ;(AP) n by value (input)
; The complete algorithm looks like this:
;
; d' = d
; l' = l & 7
; [h,l] = [h,l] >> 3
; l' = l & 3
; [h,l] = [h,l] >> 2
; [q,r] = floor([h,l] / d) # This is the EDIV operation
; if (q < 0) q = -q # I doubt this is necessary any more
;
; r' = r >> 29
; if (d' >= 0)
; q' = q >> 29
; q = q << 3
; else
; q' = q >> 30
; q = q << 2
; r = (r << 3) + l'
; r' = r >> 30
; if (d' >= 0) q = q << 1
; q = q << 1
; r = (r << 2) + l'
;
; if (d' < 0)
; {
@@ -229,14 +220,14 @@ n=12 ;(AP) n by value (input)
; while ([r',r] < 0)
; {
; [r',r] = [r',r] + d
; [q',q] = [q',q] - 1
; q = q - 1
; }
; }
;
; while ([r',r] >= d')
; while ([r',r] >= d)
; {
; [r',r] = [r',r] - d'
; [q',q] = [q',q] + 1
; [r',r] = [r',r] - d
; q = q + 1
; }
;
; return q
@@ -245,37 +236,31 @@ h=4 ;(AP) h by value (input)
l=8 ;(AP) l by value (input)
d=12 ;(AP) d by value (input)
;r2 = l, q
;r3 = h, r
;r4 = d
;r5 = l'
;r6 = r'
;r7 = d'
;r8 = q'
;lprim=r5
;rprim=r6
;dprim=r7
.psect code,nowrt
.entry bn_div_words,^m<r2,r3,r4,r5,r6,r7,r8>
.entry bn_div_words,^m<r2,r3,r4,r5,r6,r7>
movl l(ap),r2
movl h(ap),r3
movl d(ap),r4
bicl3 #^XFFFFFFF8,r2,r5 ; l' = l & 7
bicl3 #^X00000007,r2,r2
bicl3 #^XFFFFFFFC,r2,r5 ; l' = l & 3
bicl3 #^X00000003,r2,r2
bicl3 #^XFFFFFFF8,r3,r6
bicl3 #^X00000007,r3,r3
bicl3 #^XFFFFFFFC,r3,r6
bicl3 #^X00000003,r3,r3
addl r6,r2
rotl #-3,r2,r2 ; l = l >> 3
rotl #-3,r3,r3 ; h = h >> 3
rotl #-2,r2,r2 ; l = l >> 2
rotl #-2,r3,r3 ; h = h >> 2
movl #0,r6
movl r4,r7 ; d' = d
movl #0,r6 ; r' = 0
movl #0,r8 ; q' = 0
tstl r4
beql 666$ ; Uh-oh, the divisor is 0...
bgtr 1$
@@ -292,55 +277,44 @@ d=12 ;(AP) d by value (input)
3$:
tstl r7
blss 4$
rotl #3,r2,r2 ; q = q << 3
bicl3 #^XFFFFFFF8,r2,r8 ; q' gets the high bits from q
bicl3 #^X00000007,r2,r2
bsb 41$
4$: ; else
rotl #2,r2,r2 ; q = q << 2
bicl3 #^XFFFFFFFC,r2,r8 ; q' gets the high bits from q
bicl3 #^X00000003,r2,r2
41$:
rotl #3,r3,r3 ; r = r << 3
bicl3 #^XFFFFFFF8,r3,r6 ; r' gets the high bits from r
bicl3 #^X00000007,r3,r3
ashl #1,r2,r2 ; q = q << 1
4$:
ashl #1,r2,r2 ; q = q << 1
rotl #2,r3,r3 ; r = r << 2
bicl3 #^XFFFFFFFC,r3,r6 ; r' gets the high bits from r
bicl3 #^X00000003,r3,r3
addl r5,r3 ; r = r + l'
tstl r7
bgeq 5$
bitl #1,r7
beql 5$ ; if d' < 0 && d' & 1
subl r2,r3 ; [r',r] = [r',r] - [q',q]
sbwc r8,r6
beql 5$ ; if d < 0 && d & 1
subl r2,r3 ; [r',r] = [r',r] - q
sbwc #0,r6
45$:
bgeq 5$ ; while r < 0
decl r2 ; [q',q] = [q',q] - 1
sbwc #0,r8
addl r7,r3 ; [r',r] = [r',r] + d'
decl r2 ; q = q - 1
addl r7,r3 ; [r',r] = [r',r] + d
adwc #0,r6
brb 45$
; The return points are placed in the middle to keep a short distance from
; all the branch points
42$:
; movl r3,r1
movl r2,r0
ret
666$:
movl #^XFFFFFFFF,r0
ret
5$:
tstl r6
bneq 6$
cmpl r3,r7
blssu 42$ ; while [r',r] >= d'
6$:
subl r7,r3 ; [r',r] = [r',r] - d'
subl r7,r3 ; [r',r] = [r',r] - d
sbwc #0,r6
incl r2 ; [q',q] = [q',q] + 1
adwc #0,r8
incl r2 ; q = q + 1
brb 5$
42$:
; movl r3,r1
movl r2,r0
ret
666$:
movl #^XFFFFFFFF,r0
ret
.title vax_bn_add_words unsigned add of two arrays
;

View File

@@ -1,575 +0,0 @@
/*
* x86_64 BIGNUM accelerator version 0.1, December 2002.
*
* Implemented by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
* project.
*
* Rights for redistribution and usage in source and binary forms are
* granted according to the OpenSSL license. Warranty of any kind is
* disclaimed.
*
* Q. Version 0.1? It doesn't sound like Andy, he used to assign real
* versions, like 1.0...
* A. Well, that's because this code is basically a quick-n-dirty
* proof-of-concept hack. As you can see it's implemented with
* inline assembler, which means that you're bound to GCC and that
* there must be a room for fine-tuning.
*
* Q. Why inline assembler?
* A. x86_64 features own ABI I'm not familiar with. Which is why
* I decided to let the compiler take care of subroutine
* prologue/epilogue as well as register allocation.
*
* Q. How much faster does it get?
* A. Unfortunately people sitting on x86_64 hardware are prohibited
* to disclose the performance numbers, so they (SuSE labs to be
* specific) wouldn't tell me. However! Very similar coding technique
* (reaching out for 128-bit result from 64x64-bit multiplication)
* results in >3 times performance improvement on MIPS and I see no
* reason why gain on x86_64 would be so much different:-)
*/
#define BN_ULONG unsigned long
/*
* "m"(a), "+m"(r) is the way to favor DirectPath <20>-code;
* "g"(0) let the compiler to decide where does it
* want to keep the value of zero;
*/
#define mul_add(r,a,word,carry) do { \
register BN_ULONG high,low; \
asm ("mulq %3" \
: "=a"(low),"=d"(high) \
: "a"(word),"m"(a) \
: "cc"); \
asm ("addq %2,%0; adcq %3,%1" \
: "+r"(carry),"+d"(high)\
: "a"(low),"g"(0) \
: "cc"); \
asm ("addq %2,%0; adcq %3,%1" \
: "+m"(r),"+d"(high) \
: "r"(carry),"g"(0) \
: "cc"); \
carry=high; \
} while (0)
#define mul(r,a,word,carry) do { \
register BN_ULONG high,low; \
asm ("mulq %3" \
: "=a"(low),"=d"(high) \
: "a"(word),"g"(a) \
: "cc"); \
asm ("addq %2,%0; adcq %3,%1" \
: "+r"(carry),"+d"(high)\
: "a"(low),"g"(0) \
: "cc"); \
(r)=carry, carry=high; \
} while (0)
#define sqr(r0,r1,a) \
asm ("mulq %2" \
: "=a"(r0),"=d"(r1) \
: "a"(a) \
: "cc");
BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
{
BN_ULONG c1=0;
if (num <= 0) return(c1);
while (num&~3)
{
mul_add(rp[0],ap[0],w,c1);
mul_add(rp[1],ap[1],w,c1);
mul_add(rp[2],ap[2],w,c1);
mul_add(rp[3],ap[3],w,c1);
ap+=4; rp+=4; num-=4;
}
if (num)
{
mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1;
mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1;
mul_add(rp[2],ap[2],w,c1); return c1;
}
return(c1);
}
BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
{
BN_ULONG c1=0;
if (num <= 0) return(c1);
while (num&~3)
{
mul(rp[0],ap[0],w,c1);
mul(rp[1],ap[1],w,c1);
mul(rp[2],ap[2],w,c1);
mul(rp[3],ap[3],w,c1);
ap+=4; rp+=4; num-=4;
}
if (num)
{
mul(rp[0],ap[0],w,c1); if (--num == 0) return c1;
mul(rp[1],ap[1],w,c1); if (--num == 0) return c1;
mul(rp[2],ap[2],w,c1);
}
return(c1);
}
void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
{
if (n <= 0) return;
while (n&~3)
{
sqr(r[0],r[1],a[0]);
sqr(r[2],r[3],a[1]);
sqr(r[4],r[5],a[2]);
sqr(r[6],r[7],a[3]);
a+=4; r+=8; n-=4;
}
if (n)
{
sqr(r[0],r[1],a[0]); if (--n == 0) return;
sqr(r[2],r[3],a[1]); if (--n == 0) return;
sqr(r[4],r[5],a[2]);
}
}
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
{ BN_ULONG ret,waste;
asm ("divq %3"
: "=a"(ret),"=d"(waste)
: "a"(l),"d"(h),"g"(d)
: "cc");
return ret;
}
BN_ULONG bn_add_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n)
{ BN_ULONG ret,i;
if (n <= 0) return 0;
asm (
" subq %2,%2 \n"
".align 16 \n"
"1: movq (%4,%2,8),%0 \n"
" adcq (%5,%2,8),%0 \n"
" movq %0,(%3,%2,8) \n"
" leaq 1(%2),%2 \n"
" loop 1b \n"
" sbbq %0,%0 \n"
: "+a"(ret),"+c"(n),"+r"(i)
: "r"(rp),"r"(ap),"r"(bp)
: "cc"
);
return ret&1;
}
#ifndef SIMICS
BN_ULONG bn_sub_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n)
{ BN_ULONG ret,i;
if (n <= 0) return 0;
asm (
" subq %2,%2 \n"
".align 16 \n"
"1: movq (%4,%2,8),%0 \n"
" sbbq (%5,%2,8),%0 \n"
" movq %0,(%3,%2,8) \n"
" leaq 1(%2),%2 \n"
" loop 1b \n"
" sbbq %0,%0 \n"
: "+a"(ret),"+c"(n),"+r"(i)
: "r"(rp),"r"(ap),"r"(bp)
: "cc"
);
return ret&1;
}
#else
/* Simics 1.4<7 has buggy sbbq:-( */
#define BN_MASK2 0xffffffffffffffffL
BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
{
BN_ULONG t1,t2;
int c=0;
if (n <= 0) return((BN_ULONG)0);
for (;;)
{
t1=a[0]; t2=b[0];
r[0]=(t1-t2-c)&BN_MASK2;
if (t1 != t2) c=(t1 < t2);
if (--n <= 0) break;
t1=a[1]; t2=b[1];
r[1]=(t1-t2-c)&BN_MASK2;
if (t1 != t2) c=(t1 < t2);
if (--n <= 0) break;
t1=a[2]; t2=b[2];
r[2]=(t1-t2-c)&BN_MASK2;
if (t1 != t2) c=(t1 < t2);
if (--n <= 0) break;
t1=a[3]; t2=b[3];
r[3]=(t1-t2-c)&BN_MASK2;
if (t1 != t2) c=(t1 < t2);
if (--n <= 0) break;
a+=4;
b+=4;
r+=4;
}
return(c);
}
#endif
/* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */
/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
#if 0
/* original macros are kept for reference purposes */
#define mul_add_c(a,b,c0,c1,c2) { \
BN_ULONG ta=(a),tb=(b); \
t1 = ta * tb; \
t2 = BN_UMULT_HIGH(ta,tb); \
c0 += t1; t2 += (c0<t1)?1:0; \
c1 += t2; c2 += (c1<t2)?1:0; \
}
#define mul_add_c2(a,b,c0,c1,c2) { \
BN_ULONG ta=(a),tb=(b),t0; \
t1 = BN_UMULT_HIGH(ta,tb); \
t0 = ta * tb; \
t2 = t1+t1; c2 += (t2<t1)?1:0; \
t1 = t0+t0; t2 += (t1<t0)?1:0; \
c0 += t1; t2 += (c0<t1)?1:0; \
c1 += t2; c2 += (c1<t2)?1:0; \
}
#else
#define mul_add_c(a,b,c0,c1,c2) do { \
asm ("mulq %3" \
: "=a"(t1),"=d"(t2) \
: "a"(a),"m"(b) \
: "cc"); \
asm ("addq %2,%0; adcq %3,%1" \
: "+r"(c0),"+d"(t2) \
: "a"(t1),"g"(0) \
: "cc"); \
asm ("addq %2,%0; adcq %3,%1" \
: "+r"(c1),"+r"(c2) \
: "d"(t2),"g"(0) \
: "cc"); \
} while (0)
#define sqr_add_c(a,i,c0,c1,c2) do { \
asm ("mulq %2" \
: "=a"(t1),"=d"(t2) \
: "a"(a[i]) \
: "cc"); \
asm ("addq %2,%0; adcq %3,%1" \
: "+r"(c0),"+d"(t2) \
: "a"(t1),"g"(0) \
: "cc"); \
asm ("addq %2,%0; adcq %3,%1" \
: "+r"(c1),"+r"(c2) \
: "d"(t2),"g"(0) \
: "cc"); \
} while (0)
#define mul_add_c2(a,b,c0,c1,c2) do { \
asm ("mulq %3" \
: "=a"(t1),"=d"(t2) \
: "a"(a),"m"(b) \
: "cc"); \
asm ("addq %0,%0; adcq %2,%1" \
: "+d"(t2),"+r"(c2) \
: "g"(0) \
: "cc"); \
asm ("addq %0,%0; adcq %2,%1" \
: "+a"(t1),"+d"(t2) \
: "g"(0) \
: "cc"); \
asm ("addq %2,%0; adcq %3,%1" \
: "+r"(c0),"+d"(t2) \
: "a"(t1),"g"(0) \
: "cc"); \
asm ("addq %2,%0; adcq %3,%1" \
: "+r"(c1),"+r"(c2) \
: "d"(t2),"g"(0) \
: "cc"); \
} while (0)
#endif
#define sqr_add_c2(a,i,j,c0,c1,c2) \
mul_add_c2((a)[i],(a)[j],c0,c1,c2)
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
{
BN_ULONG bl,bh;
BN_ULONG t1,t2;
BN_ULONG c1,c2,c3;
c1=0;
c2=0;
c3=0;
mul_add_c(a[0],b[0],c1,c2,c3);
r[0]=c1;
c1=0;
mul_add_c(a[0],b[1],c2,c3,c1);
mul_add_c(a[1],b[0],c2,c3,c1);
r[1]=c2;
c2=0;
mul_add_c(a[2],b[0],c3,c1,c2);
mul_add_c(a[1],b[1],c3,c1,c2);
mul_add_c(a[0],b[2],c3,c1,c2);
r[2]=c3;
c3=0;
mul_add_c(a[0],b[3],c1,c2,c3);
mul_add_c(a[1],b[2],c1,c2,c3);
mul_add_c(a[2],b[1],c1,c2,c3);
mul_add_c(a[3],b[0],c1,c2,c3);
r[3]=c1;
c1=0;
mul_add_c(a[4],b[0],c2,c3,c1);
mul_add_c(a[3],b[1],c2,c3,c1);
mul_add_c(a[2],b[2],c2,c3,c1);
mul_add_c(a[1],b[3],c2,c3,c1);
mul_add_c(a[0],b[4],c2,c3,c1);
r[4]=c2;
c2=0;
mul_add_c(a[0],b[5],c3,c1,c2);
mul_add_c(a[1],b[4],c3,c1,c2);
mul_add_c(a[2],b[3],c3,c1,c2);
mul_add_c(a[3],b[2],c3,c1,c2);
mul_add_c(a[4],b[1],c3,c1,c2);
mul_add_c(a[5],b[0],c3,c1,c2);
r[5]=c3;
c3=0;
mul_add_c(a[6],b[0],c1,c2,c3);
mul_add_c(a[5],b[1],c1,c2,c3);
mul_add_c(a[4],b[2],c1,c2,c3);
mul_add_c(a[3],b[3],c1,c2,c3);
mul_add_c(a[2],b[4],c1,c2,c3);
mul_add_c(a[1],b[5],c1,c2,c3);
mul_add_c(a[0],b[6],c1,c2,c3);
r[6]=c1;
c1=0;
mul_add_c(a[0],b[7],c2,c3,c1);
mul_add_c(a[1],b[6],c2,c3,c1);
mul_add_c(a[2],b[5],c2,c3,c1);
mul_add_c(a[3],b[4],c2,c3,c1);
mul_add_c(a[4],b[3],c2,c3,c1);
mul_add_c(a[5],b[2],c2,c3,c1);
mul_add_c(a[6],b[1],c2,c3,c1);
mul_add_c(a[7],b[0],c2,c3,c1);
r[7]=c2;
c2=0;
mul_add_c(a[7],b[1],c3,c1,c2);
mul_add_c(a[6],b[2],c3,c1,c2);
mul_add_c(a[5],b[3],c3,c1,c2);
mul_add_c(a[4],b[4],c3,c1,c2);
mul_add_c(a[3],b[5],c3,c1,c2);
mul_add_c(a[2],b[6],c3,c1,c2);
mul_add_c(a[1],b[7],c3,c1,c2);
r[8]=c3;
c3=0;
mul_add_c(a[2],b[7],c1,c2,c3);
mul_add_c(a[3],b[6],c1,c2,c3);
mul_add_c(a[4],b[5],c1,c2,c3);
mul_add_c(a[5],b[4],c1,c2,c3);
mul_add_c(a[6],b[3],c1,c2,c3);
mul_add_c(a[7],b[2],c1,c2,c3);
r[9]=c1;
c1=0;
mul_add_c(a[7],b[3],c2,c3,c1);
mul_add_c(a[6],b[4],c2,c3,c1);
mul_add_c(a[5],b[5],c2,c3,c1);
mul_add_c(a[4],b[6],c2,c3,c1);
mul_add_c(a[3],b[7],c2,c3,c1);
r[10]=c2;
c2=0;
mul_add_c(a[4],b[7],c3,c1,c2);
mul_add_c(a[5],b[6],c3,c1,c2);
mul_add_c(a[6],b[5],c3,c1,c2);
mul_add_c(a[7],b[4],c3,c1,c2);
r[11]=c3;
c3=0;
mul_add_c(a[7],b[5],c1,c2,c3);
mul_add_c(a[6],b[6],c1,c2,c3);
mul_add_c(a[5],b[7],c1,c2,c3);
r[12]=c1;
c1=0;
mul_add_c(a[6],b[7],c2,c3,c1);
mul_add_c(a[7],b[6],c2,c3,c1);
r[13]=c2;
c2=0;
mul_add_c(a[7],b[7],c3,c1,c2);
r[14]=c3;
r[15]=c1;
}
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
{
BN_ULONG bl,bh;
BN_ULONG t1,t2;
BN_ULONG c1,c2,c3;
c1=0;
c2=0;
c3=0;
mul_add_c(a[0],b[0],c1,c2,c3);
r[0]=c1;
c1=0;
mul_add_c(a[0],b[1],c2,c3,c1);
mul_add_c(a[1],b[0],c2,c3,c1);
r[1]=c2;
c2=0;
mul_add_c(a[2],b[0],c3,c1,c2);
mul_add_c(a[1],b[1],c3,c1,c2);
mul_add_c(a[0],b[2],c3,c1,c2);
r[2]=c3;
c3=0;
mul_add_c(a[0],b[3],c1,c2,c3);
mul_add_c(a[1],b[2],c1,c2,c3);
mul_add_c(a[2],b[1],c1,c2,c3);
mul_add_c(a[3],b[0],c1,c2,c3);
r[3]=c1;
c1=0;
mul_add_c(a[3],b[1],c2,c3,c1);
mul_add_c(a[2],b[2],c2,c3,c1);
mul_add_c(a[1],b[3],c2,c3,c1);
r[4]=c2;
c2=0;
mul_add_c(a[2],b[3],c3,c1,c2);
mul_add_c(a[3],b[2],c3,c1,c2);
r[5]=c3;
c3=0;
mul_add_c(a[3],b[3],c1,c2,c3);
r[6]=c1;
r[7]=c2;
}
void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
{
BN_ULONG bl,bh;
BN_ULONG t1,t2;
BN_ULONG c1,c2,c3;
c1=0;
c2=0;
c3=0;
sqr_add_c(a,0,c1,c2,c3);
r[0]=c1;
c1=0;
sqr_add_c2(a,1,0,c2,c3,c1);
r[1]=c2;
c2=0;
sqr_add_c(a,1,c3,c1,c2);
sqr_add_c2(a,2,0,c3,c1,c2);
r[2]=c3;
c3=0;
sqr_add_c2(a,3,0,c1,c2,c3);
sqr_add_c2(a,2,1,c1,c2,c3);
r[3]=c1;
c1=0;
sqr_add_c(a,2,c2,c3,c1);
sqr_add_c2(a,3,1,c2,c3,c1);
sqr_add_c2(a,4,0,c2,c3,c1);
r[4]=c2;
c2=0;
sqr_add_c2(a,5,0,c3,c1,c2);
sqr_add_c2(a,4,1,c3,c1,c2);
sqr_add_c2(a,3,2,c3,c1,c2);
r[5]=c3;
c3=0;
sqr_add_c(a,3,c1,c2,c3);
sqr_add_c2(a,4,2,c1,c2,c3);
sqr_add_c2(a,5,1,c1,c2,c3);
sqr_add_c2(a,6,0,c1,c2,c3);
r[6]=c1;
c1=0;
sqr_add_c2(a,7,0,c2,c3,c1);
sqr_add_c2(a,6,1,c2,c3,c1);
sqr_add_c2(a,5,2,c2,c3,c1);
sqr_add_c2(a,4,3,c2,c3,c1);
r[7]=c2;
c2=0;
sqr_add_c(a,4,c3,c1,c2);
sqr_add_c2(a,5,3,c3,c1,c2);
sqr_add_c2(a,6,2,c3,c1,c2);
sqr_add_c2(a,7,1,c3,c1,c2);
r[8]=c3;
c3=0;
sqr_add_c2(a,7,2,c1,c2,c3);
sqr_add_c2(a,6,3,c1,c2,c3);
sqr_add_c2(a,5,4,c1,c2,c3);
r[9]=c1;
c1=0;
sqr_add_c(a,5,c2,c3,c1);
sqr_add_c2(a,6,4,c2,c3,c1);
sqr_add_c2(a,7,3,c2,c3,c1);
r[10]=c2;
c2=0;
sqr_add_c2(a,7,4,c3,c1,c2);
sqr_add_c2(a,6,5,c3,c1,c2);
r[11]=c3;
c3=0;
sqr_add_c(a,6,c1,c2,c3);
sqr_add_c2(a,7,5,c1,c2,c3);
r[12]=c1;
c1=0;
sqr_add_c2(a,7,6,c2,c3,c1);
r[13]=c2;
c2=0;
sqr_add_c(a,7,c3,c1,c2);
r[14]=c3;
r[15]=c1;
}
void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
{
BN_ULONG bl,bh;
BN_ULONG t1,t2;
BN_ULONG c1,c2,c3;
c1=0;
c2=0;
c3=0;
sqr_add_c(a,0,c1,c2,c3);
r[0]=c1;
c1=0;
sqr_add_c2(a,1,0,c2,c3,c1);
r[1]=c2;
c2=0;
sqr_add_c(a,1,c3,c1,c2);
sqr_add_c2(a,2,0,c3,c1,c2);
r[2]=c3;
c3=0;
sqr_add_c2(a,3,0,c1,c2,c3);
sqr_add_c2(a,2,1,c1,c2,c3);
r[3]=c1;
c1=0;
sqr_add_c(a,2,c2,c3,c1);
sqr_add_c2(a,3,1,c2,c3,c1);
r[4]=c2;
c2=0;
sqr_add_c2(a,3,2,c3,c1,c2);
r[5]=c3;
c3=0;
sqr_add_c(a,3,c1,c2,c3);
r[6]=c1;
r[7]=c2;
}

View File

@@ -55,6 +55,19 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the Eric Young open source
* license provided above.
*
* The binary polynomial arithmetic software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
*
*/
#ifndef HEADER_BN_H
#define HEADER_BN_H
@@ -307,6 +320,11 @@ typedef struct bn_recp_ctx_st
#define BN_one(a) (BN_set_word((a),1))
#define BN_zero(a) (BN_set_word((a),0))
/* BN_set_sign(BIGNUM *, int) sets the sign of a BIGNUM
* (0 for a non-negative value, 1 for negative) */
#define BN_set_sign(a,b) ((a)->neg = (b))
/* BN_get_sign(BIGNUM *) returns the sign of the BIGNUM */
#define BN_get_sign(a) ((a)->neg)
/*#define BN_ascii2bn(a) BN_hex2bn(a) */
/*#define BN_bn2ascii(a) BN_bn2hex(a) */
@@ -329,6 +347,8 @@ BIGNUM *BN_new(void);
void BN_init(BIGNUM *);
void BN_clear_free(BIGNUM *a);
BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
/* BN_ncopy(): like BN_copy() but copies at most the first n BN_ULONGs */
BIGNUM *BN_ncopy(BIGNUM *a, const BIGNUM *b, size_t n);
void BN_swap(BIGNUM *a, BIGNUM *b);
BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
int BN_bn2bin(const BIGNUM *a, unsigned char *to);
@@ -453,6 +473,71 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
BN_RECP_CTX *recp, BN_CTX *ctx);
/* Functions for arithmetic over binary polynomials represented by BIGNUMs.
*
* The BIGNUM::neg property of BIGNUMs representing binary polynomials is
* ignored.
*
* Note that input arguments are not const so that their bit arrays can
* be expanded to the appropriate size if needed.
*/
int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); /*r = a + b*/
#define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b)
int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); /*r=a mod p*/
int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BIGNUM *p, BN_CTX *ctx); /* r = (a * b) mod p */
int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
BN_CTX *ctx); /* r = (a * a) mod p */
int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p,
BN_CTX *ctx); /* r = (1 / b) mod p */
int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BIGNUM *p, BN_CTX *ctx); /* r = (a / b) mod p */
int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BIGNUM *p, BN_CTX *ctx); /* r = (a ^ b) mod p */
int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
BN_CTX *ctx); /* r = sqrt(a) mod p */
int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
BN_CTX *ctx); /* r^2 + r = a mod p */
#define BN_GF2m_cmp(a, b) BN_ucmp((a), (b))
/* Some functions allow for representation of the irreducible polynomials
* as an unsigned int[], say p. The irreducible f(t) is then of the form:
* t^p[0] + t^p[1] + ... + t^p[k]
* where m = p[0] > p[1] > ... > p[k] = 0.
*/
int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]);
/* r = a mod p */
int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const unsigned int p[], BN_CTX *ctx); /* r = (a * b) mod p */
int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[],
BN_CTX *ctx); /* r = (a * a) mod p */
int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const unsigned int p[],
BN_CTX *ctx); /* r = (1 / b) mod p */
int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const unsigned int p[], BN_CTX *ctx); /* r = (a / b) mod p */
int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const unsigned int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */
int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
const unsigned int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */
int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
const unsigned int p[], BN_CTX *ctx); /* r^2 + r = a mod p */
int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max);
int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a);
/* faster mod functions for the 'NIST primes'
* 0 <= a < p^2 */
int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
const BIGNUM *BN_get0_nist_prime_192(void);
const BIGNUM *BN_get0_nist_prime_224(void);
const BIGNUM *BN_get0_nist_prime_256(void);
const BIGNUM *BN_get0_nist_prime_384(void);
const BIGNUM *BN_get0_nist_prime_521(void);
/* library internal functions */
#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
@@ -510,6 +595,13 @@ void ERR_load_BN_strings(void);
#define BN_F_BN_DIV 107
#define BN_F_BN_EXPAND2 108
#define BN_F_BN_EXPAND_INTERNAL 120
#define BN_F_BN_GF2M_MOD 126
#define BN_F_BN_GF2M_MOD_DIV 123
#define BN_F_BN_GF2M_MOD_EXP 127
#define BN_F_BN_GF2M_MOD_MUL 124
#define BN_F_BN_GF2M_MOD_SOLVE_QUAD 128
#define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 129
#define BN_F_BN_GF2M_MOD_SQR 125
#define BN_F_BN_MOD_EXP2_MONT 118
#define BN_F_BN_MOD_EXP_MONT 109
#define BN_F_BN_MOD_EXP_MONT_WORD 117
@@ -535,6 +627,7 @@ void ERR_load_BN_strings(void);
#define BN_R_INVALID_LENGTH 106
#define BN_R_INVALID_RANGE 115
#define BN_R_NOT_A_SQUARE 111
#define BN_R_NOT_IMPLEMENTED 116
#define BN_R_NOT_INITIALIZED 107
#define BN_R_NO_INVERSE 108
#define BN_R_P_IS_NOT_PRIME 112

View File

@@ -150,20 +150,6 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
q; \
})
# define REMAINDER_IS_ALREADY_CALCULATED
# elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
/*
* Same story here, but it's 128-bit by 64-bit division. Wow!
* <appro@fy.chalmers.se>
*/
# define bn_div_words(n0,n1,d0) \
({ asm volatile ( \
"divq %4" \
: "=a"(q), "=d"(rem) \
: "a"(n1), "d"(n0), "g"(d0) \
: "cc"); \
q; \
})
# define REMAINDER_IS_ALREADY_CALCULATED
# endif /* __<cpu> */
# endif /* __GNUC__ */
#endif /* OPENSSL_NO_ASM */
@@ -282,11 +268,6 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0);
#else
q=bn_div_words(n0,n1,d0);
#ifdef BN_DEBUG_LEVITTE
fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
X) -> 0x%08X\n",
n0, n1, d0, q);
#endif
#endif
#ifndef REMAINDER_IS_ALREADY_CALCULATED
@@ -311,18 +292,11 @@ X) -> 0x%08X\n",
BN_ULONG t2l,t2h,ql,qh;
q=bn_div_words(n0,n1,d0);
#ifdef BN_DEBUG_LEVITTE
fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
X) -> 0x%08X\n",
n0, n1, d0, q);
#endif
#ifndef REMAINDER_IS_ALREADY_CALCULATED
rem=(n1-q*d0)&BN_MASK2;
#endif
#if defined(BN_UMULT_LOHI)
BN_UMULT_LOHI(t2l,t2h,d1,q);
#elif defined(BN_UMULT_HIGH)
#ifdef BN_UMULT_HIGH
t2l = d1 * q;
t2h = BN_UMULT_HIGH(d1,q);
#else

View File

@@ -1,6 +1,6 @@
/* crypto/bn/bn_err.c */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
* Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -77,6 +77,13 @@ static ERR_STRING_DATA BN_str_functs[]=
{ERR_PACK(0,BN_F_BN_DIV,0), "BN_div"},
{ERR_PACK(0,BN_F_BN_EXPAND2,0), "bn_expand2"},
{ERR_PACK(0,BN_F_BN_EXPAND_INTERNAL,0), "BN_EXPAND_INTERNAL"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD,0), "BN_GF2m_mod"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD_DIV,0), "BN_GF2m_mod_div"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD_EXP,0), "BN_GF2m_mod_exp"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD_MUL,0), "BN_GF2m_mod_mul"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD_SOLVE_QUAD,0), "BN_GF2m_mod_solve_quad"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR,0), "BN_GF2m_mod_solve_quad_arr"},
{ERR_PACK(0,BN_F_BN_GF2M_MOD_SQR,0), "BN_GF2m_mod_sqr"},
{ERR_PACK(0,BN_F_BN_MOD_EXP2_MONT,0), "BN_mod_exp2_mont"},
{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT,0), "BN_mod_exp_mont"},
{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT_WORD,0), "BN_mod_exp_mont_word"},
@@ -105,6 +112,7 @@ static ERR_STRING_DATA BN_str_reasons[]=
{BN_R_INVALID_LENGTH ,"invalid length"},
{BN_R_INVALID_RANGE ,"invalid range"},
{BN_R_NOT_A_SQUARE ,"not a square"},
{BN_R_NOT_IMPLEMENTED ,"not implemented"},
{BN_R_NOT_INITIALIZED ,"not initialized"},
{BN_R_NO_INVERSE ,"no inverse"},
{BN_R_P_IS_NOT_PRIME ,"p is not prime"},

996
crypto/bn/bn_gf2m.c Normal file
View File

@@ -0,0 +1,996 @@
/* crypto/bn/bn_gf2m.c */
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* The Elliptic Curve Public-Key Crypto Library (ECC Code) included
* herein is developed by SUN MICROSYSTEMS, INC., and is contributed
* to the OpenSSL project.
*
* The ECC Code is licensed pursuant to the OpenSSL open source
* license provided below.
*
* In addition, Sun covenants to all licensees who provide a reciprocal
* covenant with respect to their own patents if any, not to sue under
* current and future patent claims necessarily infringed by the making,
* using, practicing, selling, offering for sale and/or otherwise
* disposing of the ECC Code as delivered hereunder (or portions thereof),
* provided that such covenant shall not apply:
* 1) for code that a licensee deletes from the ECC Code;
* 2) separates from the ECC Code; or
* 3) for infringements caused by:
* i) the modification of the ECC Code or
* ii) the combination of the ECC Code with other software or
* devices where such combination causes the infringement.
*
* The software is originally written by Sheueling Chang Shantz and
* Douglas Stebila of Sun Microsystems Laboratories.
*
*/
/* NOTE: This file is licensed pursuant to the OpenSSL license below
* and may be modified; but after modifications, the above covenant
* may no longer apply! In such cases, the corresponding paragraph
* ["In addition, Sun covenants ... causes the infringement."] and
* this note can be edited out; but please keep the Sun copyright
* notice and attribution. */
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <assert.h>
#include <limits.h>
#include <stdio.h>
#include "cryptlib.h"
#include "bn_lcl.h"
/* Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should fail. */
#define MAX_ITERATIONS 50
static const BN_ULONG SQR_tb[16] =
{ 0, 1, 4, 5, 16, 17, 20, 21,
64, 65, 68, 69, 80, 81, 84, 85 };
/* Platform-specific macros to accelerate squaring. */
#if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
#define SQR1(w) \
SQR_tb[(w) >> 60 & 0xF] << 56 | SQR_tb[(w) >> 56 & 0xF] << 48 | \
SQR_tb[(w) >> 52 & 0xF] << 40 | SQR_tb[(w) >> 48 & 0xF] << 32 | \
SQR_tb[(w) >> 44 & 0xF] << 24 | SQR_tb[(w) >> 40 & 0xF] << 16 | \
SQR_tb[(w) >> 36 & 0xF] << 8 | SQR_tb[(w) >> 32 & 0xF]
#define SQR0(w) \
SQR_tb[(w) >> 28 & 0xF] << 56 | SQR_tb[(w) >> 24 & 0xF] << 48 | \
SQR_tb[(w) >> 20 & 0xF] << 40 | SQR_tb[(w) >> 16 & 0xF] << 32 | \
SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >> 8 & 0xF] << 16 | \
SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF]
#endif
#ifdef THIRTY_TWO_BIT
#define SQR1(w) \
SQR_tb[(w) >> 28 & 0xF] << 24 | SQR_tb[(w) >> 24 & 0xF] << 16 | \
SQR_tb[(w) >> 20 & 0xF] << 8 | SQR_tb[(w) >> 16 & 0xF]
#define SQR0(w) \
SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >> 8 & 0xF] << 16 | \
SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF]
#endif
#ifdef SIXTEEN_BIT
#define SQR1(w) \
SQR_tb[(w) >> 12 & 0xF] << 8 | SQR_tb[(w) >> 8 & 0xF]
#define SQR0(w) \
SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF]
#endif
#ifdef EIGHT_BIT
#define SQR1(w) \
SQR_tb[(w) >> 4 & 0xF]
#define SQR0(w) \
SQR_tb[(w) & 15]
#endif
/* Product of two polynomials a, b each with degree < BN_BITS2 - 1,
* result is a polynomial r with degree < 2 * BN_BITS - 1
* The caller MUST ensure that the variables have the right amount
* of space allocated.
*/
#ifdef EIGHT_BIT
static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
{
register BN_ULONG h, l, s;
BN_ULONG tab[4], top1b = a >> 7;
register BN_ULONG a1, a2;
a1 = a & (0x7F); a2 = a1 << 1;
tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2;
s = tab[b & 0x3]; l = s;
s = tab[b >> 2 & 0x3]; l ^= s << 2; h = s >> 6;
s = tab[b >> 4 & 0x3]; l ^= s << 4; h ^= s >> 4;
s = tab[b >> 6 ]; l ^= s << 6; h ^= s >> 2;
/* compensate for the top bit of a */
if (top1b & 01) { l ^= b << 7; h ^= b >> 1; }
*r1 = h; *r0 = l;
}
#endif
#ifdef SIXTEEN_BIT
static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
{
register BN_ULONG h, l, s;
BN_ULONG tab[4], top1b = a >> 15;
register BN_ULONG a1, a2;
a1 = a & (0x7FFF); a2 = a1 << 1;
tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2;
s = tab[b & 0x3]; l = s;
s = tab[b >> 2 & 0x3]; l ^= s << 2; h = s >> 14;
s = tab[b >> 4 & 0x3]; l ^= s << 4; h ^= s >> 12;
s = tab[b >> 6 & 0x3]; l ^= s << 6; h ^= s >> 10;
s = tab[b >> 8 & 0x3]; l ^= s << 8; h ^= s >> 8;
s = tab[b >>10 & 0x3]; l ^= s << 10; h ^= s >> 6;
s = tab[b >>12 & 0x3]; l ^= s << 12; h ^= s >> 4;
s = tab[b >>14 ]; l ^= s << 14; h ^= s >> 2;
/* compensate for the top bit of a */
if (top1b & 01) { l ^= b << 15; h ^= b >> 1; }
*r1 = h; *r0 = l;
}
#endif
#ifdef THIRTY_TWO_BIT
static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
{
register BN_ULONG h, l, s;
BN_ULONG tab[8], top2b = a >> 30;
register BN_ULONG a1, a2, a4;
a1 = a & (0x3FFFFFFF); a2 = a1 << 1; a4 = a2 << 1;
tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2;
tab[4] = a4; tab[5] = a1^a4; tab[6] = a2^a4; tab[7] = a1^a2^a4;
s = tab[b & 0x7]; l = s;
s = tab[b >> 3 & 0x7]; l ^= s << 3; h = s >> 29;
s = tab[b >> 6 & 0x7]; l ^= s << 6; h ^= s >> 26;
s = tab[b >> 9 & 0x7]; l ^= s << 9; h ^= s >> 23;
s = tab[b >> 12 & 0x7]; l ^= s << 12; h ^= s >> 20;
s = tab[b >> 15 & 0x7]; l ^= s << 15; h ^= s >> 17;
s = tab[b >> 18 & 0x7]; l ^= s << 18; h ^= s >> 14;
s = tab[b >> 21 & 0x7]; l ^= s << 21; h ^= s >> 11;
s = tab[b >> 24 & 0x7]; l ^= s << 24; h ^= s >> 8;
s = tab[b >> 27 & 0x7]; l ^= s << 27; h ^= s >> 5;
s = tab[b >> 30 ]; l ^= s << 30; h ^= s >> 2;
/* compensate for the top two bits of a */
if (top2b & 01) { l ^= b << 30; h ^= b >> 2; }
if (top2b & 02) { l ^= b << 31; h ^= b >> 1; }
*r1 = h; *r0 = l;
}
#endif
#if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b)
{
register BN_ULONG h, l, s;
BN_ULONG tab[16], top3b = a >> 61;
register BN_ULONG a1, a2, a4, a8;
a1 = a & (0x1FFFFFFFFFFFFFFF); a2 = a1 << 1; a4 = a2 << 1; a8 = a4 << 1;
tab[ 0] = 0; tab[ 1] = a1; tab[ 2] = a2; tab[ 3] = a1^a2;
tab[ 4] = a4; tab[ 5] = a1^a4; tab[ 6] = a2^a4; tab[ 7] = a1^a2^a4;
tab[ 8] = a8; tab[ 9] = a1^a8; tab[10] = a2^a8; tab[11] = a1^a2^a8;
tab[12] = a4^a8; tab[13] = a1^a4^a8; tab[14] = a2^a4^a8; tab[15] = a1^a2^a4^a8;
s = tab[b & 0xF]; l = s;
s = tab[b >> 4 & 0xF]; l ^= s << 4; h = s >> 60;
s = tab[b >> 8 & 0xF]; l ^= s << 8; h ^= s >> 56;
s = tab[b >> 12 & 0xF]; l ^= s << 12; h ^= s >> 52;
s = tab[b >> 16 & 0xF]; l ^= s << 16; h ^= s >> 48;
s = tab[b >> 20 & 0xF]; l ^= s << 20; h ^= s >> 44;
s = tab[b >> 24 & 0xF]; l ^= s << 24; h ^= s >> 40;
s = tab[b >> 28 & 0xF]; l ^= s << 28; h ^= s >> 36;
s = tab[b >> 32 & 0xF]; l ^= s << 32; h ^= s >> 32;
s = tab[b >> 36 & 0xF]; l ^= s << 36; h ^= s >> 28;
s = tab[b >> 40 & 0xF]; l ^= s << 40; h ^= s >> 24;
s = tab[b >> 44 & 0xF]; l ^= s << 44; h ^= s >> 20;
s = tab[b >> 48 & 0xF]; l ^= s << 48; h ^= s >> 16;
s = tab[b >> 52 & 0xF]; l ^= s << 52; h ^= s >> 12;
s = tab[b >> 56 & 0xF]; l ^= s << 56; h ^= s >> 8;
s = tab[b >> 60 ]; l ^= s << 60; h ^= s >> 4;
/* compensate for the top three bits of a */
if (top3b & 01) { l ^= b << 61; h ^= b >> 3; }
if (top3b & 02) { l ^= b << 62; h ^= b >> 2; }
if (top3b & 04) { l ^= b << 63; h ^= b >> 1; }
*r1 = h; *r0 = l;
}
#endif
/* Product of two polynomials a, b each with degree < 2 * BN_BITS2 - 1,
* result is a polynomial r with degree < 4 * BN_BITS2 - 1
* The caller MUST ensure that the variables have the right amount
* of space allocated.
*/
static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0, const BN_ULONG b1, const BN_ULONG b0)
{
BN_ULONG m1, m0;
/* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */
bn_GF2m_mul_1x1(r+3, r+2, a1, b1);
bn_GF2m_mul_1x1(r+1, r, a0, b0);
bn_GF2m_mul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1);
/* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */
r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */
r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */
}
/* Add polynomials a and b and store result in r; r could be a or b, a and b
* could be equal; r is the bitwise XOR of a and b.
*/
int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
{
int i;
const BIGNUM *at, *bt;
if (a->top < b->top) { at = b; bt = a; }
else { at = a; bt = b; }
bn_wexpand(r, at->top);
for (i = 0; i < bt->top; i++)
{
r->d[i] = at->d[i] ^ bt->d[i];
}
for (; i < at->top; i++)
{
r->d[i] = at->d[i];
}
r->top = at->top;
bn_fix_top(r);
return 1;
}
/* Some functions allow for representation of the irreducible polynomials
* as an int[], say p. The irreducible f(t) is then of the form:
* t^p[0] + t^p[1] + ... + t^p[k]
* where m = p[0] > p[1] > ... > p[k] = 0.
*/
/* Performs modular reduction of a and store result in r. r could be a. */
int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[])
{
int j, k;
int n, dN, d0, d1;
BN_ULONG zz, *z;
/* Since the algorithm does reduction in the r value, if a != r, copy the
* contents of a into r so we can do reduction in r.
*/
if (a != r)
{
if (!bn_wexpand(r, a->top)) return 0;
for (j = 0; j < a->top; j++)
{
r->d[j] = a->d[j];
}
r->top = a->top;
}
z = r->d;
/* start reduction */
dN = p[0] / BN_BITS2;
for (j = r->top - 1; j > dN;)
{
zz = z[j];
if (z[j] == 0) { j--; continue; }
z[j] = 0;
for (k = 1; p[k] > 0; k++)
{
/* reducing component t^p[k] */
n = p[0] - p[k];
d0 = n % BN_BITS2; d1 = BN_BITS2 - d0;
n /= BN_BITS2;
z[j-n] ^= (zz>>d0);
if (d0) z[j-n-1] ^= (zz<<d1);
}
/* reducing component t^0 */
n = dN;
d0 = p[0] % BN_BITS2;
d1 = BN_BITS2 - d0;
z[j-n] ^= (zz >> d0);
if (d0) z[j-n-1] ^= (zz << d1);
}
/* final round of reduction */
while (j == dN)
{
d0 = p[0] % BN_BITS2;
zz = z[dN] >> d0;
if (zz == 0) break;
d1 = BN_BITS2 - d0;
if (d0) z[dN] = (z[dN] << d1) >> d1; /* clear up the top d1 bits */
z[0] ^= zz; /* reduction t^0 component */
for (k = 1; p[k] > 0; k++)
{
BN_ULONG tmp_ulong;
/* reducing component t^p[k]*/
n = p[k] / BN_BITS2;
d0 = p[k] % BN_BITS2;
d1 = BN_BITS2 - d0;
z[n] ^= (zz << d0);
tmp_ulong = zz >> d1;
if (d0 && tmp_ulong)
z[n+1] ^= tmp_ulong;
}
}
bn_fix_top(r);
return 1;
}
/* Performs modular reduction of a by p and store result in r. r could be a.
*
* This function calls down to the BN_GF2m_mod_arr implementation; this wrapper
* function is only provided for convenience; for best performance, use the
* BN_GF2m_mod_arr function.
*/
int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
{
const int max = BN_num_bits(p);
unsigned int *arr=NULL, ret = 0;
if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
if (BN_GF2m_poly2arr(p, arr, max) > max)
{
BNerr(BN_F_BN_GF2M_MOD,BN_R_INVALID_LENGTH);
goto err;
}
ret = BN_GF2m_mod_arr(r, a, arr);
err:
if (arr) OPENSSL_free(arr);
return ret;
}
/* Compute the product of two polynomials a and b, reduce modulo p, and store
* the result in r. r could be a or b; a could be b.
*/
int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx)
{
int zlen, i, j, k, ret = 0;
BIGNUM *s;
BN_ULONG x1, x0, y1, y0, zz[4];
if (a == b)
{
return BN_GF2m_mod_sqr_arr(r, a, p, ctx);
}
BN_CTX_start(ctx);
if ((s = BN_CTX_get(ctx)) == NULL) goto err;
zlen = a->top + b->top + 4;
if (!bn_wexpand(s, zlen)) goto err;
s->top = zlen;
for (i = 0; i < zlen; i++) s->d[i] = 0;
for (j = 0; j < b->top; j += 2)
{
y0 = b->d[j];
y1 = ((j+1) == b->top) ? 0 : b->d[j+1];
for (i = 0; i < a->top; i += 2)
{
x0 = a->d[i];
x1 = ((i+1) == a->top) ? 0 : a->d[i+1];
bn_GF2m_mul_2x2(zz, x1, x0, y1, y0);
for (k = 0; k < 4; k++) s->d[i+j+k] ^= zz[k];
}
}
bn_fix_top(s);
BN_GF2m_mod_arr(r, s, p);
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
/* Compute the product of two polynomials a and b, reduce modulo p, and store
* the result in r. r could be a or b; a could equal b.
*
* This function calls down to the BN_GF2m_mod_mul_arr implementation; this wrapper
* function is only provided for convenience; for best performance, use the
* BN_GF2m_mod_mul_arr function.
*/
int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
{
const int max = BN_num_bits(p);
unsigned int *arr=NULL, ret = 0;
if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
if (BN_GF2m_poly2arr(p, arr, max) > max)
{
BNerr(BN_F_BN_GF2M_MOD_MUL,BN_R_INVALID_LENGTH);
goto err;
}
ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx);
err:
if (arr) OPENSSL_free(arr);
return ret;
}
/* Square a, reduce the result mod p, and store it in a. r could be a. */
int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_CTX *ctx)
{
int i, ret = 0;
BIGNUM *s;
BN_CTX_start(ctx);
if ((s = BN_CTX_get(ctx)) == NULL) return 0;
if (!bn_wexpand(s, 2 * a->top)) goto err;
for (i = a->top - 1; i >= 0; i--)
{
s->d[2*i+1] = SQR1(a->d[i]);
s->d[2*i ] = SQR0(a->d[i]);
}
s->top = 2 * a->top;
bn_fix_top(s);
if (!BN_GF2m_mod_arr(r, s, p)) goto err;
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
/* Square a, reduce the result mod p, and store it in a. r could be a.
*
* This function calls down to the BN_GF2m_mod_sqr_arr implementation; this wrapper
* function is only provided for convenience; for best performance, use the
* BN_GF2m_mod_sqr_arr function.
*/
int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
{
const int max = BN_num_bits(p);
unsigned int *arr=NULL, ret = 0;
if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
if (BN_GF2m_poly2arr(p, arr, max) > max)
{
BNerr(BN_F_BN_GF2M_MOD_SQR,BN_R_INVALID_LENGTH);
goto err;
}
ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx);
err:
if (arr) OPENSSL_free(arr);
return ret;
}
/* Invert a, reduce modulo p, and store the result in r. r could be a.
* Uses Modified Almost Inverse Algorithm (Algorithm 10) from
* Hankerson, D., Hernandez, J.L., and Menezes, A. "Software Implementation
* of Elliptic Curve Cryptography Over Binary Fields".
*/
int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
{
BIGNUM *b, *c, *u, *v, *tmp;
int ret = 0;
BN_CTX_start(ctx);
b = BN_CTX_get(ctx);
c = BN_CTX_get(ctx);
u = BN_CTX_get(ctx);
v = BN_CTX_get(ctx);
if (v == NULL) goto err;
if (!BN_one(b)) goto err;
if (!BN_zero(c)) goto err;
if (!BN_GF2m_mod(u, a, p)) goto err;
if (!BN_copy(v, p)) goto err;
u->neg = 0; /* Need to set u->neg = 0 because BN_is_one(u) checks
* the neg flag of the bignum.
*/
if (BN_is_zero(u)) goto err;
while (1)
{
while (!BN_is_odd(u))
{
if (!BN_rshift1(u, u)) goto err;
if (BN_is_odd(b))
{
if (!BN_GF2m_add(b, b, p)) goto err;
}
if (!BN_rshift1(b, b)) goto err;
}
if (BN_is_one(u)) break;
if (BN_num_bits(u) < BN_num_bits(v))
{
tmp = u; u = v; v = tmp;
tmp = b; b = c; c = tmp;
}
if (!BN_GF2m_add(u, u, v)) goto err;
if (!BN_GF2m_add(b, b, c)) goto err;
}
if (!BN_copy(r, b)) goto err;
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
/* Invert xx, reduce modulo p, and store the result in r. r could be xx.
*
* This function calls down to the BN_GF2m_mod_inv implementation; this wrapper
* function is only provided for convenience; for best performance, use the
* BN_GF2m_mod_inv function.
*/
int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const unsigned int p[], BN_CTX *ctx)
{
BIGNUM *field;
int ret = 0;
BN_CTX_start(ctx);
if ((field = BN_CTX_get(ctx)) == NULL) goto err;
if (!BN_GF2m_arr2poly(p, field)) goto err;
ret = BN_GF2m_mod_inv(r, xx, field, ctx);
err:
BN_CTX_end(ctx);
return ret;
}
#ifndef OPENSSL_SUN_GF2M_DIV
/* Divide y by x, reduce modulo p, and store the result in r. r could be x
* or y, x could equal y.
*/
int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p, BN_CTX *ctx)
{
BIGNUM *xinv = NULL;
int ret = 0;
BN_CTX_start(ctx);
xinv = BN_CTX_get(ctx);
if (xinv == NULL) goto err;
if (!BN_GF2m_mod_inv(xinv, x, p, ctx)) goto err;
if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx)) goto err;
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
#else
/* Divide y by x, reduce modulo p, and store the result in r. r could be x
* or y, x could equal y.
* Uses algorithm Modular_Division_GF(2^m) from
* Chang-Shantz, S. "From Euclid's GCD to Montgomery Multiplication to
* the Great Divide".
*/
int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p, BN_CTX *ctx)
{
BIGNUM *a, *b, *u, *v;
int ret = 0;
BN_CTX_start(ctx);
a = BN_CTX_get(ctx);
b = BN_CTX_get(ctx);
u = BN_CTX_get(ctx);
v = BN_CTX_get(ctx);
if (v == NULL) goto err;
/* reduce x and y mod p */
if (!BN_GF2m_mod(u, y, p)) goto err;
if (!BN_GF2m_mod(a, x, p)) goto err;
if (!BN_copy(b, p)) goto err;
if (!BN_zero(v)) goto err;
a->neg = 0; /* Need to set a->neg = 0 because BN_is_one(a) checks
* the neg flag of the bignum.
*/
while (!BN_is_odd(a))
{
if (!BN_rshift1(a, a)) goto err;
if (BN_is_odd(u)) if (!BN_GF2m_add(u, u, p)) goto err;
if (!BN_rshift1(u, u)) goto err;
}
do
{
if (BN_GF2m_cmp(b, a) > 0)
{
if (!BN_GF2m_add(b, b, a)) goto err;
if (!BN_GF2m_add(v, v, u)) goto err;
do
{
if (!BN_rshift1(b, b)) goto err;
if (BN_is_odd(v)) if (!BN_GF2m_add(v, v, p)) goto err;
if (!BN_rshift1(v, v)) goto err;
} while (!BN_is_odd(b));
}
else if (BN_is_one(a))
break;
else
{
if (!BN_GF2m_add(a, a, b)) goto err;
if (!BN_GF2m_add(u, u, v)) goto err;
do
{
if (!BN_rshift1(a, a)) goto err;
if (BN_is_odd(u)) if (!BN_GF2m_add(u, u, p)) goto err;
if (!BN_rshift1(u, u)) goto err;
} while (!BN_is_odd(a));
}
} while (1);
if (!BN_copy(r, u)) goto err;
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
#endif
/* Divide yy by xx, reduce modulo p, and store the result in r. r could be xx
* or yy, xx could equal yy.
*
* This function calls down to the BN_GF2m_mod_div implementation; this wrapper
* function is only provided for convenience; for best performance, use the
* BN_GF2m_mod_div function.
*/
int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const unsigned int p[], BN_CTX *ctx)
{
BIGNUM *field;
int ret = 0;
BN_CTX_start(ctx);
if ((field = BN_CTX_get(ctx)) == NULL) goto err;
if (!BN_GF2m_arr2poly(p, field)) goto err;
ret = BN_GF2m_mod_div(r, yy, xx, field, ctx);
err:
BN_CTX_end(ctx);
return ret;
}
/* Compute the bth power of a, reduce modulo p, and store
* the result in r. r could be a.
* Uses simple square-and-multiply algorithm A.5.1 from IEEE P1363.
*/
int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx)
{
int ret = 0, i, n;
BIGNUM *u;
if (BN_is_zero(b))
{
return(BN_one(r));
}
BN_CTX_start(ctx);
if ((u = BN_CTX_get(ctx)) == NULL) goto err;
if (!BN_GF2m_mod_arr(u, a, p)) goto err;
n = BN_num_bits(b) - 1;
for (i = n - 1; i >= 0; i--)
{
if (!BN_GF2m_mod_sqr_arr(u, u, p, ctx)) goto err;
if (BN_is_bit_set(b, i))
{
if (!BN_GF2m_mod_mul_arr(u, u, a, p, ctx)) goto err;
}
}
if (!BN_copy(r, u)) goto err;
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
/* Compute the bth power of a, reduce modulo p, and store
* the result in r. r could be a.
*
* This function calls down to the BN_GF2m_mod_exp_arr implementation; this wrapper
* function is only provided for convenience; for best performance, use the
* BN_GF2m_mod_exp_arr function.
*/
int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx)
{
const int max = BN_num_bits(p);
unsigned int *arr=NULL, ret = 0;
if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
if (BN_GF2m_poly2arr(p, arr, max) > max)
{
BNerr(BN_F_BN_GF2M_MOD_EXP,BN_R_INVALID_LENGTH);
goto err;
}
ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx);
err:
if (arr) OPENSSL_free(arr);
return ret;
}
/* Compute the square root of a, reduce modulo p, and store
* the result in r. r could be a.
* Uses exponentiation as in algorithm A.4.1 from IEEE P1363.
*/
int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_CTX *ctx)
{
int ret = 0;
BIGNUM *u;
BN_CTX_start(ctx);
if ((u = BN_CTX_get(ctx)) == NULL) goto err;
if (!BN_zero(u)) goto err;
if (!BN_set_bit(u, p[0] - 1)) goto err;
ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx);
err:
BN_CTX_end(ctx);
return ret;
}
/* Compute the square root of a, reduce modulo p, and store
* the result in r. r could be a.
*
* This function calls down to the BN_GF2m_mod_sqrt_arr implementation; this wrapper
* function is only provided for convenience; for best performance, use the
* BN_GF2m_mod_sqrt_arr function.
*/
int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
{
const int max = BN_num_bits(p);
unsigned int *arr=NULL, ret = 0;
if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
if (BN_GF2m_poly2arr(p, arr, max) > max)
{
BNerr(BN_F_BN_GF2M_MOD_EXP,BN_R_INVALID_LENGTH);
goto err;
}
ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx);
err:
if (arr) OPENSSL_free(arr);
return ret;
}
/* Find r such that r^2 + r = a mod p. r could be a. If no r exists returns 0.
* Uses algorithms A.4.7 and A.4.6 from IEEE P1363.
*/
int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const unsigned int p[], BN_CTX *ctx)
{
int ret = 0, count = 0;
unsigned int j;
BIGNUM *a, *z, *rho, *w, *w2, *tmp;
BN_CTX_start(ctx);
a = BN_CTX_get(ctx);
z = BN_CTX_get(ctx);
w = BN_CTX_get(ctx);
if (w == NULL) goto err;
if (!BN_GF2m_mod_arr(a, a_, p)) goto err;
if (BN_is_zero(a))
{
ret = BN_zero(r);
goto err;
}
if (p[0] & 0x1) /* m is odd */
{
/* compute half-trace of a */
if (!BN_copy(z, a)) goto err;
for (j = 1; j <= (p[0] - 1) / 2; j++)
{
if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err;
if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err;
if (!BN_GF2m_add(z, z, a)) goto err;
}
}
else /* m is even */
{
rho = BN_CTX_get(ctx);
w2 = BN_CTX_get(ctx);
tmp = BN_CTX_get(ctx);
if (tmp == NULL) goto err;
do
{
if (!BN_rand(rho, p[0], 0, 0)) goto err;
if (!BN_GF2m_mod_arr(rho, rho, p)) goto err;
if (!BN_zero(z)) goto err;
if (!BN_copy(w, rho)) goto err;
for (j = 1; j <= p[0] - 1; j++)
{
if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err;
if (!BN_GF2m_mod_sqr_arr(w2, w, p, ctx)) goto err;
if (!BN_GF2m_mod_mul_arr(tmp, w2, a, p, ctx)) goto err;
if (!BN_GF2m_add(z, z, tmp)) goto err;
if (!BN_GF2m_add(w, w2, rho)) goto err;
}
count++;
} while (BN_is_zero(w) && (count < MAX_ITERATIONS));
if (BN_is_zero(w))
{
BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR,BN_R_TOO_MANY_ITERATIONS);
goto err;
}
}
if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx)) goto err;
if (!BN_GF2m_add(w, z, w)) goto err;
if (BN_GF2m_cmp(w, a)) goto err;
if (!BN_copy(r, z)) goto err;
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
/* Find r such that r^2 + r = a mod p. r could be a. If no r exists returns 0.
*
* This function calls down to the BN_GF2m_mod_solve_quad_arr implementation; this wrapper
* function is only provided for convenience; for best performance, use the
* BN_GF2m_mod_solve_quad_arr function.
*/
int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
{
const int max = BN_num_bits(p);
unsigned int *arr=NULL, ret = 0;
if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err;
if (BN_GF2m_poly2arr(p, arr, max) > max)
{
BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD,BN_R_INVALID_LENGTH);
goto err;
}
ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx);
err:
if (arr) OPENSSL_free(arr);
return ret;
}
/* Convert the bit-string representation of a polynomial a into an array
* of integers corresponding to the bits with non-zero coefficient.
* Up to max elements of the array will be filled. Return value is total
* number of coefficients that would be extracted if array was large enough.
*/
int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max)
{
int i, j, k;
BN_ULONG mask;
for (k = 0; k < max; k++) p[k] = 0;
k = 0;
for (i = a->top - 1; i >= 0; i--)
{
mask = BN_TBIT;
for (j = BN_BITS2 - 1; j >= 0; j--)
{
if (a->d[i] & mask)
{
if (k < max) p[k] = BN_BITS2 * i + j;
k++;
}
mask >>= 1;
}
}
return k;
}
/* Convert the coefficient array representation of a polynomial to a
* bit-string. The array must be terminated by 0.
*/
int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a)
{
int i;
BN_zero(a);
for (i = 0; p[i] > 0; i++)
{
BN_set_bit(a, p[i]);
}
BN_set_bit(a, 0);
return 1;
}

View File

@@ -230,21 +230,6 @@ struct bignum_ctx
: "r"(a), "r"(b)); \
ret; })
# endif /* compiler */
# elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
# if defined(__GNUC__)
# define BN_UMULT_HIGH(a,b) ({ \
register BN_ULONG ret,discard; \
asm ("mulq %3" \
: "=a"(discard),"=d"(ret) \
: "a"(a), "g"(b) \
: "cc"); \
ret; })
# define BN_UMULT_LOHI(low,high,a,b) \
asm ("mulq %3" \
: "=a"(low),"=d"(high) \
: "a"(a),"g"(b) \
: "cc");
# endif
# endif /* cpu */
#endif /* OPENSSL_NO_ASM */
@@ -254,6 +239,16 @@ struct bignum_ctx
#define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
#define bn_clear_top2max(a) \
{ \
int ind = (a)->dmax - (a)->top; \
BN_ULONG *ftl = &(a)->d[(a)->top-1]; \
for (; ind != 0; ind--) \
*(++ftl) = 0x0; \
}
/* This is used for internal error checking and is not normally used */
#ifdef BN_DEBUG
# include <assert.h>
@@ -352,7 +347,7 @@ struct bignum_ctx
#define LBITS(a) ((a)&BN_MASK2l)
#define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2l)
#define L2HBITS(a) (((a)<<BN_BITS4)&BN_MASK2)
#define L2HBITS(a) ((BN_ULONG)((a)&BN_MASK2l)<<BN_BITS4)
#define LLBITS(a) ((a)&BN_MASKl)
#define LHBITS(a) (((a)>>BN_BITS2)&BN_MASKl)
@@ -368,7 +363,7 @@ struct bignum_ctx
lt=(bl)*(lt); \
m1=(bl)*(ht); \
ht =(bh)*(ht); \
m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS((BN_ULONG)1); \
m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS(1L); \
ht+=HBITS(m); \
m1=L2HBITS(m); \
lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \
@@ -433,13 +428,10 @@ void bn_sqr_comba4(BN_ULONG *r,const BN_ULONG *a);
int bn_cmp_words(const BN_ULONG *a,const BN_ULONG *b,int n);
int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
int cl, int dl);
#if 0
/* bn_mul.c rollback <appro> */
void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
int dna,int dnb,BN_ULONG *t);
void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,
int n,int tna,int tnb,BN_ULONG *t);
#endif
void bn_sqr_recursive(BN_ULONG *r,const BN_ULONG *a, int n2, BN_ULONG *t);
void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n);
void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,

View File

@@ -363,17 +363,6 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
}
}
/* Now need to zero any data between b->top and b->max */
/* XXX Why? */
A= &(a[b->top]);
for (i=(words - b->top)>>3; i>0; i--,A+=8)
{
A[0]=0; A[1]=0; A[2]=0; A[3]=0;
A[4]=0; A[5]=0; A[6]=0; A[7]=0;
}
for (i=(words - b->top)&7; i>0; i--,A++)
A[0]=0;
#else
memset(A,0,sizeof(BN_ULONG)*(words+1));
memcpy(A,b->d,sizeof(b->d[0])*b->top);
@@ -435,12 +424,16 @@ BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
}
/* This is an internal function that should not be used in applications.
* It ensures that 'b' has enough room for a 'words' word number number.
* It ensures that 'b' has enough room for a 'words' word number
* and initialises any unused part of b->d with leading zeros.
* It is mostly used by the various BIGNUM routines. If there is an error,
* NULL is returned. If not, 'b' is returned. */
BIGNUM *bn_expand2(BIGNUM *b, int words)
{
BN_ULONG *A;
int i;
if (words > b->dmax)
{
BN_ULONG *a = bn_expand_internal(b, words);
@@ -455,6 +448,21 @@ BIGNUM *bn_expand2(BIGNUM *b, int words)
else
b = NULL;
}
/* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
if ((b != NULL) && (b->top < b->dmax))
{
A = &(b->d[b->top]);
for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
{
A[0]=0; A[1]=0; A[2]=0; A[3]=0;
A[4]=0; A[5]=0; A[6]=0; A[7]=0;
}
for (i=(b->dmax - b->top)&7; i>0; i--,A++)
A[0]=0;
assert(A == &(b->d[b->dmax]));
}
return b;
}
@@ -514,6 +522,51 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
return(a);
}
BIGNUM *BN_ncopy(BIGNUM *a, const BIGNUM *b, size_t n)
{
int i, min;
BN_ULONG *A;
const BN_ULONG *B;
bn_check_top(b);
if (a == b)
return a;
min = (b->top < (int)n)? b->top: (int)n;
if (!min)
{
BN_zero(a);
return a;
}
if (bn_wexpand(a, min) == NULL)
return NULL;
A=a->d;
B=b->d;
for (i=min>>2; i>0; i--, A+=4, B+=4)
{
BN_ULONG a0,a1,a2,a3;
a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
}
switch (min&3)
{
case 3: A[2]=B[2];
case 2: A[1]=B[1];
case 1: A[0]=B[0];
case 0: ;
}
a->top = min;
a->neg = b->neg;
bn_fix_top(a);
return(a);
}
void BN_swap(BIGNUM *a, BIGNUM *b)
{
int flags_old_a, flags_old_b;

View File

@@ -56,10 +56,325 @@
* [including the GNU Public Licence.]
*/
#ifndef BN_DEBUG
# undef NDEBUG /* avoid conflicting definitions */
# define NDEBUG
#endif
#include <stdio.h>
#include <assert.h>
#include "cryptlib.h"
#include "bn_lcl.h"
#if defined(OPENSSL_NO_ASM) || !(defined(__i386) || defined(__i386__)) || defined(__DJGPP__) /* Assembler implementation exists only for x86 */
/* Here follows specialised variants of bn_add_words() and
bn_sub_words(). They have the property performing operations on
arrays of different sizes. The sizes of those arrays is expressed through
cl, which is the common length ( basicall, min(len(a),len(b)) ), and dl,
which is the delta between the two lengths, calculated as len(a)-len(b).
All lengths are the number of BN_ULONGs... For the operations that require
a result array as parameter, it must have the length cl+abs(dl).
These functions should probably end up in bn_asm.c as soon as there are
assembler counterparts for the systems that use assembler files. */
BN_ULONG bn_sub_part_words(BN_ULONG *r,
const BN_ULONG *a, const BN_ULONG *b,
int cl, int dl)
{
BN_ULONG c, t;
assert(cl >= 0);
c = bn_sub_words(r, a, b, cl);
if (dl == 0)
return c;
r += cl;
a += cl;
b += cl;
if (dl < 0)
{
#ifdef BN_COUNT
fprintf(stderr, " bn_sub_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c);
#endif
for (;;)
{
t = b[0];
r[0] = (0-t-c)&BN_MASK2;
if (t != 0) c=1;
if (++dl >= 0) break;
t = b[1];
r[1] = (0-t-c)&BN_MASK2;
if (t != 0) c=1;
if (++dl >= 0) break;
t = b[2];
r[2] = (0-t-c)&BN_MASK2;
if (t != 0) c=1;
if (++dl >= 0) break;
t = b[3];
r[3] = (0-t-c)&BN_MASK2;
if (t != 0) c=1;
if (++dl >= 0) break;
b += 4;
r += 4;
}
}
else
{
int save_dl = dl;
#ifdef BN_COUNT
fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c = %d)\n", cl, dl, c);
#endif
while(c)
{
t = a[0];
r[0] = (t-c)&BN_MASK2;
if (t != 0) c=0;
if (--dl <= 0) break;
t = a[1];
r[1] = (t-c)&BN_MASK2;
if (t != 0) c=0;
if (--dl <= 0) break;
t = a[2];
r[2] = (t-c)&BN_MASK2;
if (t != 0) c=0;
if (--dl <= 0) break;
t = a[3];
r[3] = (t-c)&BN_MASK2;
if (t != 0) c=0;
if (--dl <= 0) break;
save_dl = dl;
a += 4;
r += 4;
}
if (dl > 0)
{
#ifdef BN_COUNT
fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
#endif
if (save_dl > dl)
{
switch (save_dl - dl)
{
case 1:
r[1] = a[1];
if (--dl <= 0) break;
case 2:
r[2] = a[2];
if (--dl <= 0) break;
case 3:
r[3] = a[3];
if (--dl <= 0) break;
}
a += 4;
r += 4;
}
}
if (dl > 0)
{
#ifdef BN_COUNT
fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, copy)\n", cl, dl);
#endif
for(;;)
{
r[0] = a[0];
if (--dl <= 0) break;
r[1] = a[1];
if (--dl <= 0) break;
r[2] = a[2];
if (--dl <= 0) break;
r[3] = a[3];
if (--dl <= 0) break;
a += 4;
r += 4;
}
}
}
return c;
}
#endif
BN_ULONG bn_add_part_words(BN_ULONG *r,
const BN_ULONG *a, const BN_ULONG *b,
int cl, int dl)
{
BN_ULONG c, l, t;
assert(cl >= 0);
c = bn_add_words(r, a, b, cl);
if (dl == 0)
return c;
r += cl;
a += cl;
b += cl;
if (dl < 0)
{
int save_dl = dl;
#ifdef BN_COUNT
fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c);
#endif
while (c)
{
l=(c+b[0])&BN_MASK2;
c=(l < c);
r[0]=l;
if (++dl >= 0) break;
l=(c+b[1])&BN_MASK2;
c=(l < c);
r[1]=l;
if (++dl >= 0) break;
l=(c+b[2])&BN_MASK2;
c=(l < c);
r[2]=l;
if (++dl >= 0) break;
l=(c+b[3])&BN_MASK2;
c=(l < c);
r[3]=l;
if (++dl >= 0) break;
save_dl = dl;
b+=4;
r+=4;
}
if (dl < 0)
{
#ifdef BN_COUNT
fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c == 0)\n", cl, dl);
#endif
if (save_dl < dl)
{
switch (dl - save_dl)
{
case 1:
r[1] = b[1];
if (++dl >= 0) break;
case 2:
r[2] = b[2];
if (++dl >= 0) break;
case 3:
r[3] = b[3];
if (++dl >= 0) break;
}
b += 4;
r += 4;
}
}
if (dl < 0)
{
#ifdef BN_COUNT
fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, copy)\n", cl, dl);
#endif
for(;;)
{
r[0] = b[0];
if (++dl >= 0) break;
r[1] = b[1];
if (++dl >= 0) break;
r[2] = b[2];
if (++dl >= 0) break;
r[3] = b[3];
if (++dl >= 0) break;
b += 4;
r += 4;
}
}
}
else
{
int save_dl = dl;
#ifdef BN_COUNT
fprintf(stderr, " bn_add_part_words %d + %d (dl > 0)\n", cl, dl);
#endif
while (c)
{
t=(a[0]+c)&BN_MASK2;
c=(t < c);
r[0]=t;
if (--dl <= 0) break;
t=(a[1]+c)&BN_MASK2;
c=(t < c);
r[1]=t;
if (--dl <= 0) break;
t=(a[2]+c)&BN_MASK2;
c=(t < c);
r[2]=t;
if (--dl <= 0) break;
t=(a[3]+c)&BN_MASK2;
c=(t < c);
r[3]=t;
if (--dl <= 0) break;
save_dl = dl;
a+=4;
r+=4;
}
#ifdef BN_COUNT
fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl, dl);
#endif
if (dl > 0)
{
if (save_dl > dl)
{
switch (save_dl - dl)
{
case 1:
r[1] = a[1];
if (--dl <= 0) break;
case 2:
r[2] = a[2];
if (--dl <= 0) break;
case 3:
r[3] = a[3];
if (--dl <= 0) break;
}
a += 4;
r += 4;
}
}
if (dl > 0)
{
#ifdef BN_COUNT
fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, copy)\n", cl, dl);
#endif
for(;;)
{
r[0] = a[0];
if (--dl <= 0) break;
r[1] = a[1];
if (--dl <= 0) break;
r[2] = a[2];
if (--dl <= 0) break;
r[3] = a[3];
if (--dl <= 0) break;
a += 4;
r += 4;
}
}
}
return c;
}
#ifdef BN_RECURSION
/* Karatsuba recursive multiplication algorithm
* (cf. Knuth, The Art of Computer Programming, Vol. 2) */
@@ -75,14 +390,15 @@
* a[1]*b[1]
*/
void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
BN_ULONG *t)
int dna, int dnb, BN_ULONG *t)
{
int n=n2/2,c1,c2;
int tna=n+dna, tnb=n+dnb;
unsigned int neg,zero;
BN_ULONG ln,lo,*p;
# ifdef BN_COUNT
printf(" bn_mul_recursive %d * %d\n",n2,n2);
fprintf(stderr," bn_mul_recursive %d * %d\n",n2,n2);
# endif
# ifdef BN_MUL_COMBA
# if 0
@@ -92,34 +408,40 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
return;
}
# endif
if (n2 == 8)
/* Only call bn_mul_comba 8 if n2 == 8 and the
* two arrays are complete [steve]
*/
if (n2 == 8 && dna == 0 && dnb == 0)
{
bn_mul_comba8(r,a,b);
return;
}
# endif /* BN_MUL_COMBA */
/* Else do normal multiply */
if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL)
{
/* This should not happen */
bn_mul_normal(r,a,n2,b,n2);
bn_mul_normal(r,a,n2+dna,b,n2+dnb);
if ((dna + dnb) < 0)
memset(&r[2*n2 + dna + dnb], 0,
sizeof(BN_ULONG) * -(dna + dnb));
return;
}
/* r=(a[0]-a[1])*(b[1]-b[0]) */
c1=bn_cmp_words(a,&(a[n]),n);
c2=bn_cmp_words(&(b[n]),b,n);
c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
zero=neg=0;
switch (c1*3+c2)
{
case -4:
bn_sub_words(t, &(a[n]),a, n); /* - */
bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
break;
case -3:
zero=1;
break;
case -2:
bn_sub_words(t, &(a[n]),a, n); /* - */
bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */
bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); /* + */
neg=1;
break;
case -1:
@@ -128,21 +450,22 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
zero=1;
break;
case 2:
bn_sub_words(t, a, &(a[n]),n); /* + */
bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
bn_sub_part_words(t, a, &(a[n]),tna,n-tna); /* + */
bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
neg=1;
break;
case 3:
zero=1;
break;
case 4:
bn_sub_words(t, a, &(a[n]),n);
bn_sub_words(&(t[n]),&(b[n]),b, n);
bn_sub_part_words(t, a, &(a[n]),tna,n-tna);
bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n);
break;
}
# ifdef BN_MUL_COMBA
if (n == 4)
if (n == 4 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba4 could take
extra args to do this well */
{
if (!zero)
bn_mul_comba4(&(t[n2]),t,&(t[n]));
@@ -152,7 +475,9 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
bn_mul_comba4(r,a,b);
bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n]));
}
else if (n == 8)
else if (n == 8 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba8 could
take extra args to do this
well */
{
if (!zero)
bn_mul_comba8(&(t[n2]),t,&(t[n]));
@@ -167,11 +492,11 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
{
p= &(t[n2*2]);
if (!zero)
bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p);
bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
else
memset(&(t[n2]),0,n2*sizeof(BN_ULONG));
bn_mul_recursive(r,a,b,n,p);
bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,p);
bn_mul_recursive(r,a,b,n,0,0,p);
bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,dna,dnb,p);
}
/* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
@@ -220,39 +545,39 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
/* n+tn is the word length
* t needs to be n*4 is size, as does r */
void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn,
int n, BN_ULONG *t)
void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
int tna, int tnb, BN_ULONG *t)
{
int i,j,n2=n*2;
unsigned int c1,c2,neg,zero;
BN_ULONG ln,lo,*p;
# ifdef BN_COUNT
printf(" bn_mul_part_recursive %d * %d\n",tn+n,tn+n);
fprintf(stderr," bn_mul_part_recursive (%d+%d) * (%d+%d)\n",
tna, n, tnb, n);
# endif
if (n < 8)
{
i=tn+n;
bn_mul_normal(r,a,i,b,i);
bn_mul_normal(r,a,n+tna,b,n+tnb);
return;
}
/* r=(a[0]-a[1])*(b[1]-b[0]) */
c1=bn_cmp_words(a,&(a[n]),n);
c2=bn_cmp_words(&(b[n]),b,n);
c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna);
c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n);
zero=neg=0;
switch (c1*3+c2)
{
case -4:
bn_sub_words(t, &(a[n]),a, n); /* - */
bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
break;
case -3:
zero=1;
/* break; */
case -2:
bn_sub_words(t, &(a[n]),a, n); /* - */
bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */
bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */
bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); /* + */
neg=1;
break;
case -1:
@@ -261,16 +586,16 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn,
zero=1;
/* break; */
case 2:
bn_sub_words(t, a, &(a[n]),n); /* + */
bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */
bn_sub_part_words(t, a, &(a[n]),tna,n-tna); /* + */
bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */
neg=1;
break;
case 3:
zero=1;
/* break; */
case 4:
bn_sub_words(t, a, &(a[n]),n);
bn_sub_words(&(t[n]),&(b[n]),b, n);
bn_sub_part_words(t, a, &(a[n]),tna,n-tna);
bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n);
break;
}
/* The zero case isn't yet implemented here. The speedup
@@ -289,54 +614,59 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn,
{
bn_mul_comba8(&(t[n2]),t,&(t[n]));
bn_mul_comba8(r,a,b);
bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2));
bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
memset(&(r[n2+tna+tnb]),0,sizeof(BN_ULONG)*(n2-tna-tnb));
}
else
{
p= &(t[n2*2]);
bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p);
bn_mul_recursive(r,a,b,n,p);
bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p);
bn_mul_recursive(r,a,b,n,0,0,p);
i=n/2;
/* If there is only a bottom half to the number,
* just do it */
j=tn-i;
if (tna > tnb)
j = tna - i;
else
j = tnb - i;
if (j == 0)
{
bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),i,p);
bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),
i,tna-i,tnb-i,p);
memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2));
}
else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */
{
bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]),
j,i,p);
memset(&(r[n2+tn*2]),0,
sizeof(BN_ULONG)*(n2-tn*2));
i,tna-i,tnb-i,p);
memset(&(r[n2+tna+tnb]),0,
sizeof(BN_ULONG)*(n2-tna-tnb));
}
else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
{
memset(&(r[n2]),0,sizeof(BN_ULONG)*n2);
if (tn < BN_MUL_RECURSIVE_SIZE_NORMAL)
if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
&& tnb < BN_MUL_RECURSIVE_SIZE_NORMAL)
{
bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn);
bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb);
}
else
{
for (;;)
{
i/=2;
if (i < tn)
if (i < tna && i < tnb)
{
bn_mul_part_recursive(&(r[n2]),
&(a[n]),&(b[n]),
tn-i,i,p);
i,tna-i,tnb-i,p);
break;
}
else if (i == tn)
else if (i <= tna && i <= tnb)
{
bn_mul_recursive(&(r[n2]),
&(a[n]),&(b[n]),
i,p);
i,tna-i,tnb-i,p);
break;
}
}
@@ -397,10 +727,10 @@ void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
int n=n2/2;
# ifdef BN_COUNT
printf(" bn_mul_low_recursive %d * %d\n",n2,n2);
fprintf(stderr," bn_mul_low_recursive %d * %d\n",n2,n2);
# endif
bn_mul_recursive(r,a,b,n,&(t[0]));
bn_mul_recursive(r,a,b,n,0,0,&(t[0]));
if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL)
{
bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2]));
@@ -431,7 +761,7 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
BN_ULONG ll,lc,*lp,*mp;
# ifdef BN_COUNT
printf(" bn_mul_high %d * %d\n",n2,n2);
fprintf(stderr," bn_mul_high %d * %d\n",n2,n2);
# endif
n=n2/2;
@@ -484,8 +814,8 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
else
# endif
{
bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,&(t[n2]));
bn_mul_recursive(r,&(a[n]),&(b[n]),n,&(t[n2]));
bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,0,0,&(t[n2]));
bn_mul_recursive(r,&(a[n]),&(b[n]),n,0,0,&(t[n2]));
}
/* s0 == low(al*bl)
@@ -610,19 +940,19 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
int ret=0;
int top,al,bl;
BIGNUM *rr;
int ret = 0;
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
int i;
#endif
#ifdef BN_RECURSION
BIGNUM *t;
int j,k;
BIGNUM *t=NULL;
int j=0,k;
#endif
#ifdef BN_COUNT
printf("BN_mul %d * %d\n",a->top,b->top);
fprintf(stderr,"BN_mul %d * %d\n",a->top,b->top);
#endif
bn_check_top(a);
@@ -675,21 +1005,55 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
#ifdef BN_RECURSION
if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL))
{
if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA) && bl<b->dmax)
if (i >= -1 && i <= 1)
{
#if 0 /* tribute to const-ification, bl<b->dmax above covers for this */
if (bn_wexpand(b,al) == NULL) goto err;
#endif
b->d[bl]=0;
int sav_j =0;
/* Find out the power of two lower or equal
to the longest of the two numbers */
if (i >= 0)
{
j = BN_num_bits_word((BN_ULONG)al);
}
if (i == -1)
{
j = BN_num_bits_word((BN_ULONG)bl);
}
sav_j = j;
j = 1<<(j-1);
assert(j <= al || j <= bl);
k = j+j;
t = BN_CTX_get(ctx);
if (al > j || bl > j)
{
bn_wexpand(t,k*4);
bn_wexpand(rr,k*4);
bn_mul_part_recursive(rr->d,a->d,b->d,
j,al-j,bl-j,t->d);
}
else /* al <= j || bl <= j */
{
bn_wexpand(t,k*2);
bn_wexpand(rr,k*2);
bn_mul_recursive(rr->d,a->d,b->d,
j,al-j,bl-j,t->d);
}
rr->top=top;
goto end;
}
#if 0
if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA))
{
BIGNUM *tmp_bn = (BIGNUM *)b;
if (bn_wexpand(tmp_bn,al) == NULL) goto err;
tmp_bn->d[bl]=0;
bl++;
i--;
}
else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA) && al<a->dmax)
else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA))
{
#if 0 /* tribute to const-ification, al<a->dmax above covers for this */
if (bn_wexpand(a,bl) == NULL) goto err;
#endif
a->d[al]=0;
BIGNUM *tmp_bn = (BIGNUM *)a;
if (bn_wexpand(tmp_bn,bl) == NULL) goto err;
tmp_bn->d[al]=0;
al++;
i++;
}
@@ -706,26 +1070,17 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
if (bn_wexpand(t,k*2) == NULL) goto err;
if (bn_wexpand(rr,k*2) == NULL) goto err;
bn_mul_recursive(rr->d,a->d,b->d,al,t->d);
rr->top=top;
goto end;
}
#if 0 /* tribute to const-ification, rsa/dsa performance is not affected */
else
{
if (bn_wexpand(a,k) == NULL ) goto err;
if (bn_wexpand(b,k) == NULL ) goto err;
if (bn_wexpand(t,k*4) == NULL ) goto err;
if (bn_wexpand(rr,k*4) == NULL ) goto err;
for (i=a->top; i<k; i++)
a->d[i]=0;
for (i=b->top; i<k; i++)
b->d[i]=0;
if (bn_wexpand(t,k*4) == NULL) goto err;
if (bn_wexpand(rr,k*4) == NULL) goto err;
bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
}
rr->top=top;
goto end;
#endif
}
#endif
}
#endif /* BN_RECURSION */
if (bn_wexpand(rr,top) == NULL) goto err;
@@ -748,7 +1103,7 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
BN_ULONG *rr;
#ifdef BN_COUNT
printf(" bn_mul_normal %d * %d\n",na,nb);
fprintf(stderr," bn_mul_normal %d * %d\n",na,nb);
#endif
if (na < nb)
@@ -761,7 +1116,13 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
}
rr= &(r[na]);
rr[0]=bn_mul_words(r,a,na,b[0]);
if (nb <= 0)
{
(void)bn_mul_words(r,a,na,0);
return;
}
else
rr[0]=bn_mul_words(r,a,na,b[0]);
for (;;)
{
@@ -782,7 +1143,7 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
{
#ifdef BN_COUNT
printf(" bn_mul_low_normal %d * %d\n",n,n);
fprintf(stderr," bn_mul_low_normal %d * %d\n",n,n);
#endif
bn_mul_words(r,a,n,b[0]);

843
crypto/bn/bn_nist.c Normal file
View File

@@ -0,0 +1,843 @@
/* crypto/bn/bn_nist.p */
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "bn_lcl.h"
#include "cryptlib.h"
#define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2
#define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2
#define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2
#define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2
#define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2
#if BN_BITS2 == 64
const static BN_ULONG _nist_p_192[] = {0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFE,
0xFFFFFFFFFFFFFFFF};
const static BN_ULONG _nist_p_224[] = {0x0000000000000001,0xFFFFFFFF00000000,
0xFFFFFFFFFFFFFFFF,0x00000000FFFFFFFF};
const static BN_ULONG _nist_p_256[] = {0xFFFFFFFFFFFFFFFF,0x00000000FFFFFFFF,
0x0000000000000000,0xFFFFFFFF00000001};
const static BN_ULONG _nist_p_384[] = {0x00000000FFFFFFFF,0xFFFFFFFF00000000,
0xFFFFFFFFFFFFFFFE,0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,
0xFFFFFFFFFFFFFFFF};
const static BN_ULONG _nist_p_521[] = {0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,
0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,
0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF,
0x00000000000001FF};
#elif BN_BITS2 == 32
const static BN_ULONG _nist_p_192[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
const static BN_ULONG _nist_p_224[] = {0x00000001,0x00000000,0x00000000,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
const static BN_ULONG _nist_p_256[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0x00000000,0x00000000,0x00000000,0x00000001,0xFFFFFFFF};
const static BN_ULONG _nist_p_384[] = {0xFFFFFFFF,0x00000000,0x00000000,
0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
const static BN_ULONG _nist_p_521[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
0xFFFFFFFF,0x000001FF};
#elif BN_BITS2 == 16
const static BN_ULONG _nist_p_192[] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFE,
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF};
const static BN_ULONG _nist_p_224[] = {0x0001,0x0000,0x0000,0x0000,0x0000,
0x0000,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF};
const static BN_ULONG _nist_p_256[] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
0xFFFF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0001,0x0000,0xFFFF,
0xFFFF};
const static BN_ULONG _nist_p_384[] = {0xFFFF,0xFFFF,0x0000,0x0000,0x0000,
0x0000,0xFFFF,0xFFFF,0xFFFE,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF};
const static BN_ULONG _nist_p_521[] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x01FF};
#elif BN_BITS2 == 8
const static BN_ULONG _nist_p_192[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF};
const static BN_ULONG _nist_p_224[] = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
const static BN_ULONG _nist_p_256[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF};
const static BN_ULONG _nist_p_384[] = {0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
const static BN_ULONG _nist_p_521[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0x01};
#endif
const BIGNUM *BN_get0_nist_prime_192(void)
{
static BIGNUM const_nist_192={(BN_ULONG *)_nist_p_192,BN_NIST_192_TOP,
BN_NIST_192_TOP, 0, BN_FLG_STATIC_DATA};
return &const_nist_192;
}
const BIGNUM *BN_get0_nist_prime_224(void)
{
static BIGNUM const_nist_224={(BN_ULONG *)_nist_p_224,BN_NIST_224_TOP,
BN_NIST_224_TOP, 0, BN_FLG_STATIC_DATA};
return &const_nist_224;
}
const BIGNUM *BN_get0_nist_prime_256(void)
{
static BIGNUM const_nist_256={(BN_ULONG *)_nist_p_256,BN_NIST_256_TOP,
BN_NIST_256_TOP, 0, BN_FLG_STATIC_DATA};
return &const_nist_256;
}
const BIGNUM *BN_get0_nist_prime_384(void)
{
static BIGNUM const_nist_384={(BN_ULONG *)_nist_p_384,BN_NIST_384_TOP,
BN_NIST_384_TOP, 0, BN_FLG_STATIC_DATA};
return &const_nist_384;
}
const BIGNUM *BN_get0_nist_prime_521(void)
{
static BIGNUM const_nist_521={(BN_ULONG *)_nist_p_521,BN_NIST_521_TOP,
BN_NIST_521_TOP, 0, BN_FLG_STATIC_DATA};
return &const_nist_521;
}
/* some misc internal functions */
static BN_ULONG _256_data[BN_NIST_256_TOP*6];
static int _is_set_256_data = 0;
static void _init_256_data(void);
static BN_ULONG _384_data[BN_NIST_384_TOP*8];
static int _is_set_384_data = 0;
static void _init_384_data(void);
#define BN_NIST_ADD_ONE(a) while (!(++(*(a)))) ++(a);
#define __buf_0 (BN_ULONG)0
#define __buf_0_1 (BN_ULONG)0
#define __buf_0_2 (BN_ULONG)0
#if BN_BITS2 == 64
#define BN_64_BIT_BUF(n) BN_ULONG __buf_##n = (BN_ULONG)0;
#define BN_CP_64_TO_BUF(n) __buf_##n = (a)[(n)];
#define BN_CP_64_FROM_BUF(a,n) *(a)++ = __buf_##n;
#define BN_CASE_64_BIT(n,a) case (n): __buf_##n = (a)[(n)];
#if UINT_MAX == 4294967295UL
#define nist32 unsigned int
#define BN_32_BIT_BUF(n) nist32 __buf_##n = (nist32)0;
#define BN_CP_32_TO_BUF(n) __buf_##n = ((nist32 *)(a))[(n)];
#define BN_CP_32_FROM_BUF(a,n) *((nist32)(a))++ = __buf_##n;
#define BN_CASE_32_BIT(n,a) case (n): __buf_##n = ((nist32)(a))[(n)];
#elif ULONG_MAX == 4294967295UL
#define nist32 unsigned long
#define BN_32_BIT_BUF(n) nist32 __buf_##n = (nist32)0;
#define BN_CP_32_TO_BUF(n) __buf_##n = ((nist32 *)(a))[(n)];
#define BN_CP_32_FROM_BUF(a,n) *((nist32)(a))++ = __buf_##n;
#define BN_CASE_32_BIT(n,a) case (n): __buf_##n = ((nist32)(a))[(n)];
#else
#define NO_32_BIT_TYPE
#endif
#elif BN_BITS2 == 32
#define BN_64_BIT_BUF(n) BN_ULONG __buf_##n##_1 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_2 = (BN_ULONG)0;
#define BN_CP_64_TO_BUF(n) __buf_##n##_2 = (a)[2*(n)+1];\
__buf_##n##_1 = (a)[2*(n)];
#define BN_CP_64_FROM_BUF(a,n) *(a)++ = __buf_##n##_1;\
*(a)++ = __buf_##n##_2;
#define BN_CASE_64_BIT(n,a) case 2*(n)+1: __buf_##n##_2 = (a)[2*(n)+1];\
case 2*(n): __buf_##n##_1 = (a)[2*(n)];
#define BN_32_BIT_BUF(n) BN_ULONG __buf_##n = (BN_ULONG)0;
#define BN_CP_32_TO_BUF(n) __buf_##n = (a)[(n)];
#define BN_CP_32_FROM_BUF(a,n) *(a)++ = __buf_##n;
#define BN_CASE_32_BIT(n,a) case (n): __buf_##n = (a)[(n)];
#elif BN_BITS2 == 16
#define __buf_0_3 (BN_ULONG)0
#define __buf_0_4 (BN_ULONG)0
#define BN_64_BIT_BUF(n) BN_ULONG __buf_##n##_1 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_2 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_3 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_4 = (BN_ULONG)0;
#define BN_CP_64_TO_BUF(n) __buf_##n##_4 = (a)[4*(n)+3];\
__buf_##n##_3 = (a)[4*(n)+2];\
__buf_##n##_2 = (a)[4*(n)+1];\
__buf_##n##_1 = (a)[4*(n)];
#define BN_CP_64_FROM_BUF(a,n) *(a)++ = __buf_##n##_1;\
*(a)++ = __buf_##n##_2;\
*(a)++ = __buf_##n##_3;\
*(a)++ = __buf_##n##_4;
#define BN_CASE_64_BIT(n,a) case 4*(n)+3: __buf_##n##_4 = (a)[4*(n)+3];\
case 4*(n)+2: __buf_##n##_3 = (a)[4*(n)+2];\
case 4*(n)+1: __buf_##n##_2 = (a)[4*(n)+1];\
case 4*(n): __buf_##n##_1 = (a)[4*(n)];
#define BN_32_BIT_BUF(n) BN_ULONG __buf_##n##_1 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_2 = (BN_ULONG)0;
#define BN_CP_32_TO_BUF(n) __buf_##n##_1 = (a)[2*(n)];\
__buf_##n##_2 = (a)[2*(n)+1];
#define BN_CP_32_FROM_BUF(a,n) *(a)++ = __buf_##n##_1;\
*(a)++ = __buf_##n##_2;
#define BN_CASE_32_BIT(n,a) case 2*(n)+1: __buf_##n##_2 = (a)[2*(n)+1];\
case 2*(n): __buf_##n##_1 = (a)[2*(n)];
#elif BN_BITS2 == 8
#define __buf_0_3 (BN_ULONG)0
#define __buf_0_4 (BN_ULONG)0
#define __buf_0_5 (BN_ULONG)0
#define __buf_0_6 (BN_ULONG)0
#define __buf_0_7 (BN_ULONG)0
#define __buf_0_8 (BN_ULONG)0
#define BN_64_BIT_BUF(n) BN_ULONG __buf_##n##_1 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_2 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_3 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_4 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_5 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_6 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_7 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_8 = (BN_ULONG)0;
#define BN_CP_64_TO_BUF(n) __buf_##n##_8 = (a)[8*(n)+7];\
__buf_##n##_7 = (a)[8*(n)+6];\
__buf_##n##_6 = (a)[8*(n)+5];\
__buf_##n##_5 = (a)[8*(n)+4];\
__buf_##n##_4 = (a)[8*(n)+3];\
__buf_##n##_3 = (a)[8*(n)+2];\
__buf_##n##_2 = (a)[8*(n)+1];\
__buf_##n##_1 = (a)[8*(n)];
#define BN_CP_64_FROM_BUF(a,n) *(a)++ = __buf_##n##_1;\
*(a)++ = __buf_##n##_2;\
*(a)++ = __buf_##n##_3;\
*(a)++ = __buf_##n##_4;\
*(a)++ = __buf_##n##_5;\
*(a)++ = __buf_##n##_6;\
*(a)++ = __buf_##n##_7;\
*(a)++ = __buf_##n##_8;
#define BN_CASE_64_BIT(n,a) case 8*(n)+7: __buf_##n##_8 = (a)[8*(n)+7];\
case 8*(n)+6: __buf_##n##_7 = (a)[8*(n)+6];\
case 8*(n)+5: __buf_##n##_6 = (a)[8*(n)+5];\
case 8*(n)+4: __buf_##n##_5 = (a)[8*(n)+4];\
case 8*(n)+3: __buf_##n##_4 = (a)[8*(n)+3];\
case 8*(n)+2: __buf_##n##_3 = (a)[8*(n)+2];\
case 8*(n)+1: __buf_##n##_2 = (a)[8*(n)+1];\
case 8*(n): __buf_##n##_1 = (a)[8*(n)];
#define BN_32_BIT_BUF(n) BN_ULONG __buf_##n##_1 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_2 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_3 = (BN_ULONG)0;\
BN_ULONG __buf_##n##_4 = (BN_ULONG)0;
#define BN_CP_32_TO_BUF(n) __buf_##n##_1 = (a)[4*(n)];\
__buf_##n##_2 = (a)[4*(n)+1];\
__buf_##n##_3 = (a)[4*(n)+2];\
__buf_##n##_4 = (a)[4*(n)+3];
#define BN_CP_32_FROM_BUF(a,n) *(a)++ = __buf_##n##_1;\
*(a)++ = __buf_##n##_2;\
*(a)++ = __buf_##n##_3;\
*(a)++ = __buf_##n##_4;
#define BN_CASE_32_BIT(n,a) case 4*(n)+3: __buf_##n##_4 = (a)[4*(n)+3];\
case 4*(n)+2: __buf_##n##_3 = (a)[4*(n)+2];\
case 4*(n)+1: __buf_##n##_2 = (a)[4*(n)+1];\
case 4*(n): __buf_##n##_1 = (a)[4*(n)];
#endif
#define BN_192_SET(d,a1,a2,a3) \
{\
register BN_ULONG *td = (d);\
BN_CP_64_FROM_BUF(td,a3); BN_CP_64_FROM_BUF(td,a2);\
BN_CP_64_FROM_BUF(td,a1);\
}
int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
BN_CTX *ctx)
{
int top;
BN_ULONG carry = 0;
register BN_ULONG *r_d, *a_d;
BN_ULONG t_d[BN_NIST_192_TOP];
BN_64_BIT_BUF(3) BN_64_BIT_BUF(4)
BN_64_BIT_BUF(5)
top = BN_ucmp(field, a);
if (top == 0)
return BN_zero(r);
else if (top > 0)
return (r == a)? 1 : (BN_copy(r ,a) != NULL);
if (r != a)
if (!BN_ncopy(r, a, BN_NIST_192_TOP))
return 0;
r_d = r->d;
a_d = a->d;
top = a->top-1;
switch (top)
{
BN_CASE_64_BIT(5, a_d)
BN_CASE_64_BIT(4, a_d)
BN_CASE_64_BIT(3, a_d)
break;
default: /* a->top == field->top */
return BN_usub(r, a, field);
}
BN_192_SET(t_d,0,3,3)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP))
++carry;
BN_192_SET(t_d,4,4,0)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP))
++carry;
BN_192_SET(t_d,5,5,5)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP))
++carry;
while (carry)
{
if (bn_sub_words(r_d, r_d, _nist_p_192, BN_NIST_192_TOP))
--carry;
}
r->top = BN_NIST_192_TOP;
#if 1
bn_clear_top2max(r);
#endif
bn_fix_top(r);
if (BN_ucmp(r, field) >= 0)
{
bn_sub_words(r_d, r_d, _nist_p_192, BN_NIST_192_TOP);
bn_fix_top(r);
}
return 1;
}
#define BN_224_SET(d,a1,a2,a3,a4,a5,a6,a7) \
{\
register BN_ULONG *td = (d);\
BN_CP_32_FROM_BUF(td,a7); BN_CP_32_FROM_BUF(td,a6);\
BN_CP_32_FROM_BUF(td,a5); BN_CP_32_FROM_BUF(td,a4);\
BN_CP_32_FROM_BUF(td,a3); BN_CP_32_FROM_BUF(td,a2);\
BN_CP_32_FROM_BUF(td,a1);\
}
int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
BN_CTX *ctx)
{
#ifndef NO_32_BIT_TYPE
int tmp_int;
int carry = 0;
BN_ULONG *r_d, *a_d;
BN_ULONG t_d[BN_NIST_224_TOP];
BN_32_BIT_BUF(7) BN_32_BIT_BUF(8)
BN_32_BIT_BUF(9) BN_32_BIT_BUF(10)
BN_32_BIT_BUF(11) BN_32_BIT_BUF(12)
BN_32_BIT_BUF(13)
tmp_int = BN_ucmp(field, a);
if (tmp_int == 0)
return BN_zero(r);
else if (tmp_int > 0)
return (r == a)? 1 : (BN_copy(r ,a) != NULL);
if (r != a)
if (!BN_ncopy(r, a, BN_NIST_224_TOP))
return 0;
r_d = r->d;
a_d = a->d;
tmp_int = a->top-1;
switch (tmp_int)
{
BN_CASE_32_BIT(13, a_d)
BN_CASE_32_BIT(12, a_d)
BN_CASE_32_BIT(11, a_d)
BN_CASE_32_BIT(10, a_d)
BN_CASE_32_BIT(9, a_d)
BN_CASE_32_BIT(8, a_d)
BN_CASE_32_BIT(7, a_d)
break;
default: /* a->top == field->top */
return BN_usub(r, a, field);
}
BN_224_SET(t_d,10,9,8,7,0,0,0)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP))
++carry;
BN_224_SET(t_d,0,13,12,11,0,0,0)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP))
++carry;
BN_224_SET(t_d,13,12,11,10,9,8,7)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP))
--carry;
BN_224_SET(t_d,0,0,0,0,13,12,11)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP))
--carry;
if (carry > 0)
while (carry)
{
if (bn_sub_words(r_d,r_d,_nist_p_224,BN_NIST_224_TOP))
--carry;
}
else if (carry < 0)
while (carry)
{
if (bn_add_words(r_d,r_d,_nist_p_224,BN_NIST_224_TOP))
++carry;
}
r->top = BN_NIST_224_TOP;
#if 1
bn_clear_top2max(r);
#endif
bn_fix_top(r);
if (BN_ucmp(r, field) >= 0)
{
bn_sub_words(r_d, r_d, _nist_p_224, BN_NIST_224_TOP);
bn_fix_top(r);
}
return 1;
#else
return 0;
#endif
}
static void _init_256_data(void)
{
int i;
BN_ULONG *tmp1 = _256_data;
const BN_ULONG *tmp2 = tmp1;
memcpy(tmp1, _nist_p_256, BN_NIST_256_TOP * sizeof(BN_ULONG));
tmp1 += BN_NIST_256_TOP;
for (i=0; i<5; i++)
{
bn_add_words(tmp1, _nist_p_256, tmp2, BN_NIST_256_TOP);
tmp2 = tmp1;
tmp1 += BN_NIST_256_TOP;
}
_is_set_256_data = 1;
}
#define BN_256_SET(d,a1,a2,a3,a4,a5,a6,a7,a8) \
{\
register BN_ULONG *td = (d);\
BN_CP_32_FROM_BUF(td,a8); BN_CP_32_FROM_BUF(td,a7);\
BN_CP_32_FROM_BUF(td,a6); BN_CP_32_FROM_BUF(td,a5);\
BN_CP_32_FROM_BUF(td,a4); BN_CP_32_FROM_BUF(td,a3);\
BN_CP_32_FROM_BUF(td,a2); BN_CP_32_FROM_BUF(td,a1);\
}
int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
BN_CTX *ctx)
{
#ifndef NO_32_BIT_TYPE
int tmp_int;
int carry = 0;
register BN_ULONG *a_d, *r_d;
BN_ULONG t_d[BN_NIST_256_TOP];
BN_ULONG t_d2[BN_NIST_256_TOP];
BN_32_BIT_BUF(8) BN_32_BIT_BUF(9)
BN_32_BIT_BUF(10) BN_32_BIT_BUF(11)
BN_32_BIT_BUF(12) BN_32_BIT_BUF(13)
BN_32_BIT_BUF(14) BN_32_BIT_BUF(15)
if (!_is_set_256_data)
{
CRYPTO_w_lock(CRYPTO_LOCK_BN);
if (!_is_set_256_data)
_init_256_data();
CRYPTO_w_unlock(CRYPTO_LOCK_BN);
}
tmp_int = BN_ucmp(field, a);
if (tmp_int == 0)
return BN_zero(r);
else if (tmp_int > 0)
return (r == a)? 1 : (BN_copy(r ,a) != NULL);
if (r != a)
if (!BN_ncopy(r, a, BN_NIST_256_TOP))
return 0;
tmp_int = a->top-1;
a_d = a->d;
r_d = r->d;
switch (tmp_int)
{
BN_CASE_32_BIT(15, a_d)
BN_CASE_32_BIT(14, a_d)
BN_CASE_32_BIT(13, a_d)
BN_CASE_32_BIT(12, a_d)
BN_CASE_32_BIT(11, a_d)
BN_CASE_32_BIT(10, a_d)
BN_CASE_32_BIT(9, a_d)
BN_CASE_32_BIT(8, a_d)
break;
default: /* a->top == field->top */
return BN_usub(r, a, field);
}
/*S1*/
BN_256_SET(t_d,15,14,13,12,11,0,0,0)
/*S2*/
BN_256_SET(t_d2,0,15,14,13,12,0,0,0)
if (bn_add_words(t_d, t_d, t_d2, BN_NIST_256_TOP))
carry = 2;
/* left shift */
{
register BN_ULONG *ap,t,c;
ap = t_d;
c=0;
for (tmp_int=BN_NIST_256_TOP; tmp_int != 0; --tmp_int)
{
t= *ap;
*(ap++)=((t<<1)|c)&BN_MASK2;
c=(t & BN_TBIT)?1:0;
}
if (c)
++carry;
}
if (bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP))
++carry;
/*S3*/
BN_256_SET(t_d,15,14,0,0,0,10,9,8)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP))
++carry;
/*S4*/
BN_256_SET(t_d,8,13,15,14,13,11,10,9)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP))
++carry;
/*D1*/
BN_256_SET(t_d,10,8,0,0,0,13,12,11)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
--carry;
/*D2*/
BN_256_SET(t_d,11,9,0,0,15,14,13,12)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
--carry;
/*D3*/
BN_256_SET(t_d,12,0,10,9,8,15,14,13)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
--carry;
/*D4*/
BN_256_SET(t_d,13,0,11,10,9,0,15,14)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
--carry;
if (carry)
{
if (carry > 0)
bn_sub_words(r_d, r_d, _256_data + BN_NIST_256_TOP *
--carry, BN_NIST_256_TOP);
else
{
carry = -carry;
bn_add_words(r_d, r_d, _256_data + BN_NIST_256_TOP *
--carry, BN_NIST_256_TOP);
}
}
r->top = BN_NIST_256_TOP;
#if 1
bn_clear_top2max(r);
#endif
bn_fix_top(r);
if (BN_ucmp(r, field) >= 0)
{
bn_sub_words(r_d, r_d, _nist_p_256, BN_NIST_256_TOP);
bn_fix_top(r);
}
return 1;
#else
return 0;
#endif
}
static void _init_384_data(void)
{
int i;
BN_ULONG *tmp1 = _384_data;
const BN_ULONG *tmp2 = tmp1;
memcpy(tmp1, _nist_p_384, BN_NIST_384_TOP * sizeof(BN_ULONG));
tmp1 += BN_NIST_384_TOP;
for (i=0; i<7; i++)
{
bn_add_words(tmp1, _nist_p_384, tmp2, BN_NIST_384_TOP);
tmp2 = tmp1;
tmp1 += BN_NIST_384_TOP;
}
_is_set_384_data = 1;
}
#define BN_384_SET(d,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
{\
register BN_ULONG *td = (d);\
BN_CP_32_FROM_BUF(td,a12); BN_CP_32_FROM_BUF(td,a11);\
BN_CP_32_FROM_BUF(td,a10); BN_CP_32_FROM_BUF(td,a9);\
BN_CP_32_FROM_BUF(td,a8); BN_CP_32_FROM_BUF(td,a7);\
BN_CP_32_FROM_BUF(td,a6); BN_CP_32_FROM_BUF(td,a5);\
BN_CP_32_FROM_BUF(td,a4); BN_CP_32_FROM_BUF(td,a3);\
BN_CP_32_FROM_BUF(td,a2); BN_CP_32_FROM_BUF(td,a1);\
}
int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
BN_CTX *ctx)
{
#ifndef NO_32_BIT_TYPE
int tmp_int;
int carry = 0;
register BN_ULONG *r_d, *a_d;
BN_ULONG t_d[BN_NIST_384_TOP];
BN_32_BIT_BUF(12) BN_32_BIT_BUF(13)
BN_32_BIT_BUF(14) BN_32_BIT_BUF(15)
BN_32_BIT_BUF(16) BN_32_BIT_BUF(17)
BN_32_BIT_BUF(18) BN_32_BIT_BUF(19)
BN_32_BIT_BUF(20) BN_32_BIT_BUF(21)
BN_32_BIT_BUF(22) BN_32_BIT_BUF(23)
if (!_is_set_384_data)
{
CRYPTO_w_lock(CRYPTO_LOCK_BN);
if (!_is_set_384_data)
_init_384_data();
CRYPTO_w_unlock(CRYPTO_LOCK_BN);
}
tmp_int = BN_ucmp(field, a);
if (tmp_int == 0)
return BN_zero(r);
else if (tmp_int > 0)
return (r == a)? 1 : (BN_copy(r ,a) != NULL);
if (r != a)
if (!BN_ncopy(r, a, BN_NIST_384_TOP))
return 0;
r_d = r->d;
a_d = a->d;
tmp_int = a->top-1;
switch (tmp_int)
{
BN_CASE_32_BIT(23, a_d)
BN_CASE_32_BIT(22, a_d)
BN_CASE_32_BIT(21, a_d)
BN_CASE_32_BIT(20, a_d)
BN_CASE_32_BIT(19, a_d)
BN_CASE_32_BIT(18, a_d)
BN_CASE_32_BIT(17, a_d)
BN_CASE_32_BIT(16, a_d)
BN_CASE_32_BIT(15, a_d)
BN_CASE_32_BIT(14, a_d)
BN_CASE_32_BIT(13, a_d)
BN_CASE_32_BIT(12, a_d)
break;
default: /* a->top == field->top */
return BN_usub(r, a, field);
}
/*S1*/
BN_256_SET(t_d,0,0,0,0,0,23,22,21)
/* left shift */
{
register BN_ULONG *ap,t,c;
ap = t_d;
c=0;
for (tmp_int=BN_NIST_256_TOP; tmp_int != 0; --tmp_int)
{
t= *ap;
*(ap++)=((t<<1)|c)&BN_MASK2;
c=(t & BN_TBIT)?1:0;
}
}
if (bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2),
t_d, BN_NIST_256_TOP))
++carry;
/*S2*/
BN_384_SET(t_d,23,22,21,20,19,18,17,16,15,14,13,12)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP))
++carry;
/*S3*/
BN_384_SET(t_d,20,19,18,17,16,15,14,13,12,23,22,21)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP))
++carry;
/*S4*/
BN_384_SET(t_d,19,18,17,16,15,14,13,12,20,0,23,0)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP))
++carry;
/*S5*/
BN_256_SET(t_d,0,0,0,0,23,22,21,20)
if (bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2),
t_d, BN_NIST_256_TOP))
++carry;
/*S6*/
BN_384_SET(t_d,0,0,0,0,0,0,23,22,21,0,0,20)
if (bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP))
++carry;
/*D1*/
BN_384_SET(t_d,22,21,20,19,18,17,16,15,14,13,12,23)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP))
--carry;
/*D2*/
BN_384_SET(t_d,0,0,0,0,0,0,0,23,22,21,20,0)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP))
--carry;
/*D3*/
BN_384_SET(t_d,0,0,0,0,0,0,0,23,23,0,0,0)
if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP))
--carry;
if (carry)
{
if (carry > 0)
bn_sub_words(r_d, r_d, _384_data + BN_NIST_384_TOP *
--carry, BN_NIST_384_TOP);
else
{
carry = -carry;
bn_add_words(r_d, r_d, _384_data + BN_NIST_384_TOP *
--carry, BN_NIST_384_TOP);
}
}
r->top = BN_NIST_384_TOP;
#if 1
bn_clear_top2max(r);
#endif
bn_fix_top(r);
if (BN_ucmp(r, field) >= 0)
{
bn_sub_words(r_d, r_d, _nist_p_384, BN_NIST_384_TOP);
bn_fix_top(r);
}
return 1;
#else
return 0;
#endif
}
int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
BN_CTX *ctx)
{
#if BN_BITS2 == 64
#define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF
#elif BN_BITS2 == 32
#define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF
#elif BN_BITS2 == 16
#define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF
#elif BN_BITS2 == 8
#define BN_NIST_521_TOP_MASK (BN_ULONG)0x1
#endif
int top, ret = 0;
BN_ULONG *r_d;
BIGNUM *tmp;
/* check whether a reduction is necessary */
top = a->top;
if (top < BN_NIST_521_TOP || ( top == BN_NIST_521_TOP &&
(!(a->d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK)))))
return (r == a)? 1 : (BN_copy(r ,a) != NULL);
BN_CTX_start(ctx);
tmp = BN_CTX_get(ctx);
if (!tmp)
goto err;
if (!BN_ncopy(tmp, a, BN_NIST_521_TOP))
return 0;
if (!BN_rshift(r, a, 521))
return 0;
if (tmp->top == BN_NIST_521_TOP)
tmp->d[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK;
if (!BN_uadd(r, tmp, r))
return 0;
top = r->top;
r_d = r->d;
if (top == BN_NIST_521_TOP &&
(r_d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK)))
{
BN_NIST_ADD_ONE(r_d)
r_d[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK;
}
bn_fix_top(r);
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}

View File

@@ -230,6 +230,7 @@ static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range)
{
int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand;
int n;
int count = 100;
if (range->neg || BN_is_zero(range))
{
@@ -263,6 +264,13 @@ static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range)
if (BN_cmp(r, range) >= 0)
if (!BN_sub(r, r, range)) return 0;
}
if (!--count)
{
BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
return 0;
}
}
while (BN_cmp(r, range) >= 0);
}
@@ -272,6 +280,12 @@ static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range)
{
/* range = 11..._2 or range = 101..._2 */
if (!bn_rand(r, n, -1, 0)) return 0;
if (!--count)
{
BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
return 0;
}
}
while (BN_cmp(r, range) >= 0);
}

View File

@@ -65,14 +65,12 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
* using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course
* in Algebraic Computational Number Theory", algorithm 1.5.1).
* 'p' must be prime!
* If 'a' is not a square, this is not necessarily detected by
* the algorithms; a bogus result must be expected in this case.
*/
{
BIGNUM *ret = in;
int err = 1;
int r;
BIGNUM *b, *q, *t, *x, *y;
BIGNUM *A, *b, *q, *t, *x, *y;
int e, i, j;
if (!BN_is_odd(p) || BN_abs_is_word(p, 1))
@@ -109,17 +107,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
return ret;
}
#if 0 /* if BN_mod_sqrt is used with correct input, this just wastes time */
r = BN_kronecker(a, p, ctx);
if (r < -1) return NULL;
if (r == -1)
{
BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
return(NULL);
}
#endif
BN_CTX_start(ctx);
A = BN_CTX_get(ctx);
b = BN_CTX_get(ctx);
q = BN_CTX_get(ctx);
t = BN_CTX_get(ctx);
@@ -131,6 +120,9 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
ret = BN_new();
if (ret == NULL) goto end;
/* A = a mod p */
if (!BN_nnmod(A, a, p, ctx)) goto end;
/* now write |p| - 1 as 2^e*q where q is odd */
e = 1;
while (!BN_is_bit_set(p, e))
@@ -149,9 +141,9 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
if (!BN_rshift(q, p, 2)) goto end;
q->neg = 0;
if (!BN_add_word(q, 1)) goto end;
if (!BN_mod_exp(ret, a, q, p, ctx)) goto end;
if (!BN_mod_exp(ret, A, q, p, ctx)) goto end;
err = 0;
goto end;
goto vrfy;
}
if (e == 2)
@@ -182,15 +174,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
* November 1992.)
*/
/* make sure that a is reduced modulo p */
if (a->neg || BN_ucmp(a, p) >= 0)
{
if (!BN_nnmod(x, a, p, ctx)) goto end;
a = x; /* use x as temporary variable */
}
/* t := 2*a */
if (!BN_mod_lshift1_quick(t, a, p)) goto end;
if (!BN_mod_lshift1_quick(t, A, p)) goto end;
/* b := (2*a)^((|p|-5)/8) */
if (!BN_rshift(q, p, 3)) goto end;
@@ -205,12 +190,12 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
if (!BN_sub_word(t, 1)) goto end;
/* x = a*b*t */
if (!BN_mod_mul(x, a, b, p, ctx)) goto end;
if (!BN_mod_mul(x, A, b, p, ctx)) goto end;
if (!BN_mod_mul(x, x, t, p, ctx)) goto end;
if (!BN_copy(ret, x)) goto end;
err = 0;
goto end;
goto vrfy;
}
/* e > 2, so we really have to use the Tonelli/Shanks algorithm.
@@ -297,7 +282,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
/* x := a^((q-1)/2) */
if (BN_is_zero(t)) /* special case: p = 2^e + 1 */
{
if (!BN_nnmod(t, a, p, ctx)) goto end;
if (!BN_nnmod(t, A, p, ctx)) goto end;
if (BN_is_zero(t))
{
/* special case: a == 0 (mod p) */
@@ -310,7 +295,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
}
else
{
if (!BN_mod_exp(x, a, t, p, ctx)) goto end;
if (!BN_mod_exp(x, A, t, p, ctx)) goto end;
if (BN_is_zero(x))
{
/* special case: a == 0 (mod p) */
@@ -322,10 +307,10 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
/* b := a*x^2 (= a^q) */
if (!BN_mod_sqr(b, x, p, ctx)) goto end;
if (!BN_mod_mul(b, b, a, p, ctx)) goto end;
if (!BN_mod_mul(b, b, A, p, ctx)) goto end;
/* x := a*x (= a^((q+1)/2)) */
if (!BN_mod_mul(x, x, a, p, ctx)) goto end;
if (!BN_mod_mul(x, x, A, p, ctx)) goto end;
while (1)
{
@@ -342,7 +327,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
{
if (!BN_copy(ret, x)) goto end;
err = 0;
goto end;
goto vrfy;
}
@@ -373,6 +358,22 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
e = i;
}
vrfy:
if (!err)
{
/* verify the result -- the input might have been not a square
* (test added in 0.9.8) */
if (!BN_mod_sqr(x, ret, p, ctx))
err = 1;
if (!err && 0 != BN_cmp(x, A))
{
BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
err = 1;
}
}
end:
if (err)
{

View File

@@ -55,6 +55,19 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the Eric Young open source
* license provided above.
*
* The binary polynomial arithmetic software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
*
*/
#include <stdio.h>
#include <stdlib.h>
@@ -91,6 +104,15 @@ int test_mod(BIO *bp,BN_CTX *ctx);
int test_mod_mul(BIO *bp,BN_CTX *ctx);
int test_mod_exp(BIO *bp,BN_CTX *ctx);
int test_exp(BIO *bp,BN_CTX *ctx);
int test_gf2m_add(BIO *bp);
int test_gf2m_mod(BIO *bp);
int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx);
int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx);
int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx);
int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx);
int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx);
int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx);
int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx);
int test_kron(BIO *bp,BN_CTX *ctx);
int test_sqrt(BIO *bp,BN_CTX *ctx);
int rand_neg(void);
@@ -234,6 +256,42 @@ int main(int argc, char *argv[])
if (!test_sqrt(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_add");
if (!test_gf2m_add(out)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod");
if (!test_gf2m_mod(out)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_mul");
if (!test_gf2m_mod_mul(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_sqr");
if (!test_gf2m_mod_sqr(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_inv");
if (!test_gf2m_mod_inv(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_div");
if (!test_gf2m_mod_div(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_exp");
if (!test_gf2m_mod_exp(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_sqrt");
if (!test_gf2m_mod_sqrt(out,ctx)) goto err;
BIO_flush(out);
message(out,"BN_GF2m_mod_solve_quad");
if (!test_gf2m_mod_solve_quad(out,ctx)) goto err;
BIO_flush(out);
BN_CTX_free(ctx);
BIO_free(out);
@@ -872,6 +930,581 @@ int test_exp(BIO *bp, BN_CTX *ctx)
return(1);
}
int test_gf2m_add(BIO *bp)
{
BIGNUM a,b,c;
int i, ret = 0;
BN_init(&a);
BN_init(&b);
BN_init(&c);
for (i=0; i<num0; i++)
{
BN_rand(&a,512,0,0);
BN_copy(&b, BN_value_one());
a.neg=rand_neg();
b.neg=rand_neg();
BN_GF2m_add(&c,&a,&b);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,&a);
BIO_puts(bp," ^ ");
BN_print(bp,&b);
BIO_puts(bp," = ");
}
BN_print(bp,&c);
BIO_puts(bp,"\n");
}
#endif
/* Test that two added values have the correct parity. */
if((BN_is_odd(&a) && BN_is_odd(&c)) || (!BN_is_odd(&a) && !BN_is_odd(&c)))
{
fprintf(stderr,"GF(2^m) addition test (a) failed!\n");
goto err;
}
BN_GF2m_add(&c,&c,&c);
/* Test that c + c = 0. */
if(!BN_is_zero(&c))
{
fprintf(stderr,"GF(2^m) addition test (b) failed!\n");
goto err;
}
}
ret = 1;
err:
BN_free(&a);
BN_free(&b);
BN_free(&c);
return ret;
}
int test_gf2m_mod(BIO *bp)
{
BIGNUM *a,*b[2],*c,*d,*e;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
e=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 1024, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod(c, a, b[j]);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp," % ");
BN_print(bp,b[j]);
BIO_puts(bp," - ");
BN_print(bp,c);
BIO_puts(bp,"\n");
}
}
#endif
BN_GF2m_add(d, a, c);
BN_GF2m_mod(e, d, b[j]);
/* Test that a + (a mod p) mod p == 0. */
if(!BN_is_zero(e))
{
fprintf(stderr,"GF(2^m) modulo test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
BN_free(e);
return ret;
}
int test_gf2m_mod_mul(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d,*e,*f,*g,*h;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
e=BN_new();
f=BN_new();
g=BN_new();
h=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 1024, 0, 0);
BN_bntest_rand(c, 1024, 0, 0);
BN_bntest_rand(d, 1024, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod_mul(e, a, c, b[j], ctx);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp," * ");
BN_print(bp,c);
BIO_puts(bp," % ");
BN_print(bp,b[j]);
BIO_puts(bp," - ");
BN_print(bp,e);
BIO_puts(bp,"\n");
}
}
#endif
BN_GF2m_add(f, a, d);
BN_GF2m_mod_mul(g, f, c, b[j], ctx);
BN_GF2m_mod_mul(h, d, c, b[j], ctx);
BN_GF2m_add(f, e, g);
BN_GF2m_add(f, f, h);
/* Test that (a+d)*c = a*c + d*c. */
if(!BN_is_zero(f))
{
fprintf(stderr,"GF(2^m) modular multiplication test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
BN_free(e);
BN_free(f);
BN_free(g);
BN_free(h);
return ret;
}
int test_gf2m_mod_sqr(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 1024, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod_sqr(c, a, b[j], ctx);
BN_copy(d, a);
BN_GF2m_mod_mul(d, a, d, b[j], ctx);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp," ^ 2 % ");
BN_print(bp,b[j]);
BIO_puts(bp, " = ");
BN_print(bp,c);
BIO_puts(bp,"; a * a = ");
BN_print(bp,d);
BIO_puts(bp,"\n");
}
}
#endif
BN_GF2m_add(d, c, d);
/* Test that a*a = a^2. */
if(!BN_is_zero(d))
{
fprintf(stderr,"GF(2^m) modular squaring test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
return ret;
}
int test_gf2m_mod_inv(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 512, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod_inv(c, a, b[j], ctx);
BN_GF2m_mod_mul(d, a, c, b[j], ctx);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp, " * ");
BN_print(bp,c);
BIO_puts(bp," - 1 % ");
BN_print(bp,b[j]);
BIO_puts(bp,"\n");
}
}
#endif
/* Test that ((1/a)*a) = 1. */
if(!BN_is_one(d))
{
fprintf(stderr,"GF(2^m) modular inversion test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
return ret;
}
int test_gf2m_mod_div(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d,*e,*f;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
e=BN_new();
f=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 512, 0, 0);
BN_bntest_rand(c, 512, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod_div(d, a, c, b[j], ctx);
BN_GF2m_mod_mul(e, d, c, b[j], ctx);
BN_GF2m_mod_div(f, a, e, b[j], ctx);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp, " = ");
BN_print(bp,c);
BIO_puts(bp," * ");
BN_print(bp,d);
BIO_puts(bp, " % ");
BN_print(bp,b[j]);
BIO_puts(bp,"\n");
}
}
#endif
/* Test that ((a/c)*c)/a = 1. */
if(!BN_is_one(f))
{
fprintf(stderr,"GF(2^m) modular division test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
BN_free(e);
BN_free(f);
return ret;
}
int test_gf2m_mod_exp(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d,*e,*f;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
e=BN_new();
f=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 512, 0, 0);
BN_bntest_rand(c, 512, 0, 0);
BN_bntest_rand(d, 512, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod_exp(e, a, c, b[j], ctx);
BN_GF2m_mod_exp(f, a, d, b[j], ctx);
BN_GF2m_mod_mul(e, e, f, b[j], ctx);
BN_add(f, c, d);
BN_GF2m_mod_exp(f, a, f, b[j], ctx);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,a);
BIO_puts(bp, " ^ (");
BN_print(bp,c);
BIO_puts(bp," + ");
BN_print(bp,d);
BIO_puts(bp, ") = ");
BN_print(bp,e);
BIO_puts(bp, "; - ");
BN_print(bp,f);
BIO_puts(bp, " % ");
BN_print(bp,b[j]);
BIO_puts(bp,"\n");
}
}
#endif
BN_GF2m_add(f, e, f);
/* Test that a^(c+d)=a^c*a^d. */
if(!BN_is_zero(f))
{
fprintf(stderr,"GF(2^m) modular exponentiation test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
BN_free(e);
BN_free(f);
return ret;
}
int test_gf2m_mod_sqrt(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d,*e,*f;
int i, j, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
e=BN_new();
f=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 512, 0, 0);
for (j=0; j < 2; j++)
{
BN_GF2m_mod(c, a, b[j]);
BN_GF2m_mod_sqrt(d, a, b[j], ctx);
BN_GF2m_mod_sqr(e, d, b[j], ctx);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,d);
BIO_puts(bp, " ^ 2 - ");
BN_print(bp,a);
BIO_puts(bp,"\n");
}
}
#endif
BN_GF2m_add(f, c, e);
/* Test that d^2 = a, where d = sqrt(a). */
if(!BN_is_zero(f))
{
fprintf(stderr,"GF(2^m) modular square root test failed!\n");
goto err;
}
}
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
BN_free(e);
BN_free(f);
return ret;
}
int test_gf2m_mod_solve_quad(BIO *bp,BN_CTX *ctx)
{
BIGNUM *a,*b[2],*c,*d,*e;
int i, j, s = 0, t, ret = 0;
unsigned int p0[] = {163,7,6,3,0};
unsigned int p1[] = {193,15,0};
a=BN_new();
b[0]=BN_new();
b[1]=BN_new();
c=BN_new();
d=BN_new();
e=BN_new();
BN_GF2m_arr2poly(p0, b[0]);
BN_GF2m_arr2poly(p1, b[1]);
for (i=0; i<num0; i++)
{
BN_bntest_rand(a, 512, 0, 0);
for (j=0; j < 2; j++)
{
t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx);
if (t)
{
s++;
BN_GF2m_mod_sqr(d, c, b[j], ctx);
BN_GF2m_add(d, c, d);
BN_GF2m_mod(e, a, b[j]);
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BN_print(bp,c);
BIO_puts(bp, " is root of z^2 + z = ");
BN_print(bp,a);
BIO_puts(bp, " % ");
BN_print(bp,b[j]);
BIO_puts(bp, "\n");
}
}
#endif
BN_GF2m_add(e, e, d);
/* Test that solution of quadratic c satisfies c^2 + c = a. */
if(!BN_is_zero(e))
{
fprintf(stderr,"GF(2^m) modular solve quadratic test failed!\n");
goto err;
}
}
else
{
#if 0 /* make test uses ouput in bc but bc can't handle GF(2^m) arithmetic */
if (bp != NULL)
{
if (!results)
{
BIO_puts(bp, "There are no roots of z^2 + z = ");
BN_print(bp,a);
BIO_puts(bp, " % ");
BN_print(bp,b[j]);
BIO_puts(bp, "\n");
}
}
#endif
}
}
}
if (s == 0)
{
fprintf(stderr,"All %i tests of GF(2^m) modular solve quadratic resulted in no roots;\n", num0);
fprintf(stderr,"this is very unlikely and probably indicates an error.\n");
goto err;
}
ret = 1;
err:
BN_free(a);
BN_free(b[0]);
BN_free(b[1]);
BN_free(c);
BN_free(d);
BN_free(e);
return ret;
}
static void genprime_cb(int p, int n, void *arg)
{
char c='*';

View File

@@ -23,6 +23,13 @@ static COMP_METHOD zlib_method_nozlib={
#include <zlib.h>
static int zlib_stateful_init(COMP_CTX *ctx);
static void zlib_stateful_finish(COMP_CTX *ctx);
static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
unsigned int olen, unsigned char *in, unsigned int ilen);
static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
unsigned int olen, unsigned char *in, unsigned int ilen);
static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
unsigned int olen, unsigned char *in, unsigned int ilen);
static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
@@ -31,7 +38,7 @@ static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
uLong sourceLen);
static COMP_METHOD zlib_method={
static COMP_METHOD zlib_stateless_method={
NID_zlib_compression,
LN_zlib_compression,
NULL,
@@ -42,6 +49,17 @@ static COMP_METHOD zlib_method={
NULL,
};
static COMP_METHOD zlib_stateful_method={
NID_zlib_compression,
LN_zlib_compression,
zlib_stateful_init,
zlib_stateful_finish,
zlib_stateful_compress_block,
zlib_stateful_expand_block,
NULL,
NULL,
};
/*
* When OpenSSL is built on Windows, we do not want to require that
* the ZLIB.DLL be available in order for the OpenSSL DLLs to
@@ -75,10 +93,17 @@ typedef int (Z_CALLCONV *inflateEnd_ft)(z_streamp strm);
typedef int (Z_CALLCONV *inflate_ft)(z_streamp strm, int flush);
typedef int (Z_CALLCONV *inflateInit__ft)(z_streamp strm,
const char * version, int stream_size);
typedef int (Z_CALLCONV *deflateEnd_ft)(z_streamp strm);
typedef int (Z_CALLCONV *deflate_ft)(z_streamp strm, int flush);
typedef int (Z_CALLCONV *deflateInit__ft)(z_streamp strm, int level,
const char * version, int stream_size);
static compress_ft p_compress=NULL;
static inflateEnd_ft p_inflateEnd=NULL;
static inflate_ft p_inflate=NULL;
static inflateInit__ft p_inflateInit_=NULL;
static deflateEnd_ft p_deflateEnd=NULL;
static deflate_ft p_deflate=NULL;
static deflateInit__ft p_deflateInit_=NULL;
static int zlib_loaded = 0; /* only attempt to init func pts once */
static DSO *zlib_dso = NULL;
@@ -86,11 +111,130 @@ static DSO *zlib_dso = NULL;
#define compress stub_compress
#define inflateEnd stub_inflateEnd
#define inflate stub_inflate
#define inflateInit stub_inflateInit
#define inflateInit_ stub_inflateInit_
#define deflateEnd stub_deflateEnd
#define deflate stub_deflate
#define deflateInit stub_deflateInit
#define deflateInit_ stub_deflateInit_
#endif /* ZLIB_SHARED */
struct zlib_state
{
z_stream istream;
z_stream ostream;
};
static int zlib_stateful_ex_idx = -1;
static void zlib_stateful_free_ex_data(void *obj, void *item,
CRYPTO_EX_DATA *ad, int ind,long argl, void *argp)
{
struct zlib_state *state = (struct zlib_state *)item;
inflateEnd(&state->istream);
deflateEnd(&state->ostream);
OPENSSL_free(state);
}
static int zlib_stateful_init(COMP_CTX *ctx)
{
int err;
struct zlib_state *state =
(struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state));
if (state == NULL)
goto err;
state->istream.zalloc = Z_NULL;
state->istream.zfree = Z_NULL;
state->istream.opaque = Z_NULL;
state->istream.next_in = Z_NULL;
state->istream.next_out = Z_NULL;
state->istream.avail_in = 0;
state->istream.avail_out = 0;
err = inflateInit(&state->istream);
if (err != Z_OK)
goto err;
state->ostream.zalloc = Z_NULL;
state->ostream.zfree = Z_NULL;
state->ostream.opaque = Z_NULL;
state->ostream.next_in = Z_NULL;
state->ostream.next_out = Z_NULL;
state->ostream.avail_in = 0;
state->ostream.avail_out = 0;
err = deflateInit(&state->ostream,Z_DEFAULT_COMPRESSION);
if (err != Z_OK)
goto err;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
if (zlib_stateful_ex_idx == -1)
{
zlib_stateful_ex_idx =
CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
0,NULL,NULL,NULL,zlib_stateful_free_ex_data);
if (zlib_stateful_ex_idx == -1)
goto err;
}
CRYPTO_set_ex_data(&ctx->ex_data,zlib_stateful_ex_idx,state);
return 1;
err:
if (state) OPENSSL_free(state);
return 0;
}
static void zlib_stateful_finish(COMP_CTX *ctx)
{
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP,ctx,&ctx->ex_data);
}
static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
unsigned int olen, unsigned char *in, unsigned int ilen)
{
int err = Z_OK;
struct zlib_state *state =
(struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
zlib_stateful_ex_idx);
if (state == NULL)
return -1;
state->ostream.next_in = in;
state->ostream.avail_in = ilen;
state->ostream.next_out = out;
state->ostream.avail_out = olen;
if (ilen > 0)
err = deflate(&state->ostream, Z_SYNC_FLUSH);
if (err != Z_OK)
return -1;
return olen - state->ostream.avail_out;
}
static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
unsigned int olen, unsigned char *in, unsigned int ilen)
{
int err = Z_OK;
struct zlib_state *state =
(struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
zlib_stateful_ex_idx);
if (state == NULL)
return 0;
state->istream.next_in = in;
state->istream.avail_in = ilen;
state->istream.next_out = out;
state->istream.avail_out = olen;
if (ilen > 0)
err = inflate(&state->istream, Z_SYNC_FLUSH);
if (err != Z_OK)
return -1;
return olen - state->istream.avail_out;
}
static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
unsigned int olen, unsigned char *in, unsigned int ilen)
unsigned int olen, unsigned char *in, unsigned int ilen)
{
unsigned long l;
int i;
@@ -123,7 +267,7 @@ static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
}
static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
unsigned int olen, unsigned char *in, unsigned int ilen)
unsigned int olen, unsigned char *in, unsigned int ilen)
{
unsigned long l;
int i;
@@ -207,13 +351,22 @@ COMP_METHOD *COMP_zlib(void)
p_inflateInit_
= (inflateInit__ft) DSO_bind_func(zlib_dso,
"inflateInit_");
p_deflateEnd
= (deflateEnd_ft) DSO_bind_func(zlib_dso,
"deflateEnd");
p_deflate
= (deflate_ft) DSO_bind_func(zlib_dso,
"deflate");
p_deflateInit_
= (deflateInit__ft) DSO_bind_func(zlib_dso,
"deflateInit_");
zlib_loaded++;
}
}
#endif
#if defined(ZLIB) || defined(ZLIB_SHARED)
meth = &zlib_method;
meth = &zlib_stateful_method;
#endif
return(meth);
@@ -257,4 +410,32 @@ stub_inflateInit_(z_streamp strm, const char * version, int stream_size)
return(Z_MEM_ERROR);
}
static int
stub_deflateEnd(z_streamp strm)
{
if ( p_deflateEnd )
return(p_deflateEnd(strm));
else
return(Z_MEM_ERROR);
}
static int
stub_deflate(z_streamp strm, int flush)
{
if ( p_deflate )
return(p_deflate(strm,flush));
else
return(Z_MEM_ERROR);
}
static int
stub_deflateInit_(z_streamp strm, int level,
const char * version, int stream_size)
{
if ( p_deflateInit_ )
return(p_deflateInit_(strm,version,stream_size));
else
return(Z_MEM_ERROR);
}
#endif /* ZLIB_SHARED */

View File

@@ -20,17 +20,11 @@ COMP_CTX *COMP_CTX_new(COMP_METHOD *meth)
OPENSSL_free(ret);
ret=NULL;
}
#if 0
else
CRYPTO_new_ex_data(rsa_meth,(char *)ret,&ret->ex_data);
#endif
return(ret);
}
void COMP_CTX_free(COMP_CTX *ctx)
{
/* CRYPTO_free_ex_data(rsa_meth,(char *)ctx,&ctx->ex_data); */
if(ctx == NULL)
return;

View File

@@ -86,31 +86,32 @@ conf_api.o: ../../e_os.h ../../include/openssl/bio.h
conf_api.o: ../../include/openssl/conf.h ../../include/openssl/conf_api.h
conf_api.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
conf_api.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
conf_api.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
conf_api.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
conf_api.o: conf_api.c
conf_api.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
conf_api.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
conf_api.o: ../../include/openssl/symhacks.h conf_api.c
conf_def.o: ../../e_os.h ../../include/openssl/bio.h
conf_def.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
conf_def.o: ../../include/openssl/conf_api.h ../../include/openssl/crypto.h
conf_def.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
conf_def.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
conf_def.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
conf_def.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
conf_def.o: ../cryptlib.h conf_def.c conf_def.h
conf_def.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
conf_def.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
conf_def.o: ../../include/openssl/symhacks.h ../cryptlib.h conf_def.c
conf_def.o: conf_def.h
conf_err.o: ../../include/openssl/bio.h ../../include/openssl/conf.h
conf_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
conf_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
conf_err.o: ../../include/openssl/opensslconf.h
conf_err.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
conf_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
conf_err.o: conf_err.c
conf_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
conf_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
conf_err.o: ../../include/openssl/symhacks.h conf_err.c
conf_lib.o: ../../include/openssl/bio.h ../../include/openssl/conf.h
conf_lib.o: ../../include/openssl/conf_api.h ../../include/openssl/crypto.h
conf_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
conf_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
conf_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
conf_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
conf_lib.o: conf_lib.c
conf_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
conf_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
conf_lib.o: ../../include/openssl/symhacks.h conf_lib.c
conf_mall.o: ../../e_os.h ../../include/openssl/aes.h
conf_mall.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
conf_mall.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h
@@ -119,12 +120,13 @@ conf_mall.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
conf_mall.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
conf_mall.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
conf_mall.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
conf_mall.o: ../../include/openssl/engine.h ../../include/openssl/err.h
conf_mall.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
conf_mall.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
conf_mall.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
conf_mall.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
conf_mall.o: ../../include/openssl/objects.h
conf_mall.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
conf_mall.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
conf_mall.o: ../../include/openssl/err.h ../../include/openssl/evp.h
conf_mall.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
conf_mall.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
conf_mall.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
conf_mall.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
conf_mall.o: ../../include/openssl/opensslconf.h
conf_mall.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
conf_mall.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
@@ -143,12 +145,13 @@ conf_mod.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
conf_mod.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
conf_mod.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
conf_mod.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
conf_mod.o: ../../include/openssl/err.h ../../include/openssl/evp.h
conf_mod.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
conf_mod.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
conf_mod.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
conf_mod.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
conf_mod.o: ../../include/openssl/opensslconf.h
conf_mod.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
conf_mod.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
conf_mod.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
conf_mod.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
conf_mod.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
conf_mod.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
conf_mod.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
conf_mod.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
conf_mod.o: ../../include/openssl/pkcs7.h ../../include/openssl/rc2.h
conf_mod.o: ../../include/openssl/rc4.h ../../include/openssl/rc5.h
@@ -166,12 +169,14 @@ conf_sap.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
conf_sap.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
conf_sap.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
conf_sap.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
conf_sap.o: ../../include/openssl/engine.h ../../include/openssl/err.h
conf_sap.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
conf_sap.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
conf_sap.o: ../../include/openssl/md4.h ../../include/openssl/md5.h
conf_sap.o: ../../include/openssl/mdc2.h ../../include/openssl/obj_mac.h
conf_sap.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
conf_sap.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
conf_sap.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
conf_sap.o: ../../include/openssl/err.h ../../include/openssl/evp.h
conf_sap.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
conf_sap.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
conf_sap.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h
conf_sap.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
conf_sap.o: ../../include/openssl/opensslconf.h
conf_sap.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
conf_sap.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
conf_sap.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h

View File

@@ -65,6 +65,8 @@
#include <openssl/safestack.h>
#include <openssl/e_os2.h>
#include <openssl/ossl_typ.h>
#ifdef __cplusplus
extern "C" {
#endif
@@ -81,7 +83,6 @@ DECLARE_STACK_OF(CONF_MODULE)
DECLARE_STACK_OF(CONF_IMODULE)
struct conf_st;
typedef struct conf_st CONF;
struct conf_method_st;
typedef struct conf_method_st CONF_METHOD;

View File

@@ -1,4 +1,57 @@
/* crypto/cryptlib.c */
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -55,6 +108,11 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* ECDH support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
#include <stdio.h>
#include <string.h>
@@ -104,8 +162,11 @@ static const char* lock_names[CRYPTO_NUM_LOCKS] =
"dynlock",
"engine",
"ui",
"hwcrhk", /* This is a HACK which will disappear in 0.9.8 */
#if CRYPTO_NUM_LOCKS != 33
"ecdsa",
"ec",
"ecdh",
"bn",
#if CRYPTO_NUM_LOCKS != 36
# error "Inconsistency between crypto.h and cryptlib.c"
#endif
};
@@ -208,18 +269,10 @@ int CRYPTO_get_new_dynlockid(void)
i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
/* If there was none, push, thereby creating a new one */
if (i == -1)
/* Since sk_push() returns the number of items on the
stack, not the location of the pushed item, we need
to transform the returned number into a position,
by decreasing it. */
i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1;
else
/* If we found a place with a NULL pointer, put our pointer
in it. */
sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
i=sk_CRYPTO_dynlock_push(dyn_locks,pointer);
CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
if (i == -1)
if (!i)
{
dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
OPENSSL_free(pointer);
@@ -411,17 +464,15 @@ void CRYPTO_lock(int mode, int type, const char *file, int line)
#endif
if (type < 0)
{
if (dynlock_lock_callback != NULL)
struct CRYPTO_dynlock_value *pointer
= CRYPTO_get_dynlock_value(type);
if (pointer && dynlock_lock_callback)
{
struct CRYPTO_dynlock_value *pointer
= CRYPTO_get_dynlock_value(type);
OPENSSL_assert(pointer != NULL);
dynlock_lock_callback(mode, pointer, file, line);
CRYPTO_destroy_dynlockid(type);
}
CRYPTO_destroy_dynlockid(type);
}
else
if (locking_callback != NULL)

View File

@@ -77,7 +77,7 @@ $! Define The Different Encryption Types.
$!
$ ENCRYPT_TYPES = "Basic,MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,"+ -
"DES,RC2,RC4,RC5,IDEA,BF,CAST,"+ -
"BN,EC,RSA,DSA,DH,DSO,ENGINE,AES,"+ -
"BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,AES,"+ -
"BUFFER,BIO,STACK,LHASH,RAND,ERR,OBJECTS,"+ -
"EVP,EVP_2,ASN1,ASN1_2,PEM,X509,X509V3,"+ -
"CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,UI,KRB5"
@@ -184,22 +184,23 @@ $ IF F$TRNLNM("OPENSSL_NO_ASM").OR.ARCH.EQS."AXP" THEN LIB_BN_ASM = "bn_asm"
$ LIB_BN = "bn_add,bn_div,bn_exp,bn_lib,bn_ctx,bn_mul,bn_mod,"+ -
"bn_print,bn_rand,bn_shift,bn_word,bn_blind,"+ -
"bn_kron,bn_sqrt,bn_gcd,bn_prime,bn_err,bn_sqr,"+LIB_BN_ASM+","+ -
"bn_recp,bn_mont,bn_mpi,bn_exp2"
"bn_recp,bn_mont,bn_mpi,bn_exp2,bn_gf2m,bn_nist"
$ LIB_EC = "ec_lib,ecp_smpl,ecp_mont,ecp_recp,ecp_nist,ec_cvt,ec_mult,"+ -
"ec_err,ec_curve,ec_check,ec_print,ec_asn1,ec_key,"+ -
"ec2_smpl,ec2_mult"
$ LIB_RSA = "rsa_eay,rsa_gen,rsa_lib,rsa_sign,rsa_saos,rsa_err,"+ -
"rsa_pk1,rsa_ssl,rsa_none,rsa_oaep,rsa_chk,rsa_null,"+ -
"rsa_asn1"
$ LIB_EC = "ec_lib,ecp_smpl,ecp_mont,ecp_recp,ecp_nist,ec_cvt,ec_mult,"+ -
"ec_err"
$ LIB_DSA = "dsa_gen,dsa_key,dsa_lib,dsa_asn1,dsa_vrf,dsa_sign,dsa_err,dsa_ossl"
$ LIB_ECDSA = "ecs_lib,ecs_asn1,ecs_ossl,ecs_sign,ecs_vrf,ecs_err"
$ LIB_DH = "dh_asn1,dh_gen,dh_key,dh_lib,dh_check,dh_err"
$ LIB_ECDH = "ech_lib,ech_ossl,ech_key,ech_err"
$ LIB_DSO = "dso_dl,dso_dlfcn,dso_err,dso_lib,dso_null,"+ -
"dso_openssl,dso_win32,dso_vms"
$ LIB_ENGINE = "eng_err,eng_lib,eng_list,eng_init,eng_ctrl,"+ -
"eng_table,eng_pkey,eng_fat,eng_all,"+ -
"tb_rsa,tb_dsa,tb_dh,tb_rand,tb_cipher,tb_digest,"+ -
"eng_openssl,eng_dyn,eng_cnf,"+ -
"hw_atalla,hw_cswift,hw_ncipher,hw_nuron,hw_ubsec,"+ -
"hw_cryptodev,hw_aep,hw_sureware,hw_4758_cca"
"tb_rsa,tb_dsa,tb_ecdsa,tb_dh,tb_rand,tb_cipher,tb_digest,tb_ecdh,"+ -
"eng_openssl,eng_dyn,eng_cnf,eng_cryptodev"
$ LIB_AES = "aes_core,aes_misc,aes_ecb,aes_cbc,aes_cfb,aes_ofb,aes_ctr"
$ LIB_BUFFER = "buffer,buf_err"
$ LIB_BIO = "bio_lib,bio_cb,bio_err,"+ -
@@ -219,7 +220,7 @@ $ LIB_EVP = "encode,digest,evp_enc,evp_key,evp_acnf,"+ -
"e_rc4,e_aes,names,"+ -
"e_xcbc_d,e_rc2,e_cast,e_rc5"
$ LIB_EVP_2 = "m_null,m_md2,m_md4,m_md5,m_sha,m_sha1," + -
"m_dss,m_dss1,m_mdc2,m_ripemd,"+ -
"m_dss,m_dss1,m_mdc2,m_ripemd,m_ecdsa,"+ -
"p_open,p_seal,p_sign,p_verify,p_lib,p_enc,p_dec,"+ -
"bio_md,bio_b64,bio_enc,evp_err,e_null,"+ -
"c_all,c_allc,c_alld,evp_lib,bio_ok,"+-
@@ -234,7 +235,7 @@ $ LIB_ASN1_2 = "t_req,t_x509,t_x509a,t_crl,t_pkey,t_spki,t_bitst,"+ -
"tasn_new,tasn_fre,tasn_enc,tasn_dec,tasn_utl,tasn_typ,"+ -
"f_int,f_string,n_pkey,"+ -
"f_enum,a_hdr,x_pkey,a_bool,x_exten,"+ -
"asn1_par,asn1_lib,asn1_err,a_meth,a_bytes,a_strnid,"+ -
"asn1_gen,asn1_par,asn1_lib,asn1_err,a_meth,a_bytes,a_strnid,"+ -
"evp_asn1,asn_pack,p5_pbe,p5_pbev2,p8_pkey,asn_moid"
$ LIB_PEM = "pem_sign,pem_seal,pem_info,pem_lib,pem_all,pem_err,"+ -
"pem_x509,pem_xaux,pem_oth,pem_pk8,pem_pkey"

View File

@@ -1,4 +1,57 @@
/* crypto/crypto.h */
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -55,6 +108,11 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* ECDH support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
#ifndef HEADER_CRYPTO_H
#define HEADER_CRYPTO_H
@@ -96,11 +154,11 @@ extern "C" {
* names in cryptlib.c
*/
#define CRYPTO_LOCK_ERR 1
#define CRYPTO_LOCK_EX_DATA 2
#define CRYPTO_LOCK_X509 3
#define CRYPTO_LOCK_X509_INFO 4
#define CRYPTO_LOCK_X509_PKEY 5
#define CRYPTO_LOCK_ERR 1
#define CRYPTO_LOCK_EX_DATA 2
#define CRYPTO_LOCK_X509 3
#define CRYPTO_LOCK_X509_INFO 4
#define CRYPTO_LOCK_X509_PKEY 5
#define CRYPTO_LOCK_X509_CRL 6
#define CRYPTO_LOCK_X509_REQ 7
#define CRYPTO_LOCK_DSA 8
@@ -127,8 +185,11 @@ extern "C" {
#define CRYPTO_LOCK_DYNLOCK 29
#define CRYPTO_LOCK_ENGINE 30
#define CRYPTO_LOCK_UI 31
#define CRYPTO_LOCK_HWCRHK 32 /* This is a HACK which will disappear in 0.9.8 */
#define CRYPTO_NUM_LOCKS 33
#define CRYPTO_LOCK_ECDSA 32
#define CRYPTO_LOCK_EC 33
#define CRYPTO_LOCK_ECDH 34
#define CRYPTO_LOCK_BN 35
#define CRYPTO_NUM_LOCKS 36
#define CRYPTO_LOCK 1
#define CRYPTO_UNLOCK 2
@@ -235,6 +296,9 @@ DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS)
#define CRYPTO_EX_INDEX_ENGINE 9
#define CRYPTO_EX_INDEX_X509 10
#define CRYPTO_EX_INDEX_UI 11
#define CRYPTO_EX_INDEX_ECDSA 12
#define CRYPTO_EX_INDEX_ECDH 13
#define CRYPTO_EX_INDEX_COMP 14
/* Dynamically assigned indexes start from this value (don't use directly, use
* via CRYPTO_ex_data_new_class). */

View File

@@ -67,27 +67,19 @@ des: des.o cbc3_enc.o lib
# elf
asm/dx86-elf.o: asm/dx86unix.cpp
$(CPP) -DELF \
`(echo $(CFLAGS) | egrep -ie '-[fK]PIC') > /dev/null 2>&1 && echo -DPIC; exit 0`\
-x c asm/dx86unix.cpp | as -o asm/dx86-elf.o
$(CPP) -DELF -x c asm/dx86unix.cpp | as -o asm/dx86-elf.o
asm/yx86-elf.o: asm/yx86unix.cpp
$(CPP) -DELF \
`(echo $(CFLAGS) | egrep -ie '-[fK]PIC') > /dev/null 2>&1 && echo -DPIC; exit 0`\
-x c asm/yx86unix.cpp | as -o asm/yx86-elf.o
$(CPP) -DELF -x c asm/yx86unix.cpp | as -o asm/yx86-elf.o
# solaris
asm/dx86-sol.o: asm/dx86unix.cpp
$(CC) -E -DSOL \
`(echo $(CFLAGS) | egrep -ie '-[fK]PIC') > /dev/null 2>&1 && echo -DPIC; exit 0`\
asm/dx86unix.cpp | sed 's/^#.*//' > asm/dx86-sol.s
$(CC) -E -DSOL asm/dx86unix.cpp | sed 's/^#.*//' > asm/dx86-sol.s
as -o asm/dx86-sol.o asm/dx86-sol.s
rm -f asm/dx86-sol.s
asm/yx86-sol.o: asm/yx86unix.cpp
$(CC) -E -DSOL \
`(echo $(CFLAGS) | egrep -ie '-[fK]PIC') > /dev/null 2>&1 && echo -DPIC; exit 0`\
asm/yx86unix.cpp | sed 's/^#.*//' > asm/yx86-sol.s
$(CC) -E -DSOL asm/yx86unix.cpp | sed 's/^#.*//' > asm/yx86-sol.s
as -o asm/yx86-sol.o asm/yx86-sol.s
rm -f asm/yx86-sol.s

View File

@@ -26,17 +26,11 @@ sub fcrypt_body
&comment("");
&comment("Load the 2 words");
$trans="ebp";
$ks="ebp";
&xor( $L, $L);
&xor( $R, $R);
# PIC-ification:-)
if ($cpp) { &picmeup("edx","DES_SPtrans"); }
else { &lea("edx",&DWP("DES_SPtrans")); }
&push("edx"); # becomes &swtmp(1)
#
&mov($trans,&wparam(1)); # reloaded with DES_SPtrans in D_ENCRYPT
&mov($ks,&wparam(1));
&push(&DWC(25)); # add a variable
@@ -45,11 +39,11 @@ sub fcrypt_body
{
&comment("");
&comment("Round $i");
&D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx");
&D_ENCRYPT($i,$L,$R,$i*2,$ks,"DES_SPtrans","eax","ebx","ecx","edx");
&comment("");
&comment("Round ".sprintf("%d",$i+1));
&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx");
&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"DES_SPtrans","eax","ebx","ecx","edx");
}
&mov("ebx", &swtmp(0));
&mov("eax", $L);
@@ -67,14 +61,14 @@ sub fcrypt_body
&mov(&DWP(0,"edx","",0),"eax");
&mov(&DWP(4,"edx","",0),$L);
&add("esp",8); # remove variables
&pop("ecx"); # remove variable
&function_end($name);
}
sub D_ENCRYPT
{
local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t)=@_;
local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
&mov( $u, &wparam(2)); # 2
&mov( $t, $R);
@@ -91,9 +85,9 @@ sub D_ENCRYPT
&shl( $tmp2, 16); # 1
&xor( $u, $tmp1); # 2
&xor( $t, $tmp2); # 2
&mov( $tmp1, &DWP(&n2a($S*4),$trans,"",0)); # 2
&mov( $tmp1, &DWP(&n2a($S*4),$ks,"",0)); # 2
&xor( $u, $tmp1);
&mov( $tmp2, &DWP(&n2a(($S+1)*4),$trans,"",0)); # 2
&mov( $tmp2, &DWP(&n2a(($S+1)*4),$ks,"",0)); # 2
&xor( $u, $R);
&xor( $t, $R);
&xor( $t, $tmp2);
@@ -105,28 +99,31 @@ sub D_ENCRYPT
&movb( &LB($tmp1), &LB($u) );
&movb( &LB($tmp2), &HB($u) );
&rotr( $t, 4 );
&mov( $trans, &swtmp(1));
&xor( $L, &DWP(" ",$trans,$tmp1,0));
&mov( $ks, &DWP(" $desSP",$tmp1,"",0));
&movb( &LB($tmp1), &LB($t) );
&xor( $L, &DWP("0x200",$trans,$tmp2,0));
&xor( $L, $ks);
&mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
&xor( $L, $ks);
&movb( &LB($tmp2), &HB($t) );
&shr( $u, 16);
&xor( $L, &DWP("0x100",$trans,$tmp1,0));
&mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
&xor( $L, $ks);
&movb( &LB($tmp1), &HB($u) );
&shr( $t, 16);
&xor( $L, &DWP("0x300",$trans,$tmp2,0));
&mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
&xor( $L, $ks);
&mov( $ks, &wparam(1));
&movb( &LB($tmp2), &HB($t) );
&and( $u, "0xff" );
&and( $t, "0xff" );
&mov( $tmp1, &DWP("0x600",$trans,$tmp1,0));
&mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
&xor( $L, $tmp1);
&mov( $tmp1, &DWP("0x700",$trans,$tmp2,0));
&mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
&xor( $L, $tmp1);
&mov( $tmp1, &DWP("0x400",$trans,$u,0));
&mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
&xor( $L, $tmp1);
&mov( $tmp1, &DWP("0x500",$trans,$t,0));
&mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
&xor( $L, $tmp1);
&mov( $trans, &wparam(1));
}
sub n2a

View File

@@ -40,7 +40,7 @@ sub DES_encrypt
&comment("");
&comment("Load the 2 words");
$trans="ebp";
$ks="ebp";
if ($do_ip)
{
@@ -72,11 +72,7 @@ sub DES_encrypt
&rotl($L,3);
}
# PIC-ification:-)
if ($cpp) { &picmeup($trans,"DES_SPtrans"); }
else { &lea($trans,&DWP("DES_SPtrans")); }
&mov( "ecx", &wparam(1) );
&mov( $ks, &wparam(1) );
&cmp("ebx","0");
&je(&label("start_decrypt"));
@@ -84,11 +80,11 @@ sub DES_encrypt
{
&comment("");
&comment("Round $i");
&D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx");
&D_ENCRYPT($i,$L,$R,$i*2,$ks,"DES_SPtrans","eax","ebx","ecx","edx");
&comment("");
&comment("Round ".sprintf("%d",$i+1));
&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx");
&D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"DES_SPtrans","eax","ebx","ecx","edx");
}
&jmp(&label("end"));
@@ -98,10 +94,10 @@ sub DES_encrypt
{
&comment("");
&comment("Round $i");
&D_ENCRYPT(15-$i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx");
&D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"DES_SPtrans","eax","ebx","ecx","edx");
&comment("");
&comment("Round ".sprintf("%d",$i-1));
&D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$trans,"eax","ebx","ecx","edx");
&D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"DES_SPtrans","eax","ebx","ecx","edx");
}
&set_label("end");
@@ -138,36 +134,43 @@ sub DES_encrypt
sub D_ENCRYPT
{
local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t)=@_;
local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
&mov( $u, &DWP(&n2a($S*4),$tmp2,"",0));
&mov( $u, &DWP(&n2a($S*4),$ks,"",0));
&xor( $tmp1, $tmp1);
&mov( $t, &DWP(&n2a(($S+1)*4),$tmp2,"",0));
&mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
&xor( $u, $R);
&xor( $tmp2, $tmp2);
&xor( $t, $R);
&and( $u, "0xfcfcfcfc" );
&and( $t, "0xcfcfcfcf" );
&movb( &LB($tmp1), &LB($u) );
&movb( &LB($tmp2), &HB($u) );
&rotr( $t, 4 );
&xor( $L, &DWP(" ",$trans,$tmp1,0));
&mov( $ks, &DWP(" $desSP",$tmp1,"",0));
&movb( &LB($tmp1), &LB($t) );
&xor( $L, &DWP("0x200",$trans,$tmp2,0));
&xor( $L, $ks);
&mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
&xor( $L, $ks); ######
&movb( &LB($tmp2), &HB($t) );
&shr( $u, 16);
&xor( $L, &DWP("0x100",$trans,$tmp1,0));
&mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
&xor( $L, $ks); ######
&movb( &LB($tmp1), &HB($u) );
&shr( $t, 16);
&xor( $L, &DWP("0x300",$trans,$tmp2,0));
&mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
&xor( $L, $ks);
&mov( $ks, &wparam(1) );
&movb( &LB($tmp2), &HB($t) );
&and( $u, "0xff" );
&and( $t, "0xff" );
&xor( $L, &DWP("0x600",$trans,$tmp1,0));
&xor( $L, &DWP("0x700",$trans,$tmp2,0));
&mov( $tmp2, &wparam(1) );
&xor( $L, &DWP("0x400",$trans,$u,0));
&xor( $L, &DWP("0x500",$trans,$t,0));
&mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
&xor( $L, $tmp1);
&mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
&xor( $L, $tmp1);
&mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
&xor( $L, $tmp1);
&mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
&xor( $L, $tmp1);
}
sub n2a

View File

@@ -56,8 +56,8 @@
* [including the GNU Public Licence.]
*/
#ifndef HEADER_NEW_DES_H
#define HEADER_NEW_DES_H
#ifndef HEADER_DES_H
#define HEADER_DES_H
#ifdef OPENSSL_NO_DES
#error DES is disabled.

View File

@@ -69,6 +69,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef OPENSSL_SYS_MSDOS
#if !defined(OPENSSL_SYS_VMS) || defined(__DECC)
@@ -89,10 +90,6 @@
#include <io.h>
#endif
#if defined(__STDC__) || defined(OPENSSL_SYS_VMS) || defined(M_XENIX) || defined(OPENSSL_SYS_MSDOS)
#include <string.h>
#endif
#ifdef OPENSSL_BUILD_SHLIBCRYPTO
# undef OPENSSL_EXTERN
# define OPENSSL_EXTERN OPENSSL_EXPORT
@@ -162,18 +159,7 @@
#if defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)
#define ROTATE(a,n) (_lrotr(a,n))
#elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(NO_ASM) && !defined(NO_INLINE_ASM)
# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
# define ROTATE(a,n) ({ register unsigned int ret; \
asm ("rorl %1,%0" \
: "=r"(ret) \
: "I"(n),"0"(a) \
: "cc"); \
ret; \
})
# endif
#endif
#ifndef ROTATE
#else
#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
#endif

View File

@@ -88,14 +88,14 @@
*
*/
#ifndef HEADER_DES_H
#define HEADER_DES_H
#ifndef HEADER_DES_OLD_H
#define HEADER_DES_OLD_H
#ifdef OPENSSL_NO_DES
#error DES is disabled.
#endif
#ifndef HEADER_NEW_DES_H
#ifndef HEADER_DES_H
#error You must include des.h, not des_old.h directly.
#endif

View File

@@ -116,21 +116,23 @@ dh_key.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
dh_key.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
dh_key.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
dh_key.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
dh_key.o: ../../include/openssl/engine.h ../../include/openssl/err.h
dh_key.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
dh_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
dh_key.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
dh_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
dh_key.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
dh_key.o: ../cryptlib.h dh_key.c
dh_key.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
dh_key.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
dh_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
dh_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
dh_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
dh_key.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
dh_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
dh_key.o: ../../include/openssl/ui.h ../cryptlib.h dh_key.c
dh_lib.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
dh_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
dh_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
dh_lib.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
dh_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
dh_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
dh_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
dh_lib.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
dh_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
dh_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
dh_lib.o: ../cryptlib.h dh_lib.c
dh_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
dh_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
dh_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
dh_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
dh_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
dh_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
dh_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
dh_lib.o: ../../include/openssl/ui.h ../cryptlib.h dh_lib.c

View File

@@ -132,20 +132,23 @@ dsa_lib.o: ../../e_os.h ../../include/openssl/asn1.h
dsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
dsa_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
dsa_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
dsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
dsa_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
dsa_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
dsa_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
dsa_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
dsa_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
dsa_lib.o: ../../include/openssl/ui.h ../cryptlib.h dsa_lib.c
dsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
dsa_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
dsa_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
dsa_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
dsa_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
dsa_lib.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
dsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
dsa_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
dsa_lib.o: ../cryptlib.h dsa_lib.c
dsa_ossl.o: ../../e_os.h ../../include/openssl/asn1.h
dsa_ossl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
dsa_ossl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
dsa_ossl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
dsa_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
dsa_ossl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
dsa_ossl.o: ../../include/openssl/opensslconf.h
dsa_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
dsa_ossl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
dsa_ossl.o: ../../include/openssl/engine.h ../../include/openssl/err.h
dsa_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
dsa_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
dsa_ossl.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
dsa_ossl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
@@ -155,9 +158,10 @@ dsa_sign.o: ../../e_os.h ../../include/openssl/asn1.h
dsa_sign.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
dsa_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
dsa_sign.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
dsa_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
dsa_sign.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
dsa_sign.o: ../../include/openssl/opensslconf.h
dsa_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
dsa_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
dsa_sign.o: ../../include/openssl/engine.h ../../include/openssl/err.h
dsa_sign.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
dsa_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
dsa_sign.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
dsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
@@ -168,10 +172,11 @@ dsa_vrf.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
dsa_vrf.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
dsa_vrf.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
dsa_vrf.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
dsa_vrf.o: ../../include/openssl/engine.h ../../include/openssl/err.h
dsa_vrf.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
dsa_vrf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
dsa_vrf.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
dsa_vrf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
dsa_vrf.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
dsa_vrf.o: ../cryptlib.h dsa_vrf.c
dsa_vrf.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
dsa_vrf.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
dsa_vrf.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
dsa_vrf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
dsa_vrf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
dsa_vrf.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
dsa_vrf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
dsa_vrf.o: ../../include/openssl/ui.h ../cryptlib.h dsa_vrf.c

View File

@@ -246,12 +246,14 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
BN_init(&u2);
BN_init(&t1);
if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
if (BN_is_zero(sig->r) || BN_get_sign(sig->r) ||
BN_ucmp(sig->r, dsa->q) >= 0)
{
ret = 0;
goto err;
}
if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
if (BN_is_zero(sig->s) || BN_get_sign(sig->s) ||
BN_ucmp(sig->s, dsa->q) >= 0)
{
ret = 0;
goto err;

View File

@@ -1,4 +1,4 @@
/* dso.h */
/* dso.h -*- mode:C; c-file-style: "eay" -*- */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2000.
*/
@@ -107,6 +107,22 @@ typedef struct dso_st DSO;
* condition) or a newly allocated string containing the transformed form that
* the caller will need to free with OPENSSL_free() when done. */
typedef char* (*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *);
/* The function prototype used for method functions (or caller-provided
* callbacks) that merge two file specifications. They are passed a
* DSO structure pointer (or NULL if they are to be used independantly of
* a DSO object) and two file specifications to merge. They should
* either return NULL (if there is an error condition) or a newly allocated
* string containing the result of merging that the caller will need
* to free with OPENSSL_free() when done.
* Here, merging means that bits and pieces are taken from each of the
* file specifications and added together in whatever fashion that is
* sensible for the DSO method in question. The only rule that really
* applies is that if the two specification contain pieces of the same
* type, the copy from the string string takes priority. One could see
* it as the first specification is the one given by the user and the
* second being a bunch of defaults to add on if they're missing in the
* first. */
typedef char* (*DSO_MERGER_FUNC)(DSO *, const char *, const char *);
typedef struct dso_meth_st
{
@@ -140,6 +156,9 @@ typedef struct dso_meth_st
/* The default DSO_METHOD-specific function for converting filenames to
* a canonical native form. */
DSO_NAME_CONVERTER_FUNC dso_name_converter;
/* The default DSO_METHOD-specific function for converting filenames to
* a canonical native form. */
DSO_MERGER_FUNC dso_merger;
/* [De]Initialisation handlers. */
int (*init)(DSO *dso);
@@ -164,9 +183,13 @@ struct dso_st
* don't touch meth_data! */
CRYPTO_EX_DATA ex_data;
/* If this callback function pointer is set to non-NULL, then it will
* be used on DSO_load() in place of meth->dso_name_converter. NB: This
* be used in DSO_load() in place of meth->dso_name_converter. NB: This
* should normally set using DSO_set_name_converter(). */
DSO_NAME_CONVERTER_FUNC name_converter;
/* If this callback function pointer is set to non-NULL, then it will
* be used in DSO_load() in place of meth->dso_merger. NB: This
* should normally set using DSO_set_merger(). */
DSO_MERGER_FUNC merger;
/* This is populated with (a copy of) the platform-independant
* filename used for this DSO. */
char *filename;
@@ -209,6 +232,11 @@ int DSO_set_filename(DSO *dso, const char *filename);
* caller-created DSO_METHODs can do the same thing. A non-NULL return value
* will need to be OPENSSL_free()'d. */
char *DSO_convert_filename(DSO *dso, const char *filename);
/* This function will invoke the DSO's merger callback to merge two file
* specifications, or if the callback isn't set it will instead use the
* DSO_METHOD's merger. A non-NULL return value will need to be
* OPENSSL_free()'d. */
char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2);
/* If the DSO is currently loaded, this returns the filename that it was loaded
* under, otherwise it returns NULL. So it is also useful as a test as to
* whether the DSO is currently loaded. NB: This will not necessarily return
@@ -273,11 +301,13 @@ void ERR_load_DSO_strings(void);
#define DSO_F_DLFCN_BIND_FUNC 100
#define DSO_F_DLFCN_BIND_VAR 101
#define DSO_F_DLFCN_LOAD 102
#define DSO_F_DLFCN_MERGER 130
#define DSO_F_DLFCN_NAME_CONVERTER 123
#define DSO_F_DLFCN_UNLOAD 103
#define DSO_F_DL_BIND_FUNC 104
#define DSO_F_DL_BIND_VAR 105
#define DSO_F_DL_LOAD 106
#define DSO_F_DL_MERGER 131
#define DSO_F_DL_NAME_CONVERTER 124
#define DSO_F_DL_UNLOAD 107
#define DSO_F_DSO_BIND_FUNC 108
@@ -288,27 +318,34 @@ void ERR_load_DSO_strings(void);
#define DSO_F_DSO_GET_FILENAME 127
#define DSO_F_DSO_GET_LOADED_FILENAME 128
#define DSO_F_DSO_LOAD 112
#define DSO_F_DSO_MERGE 132
#define DSO_F_DSO_NEW_METHOD 113
#define DSO_F_DSO_SET_FILENAME 129
#define DSO_F_DSO_SET_NAME_CONVERTER 122
#define DSO_F_DSO_UP_REF 114
#define DSO_F_VMS_BIND_VAR 115
#define DSO_F_VMS_LOAD 116
#define DSO_F_VMS_MERGER 133
#define DSO_F_VMS_UNLOAD 117
#define DSO_F_WIN32_BIND_FUNC 118
#define DSO_F_WIN32_BIND_VAR 119
#define DSO_F_WIN32_LOAD 120
#define DSO_F_WIN32_MERGER 134
#define DSO_F_WIN32_NAME_CONVERTER 125
#define DSO_F_WIN32_UNLOAD 121
/* Reason codes. */
#define DSO_R_CTRL_FAILED 100
#define DSO_R_DSO_ALREADY_LOADED 110
#define DSO_R_EMPTY_FILE_STRUCTURE 113
#define DSO_R_FAILURE 114
#define DSO_R_FILENAME_TOO_BIG 101
#define DSO_R_FINISH_FAILED 102
#define DSO_R_INCORRECT_FILE_SYNTAX 115
#define DSO_R_LOAD_FAILED 103
#define DSO_R_NAME_TRANSLATION_FAILED 109
#define DSO_R_NO_FILENAME 111
#define DSO_R_NO_FILE_SPECIFICATION 116
#define DSO_R_NULL_HANDLE 104
#define DSO_R_SET_FILENAME_FAILED 112
#define DSO_R_STACK_ERROR 105

View File

@@ -1,4 +1,4 @@
/* dso_dl.c */
/* dso_dl.c -*- mode:C; c-file-style: "eay" -*- */
/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
* project 2000.
*/
@@ -84,6 +84,7 @@ static int dl_finish(DSO *dso);
static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg);
#endif
static char *dl_name_converter(DSO *dso, const char *filename);
static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2);
static DSO_METHOD dso_meth_dl = {
"OpenSSL 'dl' shared library method",
@@ -98,6 +99,7 @@ static DSO_METHOD dso_meth_dl = {
#endif
NULL, /* ctrl */
dl_name_converter,
dl_merger,
NULL, /* init */
NULL /* finish */
};
@@ -238,6 +240,72 @@ static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
return((DSO_FUNC_TYPE)sym);
}
static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
{
char *merged;
if(!filespec1 && !filespec2)
{
DSOerr(DSO_F_DL_MERGER,
ERR_R_PASSED_NULL_PARAMETER);
return(NULL);
}
/* If the first file specification is a rooted path, it rules.
same goes if the second file specification is missing. */
if (!filespec2 || filespec1[0] == '/')
{
merged = OPENSSL_malloc(strlen(filespec1) + 1);
if(!merged)
{
DSOerr(DSO_F_DL_MERGER,
ERR_R_MALLOC_FAILURE);
return(NULL);
}
strcpy(merged, filespec1);
}
/* If the first file specification is missing, the second one rules. */
else if (!filespec1)
{
merged = OPENSSL_malloc(strlen(filespec2) + 1);
if(!merged)
{
DSOerr(DSO_F_DL_MERGER,
ERR_R_MALLOC_FAILURE);
return(NULL);
}
strcpy(merged, filespec2);
}
else
/* This part isn't as trivial as it looks. It assumes that
the second file specification really is a directory, and
makes no checks whatsoever. Therefore, the result becomes
the concatenation of filespec2 followed by a slash followed
by filespec1. */
{
int spec2len, len;
spec2len = (filespec2 ? strlen(filespec2) : 0);
len = spec2len + (filespec1 ? strlen(filespec1) : 0);
if(filespec2 && filespec2[spec2len - 1] == '/')
{
spec2len--;
len--;
}
merged = OPENSSL_malloc(len + 2);
if(!merged)
{
DSOerr(DSO_F_DL_MERGER,
ERR_R_MALLOC_FAILURE);
return(NULL);
}
strcpy(merged, filespec2);
merged[spec2len] = '/';
strcpy(&merged[spec2len + 1], filespec1);
}
return(merged);
}
/* This function is identical to the one in dso_dlfcn.c, but as it is highly
* unlikely that both the "dl" *and* "dlfcn" variants are being compiled at the
* same time, there's no great duplicating the code. Figuring out an elegant

View File

@@ -1,4 +1,4 @@
/* dso_dlfcn.c */
/* dso_dlfcn.c -*- mode:C; c-file-style: "eay" -*- */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2000.
*/
@@ -85,6 +85,8 @@ static int dlfcn_finish(DSO *dso);
static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);
#endif
static char *dlfcn_name_converter(DSO *dso, const char *filename);
static char *dlfcn_merger(DSO *dso, const char *filespec1,
const char *filespec2);
static DSO_METHOD dso_meth_dlfcn = {
"OpenSSL 'dlfcn' shared library method",
@@ -99,6 +101,7 @@ static DSO_METHOD dso_meth_dlfcn = {
#endif
NULL, /* ctrl */
dlfcn_name_converter,
dlfcn_merger,
NULL, /* init */
NULL /* finish */
};
@@ -252,6 +255,73 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
return(sym);
}
static char *dlfcn_merger(DSO *dso, const char *filespec1,
const char *filespec2)
{
char *merged;
if(!filespec1 && !filespec2)
{
DSOerr(DSO_F_DLFCN_MERGER,
ERR_R_PASSED_NULL_PARAMETER);
return(NULL);
}
/* If the first file specification is a rooted path, it rules.
same goes if the second file specification is missing. */
if (!filespec2 || filespec1[0] == '/')
{
merged = OPENSSL_malloc(strlen(filespec1) + 1);
if(!merged)
{
DSOerr(DSO_F_DLFCN_MERGER,
ERR_R_MALLOC_FAILURE);
return(NULL);
}
strcpy(merged, filespec1);
}
/* If the first file specification is missing, the second one rules. */
else if (!filespec1)
{
merged = OPENSSL_malloc(strlen(filespec2) + 1);
if(!merged)
{
DSOerr(DSO_F_DLFCN_MERGER,
ERR_R_MALLOC_FAILURE);
return(NULL);
}
strcpy(merged, filespec2);
}
else
/* This part isn't as trivial as it looks. It assumes that
the second file specification really is a directory, and
makes no checks whatsoever. Therefore, the result becomes
the concatenation of filespec2 followed by a slash followed
by filespec1. */
{
int spec2len, len;
spec2len = (filespec2 ? strlen(filespec2) : 0);
len = spec2len + (filespec1 ? strlen(filespec1) : 0);
if(filespec2 && filespec2[spec2len - 1] == '/')
{
spec2len--;
len--;
}
merged = OPENSSL_malloc(len + 2);
if(!merged)
{
DSOerr(DSO_F_DLFCN_MERGER,
ERR_R_MALLOC_FAILURE);
return(NULL);
}
strcpy(merged, filespec2);
merged[spec2len] = '/';
strcpy(&merged[spec2len + 1], filespec1);
}
return(merged);
}
static char *dlfcn_name_converter(DSO *dso, const char *filename)
{
char *translated;

View File

@@ -1,6 +1,6 @@
/* crypto/dso/dso_err.c */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
* Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -69,11 +69,13 @@ static ERR_STRING_DATA DSO_str_functs[]=
{ERR_PACK(0,DSO_F_DLFCN_BIND_FUNC,0), "DLFCN_BIND_FUNC"},
{ERR_PACK(0,DSO_F_DLFCN_BIND_VAR,0), "DLFCN_BIND_VAR"},
{ERR_PACK(0,DSO_F_DLFCN_LOAD,0), "DLFCN_LOAD"},
{ERR_PACK(0,DSO_F_DLFCN_MERGER,0), "DLFCN_MERGER"},
{ERR_PACK(0,DSO_F_DLFCN_NAME_CONVERTER,0), "DLFCN_NAME_CONVERTER"},
{ERR_PACK(0,DSO_F_DLFCN_UNLOAD,0), "DLFCN_UNLOAD"},
{ERR_PACK(0,DSO_F_DL_BIND_FUNC,0), "DL_BIND_FUNC"},
{ERR_PACK(0,DSO_F_DL_BIND_VAR,0), "DL_BIND_VAR"},
{ERR_PACK(0,DSO_F_DL_LOAD,0), "DL_LOAD"},
{ERR_PACK(0,DSO_F_DL_MERGER,0), "DL_MERGER"},
{ERR_PACK(0,DSO_F_DL_NAME_CONVERTER,0), "DL_NAME_CONVERTER"},
{ERR_PACK(0,DSO_F_DL_UNLOAD,0), "DL_UNLOAD"},
{ERR_PACK(0,DSO_F_DSO_BIND_FUNC,0), "DSO_bind_func"},
@@ -84,16 +86,19 @@ static ERR_STRING_DATA DSO_str_functs[]=
{ERR_PACK(0,DSO_F_DSO_GET_FILENAME,0), "DSO_get_filename"},
{ERR_PACK(0,DSO_F_DSO_GET_LOADED_FILENAME,0), "DSO_get_loaded_filename"},
{ERR_PACK(0,DSO_F_DSO_LOAD,0), "DSO_load"},
{ERR_PACK(0,DSO_F_DSO_MERGE,0), "DSO_merge"},
{ERR_PACK(0,DSO_F_DSO_NEW_METHOD,0), "DSO_new_method"},
{ERR_PACK(0,DSO_F_DSO_SET_FILENAME,0), "DSO_set_filename"},
{ERR_PACK(0,DSO_F_DSO_SET_NAME_CONVERTER,0), "DSO_set_name_converter"},
{ERR_PACK(0,DSO_F_DSO_UP_REF,0), "DSO_up_ref"},
{ERR_PACK(0,DSO_F_VMS_BIND_VAR,0), "VMS_BIND_VAR"},
{ERR_PACK(0,DSO_F_VMS_LOAD,0), "VMS_LOAD"},
{ERR_PACK(0,DSO_F_VMS_MERGER,0), "VMS_MERGER"},
{ERR_PACK(0,DSO_F_VMS_UNLOAD,0), "VMS_UNLOAD"},
{ERR_PACK(0,DSO_F_WIN32_BIND_FUNC,0), "WIN32_BIND_FUNC"},
{ERR_PACK(0,DSO_F_WIN32_BIND_VAR,0), "WIN32_BIND_VAR"},
{ERR_PACK(0,DSO_F_WIN32_LOAD,0), "WIN32_LOAD"},
{ERR_PACK(0,DSO_F_WIN32_MERGER,0), "WIN32_MERGER"},
{ERR_PACK(0,DSO_F_WIN32_NAME_CONVERTER,0), "WIN32_NAME_CONVERTER"},
{ERR_PACK(0,DSO_F_WIN32_UNLOAD,0), "WIN32_UNLOAD"},
{0,NULL}
@@ -103,11 +108,15 @@ static ERR_STRING_DATA DSO_str_reasons[]=
{
{DSO_R_CTRL_FAILED ,"control command failed"},
{DSO_R_DSO_ALREADY_LOADED ,"dso already loaded"},
{DSO_R_EMPTY_FILE_STRUCTURE ,"empty file structure"},
{DSO_R_FAILURE ,"failure"},
{DSO_R_FILENAME_TOO_BIG ,"filename too big"},
{DSO_R_FINISH_FAILED ,"cleanup method function failed"},
{DSO_R_INCORRECT_FILE_SYNTAX ,"incorrect file syntax"},
{DSO_R_LOAD_FAILED ,"could not load the shared library"},
{DSO_R_NAME_TRANSLATION_FAILED ,"name translation failed"},
{DSO_R_NO_FILENAME ,"no filename"},
{DSO_R_NO_FILE_SPECIFICATION ,"no file specification"},
{DSO_R_NULL_HANDLE ,"a null shared library handle was used"},
{DSO_R_SET_FILENAME_FAILED ,"set filename failed"},
{DSO_R_STACK_ERROR ,"the meth_data stack is corrupt"},

View File

@@ -1,4 +1,4 @@
/* dso_lib.c */
/* dso_lib.c -*- mode:C; c-file-style: "eay" -*- */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2000.
*/
@@ -390,6 +390,33 @@ int DSO_set_filename(DSO *dso, const char *filename)
return(1);
}
char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2)
{
char *result = NULL;
if(dso == NULL || filespec1 == NULL)
{
DSOerr(DSO_F_DSO_MERGE,ERR_R_PASSED_NULL_PARAMETER);
return(NULL);
}
if(filespec1 == NULL)
filespec1 = dso->filename;
if(filespec1 == NULL)
{
DSOerr(DSO_F_DSO_MERGE,DSO_R_NO_FILE_SPECIFICATION);
return(NULL);
}
if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
{
if(dso->merger != NULL)
result = dso->merger(dso, filespec1, filespec2);
else if(dso->meth->dso_merger != NULL)
result = dso->meth->dso_merger(dso,
filespec1, filespec2);
}
return(result);
}
char *DSO_convert_filename(DSO *dso, const char *filename)
{
char *result = NULL;

View File

@@ -1,4 +1,4 @@
/* dso_vms.c */
/* dso_vms.c -*- mode:C; c-file-style: "eay" -*- */
/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
* project 2000.
*/
@@ -63,6 +63,7 @@
#include <openssl/dso.h>
#ifdef OPENSSL_SYS_VMS
#pragma message disable DOLLARID
#include <rms.h>
#include <lib$routines.h>
#include <stsdef.h>
#include <descrip.h>
@@ -89,6 +90,8 @@ static int vms_finish(DSO *dso);
static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg);
#endif
static char *vms_name_converter(DSO *dso, const char *filename);
static char *vms_merger(DSO *dso, const char *filespec1,
const char *filespec2);
static DSO_METHOD dso_meth_vms = {
"OpenSSL 'VMS' shared library method",
@@ -103,6 +106,7 @@ static DSO_METHOD dso_meth_vms = {
#endif
NULL, /* ctrl */
vms_name_converter,
vms_merger,
NULL, /* init */
NULL /* finish */
};
@@ -368,6 +372,127 @@ static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname)
return sym;
}
static char *vms_merger(DSO *dso, const char *filespec1, const char *filespec2)
{
int status;
int filespec1len, filespec2len;
struct FAB fab;
#ifdef NAML$C_MAXRSS
struct NAML nam;
char esa[NAML$C_MAXRSS];
#else
struct NAM nam;
char esa[NAM$C_MAXRSS];
#endif
char *merged;
if (!filespec1) filespec1 = "";
if (!filespec2) filespec2 = "";
filespec1len = strlen(filespec1);
filespec2len = strlen(filespec2);
fab = cc$rms_fab;
#ifdef NAML$C_MAXRSS
nam = cc$rms_naml;
#else
nam = cc$rms_nam;
#endif
fab.fab$l_fna = (char *)filespec1;
fab.fab$b_fns = filespec1len;
fab.fab$l_dna = (char *)filespec2;
fab.fab$b_dns = filespec2len;
#ifdef NAML$C_MAXRSS
if (filespec1len > NAM$C_MAXRSS)
{
fab.fab$l_fna = 0;
fab.fab$b_fns = 0;
nam.naml$l_long_filename = (char *)filespec1;
nam.naml$l_long_filename_size = filespec1len;
}
if (filespec2len > NAM$C_MAXRSS)
{
fab.fab$l_dna = 0;
fab.fab$b_dns = 0;
nam.naml$l_long_defname = (char *)filespec2;
nam.naml$l_long_defname_size = filespec2len;
}
nam.naml$l_esa = esa;
nam.naml$b_ess = NAM$C_MAXRSS;
nam.naml$l_long_expand = esa;
nam.naml$l_long_expand_alloc = sizeof(esa);
nam.naml$b_nop = NAM$M_SYNCHK | NAM$M_PWD;
nam.naml$v_no_short_upcase = 1;
fab.fab$l_naml = &nam;
#else
nam.nam$l_esa = esa;
nam.nam$b_ess = NAM$C_MAXRSS;
nam.nam$b_nop = NAM$M_SYNCHK | NAM$M_PWD;
fab.fab$l_nam = &nam;
#endif
status = sys$parse(&fab, 0, 0);
if(!$VMS_STATUS_SUCCESS(status))
{
unsigned short length;
char errstring[257];
struct dsc$descriptor_s errstring_dsc;
errstring_dsc.dsc$w_length = sizeof(errstring);
errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
errstring_dsc.dsc$a_pointer = errstring;
status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
if (!$VMS_STATUS_SUCCESS(status))
lib$signal(status); /* This is really bad. Abort! */
else
{
errstring[length] = '\0';
DSOerr(DSO_F_VMS_MERGER,DSO_R_FAILURE);
ERR_add_error_data(7,
"filespec \"", filespec1, "\", ",
"defaults \"", filespec2, "\": ",
errstring);
}
return(NULL);
}
#ifdef NAML$C_MAXRSS
if (nam.naml$l_long_expand_size)
{
merged = OPENSSL_malloc(nam.naml$l_long_expand_size + 1);
if(!merged)
goto malloc_err;
strncpy(merged, nam.naml$l_long_expand,
nam.naml$l_long_expand_size);
merged[nam.naml$l_long_expand_size] = '\0';
}
else
{
merged = OPENSSL_malloc(nam.naml$b_esl + 1);
if(!merged)
goto malloc_err;
strncpy(merged, nam.naml$l_esa,
nam.naml$b_esl);
merged[nam.naml$b_esl] = '\0';
}
#else
merged = OPENSSL_malloc(nam.nam$b_esl + 1);
if(!merged)
goto malloc_err;
strncpy(merged, nam.nam$l_esa,
nam.nam$b_esl);
merged[nam.nam$b_esl] = '\0';
#endif
return(merged);
malloc_err:
DSOerr(DSO_F_VMS_MERGER,
ERR_R_MALLOC_FAILURE);
}
static char *vms_name_converter(DSO *dso, const char *filename)
{
int len = strlen(filename);

View File

@@ -1,4 +1,4 @@
/* dso_win32.c */
/* dso_win32.c -*- mode:C; c-file-style: "eay" -*- */
/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
* project 2000.
*/
@@ -83,6 +83,10 @@ static int win32_finish(DSO *dso);
static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg);
#endif
static char *win32_name_converter(DSO *dso, const char *filename);
static char *win32_merger(DSO *dso, const char *filespec1,
const char *filespec2);
static const char *openssl_strnchr(const char *string, int c, size_t len);
static DSO_METHOD dso_meth_win32 = {
"OpenSSL 'win32' shared library method",
@@ -97,6 +101,7 @@ static DSO_METHOD dso_meth_win32 = {
#endif
NULL, /* ctrl */
win32_name_converter,
win32_merger,
NULL, /* init */
NULL /* finish */
};
@@ -248,6 +253,306 @@ static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname)
return((DSO_FUNC_TYPE)sym);
}
struct file_st
{
const char *node; int nodelen;
const char *device; int devicelen;
const char *predir; int predirlen;
const char *dir; int dirlen;
const char *file; int filelen;
};
static struct file_st *win32_splitter(DSO *dso, const char *filename,
int assume_last_is_dir)
{
struct file_st *result = NULL;
enum { IN_NODE, IN_DEVICE, IN_FILE } position;
const char *start = filename;
if (!filename)
{
DSOerr(DSO_F_WIN32_MERGER,DSO_R_NO_FILENAME);
/*goto err;*/
return(NULL);
}
result = OPENSSL_malloc(sizeof(struct file_st));
if(result == NULL)
{
DSOerr(DSO_F_WIN32_MERGER,
ERR_R_MALLOC_FAILURE);
return(NULL);
}
memset(result, 0, sizeof(struct file_st));
position = IN_DEVICE;
if(filename[0] == '\\' && filename[1] == '\\'
|| filename[0] == '/' && filename[1] == '/')
{
position = IN_NODE;
filename += 2;
start = filename;
result->node = start;
}
do
{
switch(filename[0])
{
case ':':
if(position != IN_DEVICE)
{
DSOerr(DSO_F_WIN32_MERGER,
DSO_R_INCORRECT_FILE_SYNTAX);
/*goto err;*/
return(NULL);
}
result->device = start;
result->devicelen = filename - start;
position = IN_FILE;
start = ++filename;
result->dir = start;
break;
case '\\':
case '/':
if(position == IN_NODE)
{
result->nodelen = filename - start;
position = IN_FILE;
start = ++filename;
result->dir = start;
}
else
{
filename++;
result->dirlen += filename - start;
}
break;
case '\0':
if(position == IN_NODE)
{
result->nodelen = filename - start;
}
else
{
if(filename - start > 0)
{
if (assume_last_is_dir)
{
result->devicelen += filename - start;
}
else
{
result->file = start;
result->filelen = filename - start;
}
}
}
break;
default:
filename++;
break;
}
}
while(*filename);
if(!result->nodelen) result->node = NULL;
if(!result->devicelen) result->device = NULL;
if(!result->dirlen) result->dir = NULL;
if(!result->filelen) result->file = NULL;
return(result);
}
static char *win32_joiner(DSO *dso, const struct file_st *file_split)
{
int len = 0, offset = 0;
char *result = NULL;
const char *start;
if(!file_split)
{
DSOerr(DSO_F_WIN32_MERGER,
ERR_R_PASSED_NULL_PARAMETER);
return(NULL);
}
if(file_split->node)
{
len += 2 + file_split->nodelen; /* 2 for starting \\ */
if(file_split->predir || file_split->dir || file_split->file)
len++; /* 1 for ending \ */
}
else if(file_split->device)
{
len += file_split->devicelen + 1; /* 1 for ending : */
}
len += file_split->predirlen;
if(file_split->predir && (file_split->dir || file_split->file))
{
len++; /* 1 for ending \ */
}
len += file_split->dirlen;
if(file_split->dir && file_split->file)
{
len++; /* 1 for ending \ */
}
len += file_split->filelen;
if(!len)
{
DSOerr(DSO_F_WIN32_MERGER, DSO_R_EMPTY_FILE_STRUCTURE);
return(NULL);
}
result = OPENSSL_malloc(len + 1);
if (!result)
{
DSOerr(DSO_F_WIN32_MERGER,
ERR_R_MALLOC_FAILURE);
return(NULL);
}
if(file_split->node)
{
strcpy(&result[offset], "\\\\"); offset += 2;
strncpy(&result[offset], file_split->node,
file_split->nodelen); offset += file_split->nodelen;
if(file_split->predir || file_split->dir || file_split->file)
{
result[offset] = '\\'; offset++;
}
}
else if(file_split->device)
{
strncpy(&result[offset], file_split->device,
file_split->devicelen); offset += file_split->devicelen;
result[offset] = ':'; offset++;
}
start = file_split->predir;
while(file_split->predirlen > (start - file_split->predir))
{
const char *end = openssl_strnchr(start, '/',
file_split->predirlen - (start - file_split->predir));
if(!end)
end = start
+ file_split->predirlen
- (start - file_split->predir);
strncpy(&result[offset], start,
end - start); offset += end - start;
result[offset] = '\\'; offset++;
start = end + 1;
}
if(file_split->predir && (file_split->dir || file_split->file))
{
result[offset] = '\\'; offset++;
}
start = file_split->dir;
while(file_split->dirlen > (start - file_split->dir))
{
const char *end = openssl_strnchr(start, '/',
file_split->dirlen - (start - file_split->dir));
if(!end)
end = start
+ file_split->dirlen
- (start - file_split->dir);
strncpy(&result[offset], start,
end - start); offset += end - start;
result[offset] = '\\'; offset++;
start = end + 1;
}
if(file_split->dir && file_split->file)
{
result[offset] = '\\'; offset++;
}
strncpy(&result[offset], file_split->file,
file_split->filelen); offset += file_split->filelen;
result[offset] = '\0';
return(result);
}
static char *win32_merger(DSO *dso, const char *filespec1, const char *filespec2)
{
char *merged = NULL;
struct file_st *filespec1_split = NULL;
struct file_st *filespec2_split = NULL;
if(!filespec1 && !filespec2)
{
DSOerr(DSO_F_WIN32_MERGER,
ERR_R_PASSED_NULL_PARAMETER);
return(NULL);
}
if (!filespec2)
{
merged = OPENSSL_malloc(strlen(filespec1) + 1);
if(!merged)
{
DSOerr(DSO_F_WIN32_MERGER,
ERR_R_MALLOC_FAILURE);
return(NULL);
}
strcpy(merged, filespec1);
}
else if (!filespec1)
{
merged = OPENSSL_malloc(strlen(filespec2) + 1);
if(!merged)
{
DSOerr(DSO_F_WIN32_MERGER,
ERR_R_MALLOC_FAILURE);
return(NULL);
}
strcpy(merged, filespec2);
}
else
{
filespec1_split = win32_splitter(dso, filespec1, 1);
if (!filespec1_split)
{
DSOerr(DSO_F_WIN32_MERGER,
ERR_R_MALLOC_FAILURE);
return(NULL);
}
filespec2_split = win32_splitter(dso, filespec2, 0);
if (!filespec1_split)
{
DSOerr(DSO_F_WIN32_MERGER,
ERR_R_MALLOC_FAILURE);
OPENSSL_free(filespec1_split);
return(NULL);
}
/* Fill in into filespec1_split */
if (!filespec1_split->node && !filespec1_split->device)
{
filespec1_split->node = filespec2_split->node;
filespec1_split->nodelen = filespec2_split->nodelen;
filespec1_split->device = filespec2_split->device;
filespec1_split->devicelen = filespec2_split->devicelen;
}
if (!filespec1_split->dir)
{
filespec1_split->dir = filespec2_split->dir;
filespec1_split->dirlen = filespec2_split->dirlen;
}
else if (filespec1_split->dir[0] != '\\'
&& filespec1_split->dir[0] != '/')
{
filespec1_split->predir = filespec2_split->dir;
filespec1_split->predirlen = filespec2_split->dirlen;
}
if (!filespec1_split->file)
{
filespec1_split->file = filespec2_split->file;
filespec1_split->filelen = filespec2_split->filelen;
}
merged = win32_joiner(dso, filespec1_split);
}
return(merged);
}
static char *win32_name_converter(DSO *dso, const char *filename)
{
char *translated;
@@ -276,4 +581,17 @@ static char *win32_name_converter(DSO *dso, const char *filename)
return(translated);
}
static const char *openssl_strnchr(const char *string, int c, size_t len)
{
size_t i;
const char *p;
for (i = 0, p = string; i < len && *p; i++, p++)
{
if (*p == c)
return p;
}
return NULL;
}
#endif /* OPENSSL_SYS_WIN32 */

View File

@@ -23,11 +23,13 @@ TEST=ectest.c
APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC= ec_lib.c ecp_smpl.c ecp_mont.c ecp_recp.c ecp_nist.c ec_cvt.c ec_mult.c \
ec_err.c
LIBSRC= ec_lib.c ecp_smpl.c ecp_mont.c ecp_recp.c ecp_nist.c ec_cvt.c ec_mult.c\
ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c\
ec2_smpl.c ec2_smpt.c ec2_mult.c
LIBOBJ= ec_lib.o ecp_smpl.o ecp_mont.o ecp_recp.o ecp_nist.o ec_cvt.o ec_mult.o \
ec_err.o
LIBOBJ= ec_lib.o ecp_smpl.o ecp_mont.o ecp_recp.o ecp_nist.o ec_cvt.o ec_mult.o\
ec_err.o ec_curve.o ec_check.o ec_print.o ec_asn1.o ec_key.o\
ec2_smpl.o ec2_mult.o
SRC= $(LIBSRC)
@@ -82,47 +84,123 @@ clean:
# DO NOT DELETE THIS LINE -- make depend depends on it.
ec_cvt.o: ../../include/openssl/bn.h ../../include/openssl/e_os2.h
ec_cvt.o: ../../include/openssl/ec.h ../../include/openssl/opensslconf.h
ec2_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec2_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec2_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ec2_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ec2_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ec2_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec2_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ec2_mult.o: ../../include/openssl/symhacks.h ec2_mult.c ec_lcl.h
ec2_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec2_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec2_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ec2_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ec2_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ec2_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec2_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ec2_smpl.o: ../../include/openssl/symhacks.h ec2_smpl.c ec2_smpt.c ec_lcl.h
ec2_smpt.o: ec2_smpt.c
ec_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
ec_asn1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
ec_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
ec_asn1.o: ../../include/openssl/ec.h ../../include/openssl/err.h
ec_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
ec_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
ec_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ec_asn1.o: ../../include/openssl/symhacks.h ec_asn1.c ec_lcl.h
ec_check.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec_check.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec_check.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ec_check.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ec_check.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ec_check.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec_check.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ec_check.o: ../../include/openssl/symhacks.h ec_check.c ec_lcl.h
ec_curve.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec_curve.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec_curve.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ec_curve.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ec_curve.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ec_curve.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec_curve.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ec_curve.o: ../../include/openssl/symhacks.h ec_curve.c ec_lcl.h
ec_cvt.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec_cvt.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec_cvt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ec_cvt.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ec_cvt.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ec_cvt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec_cvt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ec_cvt.o: ../../include/openssl/symhacks.h ec_cvt.c ec_lcl.h
ec_err.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
ec_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
ec_err.o: ../../include/openssl/ec.h ../../include/openssl/err.h
ec_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
ec_err.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
ec_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec_err.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec_err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ec_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ec_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
ec_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
ec_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
ec_err.o: ec_err.c
ec_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
ec_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
ec_lib.o: ../../include/openssl/ec.h ../../include/openssl/err.h
ec_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
ec_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
ec_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
ec_lib.o: ec_lcl.h ec_lib.c
ec_mult.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
ec_mult.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
ec_mult.o: ../../include/openssl/ec.h ../../include/openssl/err.h
ec_mult.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
ec_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
ec_mult.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
ec_mult.o: ec_lcl.h ec_mult.c
ecp_mont.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
ecp_mont.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
ecp_mont.o: ../../include/openssl/ec.h ../../include/openssl/err.h
ecp_mont.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
ecp_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
ecp_mont.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
ecp_mont.o: ec_lcl.h ecp_mont.c
ecp_nist.o: ../../include/openssl/bn.h ../../include/openssl/e_os2.h
ecp_nist.o: ../../include/openssl/ec.h ../../include/openssl/opensslconf.h
ec_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec_key.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ec_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ec_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ec_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ec_key.o: ../../include/openssl/symhacks.h ec_key.c ec_lcl.h
ec_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ec_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ec_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ec_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ec_lib.o: ../../include/openssl/symhacks.h ec_lcl.h ec_lib.c
ec_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ec_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ec_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ec_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ec_mult.o: ../../include/openssl/symhacks.h ec_lcl.h ec_mult.c
ec_print.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec_print.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec_print.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ec_print.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ec_print.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ec_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ec_print.o: ../../include/openssl/symhacks.h ec_lcl.h ec_print.c
ecp_mont.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ecp_mont.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ecp_mont.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ecp_mont.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ecp_mont.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ecp_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ecp_mont.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ecp_mont.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_mont.c
ecp_nist.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ecp_nist.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ecp_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ecp_nist.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ecp_nist.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ecp_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ecp_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ecp_nist.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_nist.c
ecp_recp.o: ../../include/openssl/bn.h ../../include/openssl/e_os2.h
ecp_recp.o: ../../include/openssl/ec.h ../../include/openssl/opensslconf.h
ecp_recp.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ecp_recp.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ecp_recp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ecp_recp.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ecp_recp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ecp_recp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ecp_recp.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_recp.c
ecp_smpl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
ecp_smpl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
ecp_smpl.o: ../../include/openssl/ec.h ../../include/openssl/err.h
ecp_smpl.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
ecp_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
ecp_smpl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
ecp_smpl.o: ec_lcl.h ecp_smpl.c
ecp_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ecp_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ecp_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
ecp_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
ecp_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
ecp_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ecp_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ecp_smpl.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_smpl.c

View File

@@ -1,6 +1,9 @@
/* crypto/ec/ec.h */
/*
* Originally written by Bodo Moeller for the OpenSSL project.
*/
/* ====================================================================
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -52,6 +55,19 @@
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the OpenSSL open source
* license provided above.
*
* The elliptic curve binary polynomial software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
*
*/
#ifndef HEADER_EC_H
#define HEADER_EC_H
@@ -61,6 +77,7 @@
#endif
#include <openssl/bn.h>
#include <openssl/asn1.h>
#include <openssl/symhacks.h>
#ifdef __cplusplus
@@ -85,6 +102,7 @@ typedef struct ec_group_st
-- curve coefficients
-- optional generator with associated information (order, cofactor)
-- optional extra data (TODO: precomputed table for fast computation of multiples of generator)
-- ASN1 stuff
*/
EC_GROUP;
@@ -96,40 +114,82 @@ typedef struct ec_point_st EC_POINT;
*/
const EC_METHOD *EC_GFp_simple_method(void);
const EC_METHOD *EC_GFp_mont_method(void);
const EC_METHOD *EC_GFp_nist_method(void);
#if 0
const EC_METHOD *EC_GFp_recp_method(void); /* TODO */
const EC_METHOD *EC_GFp_nist_method(void); /* TODO */
#endif
/* EC_METHOD for curves over GF(2^m).
*/
const EC_METHOD *EC_GF2m_simple_method(void);
EC_GROUP *EC_GROUP_new(const EC_METHOD *);
void EC_GROUP_free(EC_GROUP *);
void EC_GROUP_clear_free(EC_GROUP *);
int EC_GROUP_copy(EC_GROUP *, const EC_GROUP *);
EC_GROUP *EC_GROUP_dup(const EC_GROUP *);
const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *);
/* We don't have types for field specifications and field elements in general.
* Otherwise we could declare
* int EC_GROUP_set_curve(EC_GROUP *, .....);
*/
int EC_GROUP_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int EC_GROUP_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
/* EC_GROUP_new_GFp() calls EC_GROUP_new() and EC_GROUP_set_GFp()
* after choosing an appropriate EC_METHOD */
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int EC_METHOD_get_field_type(const EC_METHOD *);
int EC_GROUP_set_generator(EC_GROUP *, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *);
int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
void EC_GROUP_set_nid(EC_GROUP *, int); /* curve name */
int EC_GROUP_get_nid(const EC_GROUP *);
void EC_GROUP_set_asn1_flag(EC_GROUP *, int flag);
int EC_GROUP_get_asn1_flag(const EC_GROUP *);
void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t);
point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
unsigned char *EC_GROUP_get0_seed(const EC_GROUP *);
size_t EC_GROUP_get_seed_len(const EC_GROUP *);
size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
int EC_GROUP_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int EC_GROUP_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
int EC_GROUP_set_curve_GF2m(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
int EC_GROUP_get_curve_GF2m(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
int EC_GROUP_get_degree(const EC_GROUP *);
/* EC_GROUP_check() returns 1 if 'group' defines a valid group, 0 otherwise */
int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
/* EC_GROUP_check_discriminant() returns 1 if the discriminant of the
* elliptic curve is not zero, 0 otherwise */
int EC_GROUP_check_discriminant(const EC_GROUP *, BN_CTX *);
/* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*()
* after choosing an appropriate EC_METHOD */
EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
/* EC_GROUP_new_by_nid() creates a EC_GROUP structure specified by a NID */
EC_GROUP *EC_GROUP_new_by_nid(int nid);
/* handling of internal curves */
typedef struct {
int nid;
const char *comment;
} EC_builtin_curve;
/* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number
* of all available curves or zero if a error occurred.
* In case r ist not zero nitems EC_builtin_curve structures
* are filled with the data of the first nitems internal groups */
size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
/* EC_POINT functions */
EC_POINT *EC_POINT_new(const EC_GROUP *);
void EC_POINT_free(EC_POINT *);
void EC_POINT_clear_free(EC_POINT *);
int EC_POINT_copy(EC_POINT *, const EC_POINT *);
EC_POINT *EC_POINT_dup(const EC_POINT *, const EC_GROUP *);
const EC_METHOD *EC_POINT_method_of(const EC_POINT *);
@@ -145,11 +205,28 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, int y_bit, BN_CTX *);
int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, const BIGNUM *y, BN_CTX *);
int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *, const EC_POINT *,
BIGNUM *x, BIGNUM *y, BN_CTX *);
int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
const BIGNUM *x, int y_bit, BN_CTX *);
size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
unsigned char *buf, size_t len, BN_CTX *);
int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *,
const unsigned char *buf, size_t len, BN_CTX *);
/* other interfaces to point2oct/oct2point: */
BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
point_conversion_form_t form, BIGNUM *, BN_CTX *);
EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
EC_POINT *, BN_CTX *);
char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
point_conversion_form_t form, BN_CTX *);
EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
EC_POINT *, BN_CTX *);
int EC_POINT_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
int EC_POINT_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
@@ -168,6 +245,99 @@ int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *);
/* ASN1 stuff */
/* EC_GROUP_get_basis_type() returns the NID of the basis type
* used to represent the field elements */
int EC_GROUP_get_basis_type(const EC_GROUP *);
int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1,
unsigned int *k2, unsigned int *k3);
#define OPENSSL_EC_NAMED_CURVE 0x001
typedef struct ecpk_parameters_st ECPKPARAMETERS;
EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
#define d2i_ECPKParameters_bio(bp,x) (EC_GROUP *)ASN1_d2i_bio(NULL, \
(char *(*)())d2i_ECPKParameters,(bp),(unsigned char **)(x))
#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio(i2d_ECPKParameters,(bp), \
(unsigned char *)(x))
#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
(char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
(unsigned char *)(x))
#ifndef OPENSSL_NO_BIO
int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
#endif
#ifndef OPENSSL_NO_FP_API
int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
#endif
/* the EC_KEY stuff */
typedef struct ec_key_st EC_KEY;
typedef struct ec_key_meth_data_st {
int (*init)(EC_KEY *);
void (*finish)(EC_KEY *);
} EC_KEY_METH_DATA;
struct ec_key_st {
int version;
EC_GROUP *group;
EC_POINT *pub_key;
BIGNUM *priv_key;
unsigned int enc_flag;
point_conversion_form_t conv_form;
int references;
EC_KEY_METH_DATA *meth_data;
}/* EC_KEY */;
/* some values for the encoding_flag */
#define EC_PKEY_NO_PARAMETERS 0x001
#define EC_PKEY_NO_PUBKEY 0x002
EC_KEY *EC_KEY_new(void);
void EC_KEY_free(EC_KEY *);
EC_KEY *EC_KEY_copy(EC_KEY *, const EC_KEY *);
EC_KEY *EC_KEY_dup(const EC_KEY *);
int EC_KEY_up_ref(EC_KEY *);
/* EC_KEY_generate_key() creates a ec private (public) key */
int EC_KEY_generate_key(EC_KEY *);
/* EC_KEY_check_key() */
int EC_KEY_check_key(const EC_KEY *);
/* de- and encode functions for the SEC1 ECPrivateKey */
EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len);
int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out);
/* de- and encode functions for the elliptic curve parameters */
EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len);
int i2d_ECParameters(EC_KEY *a, unsigned char **out);
EC_KEY *ECPublicKey_set_octet_string(EC_KEY **a, const unsigned char **in,
long len);
int ECPublicKey_get_octet_string(EC_KEY *a, unsigned char **out);
#ifndef OPENSSL_NO_BIO
int ECParameters_print(BIO *bp, const EC_KEY *x);
int EC_KEY_print(BIO *bp, const EC_KEY *x, int off);
#endif
#ifndef OPENSSL_NO_FP_API
int ECParameters_print_fp(FILE *fp, const EC_KEY *x);
int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off);
#endif
#define ECParameters_dup(x) (EC_KEY *)ASN1_dup((int (*)())i2d_ECParameters,\
(char *(*)())d2i_ECParameters,(char *)(x))
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
@@ -178,66 +348,148 @@ void ERR_load_EC_strings(void);
/* Function codes. */
#define EC_F_COMPUTE_WNAF 143
#define EC_F_D2I_ECPARAMETERS 144
#define EC_F_D2I_ECPKPARAMETERS 145
#define EC_F_D2I_ECPRIVATEKEY 146
#define EC_F_ECPARAMETERS_PRINT 147
#define EC_F_ECPARAMETERS_PRINT_FP 148
#define EC_F_ECPKPARAMETERS_PRINT 149
#define EC_F_ECPKPARAMETERS_PRINT_FP 150
#define EC_F_ECPUBLICKEY_GET_OCTET 151
#define EC_F_ECPUBLICKEY_SET_OCTET 152
#define EC_F_ECP_NIST_MOD_192 203
#define EC_F_ECP_NIST_MOD_224 204
#define EC_F_ECP_NIST_MOD_256 205
#define EC_F_ECP_NIST_MOD_521 206
#define EC_F_EC_ASN1_GROUP2CURVE 153
#define EC_F_EC_ASN1_GROUP2FIELDID 154
#define EC_F_EC_ASN1_GROUP2PARAMETERS 155
#define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156
#define EC_F_EC_ASN1_PARAMETERS2GROUP 157
#define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158
#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159
#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195
#define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160
#define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161
#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164
#define EC_F_EC_GFP_MONT_FIELD_DECODE 133
#define EC_F_EC_GFP_MONT_FIELD_ENCODE 134
#define EC_F_EC_GFP_MONT_FIELD_MUL 131
#define EC_F_EC_GFP_MONT_FIELD_SQR 132
#define EC_F_EC_GFP_NIST_FIELD_MUL 200
#define EC_F_EC_GFP_NIST_FIELD_SQR 201
#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE_GFP 202
#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165
#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166
#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100
#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101
#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102
#define EC_F_EC_GFP_SIMPLE_OCT2POINT 103
#define EC_F_EC_GFP_SIMPLE_POINT2OCT 104
#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137
#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167
#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168
#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169
#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
#define EC_F_EC_GROUP_CHECK 170
#define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171
#define EC_F_EC_GROUP_COPY 106
#define EC_F_EC_GROUP_GET0_GENERATOR 139
#define EC_F_EC_GROUP_GET_COFACTOR 140
#define EC_F_EC_GROUP_GET_CURVE_GF2M 172
#define EC_F_EC_GROUP_GET_CURVE_GFP 130
#define EC_F_EC_GROUP_GET_DEGREE 173
#define EC_F_EC_GROUP_GET_EXTRA_DATA 107
#define EC_F_EC_GROUP_GET_ORDER 141
#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193
#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194
#define EC_F_EC_GROUP_GROUP2NID 147
#define EC_F_EC_GROUP_NEW 108
#define EC_F_EC_GROUP_NEW_BY_NID 174
#define EC_F_EC_GROUP_NEW_FROM_DATA 175
#define EC_F_EC_GROUP_PRECOMPUTE_MULT 142
#define EC_F_EC_GROUP_SET_CURVE_GF2M 176
#define EC_F_EC_GROUP_SET_CURVE_GFP 109
#define EC_F_EC_GROUP_SET_EXTRA_DATA 110
#define EC_F_EC_GROUP_SET_GENERATOR 111
#define EC_F_EC_KEY_CHECK_KEY 177
#define EC_F_EC_KEY_COPY 178
#define EC_F_EC_KEY_GENERATE_KEY 179
#define EC_F_EC_KEY_PRINT 180
#define EC_F_EC_KEY_PRINT_FP 181
#define EC_F_EC_NEW 182
#define EC_F_EC_POINTS_MAKE_AFFINE 136
#define EC_F_EC_POINTS_MUL 138
#define EC_F_EC_POINT_ADD 112
#define EC_F_EC_POINT_CMP 113
#define EC_F_EC_POINT_COPY 114
#define EC_F_EC_POINT_DBL 115
#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183
#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116
#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117
#define EC_F_EC_POINT_IS_AT_INFINITY 118
#define EC_F_EC_POINT_IS_ON_CURVE 119
#define EC_F_EC_POINT_MAKE_AFFINE 120
#define EC_F_EC_POINT_MUL 184
#define EC_F_EC_POINT_NEW 121
#define EC_F_EC_POINT_OCT2POINT 122
#define EC_F_EC_POINT_POINT2OCT 123
#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185
#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124
#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186
#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125
#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126
#define EC_F_EC_POINT_SET_TO_INFINITY 127
#define EC_F_EC_WNAF_MUL 187
#define EC_F_EC_WNAF_PRECOMPUTE_MULT 188
#define EC_F_GFP_MONT_GROUP_SET_CURVE 189
#define EC_F_GFP_MONT_GROUP_SET_CURVE_GFP 135
#define EC_F_I2D_ECPARAMETERS 190
#define EC_F_I2D_ECPKPARAMETERS 191
#define EC_F_I2D_ECPRIVATEKEY 192
/* Reason codes. */
#define EC_R_ASN1_ERROR 115
#define EC_R_ASN1_UNKNOWN_FIELD 116
#define EC_R_BUFFER_TOO_SMALL 100
#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
#define EC_R_DISCRIMINANT_IS_ZERO 118
#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
#define EC_R_INCOMPATIBLE_OBJECTS 101
#define EC_R_INTERNAL_ERROR 132
#define EC_R_INVALID_ARGUMENT 112
#define EC_R_INVALID_COMPRESSED_POINT 110
#define EC_R_INVALID_COMPRESSION_BIT 109
#define EC_R_INVALID_ENCODING 102
#define EC_R_INVALID_FIELD 103
#define EC_R_INVALID_FORM 104
#define EC_R_INVALID_GROUP_ORDER 122
#define EC_R_INVALID_PRIVATE_KEY 123
#define EC_R_MISSING_PARAMETERS 124
#define EC_R_MISSING_PRIVATE_KEY 125
#define EC_R_NOT_A_NIST_PRIME 135
#define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136
#define EC_R_NOT_IMPLEMENTED 126
#define EC_R_NOT_INITIALIZED 111
#define EC_R_NO_FIELD_MOD 133
#define EC_R_NO_SUCH_EXTRA_DATA 105
#define EC_R_PASSED_NULL_PARAMETER 134
#define EC_R_PKPARAMETERS2GROUP_FAILURE 127
#define EC_R_POINT_AT_INFINITY 106
#define EC_R_POINT_IS_NOT_ON_CURVE 107
#define EC_R_SLOT_FULL 108
#define EC_R_UNDEFINED_GENERATOR 113
#define EC_R_UNDEFINED_ORDER 128
#define EC_R_UNKNOWN_GROUP 129
#define EC_R_UNKNOWN_ORDER 114
#define EC_R_UNSUPPORTED_FIELD 131
#define EC_R_WRONG_ORDER 130
#ifdef __cplusplus
}

375
crypto/ec/ec2_mult.c Normal file
View File

@@ -0,0 +1,375 @@
/* crypto/ec/ec2_mult.c */
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* The Elliptic Curve Public-Key Crypto Library (ECC Code) included
* herein is developed by SUN MICROSYSTEMS, INC., and is contributed
* to the OpenSSL project.
*
* The ECC Code is licensed pursuant to the OpenSSL open source
* license provided below.
*
* The software is originally written by Sheueling Chang Shantz and
* Douglas Stebila of Sun Microsystems Laboratories.
*
*/
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <openssl/err.h>
#include "ec_lcl.h"
/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective
* coordinates.
* Uses algorithm Mdouble in appendix of
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation".
* modified to not require precomputation of c=b^{2^{m-1}}.
*/
static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx)
{
BIGNUM *t1;
int ret = 0;
/* Since Mdouble is static we can guarantee that ctx != NULL. */
BN_CTX_start(ctx);
t1 = BN_CTX_get(ctx);
if (t1 == NULL) goto err;
if (!group->meth->field_sqr(group, x, x, ctx)) goto err;
if (!group->meth->field_sqr(group, t1, z, ctx)) goto err;
if (!group->meth->field_mul(group, z, x, t1, ctx)) goto err;
if (!group->meth->field_sqr(group, x, x, ctx)) goto err;
if (!group->meth->field_sqr(group, t1, t1, ctx)) goto err;
if (!group->meth->field_mul(group, t1, &group->b, t1, ctx)) goto err;
if (!BN_GF2m_add(x, x, t1)) goto err;
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery
* projective coordinates.
* Uses algorithm Madd in appendix of
* Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation".
*/
static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1,
const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx)
{
BIGNUM *t1, *t2;
int ret = 0;
/* Since Madd is static we can guarantee that ctx != NULL. */
BN_CTX_start(ctx);
t1 = BN_CTX_get(ctx);
t2 = BN_CTX_get(ctx);
if (t2 == NULL) goto err;
if (!BN_copy(t1, x)) goto err;
if (!group->meth->field_mul(group, x1, x1, z2, ctx)) goto err;
if (!group->meth->field_mul(group, z1, z1, x2, ctx)) goto err;
if (!group->meth->field_mul(group, t2, x1, z1, ctx)) goto err;
if (!BN_GF2m_add(z1, z1, x1)) goto err;
if (!group->meth->field_sqr(group, z1, z1, ctx)) goto err;
if (!group->meth->field_mul(group, x1, z1, t1, ctx)) goto err;
if (!BN_GF2m_add(x1, x1, t2)) goto err;
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
* using Montgomery point multiplication algorithm Mxy() in appendix of
* Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation".
* Returns:
* 0 on error
* 1 if return value should be the point at infinity
* 2 otherwise
*/
static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIGNUM *x1,
BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, BN_CTX *ctx)
{
BIGNUM *t3, *t4, *t5;
int ret = 0;
if (BN_is_zero(z1))
{
if (!BN_zero(x2)) return 0;
if (!BN_zero(z2)) return 0;
return 1;
}
if (BN_is_zero(z2))
{
if (!BN_copy(x2, x)) return 0;
if (!BN_GF2m_add(z2, x, y)) return 0;
return 2;
}
/* Since Mxy is static we can guarantee that ctx != NULL. */
BN_CTX_start(ctx);
t3 = BN_CTX_get(ctx);
t4 = BN_CTX_get(ctx);
t5 = BN_CTX_get(ctx);
if (t5 == NULL) goto err;
if (!BN_one(t5)) goto err;
if (!group->meth->field_mul(group, t3, z1, z2, ctx)) goto err;
if (!group->meth->field_mul(group, z1, z1, x, ctx)) goto err;
if (!BN_GF2m_add(z1, z1, x1)) goto err;
if (!group->meth->field_mul(group, z2, z2, x, ctx)) goto err;
if (!group->meth->field_mul(group, x1, z2, x1, ctx)) goto err;
if (!BN_GF2m_add(z2, z2, x2)) goto err;
if (!group->meth->field_mul(group, z2, z2, z1, ctx)) goto err;
if (!group->meth->field_sqr(group, t4, x, ctx)) goto err;
if (!BN_GF2m_add(t4, t4, y)) goto err;
if (!group->meth->field_mul(group, t4, t4, t3, ctx)) goto err;
if (!BN_GF2m_add(t4, t4, z2)) goto err;
if (!group->meth->field_mul(group, t3, t3, x, ctx)) goto err;
if (!group->meth->field_div(group, t3, t5, t3, ctx)) goto err;
if (!group->meth->field_mul(group, t4, t3, t4, ctx)) goto err;
if (!group->meth->field_mul(group, x2, x1, t3, ctx)) goto err;
if (!BN_GF2m_add(z2, x2, x)) goto err;
if (!group->meth->field_mul(group, z2, z2, t4, ctx)) goto err;
if (!BN_GF2m_add(z2, z2, y)) goto err;
ret = 2;
err:
BN_CTX_end(ctx);
return ret;
}
/* Computes scalar*point and stores the result in r.
* point can not equal r.
* Uses algorithm 2P of
* Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation".
*/
static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
const EC_POINT *point, BN_CTX *ctx)
{
BIGNUM *x1, *x2, *z1, *z2;
int ret = 0, i, j;
BN_ULONG mask;
if (r == point)
{
ECerr(EC_F_EC_POINT_MUL, EC_R_INVALID_ARGUMENT);
return 0;
}
/* if result should be point at infinity */
if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) ||
EC_POINT_is_at_infinity(group, point))
{
return EC_POINT_set_to_infinity(group, r);
}
/* only support affine coordinates */
if (!point->Z_is_one) return 0;
/* Since point_multiply is static we can guarantee that ctx != NULL. */
BN_CTX_start(ctx);
x1 = BN_CTX_get(ctx);
z1 = BN_CTX_get(ctx);
if (z1 == NULL) goto err;
x2 = &r->X;
z2 = &r->Y;
if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */
if (!BN_one(z1)) goto err; /* z1 = 1 */
if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */
if (!group->meth->field_sqr(group, x2, z2, ctx)) goto err;
if (!BN_GF2m_add(x2, x2, &group->b)) goto err; /* x2 = x^4 + b */
/* find top most bit and go one past it */
i = scalar->top - 1; j = BN_BITS2 - 1;
mask = BN_TBIT;
while (!(scalar->d[i] & mask)) { mask >>= 1; j--; }
mask >>= 1; j--;
/* if top most bit was at word break, go to next word */
if (!mask)
{
i--; j = BN_BITS2 - 1;
mask = BN_TBIT;
}
for (; i >= 0; i--)
{
for (; j >= 0; j--)
{
if (scalar->d[i] & mask)
{
if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err;
if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err;
}
else
{
if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
}
mask >>= 1;
}
j = BN_BITS2 - 1;
mask = BN_TBIT;
}
/* convert out of "projective" coordinates */
i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx);
if (i == 0) goto err;
else if (i == 1)
{
if (!EC_POINT_set_to_infinity(group, r)) goto err;
}
else
{
if (!BN_one(&r->Z)) goto err;
r->Z_is_one = 1;
}
/* GF(2^m) field elements should always have BIGNUM::neg = 0 */
BN_set_sign(&r->X, 0);
BN_set_sign(&r->Y, 0);
ret = 1;
err:
BN_CTX_end(ctx);
return ret;
}
/* Computes the sum
* scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
* gracefully ignoring NULL scalar values.
*/
int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
int ret = 0, i;
EC_POINT *p=NULL;
if (ctx == NULL)
{
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
/* This implementation is more efficient than the wNAF implementation for 2
* or fewer points. Use the ec_wNAF_mul implementation for 3 or more points.
*/
if ((scalar && (num > 1)) || (num > 2))
{
ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
goto err;
}
if ((p = EC_POINT_new(group)) == NULL) goto err;
if (!EC_POINT_set_to_infinity(group, r)) goto err;
if (scalar)
{
if (!ec_GF2m_montgomery_point_multiply(group, p, scalar, group->generator, ctx)) goto err;
if (BN_get_sign(scalar))
if (!group->meth->invert(group, p, ctx)) goto err;
if (!group->meth->add(group, r, r, p, ctx)) goto err;
}
for (i = 0; i < num; i++)
{
if (!ec_GF2m_montgomery_point_multiply(group, p, scalars[i], points[i], ctx)) goto err;
if (BN_get_sign(scalars[i]))
if (!group->meth->invert(group, p, ctx)) goto err;
if (!group->meth->add(group, r, r, p, ctx)) goto err;
}
ret = 1;
err:
if (p) EC_POINT_free(p);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
}
/* Precomputation for point multiplication. */
int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
{
/* There is no precomputation to do for Montgomery scalar multiplication but
* since this implementation falls back to the wNAF multiplication for more than
* two points, call the wNAF implementation's precompute.
*/
return ec_wNAF_precompute_mult(group, ctx);
}

974
crypto/ec/ec2_smpl.c Normal file
View File

@@ -0,0 +1,974 @@
/* crypto/ec/ec2_smpl.c */
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* The Elliptic Curve Public-Key Crypto Library (ECC Code) included
* herein is developed by SUN MICROSYSTEMS, INC., and is contributed
* to the OpenSSL project.
*
* The ECC Code is licensed pursuant to the OpenSSL open source
* license provided below.
*
* The software is originally written by Sheueling Chang Shantz and
* Douglas Stebila of Sun Microsystems Laboratories.
*
*/
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <openssl/err.h>
#include "ec_lcl.h"
const EC_METHOD *EC_GF2m_simple_method(void)
{
static const EC_METHOD ret = {
NID_X9_62_characteristic_two_field,
ec_GF2m_simple_group_init,
ec_GF2m_simple_group_finish,
ec_GF2m_simple_group_clear_finish,
ec_GF2m_simple_group_copy,
ec_GF2m_simple_group_set_curve,
ec_GF2m_simple_group_get_curve,
ec_GF2m_simple_group_get_degree,
ec_GF2m_simple_group_check_discriminant,
ec_GF2m_simple_point_init,
ec_GF2m_simple_point_finish,
ec_GF2m_simple_point_clear_finish,
ec_GF2m_simple_point_copy,
ec_GF2m_simple_point_set_to_infinity,
0 /* set_Jprojective_coordinates_GFp */,
0 /* get_Jprojective_coordinates_GFp */,
ec_GF2m_simple_point_set_affine_coordinates,
ec_GF2m_simple_point_get_affine_coordinates,
ec_GF2m_simple_set_compressed_coordinates,
ec_GF2m_simple_point2oct,
ec_GF2m_simple_oct2point,
ec_GF2m_simple_add,
ec_GF2m_simple_dbl,
ec_GF2m_simple_invert,
ec_GF2m_simple_mul,
ec_GF2m_precompute_mult,
ec_GF2m_simple_is_at_infinity,
ec_GF2m_simple_is_on_curve,
ec_GF2m_simple_cmp,
ec_GF2m_simple_make_affine,
ec_GF2m_simple_points_make_affine,
ec_GF2m_simple_field_mul,
ec_GF2m_simple_field_sqr,
ec_GF2m_simple_field_div,
0 /* field_encode */,
0 /* field_decode */,
0 /* field_set_to_one */ };
return &ret;
}
/* Initialize a GF(2^m)-based EC_GROUP structure.
* Note that all other members are handled by EC_GROUP_new.
*/
int ec_GF2m_simple_group_init(EC_GROUP *group)
{
BN_init(&group->field);
BN_init(&group->a);
BN_init(&group->b);
return 1;
}
/* Free a GF(2^m)-based EC_GROUP structure.
* Note that all other members are handled by EC_GROUP_free.
*/
void ec_GF2m_simple_group_finish(EC_GROUP *group)
{
BN_free(&group->field);
BN_free(&group->a);
BN_free(&group->b);
}
/* Clear and free a GF(2^m)-based EC_GROUP structure.
* Note that all other members are handled by EC_GROUP_clear_free.
*/
void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
{
BN_clear_free(&group->field);
BN_clear_free(&group->a);
BN_clear_free(&group->b);
group->poly[0] = 0;
group->poly[1] = 0;
group->poly[2] = 0;
group->poly[3] = 0;
group->poly[4] = 0;
}
/* Copy a GF(2^m)-based EC_GROUP structure.
* Note that all other members are handled by EC_GROUP_copy.
*/
int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
{
int i;
if (!BN_copy(&dest->field, &src->field)) return 0;
if (!BN_copy(&dest->a, &src->a)) return 0;
if (!BN_copy(&dest->b, &src->b)) return 0;
dest->poly[0] = src->poly[0];
dest->poly[1] = src->poly[1];
dest->poly[2] = src->poly[2];
dest->poly[3] = src->poly[3];
dest->poly[4] = src->poly[4];
bn_wexpand(&dest->a, (dest->poly[0] + BN_BITS2 - 1) / BN_BITS2);
bn_wexpand(&dest->b, (dest->poly[0] + BN_BITS2 - 1) / BN_BITS2);
for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0;
for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0;
return 1;
}
/* Set the curve parameters of an EC_GROUP structure. */
int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
int ret = 0, i;
/* group->field */
if (!BN_copy(&group->field, p)) goto err;
i = BN_GF2m_poly2arr(&group->field, group->poly, 5);
if ((i != 5) && (i != 3))
{
ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
goto err;
}
/* group->a */
if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) goto err;
bn_wexpand(&group->a, (group->poly[0] + BN_BITS2 - 1) / BN_BITS2);
for (i = group->a.top; i < group->a.dmax; i++) group->a.d[i] = 0;
/* group->b */
if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) goto err;
bn_wexpand(&group->b, (group->poly[0] + BN_BITS2 - 1) / BN_BITS2);
for (i = group->b.top; i < group->b.dmax; i++) group->b.d[i] = 0;
ret = 1;
err:
return ret;
}
/* Get the curve parameters of an EC_GROUP structure.
* If p, a, or b are NULL then there values will not be set but the method will return with success.
*/
int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
{
int ret = 0;
if (p != NULL)
{
if (!BN_copy(p, &group->field)) return 0;
}
if (a != NULL)
{
if (!BN_copy(a, &group->a)) goto err;
}
if (b != NULL)
{
if (!BN_copy(b, &group->b)) goto err;
}
ret = 1;
err:
return ret;
}
/* Gets the degree of the field. For a curve over GF(2^m) this is the value m. */
int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
{
return BN_num_bits(&group->field)-1;
}
/* Checks the discriminant of the curve.
* y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
*/
int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
{
int ret = 0;
BIGNUM *b;
BN_CTX *new_ctx = NULL;
if (ctx == NULL)
{
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
{
ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
goto err;
}
}
BN_CTX_start(ctx);
b = BN_CTX_get(ctx);
if (b == NULL) goto err;
if (!BN_GF2m_mod_arr(b, &group->b, group->poly)) goto err;
/* check the discriminant:
* y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p)
*/
if (BN_is_zero(b)) goto err;
ret = 1;
err:
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
}
/* Initializes an EC_POINT. */
int ec_GF2m_simple_point_init(EC_POINT *point)
{
BN_init(&point->X);
BN_init(&point->Y);
BN_init(&point->Z);
return 1;
}
/* Frees an EC_POINT. */
void ec_GF2m_simple_point_finish(EC_POINT *point)
{
BN_free(&point->X);
BN_free(&point->Y);
BN_free(&point->Z);
}
/* Clears and frees an EC_POINT. */
void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
{
BN_clear_free(&point->X);
BN_clear_free(&point->Y);
BN_clear_free(&point->Z);
point->Z_is_one = 0;
}
/* Copy the contents of one EC_POINT into another. Assumes dest is initialized. */
int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
{
if (!BN_copy(&dest->X, &src->X)) return 0;
if (!BN_copy(&dest->Y, &src->Y)) return 0;
if (!BN_copy(&dest->Z, &src->Z)) return 0;
dest->Z_is_one = src->Z_is_one;
return 1;
}
/* Set an EC_POINT to the point at infinity.
* A point at infinity is represented by having Z=0.
*/
int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
{
point->Z_is_one = 0;
return (BN_zero(&point->Z));
}
/* Set the coordinates of an EC_POINT using affine coordinates.
* Note that the simple implementation only uses affine coordinates.
*/
int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
{
int ret = 0;
if (x == NULL || y == NULL)
{
ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (!BN_copy(&point->X, x)) goto err;
BN_set_sign(&point->X, 0);
if (!BN_copy(&point->Y, y)) goto err;
BN_set_sign(&point->Y, 0);
if (!BN_copy(&point->Z, BN_value_one())) goto err;
BN_set_sign(&point->Z, 0);
point->Z_is_one = 1;
ret = 1;
err:
return ret;
}
/* Gets the affine coordinates of an EC_POINT.
* Note that the simple implementation only uses affine coordinates.
*/
int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point,
BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
{
int ret = 0;
if (EC_POINT_is_at_infinity(group, point))
{
ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY);
return 0;
}
if (BN_cmp(&point->Z, BN_value_one()))
{
ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (x != NULL)
{
if (!BN_copy(x, &point->X)) goto err;
BN_set_sign(x, 0);
}
if (y != NULL)
{
if (!BN_copy(y, &point->Y)) goto err;
BN_set_sign(y, 0);
}
ret = 1;
err:
return ret;
}
/* Include patented algorithms. */
#include "ec2_smpt.c"
/* Converts an EC_POINT to an octet string.
* If buf is NULL, the encoded length will be returned.
* If the length len of buf is smaller than required an error will be returned.
*
* The point compression section of this function is patented by Certicom Corp.
* under US Patent 6,141,420. Point compression is disabled by default and can
* be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at
* Configure-time.
*/
size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
unsigned char *buf, size_t len, BN_CTX *ctx)
{
size_t ret;
BN_CTX *new_ctx = NULL;
int used_ctx = 0;
BIGNUM *x, *y, *yxi;
size_t field_len, i, skip;
#ifndef OPENSSL_EC_BIN_PT_COMP
if ((form == POINT_CONVERSION_COMPRESSED) || (form == POINT_CONVERSION_HYBRID))
{
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_DISABLED);
goto err;
}
#endif
if ((form != POINT_CONVERSION_COMPRESSED)
&& (form != POINT_CONVERSION_UNCOMPRESSED)
&& (form != POINT_CONVERSION_HYBRID))
{
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
goto err;
}
if (EC_POINT_is_at_infinity(group, point))
{
/* encodes to a single 0 octet */
if (buf != NULL)
{
if (len < 1)
{
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
return 0;
}
buf[0] = 0;
}
return 1;
}
/* ret := required output buffer length */
field_len = (EC_GROUP_get_degree(group) + 7) / 8;
ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
/* if 'buf' is NULL, just return required length */
if (buf != NULL)
{
if (len < ret)
{
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
goto err;
}
if (ctx == NULL)
{
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
BN_CTX_start(ctx);
used_ctx = 1;
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
yxi = BN_CTX_get(ctx);
if (yxi == NULL) goto err;
if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
buf[0] = form;
#ifdef OPENSSL_EC_BIN_PT_COMP
if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x))
{
if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
if (BN_is_odd(yxi)) buf[0]++;
}
#endif
i = 1;
skip = field_len - BN_num_bytes(x);
if (skip > field_len)
{
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
goto err;
}
while (skip > 0)
{
buf[i++] = 0;
skip--;
}
skip = BN_bn2bin(x, buf + i);
i += skip;
if (i != 1 + field_len)
{
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
goto err;
}
if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID)
{
skip = field_len - BN_num_bytes(y);
if (skip > field_len)
{
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
goto err;
}
while (skip > 0)
{
buf[i++] = 0;
skip--;
}
skip = BN_bn2bin(y, buf + i);
i += skip;
}
if (i != ret)
{
ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
goto err;
}
}
if (used_ctx)
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
err:
if (used_ctx)
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return 0;
}
/* Converts an octet string representation to an EC_POINT.
* Note that the simple implementation only uses affine coordinates.
*/
int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
const unsigned char *buf, size_t len, BN_CTX *ctx)
{
point_conversion_form_t form;
int y_bit;
BN_CTX *new_ctx = NULL;
BIGNUM *x, *y, *yxi;
size_t field_len, enc_len;
int ret = 0;
if (len == 0)
{
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
return 0;
}
form = buf[0];
y_bit = form & 1;
form = form & ~1;
if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
&& (form != POINT_CONVERSION_UNCOMPRESSED)
&& (form != POINT_CONVERSION_HYBRID))
{
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
return 0;
}
if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit)
{
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
return 0;
}
if (form == 0)
{
if (len != 1)
{
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
return 0;
}
return EC_POINT_set_to_infinity(group, point);
}
field_len = (EC_GROUP_get_degree(group) + 7) / 8;
enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len;
if (len != enc_len)
{
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
return 0;
}
if (ctx == NULL)
{
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
yxi = BN_CTX_get(ctx);
if (yxi == NULL) goto err;
if (!BN_bin2bn(buf + 1, field_len, x)) goto err;
if (BN_ucmp(x, &group->field) >= 0)
{
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
goto err;
}
if (form == POINT_CONVERSION_COMPRESSED)
{
if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err;
}
else
{
if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err;
if (BN_ucmp(y, &group->field) >= 0)
{
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
goto err;
}
if (form == POINT_CONVERSION_HYBRID)
{
if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err;
if (y_bit != BN_is_odd(yxi))
{
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
goto err;
}
}
if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
}
if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
{
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
}
ret = 1;
err:
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
}
/* Computes a + b and stores the result in r. r could be a or b, a could be b.
* Uses algorithm A.10.2 of IEEE P1363.
*/
int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
int ret = 0;
if (EC_POINT_is_at_infinity(group, a))
{
if (!EC_POINT_copy(r, b)) return 0;
return 1;
}
if (EC_POINT_is_at_infinity(group, b))
{
if (!EC_POINT_copy(r, a)) return 0;
return 1;
}
if (ctx == NULL)
{
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
BN_CTX_start(ctx);
x0 = BN_CTX_get(ctx);
y0 = BN_CTX_get(ctx);
x1 = BN_CTX_get(ctx);
y1 = BN_CTX_get(ctx);
x2 = BN_CTX_get(ctx);
y2 = BN_CTX_get(ctx);
s = BN_CTX_get(ctx);
t = BN_CTX_get(ctx);
if (t == NULL) goto err;
if (a->Z_is_one)
{
if (!BN_copy(x0, &a->X)) goto err;
if (!BN_copy(y0, &a->Y)) goto err;
}
else
{
if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) goto err;
}
if (b->Z_is_one)
{
if (!BN_copy(x1, &b->X)) goto err;
if (!BN_copy(y1, &b->Y)) goto err;
}
else
{
if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) goto err;
}
if (BN_GF2m_cmp(x0, x1))
{
if (!BN_GF2m_add(t, x0, x1)) goto err;
if (!BN_GF2m_add(s, y0, y1)) goto err;
if (!group->meth->field_div(group, s, s, t, ctx)) goto err;
if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
if (!BN_GF2m_add(x2, x2, s)) goto err;
if (!BN_GF2m_add(x2, x2, t)) goto err;
}
else
{
if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1))
{
if (!EC_POINT_set_to_infinity(group, r)) goto err;
ret = 1;
goto err;
}
if (!group->meth->field_div(group, s, y1, x1, ctx)) goto err;
if (!BN_GF2m_add(s, s, x1)) goto err;
if (!group->meth->field_sqr(group, x2, s, ctx)) goto err;
if (!BN_GF2m_add(x2, x2, s)) goto err;
if (!BN_GF2m_add(x2, x2, &group->a)) goto err;
}
if (!BN_GF2m_add(y2, x1, x2)) goto err;
if (!group->meth->field_mul(group, y2, y2, s, ctx)) goto err;
if (!BN_GF2m_add(y2, y2, x2)) goto err;
if (!BN_GF2m_add(y2, y2, y1)) goto err;
if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) goto err;
ret = 1;
err:
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
}
/* Computes 2 * a and stores the result in r. r could be a.
* Uses algorithm A.10.2 of IEEE P1363.
*/
int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx)
{
return ec_GF2m_simple_add(group, r, a, a, ctx);
}
int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
{
if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y))
/* point is its own inverse */
return 1;
if (!EC_POINT_make_affine(group, point, ctx)) return 0;
return BN_GF2m_add(&point->Y, &point->X, &point->Y);
}
/* Indicates whether the given point is the point at infinity. */
int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
{
return BN_is_zero(&point->Z);
}
/* Determines whether the given EC_POINT is an actual point on the curve defined
* in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation:
* y^2 + x*y = x^3 + a*x^2 + b.
*/
int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
BIGNUM *rh, *lh, *tmp1;
int ret = -1;
if (EC_POINT_is_at_infinity(group, point))
return 1;
/* only support affine coordinates */
if (!point->Z_is_one) goto err;
if (ctx == NULL)
{
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return -1;
}
BN_CTX_start(ctx);
rh = BN_CTX_get(ctx);
lh = BN_CTX_get(ctx);
tmp1 = BN_CTX_get(ctx);
if (tmp1 == NULL) goto err;
/* We have a curve defined by a Weierstrass equation
* y^2 + x*y = x^3 + a*x^2 + b.
* To test this, we add up the right-hand side in 'rh'
* and the left-hand side in 'lh'.
*/
/* rh := X^3 */
if (!group->meth->field_sqr(group, tmp1, &point->X, ctx)) goto err;
if (!group->meth->field_mul(group, rh, tmp1, &point->X, ctx)) goto err;
/* rh := rh + a*X^2 */
if (!group->meth->field_mul(group, tmp1, tmp1, &group->a, ctx)) goto err;
if (!BN_GF2m_add(rh, rh, tmp1)) goto err;
/* rh := rh + b */
if (!BN_GF2m_add(rh, rh, &group->b)) goto err;
/* lh := Y^2 */
if (!group->meth->field_sqr(group, lh, &point->Y, ctx)) goto err;
/* lh := lh + x*y */
if (!group->meth->field_mul(group, tmp1, &point->X, &point->Y, ctx)) goto err;
if (!BN_GF2m_add(lh, lh, tmp1)) goto err;
ret = (0 == BN_GF2m_cmp(lh, rh));
err:
if (ctx) BN_CTX_end(ctx);
if (new_ctx) BN_CTX_free(new_ctx);
return ret;
}
/* Indicates whether two points are equal.
* Return values:
* -1 error
* 0 equal (in affine coordinates)
* 1 not equal
*/
int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx)
{
BIGNUM *aX, *aY, *bX, *bY;
BN_CTX *new_ctx = NULL;
int ret = -1;
if (EC_POINT_is_at_infinity(group, a))
{
return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
}
if (a->Z_is_one && b->Z_is_one)
{
return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
}
if (ctx == NULL)
{
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return -1;
}
BN_CTX_start(ctx);
aX = BN_CTX_get(ctx);
aY = BN_CTX_get(ctx);
bX = BN_CTX_get(ctx);
bY = BN_CTX_get(ctx);
if (bY == NULL) goto err;
if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) goto err;
if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) goto err;
ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
err:
if (ctx) BN_CTX_end(ctx);
if (new_ctx) BN_CTX_free(new_ctx);
return ret;
}
/* Forces the given EC_POINT to internally use affine coordinates. */
int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
BIGNUM *x, *y;
int ret = 0;
if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
return 1;
if (ctx == NULL)
{
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
if (y == NULL) goto err;
if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
if (!BN_copy(&point->X, x)) goto err;
if (!BN_copy(&point->Y, y)) goto err;
if (!BN_one(&point->Z)) goto err;
ret = 1;
err:
if (ctx) BN_CTX_end(ctx);
if (new_ctx) BN_CTX_free(new_ctx);
return ret;
}
/* Forces each of the EC_POINTs in the given array to use affine coordinates. */
int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx)
{
size_t i;
for (i = 0; i < num; i++)
{
if (!group->meth->make_affine(group, points[i], ctx)) return 0;
}
return 1;
}
/* Wrapper to simple binary polynomial field multiplication implementation. */
int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
}
/* Wrapper to simple binary polynomial field squaring implementation. */
int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
{
return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
}
/* Wrapper to simple binary polynomial field division implementation. */
int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
return BN_GF2m_mod_div(r, a, b, &group->field, ctx);
}

125
crypto/ec/ec2_smpt.c Normal file
View File

@@ -0,0 +1,125 @@
/* crypto/ec/ec2_smpt.c */
/* This code was originally written by Douglas Stebila
* <dstebila@student.math.uwaterloo.ca> for the OpenSSL project.
*/
/* ====================================================================
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* Calaculates and sets the affine coordinates of an EC_POINT from the given
* compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
* Note that the simple implementation only uses affine coordinates.
*
* This algorithm is patented by Certicom Corp. under US Patent 6,141,420.
* This function is disabled by default and can be enabled by defining the
* preprocessor macro OPENSSL_EC_BIN_PT_COMP at Configure-time.
*/
int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x_, int y_bit, BN_CTX *ctx)
{
#ifndef OPENSSL_EC_BIN_PT_COMP
ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_DISABLED);
return 0;
#else
BN_CTX *new_ctx = NULL;
BIGNUM *tmp, *x, *y, *z;
int ret = 0, z0;
if (ctx == NULL)
{
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL)
return 0;
}
y_bit = (y_bit != 0) ? 1 : 0;
BN_CTX_start(ctx);
tmp = BN_CTX_get(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
z = BN_CTX_get(ctx);
if (z == NULL) goto err;
if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err;
if (BN_is_zero(x))
{
if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err;
}
else
{
if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err;
if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err;
if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err;
if (!BN_GF2m_add(tmp, x, tmp)) goto err;
if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) goto err;
z0 = (BN_is_odd(z)) ? 1 : 0;
if (!group->meth->field_mul(group, y, x, z, ctx)) goto err;
if (z0 != y_bit)
{
if (!BN_GF2m_add(y, y, x)) goto err;
}
}
if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
ret = 1;
err:
BN_CTX_end(ctx);
if (new_ctx != NULL)
BN_CTX_free(new_ctx);
return ret;
#endif
}

1459
crypto/ec/ec_asn1.c Normal file

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More