Project import
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..e364708
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2011-2013 Nest Labs, Inc.
+# All rights reserved.
+#
+# This document is the property of Nest. It is considered
+# confidential and proprietary information.
+#
+# This document may not be reproduced or transmitted in any form,
+# in whole or in part, without the express written permission of
+# Nest.
+#
+# Description:
+#
+
+include pre.mak
+
+# Enable warnings as errors
+WARNINGS += $(call ToolAssertWarningFlag,$(WarnWarningsAreErrors))
+
+ResultIncDir = $(call GenerateResultPaths,,openssl)
+ResultLibDir = $(call GenerateResultPaths,,.)
+BuildDir = $(CURDIR)/$(BuildDirectory)
+
+PolarsslIncDir = $(call GenerateResultPaths,,polarssl)
+
+AllLibraries = \
+ libemssl.a \
+ libbn.a \
+ libjpake.a \
+ libecdsa.a \
+ libec.a \
+ libecdh.a \
+ libpolarssl.a \
+ libctrdrbg.a
+
+all: install-includes $(BuildDir)
+ $(MAKE) \
+ BUILD_DIR="$(BuildDir)" \
+ LINK="$(LD) $(LDFLAGS)" \
+ CC="$(CC)" \
+ CPPFLAGS="$(CPPOPTFLAGS) -I$(NlEMallocIncludePath) -I$(NewLibCIncludePaths)" \
+ AR=$(AR) \
+ BN_MONT_ASM_TYPE=$(TargetProcArch) \
+ -f Makefile.emssl
+ $(INSTALL) $(INSTALLFLAGS) $(foreach l,$(AllLibraries),$(BuildDirectory)/lib/$(l)) $(ResultLibDir)
+
+clean:
+ $(MAKE) BUILD_DIR="$(BuildDir)" -f Makefile.emssl $@
+
+$(PolarsslIncDir):
+ $(MKDIR) -p $@
+
+$(BuildDir):
+ $(MKDIR) -p $@
+
+install-includes: $(ResultIncDir) $(PolarsslIncDir)
+ $(INSTALL) $(INSTALLFLAGS) openssl/*.h $(ResultIncDir)
+ $(INSTALL) $(INSTALLFLAGS) polarssl/*.h $(PolarsslIncDir)
+
+prepare: install-includes
+
+include post.mak
diff --git a/Makefile.config b/Makefile.config
new file mode 100644
index 0000000..745d98c
--- /dev/null
+++ b/Makefile.config
@@ -0,0 +1,73 @@
+# Copyright 2010 by Nest Labs, Inc. All rights reserved.
+#
+# This program is confidential and proprietary to Nest Labs, Inc.,
+# and may not be reproduced, published or disclosed to others without
+# company authorization.
+#
+
+# the setup below is for gcc on a unix-like platform.
+
+BUILD_DIR ?= $(DEPTH).build
+OBJ_DIR = $(BUILD_DIR)/objs
+LIB_DIR = $(BUILD_DIR)/lib
+BIN_DIR = $(BUILD_DIR)/bin
+
+OS_ARCH := $(shell uname -s | sed -e 's|/|_|g')
+
+ifeq ($(OS_ARCH),Darwin)
+CC = @echo $@; gcc -Os -DNL_DARWIN
+OPT_INCLUDE = /opt/local/include
+OPT_LIB = /opt/local/lib
+else
+CC = @echo $@; gcc -DNL_LINUX -Os
+OPT_INCLUDE = /usr/local/include
+OPT_LIB = /usr/local/lib -L/usr/lib
+endif
+
+#LINK = @echo $@; g++ -dead_strip
+LINK = echo $@;gcc -Wl,--gc-sections
+
+ARCHIVE = @echo $@; ar -rucs
+
+RANLIB = ranlib
+
+#MAKE = make -s
+
+RM = rm -rf
+
+MKDIR = mkdir -p
+
+CP = cp
+
+WFLAGS = \
+ -Wunused \
+ -Wimplicit \
+ -Wreturn-type \
+ -Wparentheses \
+ -Wformat \
+ -Wchar-subscripts \
+ -Wno-c++-compat \
+ -Wsequence-point
+
+# -Wmissing-prototypes \
+# -pedantic \
+
+CFLAGS = $(CPPFLAGS) \
+ $(WFLAGS) \
+ -ffunction-sections \
+ -fdata-sections \
+ -c \
+ -g \
+ $(DEFINES) \
+ -I ./ \
+ -I $(DEPTH) \
+ -I $(OPT_INCLUDE) \
+ -I $(DEPTH)include \
+ -I $(DEPTH)openssl \
+ -I $(DEPTH)polarssl \
+ -I include \
+ $(INCLUDES)
+
+LIBS = -L$(LIB_DIR) \
+ -L$(OPT_LIB) \
+
diff --git a/Makefile.emssl b/Makefile.emssl
new file mode 100644
index 0000000..0810003
--- /dev/null
+++ b/Makefile.emssl
@@ -0,0 +1,46 @@
+# Copyright 2010 by Nest Labs, Inc. All rights reserved.
+#
+# This program is confidential and proprietary to Nest Labs, Inc.,
+# and may not be reproduced, published or disclosed to others without
+# company authorization.
+#
+
+# OBJ_DIR should be set by the user to the right directory,
+# if necessary.
+
+#note that there are only dependencies on files within
+#each subdirectory. if you change in file in one subdirectory
+#nothing outside that directory will ever know about it.
+#manage dependencies on your own. it's not that hard.
+#and one final note, we are not generating shared libraries, so
+#if you make a change in a component and rebuild it, you will also
+#need to relink all executables. i should add a target to do just that.
+#mmp
+
+DEPTH = ./
+
+include $(DEPTH)Makefile.config
+
+.PHONY: libdir openssl polarssl
+
+all: libdir openssl polarssl
+
+libdir:
+ $(MKDIR) $(LIB_DIR)
+ $(MKDIR) $(BIN_DIR)
+
+openssl:
+ $(MAKE) BUILD_DIR=$(BUILD_DIR) -C $@
+
+polarssl:
+ $(MAKE) BUILD_DIR=$(BUILD_DIR) -C $@
+
+driver:
+ $(MAKE) BUILD_DIR=$(BUILD_DIR) -C $@
+
+clean:
+ $(MAKE) BUILD_DIR=$(BUILD_DIR) -C openssl $@
+ $(MAKE) BUILD_DIR=$(BUILD_DIR) -C polarssl $@
+ $(MAKE) BUILD_DIR=$(BUILD_DIR) -C driver $@
+ $(RM) $(LIB_DIR)
+ $(RM) $(BIN_DIR)
diff --git a/driver/Makefile b/driver/Makefile
new file mode 100644
index 0000000..01d0e5c
--- /dev/null
+++ b/driver/Makefile
@@ -0,0 +1,53 @@
+# Copyright 2010 by Nest Labs, Inc. All rights reserved.
+#
+# This program is confidential and proprietary to Nest Labs, Inc.,
+# and may not be reproduced, published or disclosed to others without
+# company authorization.
+#
+
+DEPTH = ../
+
+include $(DEPTH)Makefile.config
+
+OUTDIR = $(OBJ_DIR)
+SRCDIR = ./
+INCDIR = ./
+
+OBJECT_FILES = \
+ security_driver
+
+HEADER_FILES = \
+
+OBJECTS = $(OBJECT_FILES:%=$(OUTDIR)/%.o)
+HEADERS = $(HEADER_FILES:%=$(INCDIR)/%.h)
+
+LIBRARY_DEPS = \
+ $(LIB_DIR)/libbn.a \
+ $(LIB_DIR)/libjpake.a \
+ $(LIB_DIR)/libsha.a \
+ $(LIB_DIR)/libec.a \
+ $(LIB_DIR)/libecdh.a \
+ $(LIB_DIR)/libaes.a \
+ $(LIB_DIR)/libecdsa.a \
+ $(LIB_DIR)/libemssl.a \
+ $(LIB_DIR)/libctrdrbg.a \
+ $(LIB_DIR)/libpolarssl.a
+
+all: $(OUTDIR) $(OUTDIR)/security_driver
+
+$(OUTDIR):
+ $(MKDIR) $(OUTDIR)
+
+clean:
+ $(RM) $(OUTDIR)
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.c $(HEADERS)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.cpp $(HEADERS)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(OUTDIR)/security_driver: $(OUTDIR)/security_driver.o $(LIBRARY_DEPS)
+ $(LINK) $(OUTDIR)/security_driver.o $(LIBS) $(OCLIBS) -ljpake -lsha -lecdsa -lec -lecdh -lbn -lemssl -lctrdrbg -lpolarssl -laes -o $(OUTDIR)/security_driver
+ $(CP) $@ $(BIN_DIR)
+
diff --git a/driver/security_driver.c b/driver/security_driver.c
new file mode 100644
index 0000000..888118a
--- /dev/null
+++ b/driver/security_driver.c
@@ -0,0 +1,89 @@
+#include <stdio.h>
+#include <string.h>
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
+#include <openssl/obj_mac.h>
+#include <openssl/jpake.h>
+#include <openssl/ecdh.h>
+#include <polarssl/ctr_drbg.h>
+
+int entropy(void *closure, unsigned char *outentropy, size_t outsize)
+{
+ unsigned char *entropy;
+ int rval, idx;
+
+printf("hey, somebody wants entropy: %p, %d\n", outentropy, outsize);
+ do
+ {
+#ifdef gPlatformGetRandomNumber
+ rval = (int)gPlatformGetRandomNumber();
+#else
+ rval = rand();
+#endif
+
+ entropy = (unsigned char *)&rval;
+printf("got some sweet entropy: %08x\n", rval);
+
+ for (idx = 0; (idx < sizeof(int)) && (outsize > 0); idx++, outsize--)
+ *outentropy++ = *entropy++;
+ }
+ while (outsize > 0);
+
+ return 0;
+}
+
+ctr_drbg_context *gCTRDRBG_ctx = NULL;
+
+int main(int argc, char ** argv)
+{
+ int retval = 0;
+ int i;
+
+#ifdef gPlatformSetInputEntropy
+ gPlatformSetInputEntropy(seed);
+#else
+ time_t tim;
+
+ tim = time(NULL);
+
+ srand(tim);
+#endif
+
+ // Force linker references to the necessary top-level functions.
+
+ static void *functions[] =
+ {
+ (void *)ECDSA_do_sign,
+ (void *)ECDSA_do_verify,
+
+ (void *)JPAKE_STEP1_init,
+ (void *)JPAKE_STEP1_generate,
+ (void *)JPAKE_STEP1_process,
+ (void *)JPAKE_STEP1_release,
+ (void *)JPAKE_STEP2_init,
+ (void *)JPAKE_STEP2_generate,
+ (void *)JPAKE_STEP2_process,
+ (void *)JPAKE_STEP2_release,
+
+ (void *)ECDH_compute_key,
+ NULL
+ };
+
+ for (i = 0; functions[i] != NULL; i++)
+ printf("%p\n", functions[i]);
+
+ ctr_drbg_context ctx;
+
+#ifdef DEBUG
+ ctr_drbg_self_test(1);
+#endif
+
+ retval = ctr_drbg_init(&ctx, entropy, NULL, NULL, 0);
+
+ gCTRDRBG_ctx = &ctx;
+
+ printf("returning: %d\n", retval);
+
+ return retval;
+}
+
diff --git a/include/cryptlib.h b/include/cryptlib.h
new file mode 100644
index 0000000..d26f963
--- /dev/null
+++ b/include/cryptlib.h
@@ -0,0 +1,111 @@
+/* crypto/cryptlib.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_CRYPTLIB_H
+#define HEADER_CRYPTLIB_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "e_os.h"
+
+#ifdef OPENSSL_USE_APPLINK
+#define BIO_FLAGS_UPLINK 0x8000
+#include "ms/uplink.h"
+#endif
+
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/opensslconf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef OPENSSL_SYS_VMS
+#define X509_CERT_AREA OPENSSLDIR
+#define X509_CERT_DIR OPENSSLDIR "/certs"
+#define X509_CERT_FILE OPENSSLDIR "/cert.pem"
+#define X509_PRIVATE_DIR OPENSSLDIR "/private"
+#else
+#define X509_CERT_AREA "SSLROOT:[000000]"
+#define X509_CERT_DIR "SSLCERTS:"
+#define X509_CERT_FILE "SSLCERTS:cert.pem"
+#define X509_PRIVATE_DIR "SSLPRIVATE:"
+#endif
+
+#define X509_CERT_DIR_EVP "SSL_CERT_DIR"
+#define X509_CERT_FILE_EVP "SSL_CERT_FILE"
+
+/* size of string representations */
+#define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1)
+#define HEX_SIZE(type) (sizeof(type)*2)
+
+void OPENSSL_cpuid_setup(void);
+extern unsigned int OPENSSL_ia32cap_P[];
+void OPENSSL_showfatal(const char *fmta,...);
+void *OPENSSL_stderr(void);
+extern int OPENSSL_NONPIC_relocated;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/e_os.h b/include/e_os.h
new file mode 100644
index 0000000..79c1392
--- /dev/null
+++ b/include/e_os.h
@@ -0,0 +1,734 @@
+/* e_os.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_E_OS_H
+#define HEADER_E_OS_H
+
+#include <openssl/opensslconf.h>
+
+#include <openssl/e_os2.h>
+/* <openssl/e_os2.h> contains what we can justify to make visible
+ * to the outside; this file e_os.h is not part of the exported
+ * interface. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Used to checking reference counts, most while doing perl5 stuff :-) */
+#ifdef REF_PRINT
+#undef REF_PRINT
+#define REF_PRINT(a,b) fprintf(stderr,"%08X:%4d:%s\n",(int)b,b->references,a)
+#endif
+
+#ifndef DEVRANDOM
+/* set this to a comma-separated list of 'random' device files to try out.
+ * My default, we will try to read at least one of these files */
+#define DEVRANDOM "/dev/urandom","/dev/random","/dev/srandom"
+#endif
+#ifndef DEVRANDOM_EGD
+/* set this to a comma-seperated list of 'egd' sockets to try out. These
+ * sockets will be tried in the order listed in case accessing the device files
+ * listed in DEVRANDOM did not return enough entropy. */
+#define DEVRANDOM_EGD "/var/run/egd-pool","/dev/egd-pool","/etc/egd-pool","/etc/entropy"
+#endif
+
+#if defined(OPENSSL_SYS_VXWORKS)
+# define NO_SYS_PARAM_H
+# define NO_CHMOD
+# define NO_SYSLOG
+#endif
+
+#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC)
+# if macintosh==1
+# ifndef MAC_OS_GUSI_SOURCE
+# define MAC_OS_pre_X
+# define NO_SYS_TYPES_H
+# endif
+# define NO_SYS_PARAM_H
+# define NO_CHMOD
+# define NO_SYSLOG
+# undef DEVRANDOM
+# define GETPID_IS_MEANINGLESS
+# endif
+#endif
+
+/********************************************************************
+ The Microsoft section
+ ********************************************************************/
+/* The following is used because of the small stack in some
+ * Microsoft operating systems */
+#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYSNAME_WIN32)
+# define MS_STATIC static
+#else
+# define MS_STATIC
+#endif
+
+#if defined(OPENSSL_SYS_WIN32) && !defined(WIN32)
+# define WIN32
+#endif
+#if defined(OPENSSL_SYS_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(OPENSSL_SYS_MSDOS) && !defined(MSDOS)
+# define MSDOS
+#endif
+
+#if defined(MSDOS) && !defined(GETPID_IS_MEANINGLESS)
+# define GETPID_IS_MEANINGLESS
+#endif
+
+#ifdef WIN32
+#define get_last_sys_error() GetLastError()
+#define clear_sys_error() SetLastError(0)
+#if !defined(WINNT)
+#define WIN_CONSOLE_BUG
+#endif
+#else
+#define get_last_sys_error() errno
+#define clear_sys_error() errno=0
+#endif
+
+#if defined(WINDOWS)
+#define get_last_socket_error() WSAGetLastError()
+#define clear_socket_error() WSASetLastError(0)
+#define readsocket(s,b,n) recv((s),(b),(n),0)
+#define writesocket(s,b,n) send((s),(b),(n),0)
+#elif defined(__DJGPP__)
+#define WATT32
+#define get_last_socket_error() errno
+#define clear_socket_error() errno=0
+#define closesocket(s) close_s(s)
+#define readsocket(s,b,n) read_s(s,b,n)
+#define writesocket(s,b,n) send(s,b,n,0)
+#elif defined(MAC_OS_pre_X)
+#define get_last_socket_error() errno
+#define clear_socket_error() errno=0
+#define closesocket(s) MacSocket_close(s)
+#define readsocket(s,b,n) MacSocket_recv((s),(b),(n),true)
+#define writesocket(s,b,n) MacSocket_send((s),(b),(n))
+#elif defined(OPENSSL_SYS_VMS)
+#define get_last_socket_error() errno
+#define clear_socket_error() errno=0
+#define ioctlsocket(a,b,c) ioctl(a,b,c)
+#define closesocket(s) close(s)
+#define readsocket(s,b,n) recv((s),(b),(n),0)
+#define writesocket(s,b,n) send((s),(b),(n),0)
+#elif defined(OPENSSL_SYS_VXWORKS)
+#define get_last_socket_error() errno
+#define clear_socket_error() errno=0
+#define ioctlsocket(a,b,c) ioctl((a),(b),(int)(c))
+#define closesocket(s) close(s)
+#define readsocket(s,b,n) read((s),(b),(n))
+#define writesocket(s,b,n) write((s),(char *)(b),(n))
+#elif defined(OPENSSL_SYS_BEOS_R5)
+#define get_last_socket_error() errno
+#define clear_socket_error() errno=0
+#define FIONBIO SO_NONBLOCK
+#define ioctlsocket(a,b,c) setsockopt((a),SOL_SOCKET,(b),(c),sizeof(*(c)))
+#define readsocket(s,b,n) recv((s),(b),(n),0)
+#define writesocket(s,b,n) send((s),(b),(n),0)
+#elif defined(OPENSSL_SYS_NETWARE)
+#if defined(NETWARE_BSDSOCK)
+#define get_last_socket_error() errno
+#define clear_socket_error() errno=0
+#define closesocket(s) close(s)
+#define ioctlsocket(a,b,c) ioctl(a,b,c)
+#if defined(NETWARE_LIBC)
+#define readsocket(s,b,n) recv((s),(b),(n),0)
+#define writesocket(s,b,n) send((s),(b),(n),0)
+#else
+#define readsocket(s,b,n) recv((s),(char*)(b),(n),0)
+#define writesocket(s,b,n) send((s),(char*)(b),(n),0)
+#endif
+#else
+#define get_last_socket_error() WSAGetLastError()
+#define clear_socket_error() WSASetLastError(0)
+#define readsocket(s,b,n) recv((s),(b),(n),0)
+#define writesocket(s,b,n) send((s),(b),(n),0)
+#endif
+#else
+#define get_last_socket_error() errno
+#define clear_socket_error() errno=0
+#define ioctlsocket(a,b,c) ioctl(a,b,c)
+#define closesocket(s) close(s)
+#define readsocket(s,b,n) read((s),(b),(n))
+#define writesocket(s,b,n) write((s),(b),(n))
+#endif
+
+#ifdef WIN16 /* never the case */
+# define MS_CALLBACK _far _loadds
+# define MS_FAR _far
+#else
+# define MS_CALLBACK
+# define MS_FAR
+#endif
+
+#ifdef OPENSSL_NO_STDIO
+# undef OPENSSL_NO_FP_API
+# define OPENSSL_NO_FP_API
+#endif
+
+#if (defined(WINDOWS) || defined(MSDOS))
+
+# ifdef __DJGPP__
+# include <unistd.h>
+# include <sys/stat.h>
+# include <sys/socket.h>
+# include <tcp.h>
+# include <netdb.h>
+# define _setmode setmode
+# define _O_TEXT O_TEXT
+# define _O_BINARY O_BINARY
+# undef DEVRANDOM
+# define DEVRANDOM "/dev/urandom\x24"
+# endif /* __DJGPP__ */
+
+# ifndef S_IFDIR
+# define S_IFDIR _S_IFDIR
+# endif
+
+# ifndef S_IFMT
+# define S_IFMT _S_IFMT
+# endif
+
+# if !defined(WINNT) && !defined(__DJGPP__)
+# define NO_SYSLOG
+# endif
+# define NO_DIRENT
+
+# ifdef WINDOWS
+# if !defined(_WIN32_WCE) && !defined(_WIN32_WINNT)
+ /*
+ * Defining _WIN32_WINNT here in e_os.h implies certain "discipline."
+ * Most notably we ought to check for availability of each specific
+ * routine with GetProcAddress() and/or guard NT-specific calls with
+ * GetVersion() < 0x80000000. One can argue that in latter "or" case
+ * we ought to /DELAYLOAD some .DLLs in order to protect ourselves
+ * against run-time link errors. This doesn't seem to be necessary,
+ * because it turned out that already Windows 95, first non-NT Win32
+ * implementation, is equipped with at least NT 3.51 stubs, dummy
+ * routines with same name, but which do nothing. Meaning that it's
+ * apparently sufficient to guard "vanilla" NT calls with GetVersion
+ * alone, while NT 4.0 and above interfaces ought to be linked with
+ * GetProcAddress at run-time.
+ */
+# define _WIN32_WINNT 0x0400
+# endif
+# if !defined(OPENSSL_NO_SOCK) && defined(_WIN32_WINNT)
+ /*
+ * Just like defining _WIN32_WINNT including winsock2.h implies
+ * certain "discipline" for maintaining [broad] binary compatibility.
+ * As long as structures are invariant among Winsock versions,
+ * it's sufficient to check for specific Winsock2 API availability
+ * at run-time [DSO_global_lookup is recommended]...
+ */
+# include <winsock2.h>
+# include <ws2tcpip.h>
+ /* yes, they have to be #included prior to <windows.h> */
+# endif
+# include <windows.h>
+# include <stdio.h>
+# include <stddef.h>
+# include <errno.h>
+# include <string.h>
+# ifdef _WIN64
+# define strlen(s) _strlen31(s)
+/* cut strings to 2GB */
+static unsigned int _strlen31(const char *str)
+ {
+ unsigned int len=0;
+ while (*str && len<0x80000000U) str++, len++;
+ return len&0x7FFFFFFF;
+ }
+# endif
+# include <malloc.h>
+# if defined(_MSC_VER) && _MSC_VER<=1200 && defined(_MT) && defined(isspace)
+ /* compensate for bug in VC6 ctype.h */
+# undef isspace
+# undef isdigit
+# undef isalnum
+# undef isupper
+# undef isxdigit
+# endif
+# if defined(_MSC_VER) && !defined(_DLL) && defined(stdin)
+# if _MSC_VER>=1300
+# undef stdin
+# undef stdout
+# undef stderr
+ FILE *__iob_func();
+# define stdin (&__iob_func()[0])
+# define stdout (&__iob_func()[1])
+# define stderr (&__iob_func()[2])
+# elif defined(I_CAN_LIVE_WITH_LNK4049)
+# undef stdin
+# undef stdout
+# undef stderr
+ /* pre-1300 has __p__iob(), but it's available only in msvcrt.lib,
+ * or in other words with /MD. Declaring implicit import, i.e.
+ * with _imp_ prefix, works correctly with all compiler options,
+ * but without /MD results in LINK warning LNK4049:
+ * 'locally defined symbol "__iob" imported'.
+ */
+ extern FILE *_imp___iob;
+# define stdin (&_imp___iob[0])
+# define stdout (&_imp___iob[1])
+# define stderr (&_imp___iob[2])
+# endif
+# endif
+# endif
+# include <io.h>
+# include <fcntl.h>
+
+# ifdef OPENSSL_SYS_WINCE
+# define OPENSSL_NO_POSIX_IO
+# endif
+
+# if defined (__BORLANDC__)
+# define _setmode setmode
+# define _O_TEXT O_TEXT
+# define _O_BINARY O_BINARY
+# define _int64 __int64
+# define _kbhit kbhit
+# endif
+
+# define EXIT(n) exit(n)
+# define LIST_SEPARATOR_CHAR ';'
+# ifndef X_OK
+# define X_OK 0
+# endif
+# ifndef W_OK
+# define W_OK 2
+# endif
+# ifndef R_OK
+# define R_OK 4
+# endif
+# define OPENSSL_CONF "openssl.cnf"
+# define SSLEAY_CONF OPENSSL_CONF
+# define NUL_DEV "nul"
+# define RFILE ".rnd"
+# ifdef OPENSSL_SYS_WINCE
+# define DEFAULT_HOME ""
+# else
+# define DEFAULT_HOME "C:"
+# endif
+
+#else /* The non-microsoft world */
+
+# ifdef OPENSSL_SYS_VMS
+# define VMS 1
+ /* some programs don't include stdlib, so exit() and others give implicit
+ function warnings */
+# include <stdlib.h>
+# if defined(__DECC)
+# include <unistd.h>
+# else
+# include <unixlib.h>
+# endif
+# define OPENSSL_CONF "openssl.cnf"
+# define SSLEAY_CONF OPENSSL_CONF
+# define RFILE ".rnd"
+# define LIST_SEPARATOR_CHAR ','
+# define NUL_DEV "NLA0:"
+ /* We don't have any well-defined random devices on VMS, yet... */
+# undef DEVRANDOM
+ /* We need to do this since VMS has the following coding on status codes:
+
+ Bits 0-2: status type: 0 = warning, 1 = success, 2 = error, 3 = info ...
+ The important thing to know is that odd numbers are considered
+ good, while even ones are considered errors.
+ Bits 3-15: actual status number
+ Bits 16-27: facility number. 0 is considered "unknown"
+ Bits 28-31: control bits. If bit 28 is set, the shell won't try to
+ output the message (which, for random codes, just looks ugly)
+
+ So, what we do here is to change 0 to 1 to get the default success status,
+ and everything else is shifted up to fit into the status number field, and
+ the status is tagged as an error, which I believe is what is wanted here.
+ -- Richard Levitte
+ */
+# define EXIT(n) do { int __VMS_EXIT = n; \
+ if (__VMS_EXIT == 0) \
+ __VMS_EXIT = 1; \
+ else \
+ __VMS_EXIT = (n << 3) | 2; \
+ __VMS_EXIT |= 0x10000000; \
+ exit(__VMS_EXIT); } while(0)
+# define NO_SYS_PARAM_H
+
+# elif defined(OPENSSL_SYS_NETWARE)
+# include <fcntl.h>
+# include <unistd.h>
+# define NO_SYS_TYPES_H
+# undef DEVRANDOM
+# ifdef NETWARE_CLIB
+# define getpid GetThreadID
+ extern int GetThreadID(void);
+/* # include <conio.h> */
+ extern int kbhit(void);
+# else
+# include <screen.h>
+# endif
+# define NO_SYSLOG
+# define _setmode setmode
+# define _kbhit kbhit
+# define _O_TEXT O_TEXT
+# define _O_BINARY O_BINARY
+# define OPENSSL_CONF "openssl.cnf"
+# define SSLEAY_CONF OPENSSL_CONF
+# define RFILE ".rnd"
+# define LIST_SEPARATOR_CHAR ';'
+# define EXIT(n) { if (n) printf("ERROR: %d\n", (int)n); exit(n); }
+
+# else
+ /* !defined VMS */
+# ifdef OPENSSL_SYS_MPE
+# define NO_SYS_PARAM_H
+# endif
+# ifdef OPENSSL_UNISTD
+# include OPENSSL_UNISTD
+# else
+# include <unistd.h>
+# endif
+# ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+# if defined(NeXT) || defined(OPENSSL_SYS_NEWS4)
+# define pid_t int /* pid_t is missing on NEXTSTEP/OPENSTEP
+ * (unless when compiling with -D_POSIX_SOURCE,
+ * which doesn't work for us) */
+# endif
+# ifdef OPENSSL_SYS_NEWS4 /* setvbuf is missing on mips-sony-bsd */
+# define setvbuf(a, b, c, d) setbuffer((a), (b), (d))
+ typedef unsigned long clock_t;
+# endif
+# ifdef OPENSSL_SYS_WIN32_CYGWIN
+# include <io.h>
+# include <fcntl.h>
+# endif
+
+# define OPENSSL_CONF "openssl.cnf"
+# define SSLEAY_CONF OPENSSL_CONF
+# define RFILE ".rnd"
+# define LIST_SEPARATOR_CHAR ':'
+# define NUL_DEV "/dev/null"
+# define EXIT(n) exit(n)
+# endif
+
+# define SSLeay_getpid() getpid()
+
+#endif
+
+
+/*************/
+
+#ifdef USE_SOCKETS
+# if defined(WINDOWS) || defined(MSDOS)
+ /* windows world */
+
+# ifdef OPENSSL_NO_SOCK
+# define SSLeay_Write(a,b,c) (-1)
+# define SSLeay_Read(a,b,c) (-1)
+# define SHUTDOWN(fd) close(fd)
+# define SHUTDOWN2(fd) close(fd)
+# elif !defined(__DJGPP__)
+# if defined(_WIN32_WCE) && _WIN32_WCE<410
+# define getservbyname _masked_declaration_getservbyname
+# endif
+# if !defined(IPPROTO_IP)
+ /* winsock[2].h was included already? */
+# include <winsock.h>
+# endif
+# ifdef getservbyname
+# undef getservbyname
+ /* this is used to be wcecompat/include/winsock_extras.h */
+ struct servent* PASCAL getservbyname(const char*,const char*);
+# endif
+
+# ifdef _WIN64
+/*
+ * Even though sizeof(SOCKET) is 8, it's safe to cast it to int, because
+ * the value constitutes an index in per-process table of limited size
+ * and not a real pointer.
+ */
+# define socket(d,t,p) ((int)socket(d,t,p))
+# define accept(s,f,l) ((int)accept(s,f,l))
+# endif
+# define SSLeay_Write(a,b,c) send((a),(b),(c),0)
+# define SSLeay_Read(a,b,c) recv((a),(b),(c),0)
+# define SHUTDOWN(fd) { shutdown((fd),0); closesocket(fd); }
+# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket(fd); }
+# else
+# define SSLeay_Write(a,b,c) write_s(a,b,c,0)
+# define SSLeay_Read(a,b,c) read_s(a,b,c)
+# define SHUTDOWN(fd) close_s(fd)
+# define SHUTDOWN2(fd) close_s(fd)
+# endif
+
+# elif defined(MAC_OS_pre_X)
+
+# include "MacSocket.h"
+# define SSLeay_Write(a,b,c) MacSocket_send((a),(b),(c))
+# define SSLeay_Read(a,b,c) MacSocket_recv((a),(b),(c),true)
+# define SHUTDOWN(fd) MacSocket_close(fd)
+# define SHUTDOWN2(fd) MacSocket_close(fd)
+
+# elif defined(OPENSSL_SYS_NETWARE)
+ /* NetWare uses the WinSock2 interfaces by default, but can be configured for BSD
+ */
+# if defined(NETWARE_BSDSOCK)
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <sys/time.h>
+# if defined(NETWARE_CLIB)
+# include <sys/bsdskt.h>
+# else
+# include <sys/select.h>
+# endif
+# define INVALID_SOCKET (int)(~0)
+# else
+# include <novsock2.h>
+# endif
+# define SSLeay_Write(a,b,c) send((a),(b),(c),0)
+# define SSLeay_Read(a,b,c) recv((a),(b),(c),0)
+# define SHUTDOWN(fd) { shutdown((fd),0); closesocket(fd); }
+# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket(fd); }
+
+# else
+
+# ifndef NO_SYS_PARAM_H
+# include <sys/param.h>
+# endif
+# ifdef OPENSSL_SYS_VXWORKS
+# include <time.h>
+# elif !defined(OPENSSL_SYS_MPE)
+# include <sys/time.h> /* Needed under linux for FD_XXX */
+# endif
+
+# include <netdb.h>
+# if defined(OPENSSL_SYS_VMS_NODECC)
+# include <socket.h>
+# include <in.h>
+# include <inet.h>
+# else
+# include <sys/socket.h>
+# ifdef FILIO_H
+# include <sys/filio.h> /* Added for FIONBIO under unixware */
+# endif
+# include <netinet/in.h>
+# if !defined(OPENSSL_SYS_BEOS_R5)
+# include <arpa/inet.h>
+# endif
+# endif
+
+# if defined(NeXT) || defined(_NEXT_SOURCE)
+# include <sys/fcntl.h>
+# include <sys/types.h>
+# endif
+
+# ifdef OPENSSL_SYS_AIX
+# include <sys/select.h>
+# endif
+
+# ifdef __QNX__
+# include <sys/select.h>
+# endif
+
+# if defined(sun)
+# include <sys/filio.h>
+# else
+# ifndef VMS
+# include <sys/ioctl.h>
+# else
+ /* ioctl is only in VMS > 7.0 and when socketshr is not used */
+# if !defined(TCPIP_TYPE_SOCKETSHR) && defined(__VMS_VER) && (__VMS_VER > 70000000)
+# include <sys/ioctl.h>
+# endif
+# endif
+# endif
+
+# ifdef VMS
+# include <unixio.h>
+# if defined(TCPIP_TYPE_SOCKETSHR)
+# include <socketshr.h>
+# endif
+# endif
+
+# define SSLeay_Read(a,b,c) read((a),(b),(c))
+# define SSLeay_Write(a,b,c) write((a),(b),(c))
+# define SHUTDOWN(fd) { shutdown((fd),0); closesocket((fd)); }
+# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket((fd)); }
+# ifndef INVALID_SOCKET
+# define INVALID_SOCKET (-1)
+# endif /* INVALID_SOCKET */
+# endif
+
+/* Some IPv6 implementations are broken, disable them in known bad
+ * versions.
+ */
+# if !defined(OPENSSL_USE_IPV6)
+# if defined(AF_INET6) && !defined(OPENSSL_SYS_BEOS_BONE) && !defined(NETWARE_CLIB)
+# define OPENSSL_USE_IPV6 1
+# else
+# define OPENSSL_USE_IPV6 0
+# endif
+# endif
+
+#endif
+
+#if defined(sun) && !defined(__svr4__) && !defined(__SVR4)
+ /* include headers first, so our defines don't break it */
+#include <stdlib.h>
+#include <string.h>
+ /* bcopy can handle overlapping moves according to SunOS 4.1.4 manpage */
+# define memmove(s1,s2,n) bcopy((s2),(s1),(n))
+# define strtoul(s,e,b) ((unsigned long int)strtol((s),(e),(b)))
+extern char *sys_errlist[]; extern int sys_nerr;
+# define strerror(errnum) \
+ (((errnum)<0 || (errnum)>=sys_nerr) ? NULL : sys_errlist[errnum])
+ /* Being signed SunOS 4.x memcpy breaks ASN1_OBJECT table lookup */
+#include "crypto/o_str.h"
+# define memcmp OPENSSL_memcmp
+#endif
+
+#ifndef OPENSSL_EXIT
+# if defined(MONOLITH) && !defined(OPENSSL_C)
+# define OPENSSL_EXIT(n) return(n)
+# else
+# define OPENSSL_EXIT(n) do { EXIT(n); return(n); } while(0)
+# endif
+#endif
+
+/***********************************************/
+
+#define DG_GCC_BUG /* gcc < 2.6.3 on DGUX */
+
+#ifdef sgi
+#define IRIX_CC_BUG /* all version of IRIX I've tested (4.* 5.*) */
+#endif
+#ifdef OPENSSL_SYS_SNI
+#define IRIX_CC_BUG /* CDS++ up to V2.0Bsomething suffered from the same bug.*/
+#endif
+
+#if defined(OPENSSL_SYS_WINDOWS)
+# define strcasecmp _stricmp
+# define strncasecmp _strnicmp
+#elif defined(OPENSSL_SYS_VMS)
+/* VMS below version 7.0 doesn't have strcasecmp() */
+# include "o_str.h"
+# define strcasecmp OPENSSL_strcasecmp
+# define strncasecmp OPENSSL_strncasecmp
+# define OPENSSL_IMPLEMENTS_strncasecmp
+#elif defined(OPENSSL_SYS_OS2) && defined(__EMX__)
+# define strcasecmp stricmp
+# define strncasecmp strnicmp
+#elif defined(OPENSSL_SYS_NETWARE)
+# include <string.h>
+# if defined(NETWARE_CLIB)
+# define strcasecmp stricmp
+# define strncasecmp strnicmp
+# endif /* NETWARE_CLIB */
+#endif
+
+#if defined(OPENSSL_SYS_OS2) && defined(__EMX__)
+# include <io.h>
+# include <fcntl.h>
+# define NO_SYSLOG
+#endif
+
+/* vxworks */
+#if defined(OPENSSL_SYS_VXWORKS)
+#include <ioLib.h>
+#include <tickLib.h>
+#include <sysLib.h>
+
+#define TTY_STRUCT int
+
+#define sleep(a) taskDelay((a) * sysClkRateGet())
+
+#include <vxWorks.h>
+#include <sockLib.h>
+#include <taskLib.h>
+
+#define getpid taskIdSelf
+
+/* NOTE: these are implemented by helpers in database app!
+ * if the database is not linked, we need to implement them
+ * elswhere */
+struct hostent *gethostbyname(const char *name);
+struct hostent *gethostbyaddr(const char *addr, int length, int type);
+struct servent *getservbyname(const char *name, const char *proto);
+
+#endif
+/* end vxworks */
+
+/* beos */
+#if defined(OPENSSL_SYS_BEOS_R5)
+#define SO_ERROR 0
+#define NO_SYS_UN
+#define IPPROTO_IP 0
+#include <OS.h>
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/openssl/LICENCE b/openssl/LICENCE
new file mode 100644
index 0000000..e47d101
--- /dev/null
+++ b/openssl/LICENCE
@@ -0,0 +1,127 @@
+
+ LICENSE ISSUES
+ ==============
+
+ The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+ the OpenSSL License and the original SSLeay license apply to the toolkit.
+ See below for the actual license texts. Actually both licenses are BSD-style
+ Open Source licenses. In case of any license issues related to OpenSSL
+ please contact openssl-core@openssl.org.
+
+ OpenSSL License
+ ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2011 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).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
diff --git a/openssl/Makefile b/openssl/Makefile
new file mode 100644
index 0000000..c6d11b8
--- /dev/null
+++ b/openssl/Makefile
@@ -0,0 +1,80 @@
+# Copyright 2010 by Nest Labs, Inc. All rights reserved.
+#
+# This program is confidential and proprietary to Nest Labs, Inc.,
+# and may not be reproduced, published or disclosed to others without
+# company authorization.
+#
+
+DEPTH = ../
+
+include $(DEPTH)Makefile.config
+
+CFLAGS += -Os
+OUTDIR = $(OBJ_DIR)
+SRCDIR = ./
+INCDIR = ./
+
+VPATH = emssl-custom lhash stack
+
+OBJECT_FILES = \
+ ex_data \
+ lhash/lhash \
+ stack/stack \
+ emssl-custom/die \
+ emssl-custom/ecdsa_sig \
+ emssl-custom/err \
+ emssl-custom/mem \
+ emssl-custom/mem_clr \
+ emssl-custom/rand
+
+HEADER_FILES =
+
+OBJECTS = $(patsubst %,$(OUTDIR)/%.o, $(notdir $(OBJECT_FILES)))
+HEADERS = $(HEADER_FILES:%=$(INCDIR)/%.h)
+
+$(warning $(OBJECTS))
+
+.PHONY: bn jpake ecdsa ec ecdh
+
+all: $(OUTDIR) bn jpake ecdsa ec ecdh $(LIB_DIR)/libemssl.a
+
+$(OUTDIR):
+ $(MKDIR) $(OUTDIR)
+
+$(OUTDIR)/%.o: %.c $(HEADERS)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.cpp $(HEADERS)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(OUTDIR)/libemssl.a: $(OBJECTS)
+ $(ARCHIVE) $@ $(OBJECTS)
+ $(RANLIB) $@
+
+$(LIB_DIR)/libemssl.a: $(OUTDIR)/libemssl.a
+ $(MKDIR) $(dir $@)
+ $(CP) $< $@
+
+bn:
+ $(MAKE) BUILD_DIR="$(BUILD_DIR)" -C $@
+
+jpake:
+ $(MAKE) BUILD_DIR="$(BUILD_DIR)" -C $@
+
+ecdsa:
+ $(MAKE) BUILD_DIR="$(BUILD_DIR)" -C $@
+
+ec:
+ $(MAKE) BUILD_DIR="$(BUILD_DIR)" -C $@
+
+ecdh:
+ $(MAKE) BUILD_DIR="$(BUILD_DIR)" -C $@
+
+clean:
+ $(MAKE) BUILD_DIR="$(BUILD_DIR)" -C bn $@
+ $(MAKE) BUILD_DIR="$(BUILD_DIR)" -C jpake $@
+ $(MAKE) BUILD_DIR="$(BUILD_DIR)" -C ecdsa $@
+ $(MAKE) BUILD_DIR="$(BUILD_DIR)" -C ec $@
+ $(MAKE) BUILD_DIR="$(BUILD_DIR)" -C ecdh $@
+ $(RM) $(OUTDIR)
+
diff --git a/openssl/README.third_party b/openssl/README.third_party
new file mode 100644
index 0000000..fee53cf
--- /dev/null
+++ b/openssl/README.third_party
@@ -0,0 +1,29 @@
+URL: https://www.openssl.org/source/openssl-1.0.1m.tar.gz
+Version: 1.0.1m
+License: Multiple BSD-style Open Source licenses.
+License File: LICENSE
+
+Description:
+
+ An adaptation of OpenSSL crypto functions for use in the Nest Protect product.
+
+Local Modifications:
+
+ Only a small portion of the OpenSSL crypto library is included in emssl. This subset
+ consists of:
+
+ -- BN (big number) functions
+ -- EC, ECDH and ECDSA functions
+ -- Experimental J-PAKE functions
+ -- Misc support functions and header files
+
+ (Note that *no* SSL/TLS code from OpenSSL is included in emssl.)
+
+ Within this code a number of customizations have been made to accommodate the limitations
+ of the target environment. Where these customizations required minor modifications to the original
+ OpenSSL source files, the diffs for these changes have been captured in the patches directory.
+ In cases where the changes involved wholesale replacement of OpenSSL functions, the files
+ containing the new functions have been placed in the emssl-custom directory. Additionally the
+ configuration and makefile system provided by OpenSSL has been entirely replaced with
+ Pumice-compatible makefiles.
+
diff --git a/openssl/aes.h b/openssl/aes.h
new file mode 120000
index 0000000..a425a6d
--- /dev/null
+++ b/openssl/aes.h
@@ -0,0 +1 @@
+aes/aes.h
\ No newline at end of file
diff --git a/openssl/aes/aes.h b/openssl/aes/aes.h
new file mode 100644
index 0000000..87bf60f
--- /dev/null
+++ b/openssl/aes/aes.h
@@ -0,0 +1,149 @@
+/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ */
+
+#ifndef HEADER_AES_H
+# define HEADER_AES_H
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_AES
+# error AES is disabled.
+# endif
+
+# include <stddef.h>
+
+# define AES_ENCRYPT 1
+# define AES_DECRYPT 0
+
+/*
+ * Because array size can't be a const in C, the following two are macros.
+ * Both sizes are in bytes.
+ */
+# define AES_MAXNR 14
+# define AES_BLOCK_SIZE 16
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This should be a hidden type, but EVP requires that the size be known */
+struct aes_key_st {
+# ifdef AES_LONG
+ unsigned long rd_key[4 * (AES_MAXNR + 1)];
+# else
+ unsigned int rd_key[4 * (AES_MAXNR + 1)];
+# endif
+ int rounds;
+};
+typedef struct aes_key_st AES_KEY;
+
+const char *AES_options(void);
+
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key);
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key);
+
+int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key);
+int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+ AES_KEY *key);
+
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key);
+
+void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
+ const AES_KEY *key, const int enc);
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char *ivec, const int enc);
+void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char *ivec, int *num, const int enc);
+void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char *ivec, int *num, const int enc);
+void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char *ivec, int *num, const int enc);
+void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char *ivec, int *num);
+void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char ivec[AES_BLOCK_SIZE],
+ unsigned char ecount_buf[AES_BLOCK_SIZE],
+ unsigned int *num);
+/* NB: the IV is _two_ blocks long */
+void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ unsigned char *ivec, const int enc);
+/* NB: the IV is _four_ blocks long */
+void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const AES_KEY *key,
+ const AES_KEY *key2, const unsigned char *ivec,
+ const int enc);
+
+int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
+ unsigned char *out,
+ const unsigned char *in, unsigned int inlen);
+int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
+ unsigned char *out,
+ const unsigned char *in, unsigned int inlen);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !HEADER_AES_H */
diff --git a/openssl/aes/aes_locl.h b/openssl/aes/aes_locl.h
new file mode 100644
index 0000000..fabfd02
--- /dev/null
+++ b/openssl/aes/aes_locl.h
@@ -0,0 +1,89 @@
+/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * 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.
+ * ====================================================================
+ *
+ */
+
+#ifndef HEADER_AES_LOCL_H
+# define HEADER_AES_LOCL_H
+
+# include <openssl/e_os2.h>
+
+# ifdef OPENSSL_NO_AES
+# error AES is disabled.
+# endif
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+
+# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
+# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+# define GETU32(p) SWAP(*((u32 *)(p)))
+# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
+# else
+# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
+# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
+# endif
+
+# ifdef AES_LONG
+typedef unsigned long u32;
+# else
+typedef unsigned int u32;
+# endif
+typedef unsigned short u16;
+typedef unsigned char u8;
+
+# define MAXKC (256/32)
+# define MAXKB (256/8)
+# define MAXNR 14
+
+/* This controls loop-unrolling in aes_core.c */
+# undef FULL_UNROLL
+
+#endif /* !HEADER_AES_LOCL_H */
diff --git a/openssl/asn1.h b/openssl/asn1.h
new file mode 120000
index 0000000..e5cdfa8
--- /dev/null
+++ b/openssl/asn1.h
@@ -0,0 +1 @@
+asn1/asn1.h
\ No newline at end of file
diff --git a/openssl/asn1/asn1.h b/openssl/asn1/asn1.h
new file mode 100644
index 0000000..39b7833
--- /dev/null
+++ b/openssl/asn1/asn1.h
@@ -0,0 +1,1417 @@
+/* crypto/asn1/asn1.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ASN1_H
+# define HEADER_ASN1_H
+
+# include <time.h>
+# include <openssl/e_os2.h>
+# ifndef OPENSSL_NO_BIO
+# include <openssl/bio.h>
+# endif
+# include <openssl/stack.h>
+# include <openssl/safestack.h>
+
+# include <openssl/symhacks.h>
+
+# include <openssl/ossl_typ.h>
+# ifndef OPENSSL_NO_DEPRECATED
+# include <openssl/bn.h>
+# endif
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# define V_ASN1_UNIVERSAL 0x00
+# define V_ASN1_APPLICATION 0x40
+# define V_ASN1_CONTEXT_SPECIFIC 0x80
+# define V_ASN1_PRIVATE 0xc0
+
+# define V_ASN1_CONSTRUCTED 0x20
+# define V_ASN1_PRIMITIVE_TAG 0x1f
+# define V_ASN1_PRIMATIVE_TAG 0x1f
+
+# define V_ASN1_APP_CHOOSE -2/* let the recipient choose */
+# define V_ASN1_OTHER -3/* used in ASN1_TYPE */
+# define V_ASN1_ANY -4/* used in ASN1 template code */
+
+# define V_ASN1_NEG 0x100/* negative flag */
+
+# define V_ASN1_UNDEF -1
+# define V_ASN1_EOC 0
+# define V_ASN1_BOOLEAN 1 /**/
+# define V_ASN1_INTEGER 2
+# define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG)
+# define V_ASN1_BIT_STRING 3
+# define V_ASN1_OCTET_STRING 4
+# define V_ASN1_NULL 5
+# define V_ASN1_OBJECT 6
+# define V_ASN1_OBJECT_DESCRIPTOR 7
+# define V_ASN1_EXTERNAL 8
+# define V_ASN1_REAL 9
+# define V_ASN1_ENUMERATED 10
+# define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG)
+# define V_ASN1_UTF8STRING 12
+# define V_ASN1_SEQUENCE 16
+# define V_ASN1_SET 17
+# define V_ASN1_NUMERICSTRING 18 /**/
+# define V_ASN1_PRINTABLESTRING 19
+# define V_ASN1_T61STRING 20
+# define V_ASN1_TELETEXSTRING 20/* alias */
+# define V_ASN1_VIDEOTEXSTRING 21 /**/
+# define V_ASN1_IA5STRING 22
+# define V_ASN1_UTCTIME 23
+# define V_ASN1_GENERALIZEDTIME 24 /**/
+# define V_ASN1_GRAPHICSTRING 25 /**/
+# define V_ASN1_ISO64STRING 26 /**/
+# define V_ASN1_VISIBLESTRING 26/* alias */
+# define V_ASN1_GENERALSTRING 27 /**/
+# define V_ASN1_UNIVERSALSTRING 28 /**/
+# define V_ASN1_BMPSTRING 30
+/* For use with d2i_ASN1_type_bytes() */
+# define B_ASN1_NUMERICSTRING 0x0001
+# define B_ASN1_PRINTABLESTRING 0x0002
+# define B_ASN1_T61STRING 0x0004
+# define B_ASN1_TELETEXSTRING 0x0004
+# define B_ASN1_VIDEOTEXSTRING 0x0008
+# define B_ASN1_IA5STRING 0x0010
+# define B_ASN1_GRAPHICSTRING 0x0020
+# define B_ASN1_ISO64STRING 0x0040
+# define B_ASN1_VISIBLESTRING 0x0040
+# define B_ASN1_GENERALSTRING 0x0080
+# define B_ASN1_UNIVERSALSTRING 0x0100
+# define B_ASN1_OCTET_STRING 0x0200
+# define B_ASN1_BIT_STRING 0x0400
+# define B_ASN1_BMPSTRING 0x0800
+# define B_ASN1_UNKNOWN 0x1000
+# define B_ASN1_UTF8STRING 0x2000
+# define B_ASN1_UTCTIME 0x4000
+# define B_ASN1_GENERALIZEDTIME 0x8000
+# define B_ASN1_SEQUENCE 0x10000
+/* For use with ASN1_mbstring_copy() */
+# define MBSTRING_FLAG 0x1000
+# define MBSTRING_UTF8 (MBSTRING_FLAG)
+# define MBSTRING_ASC (MBSTRING_FLAG|1)
+# define MBSTRING_BMP (MBSTRING_FLAG|2)
+# define MBSTRING_UNIV (MBSTRING_FLAG|4)
+# define SMIME_OLDMIME 0x400
+# define SMIME_CRLFEOL 0x800
+# define SMIME_STREAM 0x1000
+ struct X509_algor_st;
+DECLARE_STACK_OF(X509_ALGOR)
+
+# define DECLARE_ASN1_SET_OF(type)/* filled in by mkstack.pl */
+# define IMPLEMENT_ASN1_SET_OF(type)/* nothing, no longer needed */
+
+/*
+ * We MUST make sure that, except for constness, asn1_ctx_st and
+ * asn1_const_ctx are exactly the same. Fortunately, as soon as the old ASN1
+ * parsing macros are gone, we can throw this away as well...
+ */
+typedef struct asn1_ctx_st {
+ unsigned char *p; /* work char pointer */
+ int eos; /* end of sequence read for indefinite
+ * encoding */
+ int error; /* error code to use when returning an error */
+ int inf; /* constructed if 0x20, indefinite is 0x21 */
+ int tag; /* tag from last 'get object' */
+ int xclass; /* class from last 'get object' */
+ long slen; /* length of last 'get object' */
+ unsigned char *max; /* largest value of p allowed */
+ unsigned char *q; /* temporary variable */
+ unsigned char **pp; /* variable */
+ int line; /* used in error processing */
+} ASN1_CTX;
+
+typedef struct asn1_const_ctx_st {
+ const unsigned char *p; /* work char pointer */
+ int eos; /* end of sequence read for indefinite
+ * encoding */
+ int error; /* error code to use when returning an error */
+ int inf; /* constructed if 0x20, indefinite is 0x21 */
+ int tag; /* tag from last 'get object' */
+ int xclass; /* class from last 'get object' */
+ long slen; /* length of last 'get object' */
+ const unsigned char *max; /* largest value of p allowed */
+ const unsigned char *q; /* temporary variable */
+ const unsigned char **pp; /* variable */
+ int line; /* used in error processing */
+} ASN1_const_CTX;
+
+/*
+ * These are used internally in the ASN1_OBJECT to keep track of whether the
+ * names and data need to be free()ed
+ */
+# define ASN1_OBJECT_FLAG_DYNAMIC 0x01/* internal use */
+# define ASN1_OBJECT_FLAG_CRITICAL 0x02/* critical x509v3 object id */
+# define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04/* internal use */
+# define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08/* internal use */
+typedef struct asn1_object_st {
+ const char *sn, *ln;
+ int nid;
+ int length;
+ const unsigned char *data; /* data remains const after init */
+ int flags; /* Should we free this one */
+} 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 flag is used by the CMS code to indicate that a string is not
+ * complete and is a place holder for content when it had all been accessed.
+ * The flag will be reset when content has been written to it.
+ */
+
+# define ASN1_STRING_FLAG_CONT 0x020
+/*
+ * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING
+ * type.
+ */
+# define ASN1_STRING_FLAG_MSTRING 0x040
+/* This is the base type that holds just about everything :-) */
+struct asn1_string_st {
+ int length;
+ int type;
+ unsigned char *data;
+ /*
+ * The value of the following field depends on the type being held. It
+ * is mostly being used for BIT_STRING so if the input data has a
+ * non-zero 'unused bits' value, it will be handled correctly
+ */
+ long flags;
+};
+
+/*
+ * ASN1_ENCODING structure: this is used to save the received encoding of an
+ * ASN1 type. This is useful to get round problems with invalid encodings
+ * which can break signatures.
+ */
+
+typedef struct ASN1_ENCODING_st {
+ unsigned char *enc; /* DER encoding */
+ long len; /* Length of encoding */
+ int modified; /* set to 1 if 'enc' is invalid */
+} ASN1_ENCODING;
+
+/* Used with ASN1 LONG type: if a long is set to this it is omitted */
+# define ASN1_LONG_UNDEF 0x7fffffffL
+
+# define STABLE_FLAGS_MALLOC 0x01
+# define STABLE_NO_MASK 0x02
+# define DIRSTRING_TYPE \
+ (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING)
+# define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING)
+
+typedef struct asn1_string_table_st {
+ int nid;
+ long minsize;
+ long maxsize;
+ unsigned long mask;
+ unsigned long flags;
+} ASN1_STRING_TABLE;
+
+DECLARE_STACK_OF(ASN1_STRING_TABLE)
+
+/* size limits: this stuff is taken straight from RFC2459 */
+
+# define ub_name 32768
+# define ub_common_name 64
+# define ub_locality_name 128
+# define ub_state_name 128
+# define ub_organization_name 64
+# define ub_organization_unit_name 64
+# define ub_title 64
+# define ub_email_address 128
+
+/*
+ * Declarations for template structures: for full definitions see asn1t.h
+ */
+typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
+typedef struct ASN1_TLC_st ASN1_TLC;
+/* This is just an opaque pointer */
+typedef struct ASN1_VALUE_st ASN1_VALUE;
+
+/* Declare ASN1 functions: the implement macro in in asn1t.h */
+
+# define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type)
+
+# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \
+ DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type)
+
+# define DECLARE_ASN1_FUNCTIONS_name(type, name) \
+ DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+ DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)
+
+# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \
+ DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+ DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)
+
+# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \
+ type *d2i_##name(type **a, const unsigned char **in, long len); \
+ int i2d_##name(type *a, unsigned char **out); \
+ DECLARE_ASN1_ITEM(itname)
+
+# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
+ type *d2i_##name(type **a, const unsigned char **in, long len); \
+ 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) \
+ DECLARE_ASN1_ALLOC_FUNCTIONS(name) \
+ DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name)
+
+# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+ type *name##_new(void); \
+ void name##_free(type *a);
+
+# define DECLARE_ASN1_PRINT_FUNCTION(stname) \
+ DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)
+
+# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
+ int fname##_print_ctx(BIO *out, stname *x, int indent, \
+ const ASN1_PCTX *pctx);
+
+# define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
+# define I2D_OF(type) int (*)(type *,unsigned char **)
+# define I2D_OF_const(type) int (*)(const type *,unsigned char **)
+
+# define CHECKED_D2I_OF(type, d2i) \
+ ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0)))
+# define CHECKED_I2D_OF(type, i2d) \
+ ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0)))
+# define CHECKED_NEW_OF(type, xnew) \
+ ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0)))
+# define CHECKED_PTR_OF(type, p) \
+ ((void*) (1 ? p : (type*)0))
+# define CHECKED_PPTR_OF(type, p) \
+ ((void**) (1 ? p : (type**)0))
+
+# define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
+# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
+# define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type)
+
+TYPEDEF_D2I2D_OF(void);
+
+/*-
+ * The following macros and typedefs allow an ASN1_ITEM
+ * to be embedded in a structure and referenced. Since
+ * the ASN1_ITEM pointers need to be globally accessible
+ * (possibly from shared libraries) they may exist in
+ * different forms. On platforms that support it the
+ * ASN1_ITEM structure itself will be globally exported.
+ * Other platforms will export a function that returns
+ * an ASN1_ITEM pointer.
+ *
+ * To handle both cases transparently the macros below
+ * should be used instead of hard coding an ASN1_ITEM
+ * pointer in a structure.
+ *
+ * The structure will look like this:
+ *
+ * typedef struct SOMETHING_st {
+ * ...
+ * ASN1_ITEM_EXP *iptr;
+ * ...
+ * } SOMETHING;
+ *
+ * It would be initialised as e.g.:
+ *
+ * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...};
+ *
+ * and the actual pointer extracted with:
+ *
+ * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr);
+ *
+ * Finally an ASN1_ITEM pointer can be extracted from an
+ * appropriate reference with: ASN1_ITEM_rptr(X509). This
+ * would be used when a function takes an ASN1_ITEM * argument.
+ *
+ */
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM ASN1_ITEM_EXP;
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+# define ASN1_ITEM_ptr(iptr) (iptr)
+
+/* Macro to include ASN1_ITEM pointer from base type */
+# define ASN1_ITEM_ref(iptr) (&(iptr##_it))
+
+# define ASN1_ITEM_rptr(ref) (&(ref##_it))
+
+# define DECLARE_ASN1_ITEM(name) \
+ OPENSSL_EXTERN const ASN1_ITEM name##_it;
+
+# else
+
+/*
+ * Platforms that can't easily handle shared global variables are declared as
+ * functions returning ASN1_ITEM pointers.
+ */
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM *ASN1_ITEM_EXP (void);
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+# define ASN1_ITEM_ptr(iptr) (iptr())
+
+/* Macro to include ASN1_ITEM pointer from base type */
+# define ASN1_ITEM_ref(iptr) (iptr##_it)
+
+# define ASN1_ITEM_rptr(ref) (ref##_it())
+
+# define DECLARE_ASN1_ITEM(name) \
+ const ASN1_ITEM * name##_it(void);
+
+# endif
+
+/* Parameters used by ASN1_STRING_print_ex() */
+
+/*
+ * These determine which characters to escape: RFC2253 special characters,
+ * control characters and MSB set characters
+ */
+
+# define ASN1_STRFLGS_ESC_2253 1
+# define ASN1_STRFLGS_ESC_CTRL 2
+# define ASN1_STRFLGS_ESC_MSB 4
+
+/*
+ * This flag determines how we do escaping: normally RC2253 backslash only,
+ * set this to use backslash and quote.
+ */
+
+# define ASN1_STRFLGS_ESC_QUOTE 8
+
+/* These three flags are internal use only. */
+
+/* Character is a valid PrintableString character */
+# define CHARTYPE_PRINTABLESTRING 0x10
+/* Character needs escaping if it is the first character */
+# define CHARTYPE_FIRST_ESC_2253 0x20
+/* Character needs escaping if it is the last character */
+# define CHARTYPE_LAST_ESC_2253 0x40
+
+/*
+ * NB the internal flags are safely reused below by flags handled at the top
+ * level.
+ */
+
+/*
+ * If this is set we convert all character strings to UTF8 first
+ */
+
+# define ASN1_STRFLGS_UTF8_CONVERT 0x10
+
+/*
+ * If this is set we don't attempt to interpret content: just assume all
+ * strings are 1 byte per character. This will produce some pretty odd
+ * looking output!
+ */
+
+# define ASN1_STRFLGS_IGNORE_TYPE 0x20
+
+/* If this is set we include the string type in the output */
+# define ASN1_STRFLGS_SHOW_TYPE 0x40
+
+/*
+ * This determines which strings to display and which to 'dump' (hex dump of
+ * content octets or DER encoding). We can only dump non character strings or
+ * everything. If we don't dump 'unknown' they are interpreted as character
+ * strings with 1 octet per character and are subject to the usual escaping
+ * options.
+ */
+
+# define ASN1_STRFLGS_DUMP_ALL 0x80
+# define ASN1_STRFLGS_DUMP_UNKNOWN 0x100
+
+/*
+ * These determine what 'dumping' does, we can dump the content octets or the
+ * DER encoding: both use the RFC2253 #XXXXX notation.
+ */
+
+# define ASN1_STRFLGS_DUMP_DER 0x200
+
+/*
+ * All the string flags consistent with RFC2253, escaping control characters
+ * isn't essential in RFC2253 but it is advisable anyway.
+ */
+
+# define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \
+ ASN1_STRFLGS_ESC_CTRL | \
+ ASN1_STRFLGS_ESC_MSB | \
+ ASN1_STRFLGS_UTF8_CONVERT | \
+ ASN1_STRFLGS_DUMP_UNKNOWN | \
+ ASN1_STRFLGS_DUMP_DER)
+
+DECLARE_STACK_OF(ASN1_INTEGER)
+DECLARE_ASN1_SET_OF(ASN1_INTEGER)
+
+DECLARE_STACK_OF(ASN1_GENERALSTRING)
+
+typedef struct asn1_type_st {
+ int type;
+ union {
+ char *ptr;
+ ASN1_BOOLEAN boolean;
+ ASN1_STRING *asn1_string;
+ ASN1_OBJECT *object;
+ ASN1_INTEGER *integer;
+ ASN1_ENUMERATED *enumerated;
+ ASN1_BIT_STRING *bit_string;
+ ASN1_OCTET_STRING *octet_string;
+ ASN1_PRINTABLESTRING *printablestring;
+ ASN1_T61STRING *t61string;
+ ASN1_IA5STRING *ia5string;
+ ASN1_GENERALSTRING *generalstring;
+ ASN1_BMPSTRING *bmpstring;
+ ASN1_UNIVERSALSTRING *universalstring;
+ ASN1_UTCTIME *utctime;
+ ASN1_GENERALIZEDTIME *generalizedtime;
+ ASN1_VISIBLESTRING *visiblestring;
+ ASN1_UTF8STRING *utf8string;
+ /*
+ * set and sequence are left complete and still contain the set or
+ * sequence bytes
+ */
+ ASN1_STRING *set;
+ ASN1_STRING *sequence;
+ ASN1_VALUE *asn1_value;
+ } value;
+} ASN1_TYPE;
+
+DECLARE_STACK_OF(ASN1_TYPE)
+DECLARE_ASN1_SET_OF(ASN1_TYPE)
+
+typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;
+
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
+
+typedef struct NETSCAPE_X509_st {
+ ASN1_OCTET_STRING *header;
+ X509 *cert;
+} NETSCAPE_X509;
+
+/* This is used to contain a list of bit names */
+typedef struct BIT_STRING_BITNAME_st {
+ int bitnum;
+ const char *lname;
+ const char *sname;
+} BIT_STRING_BITNAME;
+
+# define M_ASN1_STRING_length(x) ((x)->length)
+# define M_ASN1_STRING_length_set(x, n) ((x)->length = (n))
+# define M_ASN1_STRING_type(x) ((x)->type)
+# define M_ASN1_STRING_data(x) ((x)->data)
+
+/* Macros for string operations */
+# define M_ASN1_BIT_STRING_new() (ASN1_BIT_STRING *)\
+ ASN1_STRING_type_new(V_ASN1_BIT_STRING)
+# define M_ASN1_BIT_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\
+ ASN1_STRING_dup((const ASN1_STRING *)a)
+# define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\
+ (const ASN1_STRING *)a,(const ASN1_STRING *)b)
+# define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
+
+# define M_ASN1_INTEGER_new() (ASN1_INTEGER *)\
+ ASN1_STRING_type_new(V_ASN1_INTEGER)
+# define M_ASN1_INTEGER_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\
+ ASN1_STRING_dup((const ASN1_STRING *)a)
+# define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\
+ (const ASN1_STRING *)a,(const ASN1_STRING *)b)
+
+# define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\
+ ASN1_STRING_type_new(V_ASN1_ENUMERATED)
+# define M_ASN1_ENUMERATED_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\
+ ASN1_STRING_dup((const ASN1_STRING *)a)
+# define M_ASN1_ENUMERATED_cmp(a,b) ASN1_STRING_cmp(\
+ (const ASN1_STRING *)a,(const ASN1_STRING *)b)
+
+# define M_ASN1_OCTET_STRING_new() (ASN1_OCTET_STRING *)\
+ ASN1_STRING_type_new(V_ASN1_OCTET_STRING)
+# define M_ASN1_OCTET_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\
+ ASN1_STRING_dup((const ASN1_STRING *)a)
+# define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\
+ (const ASN1_STRING *)a,(const ASN1_STRING *)b)
+# define M_ASN1_OCTET_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
+# define M_ASN1_OCTET_STRING_print(a,b) ASN1_STRING_print(a,(ASN1_STRING *)b)
+# define M_i2d_ASN1_OCTET_STRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\
+ V_ASN1_UNIVERSAL)
+
+# define B_ASN1_TIME \
+ B_ASN1_UTCTIME | \
+ B_ASN1_GENERALIZEDTIME
+
+# define B_ASN1_PRINTABLE \
+ B_ASN1_NUMERICSTRING| \
+ B_ASN1_PRINTABLESTRING| \
+ B_ASN1_T61STRING| \
+ B_ASN1_IA5STRING| \
+ B_ASN1_BIT_STRING| \
+ B_ASN1_UNIVERSALSTRING|\
+ B_ASN1_BMPSTRING|\
+ B_ASN1_UTF8STRING|\
+ B_ASN1_SEQUENCE|\
+ B_ASN1_UNKNOWN
+
+# define B_ASN1_DIRECTORYSTRING \
+ B_ASN1_PRINTABLESTRING| \
+ B_ASN1_TELETEXSTRING|\
+ B_ASN1_BMPSTRING|\
+ B_ASN1_UNIVERSALSTRING|\
+ B_ASN1_UTF8STRING
+
+# define B_ASN1_DISPLAYTEXT \
+ B_ASN1_IA5STRING| \
+ B_ASN1_VISIBLESTRING| \
+ B_ASN1_BMPSTRING|\
+ B_ASN1_UTF8STRING
+
+# define M_ASN1_PRINTABLE_new() ASN1_STRING_type_new(V_ASN1_T61STRING)
+# define M_ASN1_PRINTABLE_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+ pp,a->type,V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_PRINTABLE(a,pp,l) \
+ d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+ B_ASN1_PRINTABLE)
+
+# define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+# define M_DIRECTORYSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+ pp,a->type,V_ASN1_UNIVERSAL)
+# define M_d2i_DIRECTORYSTRING(a,pp,l) \
+ d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+ B_ASN1_DIRECTORYSTRING)
+
+# define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+# define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+ pp,a->type,V_ASN1_UNIVERSAL)
+# define M_d2i_DISPLAYTEXT(a,pp,l) \
+ d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+ B_ASN1_DISPLAYTEXT)
+
+# define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\
+ ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+# define M_ASN1_PRINTABLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_PRINTABLESTRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\
+ V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \
+ (ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING)
+
+# define M_ASN1_T61STRING_new() (ASN1_T61STRING *)\
+ ASN1_STRING_type_new(V_ASN1_T61STRING)
+# define M_ASN1_T61STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_T61STRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\
+ V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_T61STRING(a,pp,l) \
+ (ASN1_T61STRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING)
+
+# define M_ASN1_IA5STRING_new() (ASN1_IA5STRING *)\
+ ASN1_STRING_type_new(V_ASN1_IA5STRING)
+# define M_ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_IA5STRING_dup(a) \
+ (ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a)
+# define M_i2d_ASN1_IA5STRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
+ V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_IA5STRING(a,pp,l) \
+ (ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\
+ B_ASN1_IA5STRING)
+
+# define M_ASN1_UTCTIME_new() (ASN1_UTCTIME *)\
+ ASN1_STRING_type_new(V_ASN1_UTCTIME)
+# define M_ASN1_UTCTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\
+ ASN1_STRING_dup((const ASN1_STRING *)a)
+
+# define M_ASN1_GENERALIZEDTIME_new() (ASN1_GENERALIZEDTIME *)\
+ ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME)
+# define M_ASN1_GENERALIZEDTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\
+ (const ASN1_STRING *)a)
+
+# define M_ASN1_TIME_new() (ASN1_TIME *)\
+ ASN1_STRING_type_new(V_ASN1_UTCTIME)
+# define M_ASN1_TIME_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_ASN1_TIME_dup(a) (ASN1_TIME *)\
+ ASN1_STRING_dup((const ASN1_STRING *)a)
+
+# define M_ASN1_GENERALSTRING_new() (ASN1_GENERALSTRING *)\
+ ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
+# define M_ASN1_GENERALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_GENERALSTRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\
+ V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_GENERALSTRING(a,pp,l) \
+ (ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING)
+
+# define M_ASN1_UNIVERSALSTRING_new() (ASN1_UNIVERSALSTRING *)\
+ ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING)
+# define M_ASN1_UNIVERSALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\
+ V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \
+ (ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING)
+
+# define M_ASN1_BMPSTRING_new() (ASN1_BMPSTRING *)\
+ ASN1_STRING_type_new(V_ASN1_BMPSTRING)
+# define M_ASN1_BMPSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_BMPSTRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\
+ V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_BMPSTRING(a,pp,l) \
+ (ASN1_BMPSTRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING)
+
+# define M_ASN1_VISIBLESTRING_new() (ASN1_VISIBLESTRING *)\
+ ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+# define M_ASN1_VISIBLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_VISIBLESTRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\
+ V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \
+ (ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING)
+
+# define M_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\
+ ASN1_STRING_type_new(V_ASN1_UTF8STRING)
+# define M_ASN1_UTF8STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+# define M_i2d_ASN1_UTF8STRING(a,pp) \
+ i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\
+ V_ASN1_UNIVERSAL)
+# define M_d2i_ASN1_UTF8STRING(a,pp,l) \
+ (ASN1_UTF8STRING *)d2i_ASN1_type_bytes\
+ ((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING)
+
+ /* for the is_set parameter to i2d_ASN1_SET */
+# define IS_SEQUENCE 0
+# define IS_SET 1
+
+DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
+
+int ASN1_TYPE_get(ASN1_TYPE *a);
+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
+
+ASN1_OBJECT *ASN1_OBJECT_new(void);
+void ASN1_OBJECT_free(ASN1_OBJECT *a);
+int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp);
+ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+ long length);
+ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+ long length);
+
+DECLARE_ASN1_ITEM(ASN1_OBJECT)
+
+DECLARE_STACK_OF(ASN1_OBJECT)
+DECLARE_ASN1_SET_OF(ASN1_OBJECT)
+
+ASN1_STRING *ASN1_STRING_new(void);
+void ASN1_STRING_free(ASN1_STRING *a);
+void ASN1_STRING_clear_free(ASN1_STRING *a);
+int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
+ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a);
+ASN1_STRING *ASN1_STRING_type_new(int type);
+int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
+ /*
+ * Since this is used to store all sorts of things, via macros, for now,
+ * make its data void *
+ */
+int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
+void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
+int ASN1_STRING_length(const ASN1_STRING *x);
+void ASN1_STRING_length_set(ASN1_STRING *x, int n);
+int ASN1_STRING_type(ASN1_STRING *x);
+unsigned char *ASN1_STRING_data(ASN1_STRING *x);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
+int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp);
+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
+ const unsigned char **pp, long length);
+int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length);
+int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
+int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
+int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
+ unsigned char *flags, int flags_len);
+
+# ifndef OPENSSL_NO_BIO
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+ BIT_STRING_BITNAME *tbl, int indent);
+# endif
+int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl);
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
+ BIT_STRING_BITNAME *tbl);
+
+int i2d_ASN1_BOOLEAN(int a, unsigned char **pp);
+int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
+int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp);
+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+ long length);
+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+ long length);
+ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x);
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
+
+int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
+ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t);
+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
+ int offset_day, long offset_sec);
+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
+# if 0
+time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s);
+# endif
+
+int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
+ time_t t);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
+ time_t t, int offset_day,
+ long offset_sec);
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
+ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
+int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
+ const ASN1_OCTET_STRING *b);
+int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data,
+ int len);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
+DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING)
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
+int UTF8_putc(unsigned char *str, int len, unsigned long value);
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
+DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
+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);
+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
+ int offset_day, long offset_sec);
+int ASN1_TIME_check(ASN1_TIME *t);
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME
+ **out);
+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
+
+int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
+ i2d_of_void *i2d, int ex_tag, int ex_class, int is_set);
+STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
+ const unsigned char **pp,
+ long length, d2i_of_void *d2i,
+ void (*free_func) (OPENSSL_BLOCK),
+ int ex_tag, int ex_class);
+
+# ifndef OPENSSL_NO_BIO
+int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
+int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size);
+int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
+int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size);
+int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a);
+int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size);
+int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
+# endif
+int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a);
+
+int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num);
+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
+ const char *sn, const char *ln);
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
+long ASN1_INTEGER_get(const ASN1_INTEGER *a);
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn);
+
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
+long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai);
+BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn);
+
+/* General */
+/* given a string, return the correct type, max is the maximum length */
+int ASN1_PRINTABLE_type(const unsigned char *s, int max);
+
+int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
+ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
+ long length, int Ptag, int Pclass);
+unsigned long ASN1_tag2bit(int tag);
+/* type is one or more of the B_ASN1_ values. */
+ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
+ long length, int type);
+
+/* PARSING */
+int asn1_Finish(ASN1_CTX *c);
+int asn1_const_Finish(ASN1_const_CTX *c);
+
+/* SPECIALS */
+int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
+ int *pclass, long omax);
+int ASN1_check_infinite_end(unsigned char **p, long len);
+int ASN1_const_check_infinite_end(const 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 */
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
+
+# define ASN1_dup_of(type,i2d,d2i,x) \
+ ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
+ CHECKED_D2I_OF(type, d2i), \
+ CHECKED_PTR_OF(type, x)))
+
+# define ASN1_dup_of_const(type,i2d,d2i,x) \
+ ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
+ CHECKED_D2I_OF(type, d2i), \
+ CHECKED_PTR_OF(const type, x)))
+
+void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
+
+/* ASN1 alloc/free macros for when a type is only used internally */
+
+# define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type))
+# define M_ASN1_free_of(x, type) \
+ ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type))
+
+# ifndef OPENSSL_NO_FP_API
+void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x);
+
+# define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
+ ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \
+ CHECKED_D2I_OF(type, d2i), \
+ in, \
+ CHECKED_PPTR_OF(type, x)))
+
+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
+int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x);
+
+# define ASN1_i2d_fp_of(type,i2d,out,x) \
+ (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \
+ out, \
+ CHECKED_PTR_OF(type, x)))
+
+# define ASN1_i2d_fp_of_const(type,i2d,out,x) \
+ (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \
+ out, \
+ CHECKED_PTR_OF(const type, x)))
+
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
+int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
+# endif
+
+int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
+
+# ifndef OPENSSL_NO_BIO
+void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x);
+
+# define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
+ ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \
+ CHECKED_D2I_OF(type, d2i), \
+ in, \
+ CHECKED_PPTR_OF(type, x)))
+
+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x);
+
+# define ASN1_i2d_bio_of(type,i2d,out,x) \
+ (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
+ out, \
+ CHECKED_PTR_OF(type, x)))
+
+# define ASN1_i2d_bio_of_const(type,i2d,out,x) \
+ (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \
+ out, \
+ CHECKED_PTR_OF(const type, x)))
+
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
+int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
+int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
+int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
+int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+ unsigned char *buf, int off);
+int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent);
+int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
+ int dump);
+# endif
+const char *ASN1_tag2str(int tag);
+
+/* Used to load and write netscape format cert */
+
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509)
+
+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
+
+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len);
+int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len);
+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num,
+ unsigned char *data, int len);
+int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num,
+ unsigned char *data, int max_len);
+
+STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
+ d2i_of_void *d2i,
+ void (*free_func) (OPENSSL_BLOCK));
+unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
+ unsigned char **buf, int *len);
+void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
+void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
+ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d,
+ ASN1_OCTET_STRING **oct);
+
+# define ASN1_pack_string_of(type,obj,i2d,oct) \
+ (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \
+ CHECKED_I2D_OF(type, i2d), \
+ oct))
+
+ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it,
+ ASN1_OCTET_STRING **oct);
+
+void ASN1_STRING_set_default_mask(unsigned long mask);
+int ASN1_STRING_set_default_mask_asc(const char *p);
+unsigned long ASN1_STRING_get_default_mask(void);
+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+ int inform, unsigned long mask);
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+ int inform, unsigned long mask,
+ long minsize, long maxsize);
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
+ const unsigned char *in, int inlen,
+ int inform, int nid);
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
+int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
+void ASN1_STRING_TABLE_cleanup(void);
+
+/* ASN1 template functions */
+
+/* Old API compatible functions */
+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, const 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);
+
+/* ASN1 Print flags */
+
+/* Indicate missing OPTIONAL fields */
+# define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001
+/* Mark start and end of SEQUENCE */
+# define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002
+/* Mark start and end of SEQUENCE/SET OF */
+# define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004
+/* Show the ASN1 type of primitives */
+# define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008
+/* Don't show ASN1 type of ANY */
+# define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010
+/* Don't show ASN1 type of MSTRINGs */
+# define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020
+/* Don't show field names in SEQUENCE */
+# define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040
+/* Show structure names of each SEQUENCE field */
+# define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080
+/* Don't show structure name even at top level */
+# define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100
+
+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+ const ASN1_ITEM *it, const ASN1_PCTX *pctx);
+ASN1_PCTX *ASN1_PCTX_new(void);
+void ASN1_PCTX_free(ASN1_PCTX *p);
+unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p);
+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);
+
+BIO_METHOD *BIO_f_asn1(void);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
+
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+ const ASN1_ITEM *it);
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+ const char *hdr, const ASN1_ITEM *it);
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+ int ctype_nid, int econt_nid,
+ STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it);
+ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
+int SMIME_text(BIO *in, BIO *out);
+
+/* 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.
+ */
+void ERR_load_ASN1_strings(void);
+
+/* Error codes for the ASN1 functions. */
+
+/* Function codes. */
+# define ASN1_F_A2D_ASN1_OBJECT 100
+# 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_EXP 176
+# define ASN1_F_ASN1_BIT_STRING_SET_BIT 183
+# define ASN1_F_ASN1_CB 177
+# define ASN1_F_ASN1_CHECK_TLEN 104
+# define ASN1_F_ASN1_COLLATE_PRIMITIVE 105
+# define ASN1_F_ASN1_COLLECT 106
+# define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108
+# define ASN1_F_ASN1_D2I_FP 109
+# define ASN1_F_ASN1_D2I_READ_BIO 107
+# define ASN1_F_ASN1_DIGEST 184
+# define ASN1_F_ASN1_DO_ADB 110
+# 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_EX_C2I 204
+# define ASN1_F_ASN1_FIND_END 190
+# define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216
+# define ASN1_F_ASN1_GENERALIZEDTIME_SET 185
+# define ASN1_F_ASN1_GENERATE_V3 178
+# define ASN1_F_ASN1_GET_OBJECT 114
+# define ASN1_F_ASN1_HEADER_NEW 115
+# define ASN1_F_ASN1_I2D_BIO 116
+# define ASN1_F_ASN1_I2D_FP 117
+# define ASN1_F_ASN1_INTEGER_SET 118
+# define ASN1_F_ASN1_INTEGER_TO_BN 119
+# define ASN1_F_ASN1_ITEM_D2I_FP 206
+# define ASN1_F_ASN1_ITEM_DUP 191
+# define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW 121
+# define ASN1_F_ASN1_ITEM_EX_D2I 120
+# define ASN1_F_ASN1_ITEM_I2D_BIO 192
+# define ASN1_F_ASN1_ITEM_I2D_FP 193
+# define ASN1_F_ASN1_ITEM_PACK 198
+# define ASN1_F_ASN1_ITEM_SIGN 195
+# define ASN1_F_ASN1_ITEM_SIGN_CTX 220
+# define ASN1_F_ASN1_ITEM_UNPACK 199
+# define ASN1_F_ASN1_ITEM_VERIFY 197
+# define ASN1_F_ASN1_MBSTRING_NCOPY 122
+# define ASN1_F_ASN1_OBJECT_NEW 123
+# define ASN1_F_ASN1_OUTPUT_DATA 214
+# define ASN1_F_ASN1_PACK_STRING 124
+# define ASN1_F_ASN1_PCTX_NEW 205
+# define ASN1_F_ASN1_PKCS5_PBE_SET 125
+# 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_SET 186
+# define ASN1_F_ASN1_STRING_TABLE_ADD 129
+# define ASN1_F_ASN1_STRING_TYPE_NEW 130
+# define ASN1_F_ASN1_TEMPLATE_EX_D2I 132
+# define ASN1_F_ASN1_TEMPLATE_NEW 133
+# define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131
+# define ASN1_F_ASN1_TIME_ADJ 217
+# define ASN1_F_ASN1_TIME_SET 175
+# define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134
+# define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135
+# define ASN1_F_ASN1_UNPACK_STRING 136
+# define ASN1_F_ASN1_UTCTIME_ADJ 218
+# define ASN1_F_ASN1_UTCTIME_SET 187
+# define ASN1_F_ASN1_VERIFY 137
+# define ASN1_F_B64_READ_ASN1 209
+# define ASN1_F_B64_WRITE_ASN1 210
+# define ASN1_F_BIO_NEW_NDEF 208
+# 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_C2I_ASN1_BIT_STRING 189
+# define ASN1_F_C2I_ASN1_INTEGER 194
+# define ASN1_F_C2I_ASN1_OBJECT 196
+# define ASN1_F_COLLECT_DATA 140
+# define ASN1_F_D2I_ASN1_BIT_STRING 141
+# define ASN1_F_D2I_ASN1_BOOLEAN 142
+# define ASN1_F_D2I_ASN1_BYTES 143
+# define ASN1_F_D2I_ASN1_GENERALIZEDTIME 144
+# define ASN1_F_D2I_ASN1_HEADER 145
+# define ASN1_F_D2I_ASN1_INTEGER 146
+# define ASN1_F_D2I_ASN1_OBJECT 147
+# define ASN1_F_D2I_ASN1_SET 148
+# define ASN1_F_D2I_ASN1_TYPE_BYTES 149
+# define ASN1_F_D2I_ASN1_UINTEGER 150
+# define ASN1_F_D2I_ASN1_UTCTIME 151
+# define ASN1_F_D2I_AUTOPRIVATEKEY 207
+# define ASN1_F_D2I_NETSCAPE_RSA 152
+# define ASN1_F_D2I_NETSCAPE_RSA_2 153
+# define ASN1_F_D2I_PRIVATEKEY 154
+# define ASN1_F_D2I_PUBLICKEY 155
+# define ASN1_F_D2I_RSA_NET 200
+# define ASN1_F_D2I_RSA_NET_2 201
+# define ASN1_F_D2I_X509 156
+# define ASN1_F_D2I_X509_CINF 157
+# define ASN1_F_D2I_X509_PKEY 159
+# define ASN1_F_I2D_ASN1_BIO_STREAM 211
+# define ASN1_F_I2D_ASN1_SET 188
+# define ASN1_F_I2D_ASN1_TIME 160
+# define ASN1_F_I2D_DSA_PUBKEY 161
+# define ASN1_F_I2D_EC_PUBKEY 181
+# define ASN1_F_I2D_PRIVATEKEY 163
+# define ASN1_F_I2D_PUBLICKEY 164
+# define ASN1_F_I2D_RSA_NET 162
+# define ASN1_F_I2D_RSA_PUBKEY 165
+# define ASN1_F_LONG_C2I 166
+# define ASN1_F_OID_MODULE_INIT 174
+# define ASN1_F_PARSE_TAGGING 182
+# define ASN1_F_PKCS5_PBE2_SET_IV 167
+# define ASN1_F_PKCS5_PBE_SET 202
+# define ASN1_F_PKCS5_PBE_SET0_ALGOR 215
+# define ASN1_F_PKCS5_PBKDF2_SET 219
+# define ASN1_F_SMIME_READ_ASN1 212
+# define ASN1_F_SMIME_TEXT 213
+# define ASN1_F_X509_CINF_NEW 168
+# define ASN1_F_X509_CRL_ADD0_REVOKED 169
+# define ASN1_F_X509_INFO_NEW 170
+# define ASN1_F_X509_NAME_ENCODE 203
+# define ASN1_F_X509_NAME_EX_D2I 158
+# define ASN1_F_X509_NAME_EX_NEW 171
+# define ASN1_F_X509_NEW 172
+# define ASN1_F_X509_PKEY_NEW 173
+
+/* Reason codes. */
+# define ASN1_R_ADDING_OBJECT 171
+# define ASN1_R_ASN1_PARSE_ERROR 203
+# define ASN1_R_ASN1_SIG_PARSE_ERROR 204
+# define ASN1_R_AUX_ERROR 100
+# define ASN1_R_BAD_CLASS 101
+# define ASN1_R_BAD_OBJECT_HEADER 102
+# define ASN1_R_BAD_PASSWORD_READ 103
+# define ASN1_R_BAD_TAG 104
+# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214
+# define ASN1_R_BN_LIB 105
+# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106
+# define ASN1_R_BUFFER_TOO_SMALL 107
+# define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108
+# define ASN1_R_CONTEXT_NOT_INITIALISED 217
+# define ASN1_R_DATA_IS_WRONG 109
+# define ASN1_R_DECODE_ERROR 110
+# define ASN1_R_DECODING_ERROR 111
+# define ASN1_R_DEPTH_EXCEEDED 174
+# define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198
+# define ASN1_R_ENCODE_ERROR 112
+# define ASN1_R_ERROR_GETTING_TIME 173
+# define ASN1_R_ERROR_LOADING_SECTION 172
+# define ASN1_R_ERROR_PARSING_SET_ELEMENT 113
+# define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114
+# define ASN1_R_EXPECTING_AN_INTEGER 115
+# define ASN1_R_EXPECTING_AN_OBJECT 116
+# define ASN1_R_EXPECTING_A_BOOLEAN 117
+# define ASN1_R_EXPECTING_A_TIME 118
+# define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119
+# define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120
+# 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 175
+# define ASN1_R_ILLEGAL_BOOLEAN 176
+# define ASN1_R_ILLEGAL_CHARACTERS 124
+# define ASN1_R_ILLEGAL_FORMAT 177
+# define ASN1_R_ILLEGAL_HEX 178
+# define ASN1_R_ILLEGAL_IMPLICIT_TAG 179
+# define ASN1_R_ILLEGAL_INTEGER 180
+# define ASN1_R_ILLEGAL_NESTED_TAGGING 181
+# define ASN1_R_ILLEGAL_NULL 125
+# define ASN1_R_ILLEGAL_NULL_VALUE 182
+# define ASN1_R_ILLEGAL_OBJECT 183
+# 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 184
+# define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185
+# define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128
+# define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220
+# define ASN1_R_INVALID_BMPSTRING_LENGTH 129
+# define ASN1_R_INVALID_DIGIT 130
+# define ASN1_R_INVALID_MIME_TYPE 205
+# define ASN1_R_INVALID_MODIFIER 186
+# define ASN1_R_INVALID_NUMBER 187
+# define ASN1_R_INVALID_OBJECT_ENCODING 216
+# 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 188
+# define ASN1_R_MIME_NO_CONTENT_TYPE 206
+# define ASN1_R_MIME_PARSE_ERROR 207
+# define ASN1_R_MIME_SIG_PARSE_ERROR 208
+# define ASN1_R_MISSING_EOC 137
+# define ASN1_R_MISSING_SECOND_NUMBER 138
+# define ASN1_R_MISSING_VALUE 189
+# define ASN1_R_MSTRING_NOT_UNIVERSAL 139
+# define ASN1_R_MSTRING_WRONG_TAG 140
+# define ASN1_R_NESTED_ASN1_STRING 197
+# define ASN1_R_NON_HEX_CHARACTERS 141
+# define ASN1_R_NOT_ASCII_FORMAT 190
+# define ASN1_R_NOT_ENOUGH_DATA 142
+# define ASN1_R_NO_CONTENT_TYPE 209
+# define ASN1_R_NO_DEFAULT_DIGEST 201
+# define ASN1_R_NO_MATCHING_CHOICE_TYPE 143
+# define ASN1_R_NO_MULTIPART_BODY_FAILURE 210
+# define ASN1_R_NO_MULTIPART_BOUNDARY 211
+# define ASN1_R_NO_SIG_CONTENT_TYPE 212
+# define ASN1_R_NULL_IS_WRONG_LENGTH 144
+# define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191
+# 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 192
+# define ASN1_R_SHORT_LINE 150
+# define ASN1_R_SIG_INVALID_MIME_TYPE 213
+# define ASN1_R_STREAMING_NOT_SUPPORTED 202
+# 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 193
+# define ASN1_R_TOO_LONG 155
+# define ASN1_R_TYPE_NOT_CONSTRUCTED 156
+# define ASN1_R_TYPE_NOT_PRIMITIVE 218
+# define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157
+# define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158
+# define ASN1_R_UNEXPECTED_EOC 159
+# define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215
+# define ASN1_R_UNKNOWN_FORMAT 160
+# 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_SIGNATURE_ALGORITHM 199
+# define ASN1_R_UNKNOWN_TAG 194
+# define ASN1_R_UNKOWN_FORMAT 195
+# 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 196
+# define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200
+# define ASN1_R_WRONG_TAG 168
+# define ASN1_R_WRONG_TYPE 169
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/asn1/asn1_locl.h b/openssl/asn1/asn1_locl.h
new file mode 100644
index 0000000..9f5ed84
--- /dev/null
+++ b/openssl/asn1/asn1_locl.h
@@ -0,0 +1,132 @@
+/* asn1t.h */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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).
+ *
+ */
+
+/* Internal ASN1 structures and functions: not for application use */
+
+/* ASN1 print context structure */
+
+struct asn1_pctx_st {
+ unsigned long flags;
+ unsigned long nm_flags;
+ unsigned long cert_flags;
+ unsigned long oid_flags;
+ unsigned long str_flags;
+} /* ASN1_PCTX */ ;
+
+/* ASN1 public key method structure */
+
+struct evp_pkey_asn1_method_st {
+ int pkey_id;
+ int pkey_base_id;
+ unsigned long pkey_flags;
+ char *pem_str;
+ char *info;
+ int (*pub_decode) (EVP_PKEY *pk, X509_PUBKEY *pub);
+ int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk);
+ int (*pub_cmp) (const EVP_PKEY *a, const EVP_PKEY *b);
+ int (*pub_print) (BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx);
+ int (*priv_decode) (EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
+ int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
+ int (*priv_print) (BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx);
+ int (*pkey_size) (const EVP_PKEY *pk);
+ int (*pkey_bits) (const EVP_PKEY *pk);
+ int (*param_decode) (EVP_PKEY *pkey,
+ const unsigned char **pder, int derlen);
+ int (*param_encode) (const EVP_PKEY *pkey, unsigned char **pder);
+ int (*param_missing) (const EVP_PKEY *pk);
+ int (*param_copy) (EVP_PKEY *to, const EVP_PKEY *from);
+ int (*param_cmp) (const EVP_PKEY *a, const EVP_PKEY *b);
+ int (*param_print) (BIO *out, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *pctx);
+ int (*sig_print) (BIO *out,
+ const X509_ALGOR *sigalg, const ASN1_STRING *sig,
+ int indent, ASN1_PCTX *pctx);
+ void (*pkey_free) (EVP_PKEY *pkey);
+ int (*pkey_ctrl) (EVP_PKEY *pkey, int op, long arg1, void *arg2);
+ /* Legacy functions for old PEM */
+ int (*old_priv_decode) (EVP_PKEY *pkey,
+ const unsigned char **pder, int derlen);
+ int (*old_priv_encode) (const EVP_PKEY *pkey, unsigned char **pder);
+ /* Custom ASN1 signature verification */
+ int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+ X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey);
+ int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+ X509_ALGOR *alg1, X509_ALGOR *alg2,
+ ASN1_BIT_STRING *sig);
+} /* EVP_PKEY_ASN1_METHOD */ ;
+
+/*
+ * Method to handle CRL access. In general a CRL could be very large (several
+ * Mb) and can consume large amounts of resources if stored in memory by
+ * multiple processes. This method allows general CRL operations to be
+ * redirected to more efficient callbacks: for example a CRL entry database.
+ */
+
+#define X509_CRL_METHOD_DYNAMIC 1
+
+struct x509_crl_method_st {
+ int flags;
+ int (*crl_init) (X509_CRL *crl);
+ int (*crl_free) (X509_CRL *crl);
+ int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret,
+ ASN1_INTEGER *ser, X509_NAME *issuer);
+ int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk);
+};
diff --git a/openssl/asn1/asn1t.h b/openssl/asn1/asn1t.h
new file mode 100644
index 0000000..99bc0ee
--- /dev/null
+++ b/openssl/asn1/asn1t.h
@@ -0,0 +1,973 @@
+/* asn1t.h */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 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).
+ *
+ */
+#ifndef HEADER_ASN1T_H
+# define HEADER_ASN1T_H
+
+# include <stddef.h>
+# include <openssl/e_os2.h>
+# include <openssl/asn1.h>
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+/* ASN1 template defines, structures and functions */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+# define ASN1_ITEM_start(itname) \
+ OPENSSL_GLOBAL const ASN1_ITEM itname##_it = {
+
+# define ASN1_ITEM_end(itname) \
+ };
+
+# else
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr()))
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+# define ASN1_ITEM_start(itname) \
+ const ASN1_ITEM * itname##_it(void) \
+ { \
+ static const ASN1_ITEM local_it = {
+
+# define ASN1_ITEM_end(itname) \
+ }; \
+ return &local_it; \
+ }
+
+# endif
+
+/* Macros to aid ASN1 template writing */
+
+# define ASN1_ITEM_TEMPLATE(tname) \
+ static const ASN1_TEMPLATE tname##_item_tt
+
+# define ASN1_ITEM_TEMPLATE_END(tname) \
+ ;\
+ ASN1_ITEM_start(tname) \
+ ASN1_ITYPE_PRIMITIVE,\
+ -1,\
+ &tname##_item_tt,\
+ 0,\
+ NULL,\
+ 0,\
+ #tname \
+ ASN1_ITEM_end(tname)
+
+/* This is a ASN1 type which just embeds a template */
+
+/*-
+ * This pair helps declare a SEQUENCE. We can do:
+ *
+ * ASN1_SEQUENCE(stname) = {
+ * ... SEQUENCE components ...
+ * } ASN1_SEQUENCE_END(stname)
+ *
+ * This will produce an ASN1_ITEM called stname_it
+ * for a structure called stname.
+ *
+ * If you want the same structure but a different
+ * name then use:
+ *
+ * ASN1_SEQUENCE(itname) = {
+ * ... SEQUENCE components ...
+ * } ASN1_SEQUENCE_END_name(stname, itname)
+ *
+ * This will create an item called itname_it using
+ * a structure called stname.
+ */
+
+# define ASN1_SEQUENCE(tname) \
+ static const ASN1_TEMPLATE tname##_seq_tt[]
+
+# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
+
+# define ASN1_SEQUENCE_END_name(stname, tname) \
+ ;\
+ ASN1_ITEM_start(tname) \
+ ASN1_ITYPE_SEQUENCE,\
+ V_ASN1_SEQUENCE,\
+ tname##_seq_tt,\
+ sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+ NULL,\
+ sizeof(stname),\
+ #stname \
+ ASN1_ITEM_end(tname)
+
+# define ASN1_NDEF_SEQUENCE(tname) \
+ ASN1_SEQUENCE(tname)
+
+# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \
+ ASN1_SEQUENCE_cb(tname, cb)
+
+# define ASN1_SEQUENCE_cb(tname, cb) \
+ static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+ ASN1_SEQUENCE(tname)
+
+# define ASN1_BROKEN_SEQUENCE(tname) \
+ static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
+ ASN1_SEQUENCE(tname)
+
+# define ASN1_SEQUENCE_ref(tname, cb, lck) \
+ 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) \
+ 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)
+
+# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+
+# define ASN1_SEQUENCE_END_ref(stname, tname) \
+ ;\
+ ASN1_ITEM_start(tname) \
+ ASN1_ITYPE_SEQUENCE,\
+ V_ASN1_SEQUENCE,\
+ tname##_seq_tt,\
+ sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+ &tname##_aux,\
+ sizeof(stname),\
+ #stname \
+ ASN1_ITEM_end(tname)
+
+# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
+ ;\
+ ASN1_ITEM_start(tname) \
+ ASN1_ITYPE_NDEF_SEQUENCE,\
+ V_ASN1_SEQUENCE,\
+ tname##_seq_tt,\
+ sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+ &tname##_aux,\
+ sizeof(stname),\
+ #stname \
+ ASN1_ITEM_end(tname)
+
+/*-
+ * This pair helps declare a CHOICE type. We can do:
+ *
+ * ASN1_CHOICE(chname) = {
+ * ... CHOICE options ...
+ * ASN1_CHOICE_END(chname)
+ *
+ * This will produce an ASN1_ITEM called chname_it
+ * for a structure called chname. The structure
+ * definition must look like this:
+ * typedef struct {
+ * int type;
+ * union {
+ * ASN1_SOMETHING *opt1;
+ * ASN1_SOMEOTHER *opt2;
+ * } value;
+ * } chname;
+ *
+ * the name of the selector must be 'type'.
+ * to use an alternative selector name use the
+ * ASN1_CHOICE_END_selector() version.
+ */
+
+# define ASN1_CHOICE(tname) \
+ static const ASN1_TEMPLATE tname##_ch_tt[]
+
+# define ASN1_CHOICE_cb(tname, cb) \
+ 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)
+
+# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
+
+# define ASN1_CHOICE_END_selector(stname, tname, selname) \
+ ;\
+ ASN1_ITEM_start(tname) \
+ ASN1_ITYPE_CHOICE,\
+ offsetof(stname,selname) ,\
+ tname##_ch_tt,\
+ sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+ NULL,\
+ sizeof(stname),\
+ #stname \
+ ASN1_ITEM_end(tname)
+
+# define ASN1_CHOICE_END_cb(stname, tname, selname) \
+ ;\
+ ASN1_ITEM_start(tname) \
+ ASN1_ITYPE_CHOICE,\
+ offsetof(stname,selname) ,\
+ tname##_ch_tt,\
+ sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+ &tname##_aux,\
+ sizeof(stname),\
+ #stname \
+ ASN1_ITEM_end(tname)
+
+/* This helps with the template wrapper form of ASN1_ITEM */
+
+# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
+ (flags), (tag), 0,\
+ #name, ASN1_ITEM_ref(type) }
+
+/* These help with SEQUENCE or CHOICE components */
+
+/* used to declare other types */
+
+# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
+ (flags), (tag), offsetof(stname, field),\
+ #field, ASN1_ITEM_ref(type) }
+
+/* used when the structure is combined with the parent */
+
+# define ASN1_EX_COMBINE(flags, tag, type) { \
+ (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) }
+
+/* implicit and explicit helper macros */
+
+# define ASN1_IMP_EX(stname, field, type, tag, ex) \
+ ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)
+
+# define ASN1_EXP_EX(stname, field, type, tag, ex) \
+ ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)
+
+/* Any defined by macros: the field used is in the table itself */
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+# else
+# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
+# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
+# endif
+/* Plain simple type */
+# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
+
+/* OPTIONAL simple type */
+# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* IMPLICIT tagged simple type */
+# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
+
+/* IMPLICIT tagged OPTIONAL simple type */
+# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* Same as above but EXPLICIT */
+
+# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
+# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* SEQUENCE OF type */
+# define ASN1_SEQUENCE_OF(stname, field, type) \
+ ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
+
+/* OPTIONAL SEQUENCE OF */
+# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
+ ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Same as above but for SET OF */
+
+# define ASN1_SET_OF(stname, field, type) \
+ ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
+
+# define ASN1_SET_OF_OPT(stname, field, type) \
+ ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
+
+# define ASN1_IMP_SET_OF(stname, field, type, tag) \
+ ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+# define ASN1_EXP_SET_OF(stname, field, type, tag) \
+ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
+ ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
+ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
+ ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+ ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
+ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+# 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 using indefinite length constructed form */
+# define ASN1_NDEF_EXP(stname, field, type, tag) \
+ ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF)
+
+/* 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) \
+ static const ASN1_ADB_TABLE name##_adbtbl[]
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+# define ASN1_ADB_END(name, flags, field, app_table, def, none) \
+ ;\
+ static const ASN1_ADB name##_adb = {\
+ flags,\
+ offsetof(name, field),\
+ app_table,\
+ name##_adbtbl,\
+ sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+ def,\
+ none\
+ }
+
+# else
+
+# define ASN1_ADB_END(name, flags, field, app_table, def, none) \
+ ;\
+ static const ASN1_ITEM *name##_adb(void) \
+ { \
+ static const ASN1_ADB internal_adb = \
+ {\
+ flags,\
+ offsetof(name, field),\
+ app_table,\
+ name##_adbtbl,\
+ sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+ def,\
+ none\
+ }; \
+ return (const ASN1_ITEM *) &internal_adb; \
+ } \
+ void dummy_function(void)
+
+# endif
+
+# define ADB_ENTRY(val, template) {val, template}
+
+# define ASN1_ADB_TEMPLATE(name) \
+ static const ASN1_TEMPLATE name##_tt
+
+/*
+ * This is the ASN1 template structure that defines a wrapper round the
+ * actual type. It determines the actual position of the field in the value
+ * structure, various flags such as OPTIONAL and the field name.
+ */
+
+struct ASN1_TEMPLATE_st {
+ unsigned long flags; /* Various flags */
+ long tag; /* tag, not used if no tagging */
+ unsigned long offset; /* Offset of this field in structure */
+# ifndef NO_ASN1_FIELD_NAMES
+ const char *field_name; /* Field name */
+# endif
+ ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */
+};
+
+/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
+
+# define ASN1_TEMPLATE_item(t) (t->item_ptr)
+# define ASN1_TEMPLATE_adb(t) (t->item_ptr)
+
+typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
+typedef struct ASN1_ADB_st ASN1_ADB;
+
+struct ASN1_ADB_st {
+ unsigned long flags; /* Various flags */
+ unsigned long offset; /* Offset of selector field */
+ STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */
+ const ASN1_ADB_TABLE *tbl; /* Table of possible types */
+ long tblcount; /* Number of entries in tbl */
+ const ASN1_TEMPLATE *default_tt; /* Type to use if no match */
+ const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */
+};
+
+struct ASN1_ADB_TABLE_st {
+ long value; /* NID for an object or value for an int */
+ const ASN1_TEMPLATE tt; /* item for this value */
+};
+
+/* template flags */
+
+/* Field is optional */
+# define ASN1_TFLG_OPTIONAL (0x1)
+
+/* Field is a SET OF */
+# define ASN1_TFLG_SET_OF (0x1 << 1)
+
+/* Field is a SEQUENCE OF */
+# define ASN1_TFLG_SEQUENCE_OF (0x2 << 1)
+
+/*
+ * Special case: this refers to a SET OF that will be sorted into DER order
+ * when encoded *and* the corresponding STACK will be modified to match the
+ * new order.
+ */
+# define ASN1_TFLG_SET_ORDER (0x3 << 1)
+
+/* Mask for SET OF or SEQUENCE OF */
+# define ASN1_TFLG_SK_MASK (0x3 << 1)
+
+/*
+ * These flags mean the tag should be taken from the tag field. If EXPLICIT
+ * then the underlying type is used for the inner tag.
+ */
+
+/* IMPLICIT tagging */
+# define ASN1_TFLG_IMPTAG (0x1 << 3)
+
+/* EXPLICIT tagging, inner tag from underlying type */
+# define ASN1_TFLG_EXPTAG (0x2 << 3)
+
+# define ASN1_TFLG_TAG_MASK (0x3 << 3)
+
+/* context specific IMPLICIT */
+# define ASN1_TFLG_IMPLICIT ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT
+
+/* context specific EXPLICIT */
+# define ASN1_TFLG_EXPLICIT ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT
+
+/*
+ * If tagging is in force these determine the type of tag to use. Otherwise
+ * the tag is determined by the underlying type. These values reflect the
+ * actual octet format.
+ */
+
+/* Universal tag */
+# define ASN1_TFLG_UNIVERSAL (0x0<<6)
+/* Application tag */
+# define ASN1_TFLG_APPLICATION (0x1<<6)
+/* Context specific tag */
+# define ASN1_TFLG_CONTEXT (0x2<<6)
+/* Private tag */
+# define ASN1_TFLG_PRIVATE (0x3<<6)
+
+# define ASN1_TFLG_TAG_CLASS (0x3<<6)
+
+/*
+ * These are for ANY DEFINED BY type. In this case the 'item' field points to
+ * an ASN1_ADB structure which contains a table of values to decode the
+ * relevant type
+ */
+
+# define ASN1_TFLG_ADB_MASK (0x3<<8)
+
+# define ASN1_TFLG_ADB_OID (0x1<<8)
+
+# define ASN1_TFLG_ADB_INT (0x1<<9)
+
+/*
+ * This flag means a parent structure is passed instead of the field: this is
+ * useful is a SEQUENCE is being combined with a CHOICE for example. Since
+ * this means the structure and item name will differ we need to use the
+ * ASN1_CHOICE_END_name() macro for example.
+ */
+
+# 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 {
+ char itype; /* The item type, primitive, SEQUENCE, CHOICE
+ * or extern */
+ long utype; /* underlying type */
+ const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains
+ * the contents */
+ long tcount; /* Number of templates if SEQUENCE or CHOICE */
+ const void *funcs; /* functions that handle this type */
+ long size; /* Structure size (usually) */
+# ifndef NO_ASN1_FIELD_NAMES
+ const char *sname; /* Structure name */
+# endif
+};
+
+/*-
+ * These are values for the itype field and
+ * determine how the type is interpreted.
+ *
+ * For PRIMITIVE types the underlying type
+ * determines the behaviour if items is NULL.
+ *
+ * Otherwise templates must contain a single
+ * template and the type is treated in the
+ * same way as the type specified in the template.
+ *
+ * For SEQUENCE types the templates field points
+ * to the members, the size field is the
+ * structure size.
+ *
+ * For CHOICE types the templates field points
+ * to each possible member (typically a union)
+ * and the 'size' field is the offset of the
+ * selector.
+ *
+ * The 'funcs' field is used for application
+ * specific functions.
+ *
+ * For COMPAT types the funcs field gives a
+ * set of functions that handle this type, this
+ * supports the old d2i, i2d convention.
+ *
+ * The EXTERN type uses a new style d2i/i2d.
+ * The new style should be used where possible
+ * because it avoids things like the d2i IMPLICIT
+ * hack.
+ *
+ * MSTRING is a multiple string type, it is used
+ * for a CHOICE of character strings where the
+ * actual strings all occupy an ASN1_STRING
+ * structure. In this case the 'utype' field
+ * 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_SEQUENCE 0x1
+
+# define ASN1_ITYPE_CHOICE 0x2
+
+# define ASN1_ITYPE_COMPAT 0x3
+
+# define ASN1_ITYPE_EXTERN 0x4
+
+# 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
+ * like CHOICE
+ */
+
+struct ASN1_TLC_st {
+ char valid; /* Values below are valid */
+ int ret; /* return value */
+ long plen; /* length */
+ int ptag; /* class value */
+ int pclass; /* class value */
+ int hdrlen; /* header length */
+};
+
+/* Typedefs for ASN1 function pointers */
+
+typedef ASN1_VALUE *ASN1_new_func(void);
+typedef void ASN1_free_func(ASN1_VALUE *a);
+typedef ASN1_VALUE *ASN1_d2i_func(ASN1_VALUE **a, const unsigned char **in,
+ long length);
+typedef int ASN1_i2d_func(ASN1_VALUE *a, unsigned char **in);
+
+typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+ const ASN1_ITEM *it, int tag, int aclass, char opt,
+ ASN1_TLC *ctx);
+
+typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+ const ASN1_ITEM *it, int tag, int aclass);
+typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval,
+ int indent, const char *fname,
+ const ASN1_PCTX *pctx);
+
+typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont,
+ int *putype, const ASN1_ITEM *it);
+typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont,
+ int len, int utype, char *free_cont,
+ const ASN1_ITEM *it);
+typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval,
+ const ASN1_ITEM *it, int indent,
+ const ASN1_PCTX *pctx);
+
+typedef struct ASN1_COMPAT_FUNCS_st {
+ ASN1_new_func *asn1_new;
+ ASN1_free_func *asn1_free;
+ ASN1_d2i_func *asn1_d2i;
+ ASN1_i2d_func *asn1_i2d;
+} ASN1_COMPAT_FUNCS;
+
+typedef struct ASN1_EXTERN_FUNCS_st {
+ void *app_data;
+ ASN1_ex_new_func *asn1_ex_new;
+ ASN1_ex_free_func *asn1_ex_free;
+ ASN1_ex_free_func *asn1_ex_clear;
+ ASN1_ex_d2i *asn1_ex_d2i;
+ ASN1_ex_i2d *asn1_ex_i2d;
+ ASN1_ex_print_func *asn1_ex_print;
+} ASN1_EXTERN_FUNCS;
+
+typedef struct ASN1_PRIMITIVE_FUNCS_st {
+ void *app_data;
+ unsigned long flags;
+ ASN1_ex_new_func *prim_new;
+ ASN1_ex_free_func *prim_free;
+ ASN1_ex_free_func *prim_clear;
+ ASN1_primitive_c2i *prim_c2i;
+ ASN1_primitive_i2c *prim_i2c;
+ ASN1_primitive_print *prim_print;
+} ASN1_PRIMITIVE_FUNCS;
+
+/*
+ * This is the ASN1_AUX structure: it handles various miscellaneous
+ * requirements. For example the use of reference counts and an informational
+ * callback. The "informational callback" is called at various points during
+ * the ASN1 encoding and decoding. It can be used to provide minor
+ * customisation of the structures used. This is most useful where the
+ * supplied routines *almost* do the right thing but need some extra help at
+ * a few points. If the callback returns zero then it is assumed a fatal
+ * error has occurred and the main operation should be abandoned. If major
+ * changes in the default behaviour are required then an external type is
+ * more appropriate.
+ */
+
+typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
+ void *exarg);
+
+typedef struct ASN1_AUX_st {
+ void *app_data;
+ int flags;
+ int ref_offset; /* Offset of reference value */
+ int ref_lock; /* Lock type to use */
+ ASN1_aux_cb *asn1_cb;
+ int enc_offset; /* Offset of ASN1_ENCODING structure */
+} ASN1_AUX;
+
+/* For print related callbacks exarg points to this structure */
+typedef struct ASN1_PRINT_ARG_st {
+ BIO *out;
+ int indent;
+ const ASN1_PCTX *pctx;
+} ASN1_PRINT_ARG;
+
+/* For streaming related callbacks exarg points to this structure */
+typedef struct ASN1_STREAM_ARG_st {
+ /* BIO to stream through */
+ BIO *out;
+ /* BIO with filters appended */
+ BIO *ndef_bio;
+ /* Streaming I/O boundary */
+ unsigned char **boundary;
+} ASN1_STREAM_ARG;
+
+/* Flags in ASN1_AUX */
+
+/* Use a reference count */
+# define ASN1_AFLG_REFCOUNT 1
+/* Save the encoding of structure (useful for signatures) */
+# define ASN1_AFLG_ENCODING 2
+/* The Sequence length is invalid */
+# define ASN1_AFLG_BROKEN 4
+
+/* operation values for asn1_cb */
+
+# define ASN1_OP_NEW_PRE 0
+# define ASN1_OP_NEW_POST 1
+# define ASN1_OP_FREE_PRE 2
+# define ASN1_OP_FREE_POST 3
+# define ASN1_OP_D2I_PRE 4
+# define ASN1_OP_D2I_POST 5
+# define ASN1_OP_I2D_PRE 6
+# define ASN1_OP_I2D_POST 7
+# define ASN1_OP_PRINT_PRE 8
+# define ASN1_OP_PRINT_POST 9
+# define ASN1_OP_STREAM_PRE 10
+# define ASN1_OP_STREAM_POST 11
+# define ASN1_OP_DETACHED_PRE 12
+# define ASN1_OP_DETACHED_POST 13
+
+/* Macro to implement a primitive type */
+# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
+# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
+ ASN1_ITEM_start(itname) \
+ ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
+ ASN1_ITEM_end(itname)
+
+/* Macro to implement a multi string type */
+# define IMPLEMENT_ASN1_MSTRING(itname, mask) \
+ ASN1_ITEM_start(itname) \
+ ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
+ ASN1_ITEM_end(itname)
+
+/* Macro to implement an ASN1_ITEM in terms of old style funcs */
+
+# define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)
+
+# define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \
+ static const ASN1_COMPAT_FUNCS sname##_ff = { \
+ (ASN1_new_func *)sname##_new, \
+ (ASN1_free_func *)sname##_free, \
+ (ASN1_d2i_func *)d2i_##sname, \
+ (ASN1_i2d_func *)i2d_##sname, \
+ }; \
+ ASN1_ITEM_start(sname) \
+ ASN1_ITYPE_COMPAT, \
+ tag, \
+ NULL, \
+ 0, \
+ &sname##_ff, \
+ 0, \
+ #sname \
+ ASN1_ITEM_end(sname)
+
+# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
+ ASN1_ITEM_start(sname) \
+ ASN1_ITYPE_EXTERN, \
+ tag, \
+ NULL, \
+ 0, \
+ &fptrs, \
+ 0, \
+ #sname \
+ ASN1_ITEM_end(sname)
+
+/* Macro to implement standard functions in terms of ASN1_ITEM structures */
+
+# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
+
+# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
+
+# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
+ IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
+
+# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
+ IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)
+
+# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
+ IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
+
+# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
+ pre stname *fname##_new(void) \
+ { \
+ return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+ } \
+ pre void fname##_free(stname *a) \
+ { \
+ ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+ }
+
+# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
+ stname *fname##_new(void) \
+ { \
+ return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+ } \
+ void fname##_free(stname *a) \
+ { \
+ ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+ }
+
+# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
+ IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+ IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+ stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+ { \
+ return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+ } \
+ int i2d_##fname(stname *a, unsigned char **out) \
+ { \
+ 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.
+ */
+# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+ stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+ { \
+ return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+ } \
+ int i2d_##fname(const stname *a, unsigned char **out) \
+ { \
+ return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
+ }
+
+# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
+ stname * stname##_dup(stname *x) \
+ { \
+ return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
+ }
+
+# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
+ IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
+
+# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
+ int fname##_print_ctx(BIO *out, stname *x, int indent, \
+ const ASN1_PCTX *pctx) \
+ { \
+ return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
+ ASN1_ITEM_rptr(itname), pctx); \
+ }
+
+# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
+ IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
+
+# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
+ IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+ IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+/* external definitions for primitive types */
+
+DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_SEQUENCE)
+DECLARE_ASN1_ITEM(CBIGNUM)
+DECLARE_ASN1_ITEM(BIGNUM)
+DECLARE_ASN1_ITEM(LONG)
+DECLARE_ASN1_ITEM(ZLONG)
+
+DECLARE_STACK_OF(ASN1_VALUE)
+
+/* Functions used internally by the ASN1 code */
+
+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+ const ASN1_TEMPLATE *tt);
+int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+ const ASN1_ITEM *it, int tag, int aclass, char opt,
+ ASN1_TLC *ctx);
+
+int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+ const ASN1_ITEM *it, int tag, int aclass);
+int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
+ const ASN1_TEMPLATE *tt);
+void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+ const ASN1_ITEM *it);
+int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+ int utype, char *free_cont, const ASN1_ITEM *it);
+
+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
+ const ASN1_ITEM *it);
+
+ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
+ int nullerr);
+
+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
+
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
+ const ASN1_ITEM *it);
+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
+ const ASN1_ITEM *it);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/asn1t.h b/openssl/asn1t.h
new file mode 120000
index 0000000..6db3836
--- /dev/null
+++ b/openssl/asn1t.h
@@ -0,0 +1 @@
+asn1/asn1t.h
\ No newline at end of file
diff --git a/openssl/bio.h b/openssl/bio.h
new file mode 120000
index 0000000..29d2761
--- /dev/null
+++ b/openssl/bio.h
@@ -0,0 +1 @@
+bio/bio.h
\ No newline at end of file
diff --git a/openssl/bio/bio.h b/openssl/bio/bio.h
new file mode 100644
index 0000000..be9cd0e
--- /dev/null
+++ b/openssl/bio/bio.h
@@ -0,0 +1,875 @@
+/* crypto/bio/bio.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BIO_H
+# define HEADER_BIO_H
+
+# include <openssl/e_os2.h>
+
+# ifndef OPENSSL_NO_FP_API
+# include <stdio.h>
+# endif
+# include <stdarg.h>
+
+# include <openssl/crypto.h>
+
+# ifndef OPENSSL_NO_SCTP
+# ifndef OPENSSL_SYS_VMS
+# include <stdint.h>
+# else
+# include <inttypes.h>
+# endif
+# endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* These are the 'types' of BIOs */
+# define BIO_TYPE_NONE 0
+# define BIO_TYPE_MEM (1|0x0400)
+# define BIO_TYPE_FILE (2|0x0400)
+
+# define BIO_TYPE_FD (4|0x0400|0x0100)
+# define BIO_TYPE_SOCKET (5|0x0400|0x0100)
+# define BIO_TYPE_NULL (6|0x0400)
+# define BIO_TYPE_SSL (7|0x0200)
+# define BIO_TYPE_MD (8|0x0200)/* passive filter */
+# define BIO_TYPE_BUFFER (9|0x0200)/* filter */
+# define BIO_TYPE_CIPHER (10|0x0200)/* filter */
+# define BIO_TYPE_BASE64 (11|0x0200)/* filter */
+# define BIO_TYPE_CONNECT (12|0x0400|0x0100)/* socket - connect */
+# define BIO_TYPE_ACCEPT (13|0x0400|0x0100)/* socket for accept */
+# define BIO_TYPE_PROXY_CLIENT (14|0x0200)/* client proxy BIO */
+# define BIO_TYPE_PROXY_SERVER (15|0x0200)/* server proxy BIO */
+# define BIO_TYPE_NBIO_TEST (16|0x0200)/* server proxy BIO */
+# define BIO_TYPE_NULL_FILTER (17|0x0200)
+# define BIO_TYPE_BER (18|0x0200)/* BER -> bin filter */
+# define BIO_TYPE_BIO (19|0x0400)/* (half a) BIO pair */
+# define BIO_TYPE_LINEBUFFER (20|0x0200)/* filter */
+# define BIO_TYPE_DGRAM (21|0x0400|0x0100)
+# ifndef OPENSSL_NO_SCTP
+# define BIO_TYPE_DGRAM_SCTP (24|0x0400|0x0100)
+# endif
+# define BIO_TYPE_ASN1 (22|0x0200)/* filter */
+# define BIO_TYPE_COMP (23|0x0200)/* filter */
+
+# define BIO_TYPE_DESCRIPTOR 0x0100/* socket, fd, connect or accept */
+# define BIO_TYPE_FILTER 0x0200
+# define BIO_TYPE_SOURCE_SINK 0x0400
+
+/*
+ * BIO_FILENAME_READ|BIO_CLOSE to open or close on free.
+ * BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ */
+# define BIO_NOCLOSE 0x00
+# define BIO_CLOSE 0x01
+
+/*
+ * These are used in the following macros and are passed to BIO_ctrl()
+ */
+# define BIO_CTRL_RESET 1/* opt - rewind/zero etc */
+# define BIO_CTRL_EOF 2/* opt - are we at the eof */
+# define BIO_CTRL_INFO 3/* opt - extra tit-bits */
+# define BIO_CTRL_SET 4/* man - set the 'IO' type */
+# define BIO_CTRL_GET 5/* man - get the 'IO' type */
+# define BIO_CTRL_PUSH 6/* opt - internal, used to signify change */
+# define BIO_CTRL_POP 7/* opt - internal, used to signify change */
+# define BIO_CTRL_GET_CLOSE 8/* man - set the 'close' on free */
+# define BIO_CTRL_SET_CLOSE 9/* man - set the 'close' on free */
+# define BIO_CTRL_PENDING 10/* opt - is their more data buffered */
+# define BIO_CTRL_FLUSH 11/* opt - 'flush' buffered output */
+# define BIO_CTRL_DUP 12/* man - extra stuff for 'duped' BIO */
+# define BIO_CTRL_WPENDING 13/* opt - number of bytes still to write */
+/* callback is int cb(BIO *bio,state,ret); */
+# define BIO_CTRL_SET_CALLBACK 14/* opt - set callback function */
+# define BIO_CTRL_GET_CALLBACK 15/* opt - set callback function */
+
+# define BIO_CTRL_SET_FILENAME 30/* BIO_s_file special */
+
+/* dgram BIO stuff */
+# define BIO_CTRL_DGRAM_CONNECT 31/* BIO dgram special */
+# define BIO_CTRL_DGRAM_SET_CONNECTED 32/* allow for an externally connected
+ * socket to be passed in */
+# define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33/* setsockopt, essentially */
+# define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34/* getsockopt, essentially */
+# define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35/* setsockopt, essentially */
+# define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36/* getsockopt, essentially */
+
+# define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37/* flag whether the last */
+# define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38/* I/O operation tiemd out */
+
+/* #ifdef IP_MTU_DISCOVER */
+# define BIO_CTRL_DGRAM_MTU_DISCOVER 39/* set DF bit on egress packets */
+/* #endif */
+
+# define BIO_CTRL_DGRAM_QUERY_MTU 40/* as kernel for current MTU */
+# define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47
+# define BIO_CTRL_DGRAM_GET_MTU 41/* get cached value for MTU */
+# define BIO_CTRL_DGRAM_SET_MTU 42/* set cached value for MTU.
+ * want to use this if asking
+ * the kernel fails */
+
+# define BIO_CTRL_DGRAM_MTU_EXCEEDED 43/* check whether the MTU was
+ * exceed in the previous write
+ * operation */
+
+# define BIO_CTRL_DGRAM_GET_PEER 46
+# define BIO_CTRL_DGRAM_SET_PEER 44/* Destination for the data */
+
+# define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45/* Next DTLS handshake timeout
+ * to adjust socket timeouts */
+
+# define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD 49
+
+# ifndef OPENSSL_NO_SCTP
+/* SCTP stuff */
+# define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50
+# define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY 51
+# define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY 52
+# define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD 53
+# define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO 60
+# define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO 61
+# define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO 62
+# define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO 63
+# define BIO_CTRL_DGRAM_SCTP_GET_PRINFO 64
+# define BIO_CTRL_DGRAM_SCTP_SET_PRINFO 65
+# define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN 70
+# endif
+
+/* modifiers */
+# define BIO_FP_READ 0x02
+# define BIO_FP_WRITE 0x04
+# define BIO_FP_APPEND 0x08
+# define BIO_FP_TEXT 0x10
+
+# define BIO_FLAGS_READ 0x01
+# define BIO_FLAGS_WRITE 0x02
+# define BIO_FLAGS_IO_SPECIAL 0x04
+# define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
+# define BIO_FLAGS_SHOULD_RETRY 0x08
+# ifndef BIO_FLAGS_UPLINK
+/*
+ * "UPLINK" flag denotes file descriptors provided by application. It
+ * defaults to 0, as most platforms don't require UPLINK interface.
+ */
+# define BIO_FLAGS_UPLINK 0
+# endif
+
+/* Used in BIO_gethostbyname() */
+# define BIO_GHBN_CTRL_HITS 1
+# define BIO_GHBN_CTRL_MISSES 2
+# define BIO_GHBN_CTRL_CACHE_SIZE 3
+# define BIO_GHBN_CTRL_GET_ENTRY 4
+# define BIO_GHBN_CTRL_FLUSH 5
+
+/* Mostly used in the SSL BIO */
+/*-
+ * Not used anymore
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20
+ * #define BIO_FLAGS_PROTOCOL_STARTUP 0x40
+ */
+
+# define BIO_FLAGS_BASE64_NO_NL 0x100
+
+/*
+ * This is used with memory BIOs: it means we shouldn't free up or change the
+ * data in any way.
+ */
+# define BIO_FLAGS_MEM_RDONLY 0x200
+
+typedef struct bio_st BIO;
+
+void BIO_set_flags(BIO *b, int flags);
+int BIO_test_flags(const BIO *b, int flags);
+void BIO_clear_flags(BIO *b, int flags);
+
+# define BIO_get_flags(b) BIO_test_flags(b, ~(0x0))
+# define BIO_set_retry_special(b) \
+ BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
+# define BIO_set_retry_read(b) \
+ BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
+# define BIO_set_retry_write(b) \
+ BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
+
+/* These are normally used internally in BIOs */
+# define BIO_clear_retry_flags(b) \
+ BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+# define BIO_get_retry_flags(b) \
+ BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+
+/* These should be used by the application to tell why we should retry */
+# define BIO_should_read(a) BIO_test_flags(a, BIO_FLAGS_READ)
+# define BIO_should_write(a) BIO_test_flags(a, BIO_FLAGS_WRITE)
+# define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL)
+# define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS)
+# define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY)
+
+/*
+ * The next three are used in conjunction with the BIO_should_io_special()
+ * condition. After this returns true, BIO *BIO_get_retry_BIO(BIO *bio, int
+ * *reason); will walk the BIO stack and return the 'reason' for the special
+ * and the offending BIO. Given a BIO, BIO_get_retry_reason(bio) will return
+ * the code.
+ */
+/*
+ * Returned from the SSL bio when the certificate retrieval code had an error
+ */
+# define BIO_RR_SSL_X509_LOOKUP 0x01
+/* Returned from the connect BIO when a connect would have blocked */
+# define BIO_RR_CONNECT 0x02
+/* Returned from the accept BIO when an accept would have blocked */
+# define BIO_RR_ACCEPT 0x03
+
+/* These are passed by the BIO callback */
+# define BIO_CB_FREE 0x01
+# define BIO_CB_READ 0x02
+# define BIO_CB_WRITE 0x03
+# define BIO_CB_PUTS 0x04
+# define BIO_CB_GETS 0x05
+# define BIO_CB_CTRL 0x06
+
+/*
+ * The callback is called before and after the underling operation, The
+ * BIO_CB_RETURN flag indicates if it is after the call
+ */
+# define BIO_CB_RETURN 0x80
+# define BIO_CB_return(a) ((a)|BIO_CB_RETURN))
+# define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN))
+# define BIO_cb_post(a) ((a)&BIO_CB_RETURN)
+
+long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *,
+ int, long, long);
+void BIO_set_callback(BIO *b,
+ long (*callback) (struct bio_st *, int, const char *,
+ int, long, long));
+char *BIO_get_callback_arg(const BIO *b);
+void BIO_set_callback_arg(BIO *b, char *arg);
+
+const char *BIO_method_name(const BIO *b);
+int BIO_method_type(const BIO *b);
+
+typedef void bio_info_cb (struct bio_st *, int, const char *, int, long,
+ long);
+
+typedef struct bio_method_st {
+ int type;
+ const char *name;
+ int (*bwrite) (BIO *, const char *, int);
+ int (*bread) (BIO *, char *, int);
+ int (*bputs) (BIO *, const char *);
+ int (*bgets) (BIO *, char *, int);
+ long (*ctrl) (BIO *, int, long, void *);
+ int (*create) (BIO *);
+ int (*destroy) (BIO *);
+ long (*callback_ctrl) (BIO *, int, bio_info_cb *);
+} BIO_METHOD;
+
+struct bio_st {
+ BIO_METHOD *method;
+ /* bio, mode, argp, argi, argl, ret */
+ long (*callback) (struct bio_st *, int, const char *, int, long, long);
+ char *cb_arg; /* first argument for the callback */
+ int init;
+ int shutdown;
+ int flags; /* extra storage */
+ int retry_reason;
+ int num;
+ void *ptr;
+ struct bio_st *next_bio; /* used by filter BIOs */
+ struct bio_st *prev_bio; /* used by filter BIOs */
+ int references;
+ unsigned long num_read;
+ unsigned long num_write;
+ CRYPTO_EX_DATA ex_data;
+};
+
+DECLARE_STACK_OF(BIO)
+
+typedef struct bio_f_buffer_ctx_struct {
+ /*-
+ * Buffers are setup like this:
+ *
+ * <---------------------- size ----------------------->
+ * +---------------------------------------------------+
+ * | consumed | remaining | free space |
+ * +---------------------------------------------------+
+ * <-- off --><------- len ------->
+ */
+ /*- BIO *bio; *//*
+ * this is now in the BIO struct
+ */
+ int ibuf_size; /* how big is the input buffer */
+ int obuf_size; /* how big is the output buffer */
+ char *ibuf; /* the char array */
+ int ibuf_len; /* how many bytes are in it */
+ int ibuf_off; /* write/read offset */
+ char *obuf; /* the char array */
+ int obuf_len; /* how many bytes are in it */
+ int obuf_off; /* write/read offset */
+} BIO_F_BUFFER_CTX;
+
+/* Prefix and suffix callback in ASN1 BIO */
+typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen,
+ void *parg);
+
+# ifndef OPENSSL_NO_SCTP
+/* SCTP parameter structs */
+struct bio_dgram_sctp_sndinfo {
+ uint16_t snd_sid;
+ uint16_t snd_flags;
+ uint32_t snd_ppid;
+ uint32_t snd_context;
+};
+
+struct bio_dgram_sctp_rcvinfo {
+ uint16_t rcv_sid;
+ uint16_t rcv_ssn;
+ uint16_t rcv_flags;
+ uint32_t rcv_ppid;
+ uint32_t rcv_tsn;
+ uint32_t rcv_cumtsn;
+ uint32_t rcv_context;
+};
+
+struct bio_dgram_sctp_prinfo {
+ uint16_t pr_policy;
+ uint32_t pr_value;
+};
+# endif
+
+/* connect BIO stuff */
+# define BIO_CONN_S_BEFORE 1
+# define BIO_CONN_S_GET_IP 2
+# define BIO_CONN_S_GET_PORT 3
+# define BIO_CONN_S_CREATE_SOCKET 4
+# define BIO_CONN_S_CONNECT 5
+# define BIO_CONN_S_OK 6
+# define BIO_CONN_S_BLOCKED_CONNECT 7
+# define BIO_CONN_S_NBIO 8
+/*
+ * #define BIO_CONN_get_param_hostname BIO_ctrl
+ */
+
+# define BIO_C_SET_CONNECT 100
+# define BIO_C_DO_STATE_MACHINE 101
+# define BIO_C_SET_NBIO 102
+# define BIO_C_SET_PROXY_PARAM 103
+# define BIO_C_SET_FD 104
+# define BIO_C_GET_FD 105
+# define BIO_C_SET_FILE_PTR 106
+# define BIO_C_GET_FILE_PTR 107
+# define BIO_C_SET_FILENAME 108
+# define BIO_C_SET_SSL 109
+# define BIO_C_GET_SSL 110
+# define BIO_C_SET_MD 111
+# define BIO_C_GET_MD 112
+# define BIO_C_GET_CIPHER_STATUS 113
+# define BIO_C_SET_BUF_MEM 114
+# define BIO_C_GET_BUF_MEM_PTR 115
+# define BIO_C_GET_BUFF_NUM_LINES 116
+# define BIO_C_SET_BUFF_SIZE 117
+# define BIO_C_SET_ACCEPT 118
+# define BIO_C_SSL_MODE 119
+# define BIO_C_GET_MD_CTX 120
+# define BIO_C_GET_PROXY_PARAM 121
+# define BIO_C_SET_BUFF_READ_DATA 122/* data to read first */
+# define BIO_C_GET_CONNECT 123
+# define BIO_C_GET_ACCEPT 124
+# define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125
+# define BIO_C_GET_SSL_NUM_RENEGOTIATES 126
+# define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127
+# define BIO_C_FILE_SEEK 128
+# define BIO_C_GET_CIPHER_CTX 129
+# define BIO_C_SET_BUF_MEM_EOF_RETURN 130/* return end of input
+ * value */
+# define BIO_C_SET_BIND_MODE 131
+# define BIO_C_GET_BIND_MODE 132
+# define BIO_C_FILE_TELL 133
+# define BIO_C_GET_SOCKS 134
+# define BIO_C_SET_SOCKS 135
+
+# define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */
+# define BIO_C_GET_WRITE_BUF_SIZE 137
+# define BIO_C_MAKE_BIO_PAIR 138
+# define BIO_C_DESTROY_BIO_PAIR 139
+# define BIO_C_GET_WRITE_GUARANTEE 140
+# define BIO_C_GET_READ_REQUEST 141
+# define BIO_C_SHUTDOWN_WR 142
+# define BIO_C_NREAD0 143
+# define BIO_C_NREAD 144
+# define BIO_C_NWRITE0 145
+# define BIO_C_NWRITE 146
+# define BIO_C_RESET_READ_REQUEST 147
+# define BIO_C_SET_MD_CTX 148
+
+# define BIO_C_SET_PREFIX 149
+# define BIO_C_GET_PREFIX 150
+# define BIO_C_SET_SUFFIX 151
+# define BIO_C_GET_SUFFIX 152
+
+# define BIO_C_SET_EX_ARG 153
+# define BIO_C_GET_EX_ARG 154
+
+# define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg)
+# define BIO_get_app_data(s) BIO_get_ex_data(s,0)
+
+/* BIO_s_connect() and BIO_s_socks4a_connect() */
+# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
+# define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
+# define BIO_set_conn_ip(b,ip) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip)
+# define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port)
+# define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)
+# define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)
+# define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)
+# define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3,0)
+
+# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
+
+/* BIO_s_accept_socket() */
+# define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
+# define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)
+/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
+# define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL)
+# define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio)
+
+# define BIO_BIND_NORMAL 0
+# define BIO_BIND_REUSEADDR_IF_UNUSED 1
+# define BIO_BIND_REUSEADDR 2
+# define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
+# define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)
+
+# define BIO_do_connect(b) BIO_do_handshake(b)
+# define BIO_do_accept(b) BIO_do_handshake(b)
+# define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)
+
+/* BIO_s_proxy_client() */
+# define BIO_set_url(b,url) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url))
+# define BIO_set_proxies(b,p) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p))
+/* BIO_set_nbio(b,n) */
+# define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s))
+/* BIO *BIO_get_filter_bio(BIO *bio); */
+# define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)()))
+# define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk)
+# define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool)
+
+# define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp)
+# define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p))
+# define BIO_get_url(b,url) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url))
+# define BIO_get_no_connect_return(b) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL)
+
+# define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
+# define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c)
+
+# define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)
+# define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp)
+
+# define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
+# define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)
+
+/*
+ * name is cast to lose const, but might be better to route through a
+ * function so we can do it safely
+ */
+# ifdef CONST_STRICT
+/*
+ * If you are wondering why this isn't defined, its because CONST_STRICT is
+ * purely a compile-time kludge to allow const to be checked.
+ */
+int BIO_read_filename(BIO *b, const char *name);
+# else
+# define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+ BIO_CLOSE|BIO_FP_READ,(char *)name)
+# endif
+# define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+ BIO_CLOSE|BIO_FP_WRITE,name)
+# define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+ BIO_CLOSE|BIO_FP_APPEND,name)
+# define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+ BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name)
+
+/*
+ * WARNING WARNING, this ups the reference count on the read bio of the SSL
+ * structure. This is because the ssl read BIO is now pointed to by the
+ * next_bio field in the bio. So when you free the BIO, make sure you are
+ * doing a BIO_free_all() to catch the underlying BIO.
+ */
+# define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
+# define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
+# define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
+# define BIO_set_ssl_renegotiate_bytes(b,num) \
+ BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL);
+# define BIO_get_num_renegotiates(b) \
+ BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL);
+# define BIO_set_ssl_renegotiate_timeout(b,seconds) \
+ BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL);
+
+/* defined in evp.h */
+/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */
+
+# define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
+# define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm)
+# define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp)
+# define BIO_set_mem_eof_return(b,v) \
+ BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL)
+
+/* For the BIO_f_buffer() type */
+# define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
+# define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
+# define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
+# define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
+# define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)
+
+/* Don't use the next one unless you know what you are doing :-) */
+# define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret))
+
+# define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL)
+# define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL)
+# define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL)
+# define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL)
+# define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
+# define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL)
+/* ...pending macros have inappropriate return type */
+size_t BIO_ctrl_pending(BIO *b);
+size_t BIO_ctrl_wpending(BIO *b);
+# define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
+# define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \
+ cbp)
+# define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb)
+
+/* For the BIO_f_buffer() type */
+# define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
+
+/* For BIO_s_bio() */
+# define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL)
+# define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL)
+# define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2)
+# define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL)
+# define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL)
+/* macros with inappropriate type -- but ...pending macros use int too: */
+# define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL)
+# define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL)
+size_t BIO_ctrl_get_write_guarantee(BIO *b);
+size_t BIO_ctrl_get_read_request(BIO *b);
+int BIO_ctrl_reset_read_request(BIO *b);
+
+/* ctrl macros for dgram */
+# define BIO_ctrl_dgram_connect(b,peer) \
+ (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer)
+# define BIO_ctrl_set_connected(b, state, peer) \
+ (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer)
+# define BIO_dgram_recv_timedout(b) \
+ (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL)
+# define BIO_dgram_send_timedout(b) \
+ (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL)
+# define BIO_dgram_get_peer(b,peer) \
+ (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer)
+# define BIO_dgram_set_peer(b,peer) \
+ (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
+# define BIO_dgram_get_mtu_overhead(b) \
+ (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL)
+
+/* These two aren't currently implemented */
+/* int BIO_get_ex_num(BIO *bio); */
+/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */
+int BIO_set_ex_data(BIO *bio, int idx, void *data);
+void *BIO_get_ex_data(BIO *bio, int idx);
+int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+unsigned long BIO_number_read(BIO *bio);
+unsigned long BIO_number_written(BIO *bio);
+
+/* For BIO_f_asn1() */
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
+ asn1_ps_func *prefix_free);
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
+ asn1_ps_func **pprefix_free);
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
+ asn1_ps_func *suffix_free);
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
+ asn1_ps_func **psuffix_free);
+
+# ifndef OPENSSL_NO_FP_API
+BIO_METHOD *BIO_s_file(void);
+BIO *BIO_new_file(const char *filename, const char *mode);
+BIO *BIO_new_fp(FILE *stream, int close_flag);
+# define BIO_s_file_internal BIO_s_file
+# endif
+BIO *BIO_new(BIO_METHOD *type);
+int BIO_set(BIO *a, BIO_METHOD *type);
+int BIO_free(BIO *a);
+void BIO_vfree(BIO *a);
+int BIO_read(BIO *b, void *data, int len);
+int BIO_gets(BIO *bp, char *buf, int size);
+int BIO_write(BIO *b, const void *data, int len);
+int BIO_puts(BIO *bp, const char *buf);
+int BIO_indent(BIO *b, int indent, int max);
+long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg);
+long BIO_callback_ctrl(BIO *b, int cmd,
+ void (*fp) (struct bio_st *, int, const char *, int,
+ long, long));
+char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg);
+long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg);
+BIO *BIO_push(BIO *b, BIO *append);
+BIO *BIO_pop(BIO *b);
+void BIO_free_all(BIO *a);
+BIO *BIO_find_type(BIO *b, int bio_type);
+BIO *BIO_next(BIO *b);
+BIO *BIO_get_retry_BIO(BIO *bio, int *reason);
+int BIO_get_retry_reason(BIO *bio);
+BIO *BIO_dup_chain(BIO *in);
+
+int BIO_nread0(BIO *bio, char **buf);
+int BIO_nread(BIO *bio, char **buf, int num);
+int BIO_nwrite0(BIO *bio, char **buf);
+int BIO_nwrite(BIO *bio, char **buf, int num);
+
+long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi,
+ long argl, long ret);
+
+BIO_METHOD *BIO_s_mem(void);
+BIO *BIO_new_mem_buf(void *buf, int len);
+BIO_METHOD *BIO_s_socket(void);
+BIO_METHOD *BIO_s_connect(void);
+BIO_METHOD *BIO_s_accept(void);
+BIO_METHOD *BIO_s_fd(void);
+# ifndef OPENSSL_SYS_OS2
+BIO_METHOD *BIO_s_log(void);
+# endif
+BIO_METHOD *BIO_s_bio(void);
+BIO_METHOD *BIO_s_null(void);
+BIO_METHOD *BIO_f_null(void);
+BIO_METHOD *BIO_f_buffer(void);
+# ifdef OPENSSL_SYS_VMS
+BIO_METHOD *BIO_f_linebuffer(void);
+# endif
+BIO_METHOD *BIO_f_nbio_test(void);
+# ifndef OPENSSL_NO_DGRAM
+BIO_METHOD *BIO_s_datagram(void);
+# ifndef OPENSSL_NO_SCTP
+BIO_METHOD *BIO_s_datagram_sctp(void);
+# endif
+# endif
+
+/* BIO_METHOD *BIO_f_ber(void); */
+
+int BIO_sock_should_retry(int i);
+int BIO_sock_non_fatal_error(int error);
+int BIO_dgram_non_fatal_error(int error);
+
+int BIO_fd_should_retry(int i);
+int BIO_fd_non_fatal_error(int error);
+int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u),
+ void *u, const char *s, int len);
+int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
+ void *u, const char *s, int len, int indent);
+int BIO_dump(BIO *b, const char *bytes, int len);
+int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent);
+# ifndef OPENSSL_NO_FP_API
+int BIO_dump_fp(FILE *fp, const char *s, int len);
+int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent);
+# endif
+struct hostent *BIO_gethostbyname(const char *name);
+/*-
+ * We might want a thread-safe interface too:
+ * struct hostent *BIO_gethostbyname_r(const char *name,
+ * struct hostent *result, void *buffer, size_t buflen);
+ * or something similar (caller allocates a struct hostent,
+ * pointed to by "result", and additional buffer space for the various
+ * substructures; if the buffer does not suffice, NULL is returned
+ * and an appropriate error code is set).
+ */
+int BIO_sock_error(int sock);
+int BIO_socket_ioctl(int fd, long type, void *arg);
+int BIO_socket_nbio(int fd, int mode);
+int BIO_get_port(const char *str, unsigned short *port_ptr);
+int BIO_get_host_ip(const char *str, unsigned char *ip);
+int BIO_get_accept_socket(char *host_port, int mode);
+int BIO_accept(int sock, char **ip_port);
+int BIO_sock_init(void);
+void BIO_sock_cleanup(void);
+int BIO_set_tcp_ndelay(int sock, int turn_on);
+
+BIO *BIO_new_socket(int sock, int close_flag);
+BIO *BIO_new_dgram(int fd, int close_flag);
+# ifndef OPENSSL_NO_SCTP
+BIO *BIO_new_dgram_sctp(int fd, int close_flag);
+int BIO_dgram_is_sctp(BIO *bio);
+int BIO_dgram_sctp_notification_cb(BIO *b,
+ void (*handle_notifications) (BIO *bio,
+ void
+ *context,
+ void *buf),
+ void *context);
+int BIO_dgram_sctp_wait_for_dry(BIO *b);
+int BIO_dgram_sctp_msg_waiting(BIO *b);
+# endif
+BIO *BIO_new_fd(int fd, int close_flag);
+BIO *BIO_new_connect(char *host_port);
+BIO *BIO_new_accept(char *host_port);
+
+int BIO_new_bio_pair(BIO **bio1, size_t writebuf1,
+ BIO **bio2, size_t writebuf2);
+/*
+ * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints.
+ * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default
+ * value.
+ */
+
+void BIO_copy_next_retry(BIO *b);
+
+/*
+ * long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);
+ */
+
+# ifdef __GNUC__
+# define __bio_h__attr__ __attribute__
+# else
+# define __bio_h__attr__(x)
+# endif
+int BIO_printf(BIO *bio, const char *format, ...)
+__bio_h__attr__((__format__(__printf__, 2, 3)));
+int BIO_vprintf(BIO *bio, const char *format, va_list args)
+__bio_h__attr__((__format__(__printf__, 2, 0)));
+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
+__bio_h__attr__((__format__(__printf__, 3, 4)));
+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+__bio_h__attr__((__format__(__printf__, 3, 0)));
+# undef __bio_h__attr__
+
+/* 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.
+ */
+void ERR_load_BIO_strings(void);
+
+/* Error codes for the BIO functions. */
+
+/* Function codes. */
+# define BIO_F_ACPT_STATE 100
+# define BIO_F_BIO_ACCEPT 101
+# define BIO_F_BIO_BER_GET_HEADER 102
+# define BIO_F_BIO_CALLBACK_CTRL 131
+# define BIO_F_BIO_CTRL 103
+# define BIO_F_BIO_GETHOSTBYNAME 120
+# define BIO_F_BIO_GETS 104
+# define BIO_F_BIO_GET_ACCEPT_SOCKET 105
+# define BIO_F_BIO_GET_HOST_IP 106
+# define BIO_F_BIO_GET_PORT 107
+# define BIO_F_BIO_MAKE_PAIR 121
+# define BIO_F_BIO_NEW 108
+# define BIO_F_BIO_NEW_FILE 109
+# define BIO_F_BIO_NEW_MEM_BUF 126
+# define BIO_F_BIO_NREAD 123
+# define BIO_F_BIO_NREAD0 124
+# define BIO_F_BIO_NWRITE 125
+# define BIO_F_BIO_NWRITE0 122
+# define BIO_F_BIO_PUTS 110
+# define BIO_F_BIO_READ 111
+# define BIO_F_BIO_SOCK_INIT 112
+# define BIO_F_BIO_WRITE 113
+# define BIO_F_BUFFER_CTRL 114
+# define BIO_F_CONN_CTRL 127
+# define BIO_F_CONN_STATE 115
+# define BIO_F_DGRAM_SCTP_READ 132
+# define BIO_F_DGRAM_SCTP_WRITE 133
+# define BIO_F_FILE_CTRL 116
+# define BIO_F_FILE_READ 130
+# define BIO_F_LINEBUFFER_CTRL 129
+# define BIO_F_MEM_READ 128
+# define BIO_F_MEM_WRITE 117
+# define BIO_F_SSL_NEW 118
+# define BIO_F_WSASTARTUP 119
+
+/* Reason codes. */
+# define BIO_R_ACCEPT_ERROR 100
+# define BIO_R_BAD_FOPEN_MODE 101
+# define BIO_R_BAD_HOSTNAME_LOOKUP 102
+# define BIO_R_BROKEN_PIPE 124
+# define BIO_R_CONNECT_ERROR 103
+# define BIO_R_EOF_ON_MEMORY_BIO 127
+# define BIO_R_ERROR_SETTING_NBIO 104
+# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET 105
+# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET 106
+# define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107
+# define BIO_R_INVALID_ARGUMENT 125
+# define BIO_R_INVALID_IP_ADDRESS 108
+# define BIO_R_IN_USE 123
+# define BIO_R_KEEPALIVE 109
+# define BIO_R_NBIO_CONNECT_ERROR 110
+# define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111
+# define BIO_R_NO_HOSTNAME_SPECIFIED 112
+# define BIO_R_NO_PORT_DEFINED 113
+# define BIO_R_NO_PORT_SPECIFIED 114
+# define BIO_R_NO_SUCH_FILE 128
+# define BIO_R_NULL_PARAMETER 115
+# define BIO_R_TAG_MISMATCH 116
+# define BIO_R_UNABLE_TO_BIND_SOCKET 117
+# define BIO_R_UNABLE_TO_CREATE_SOCKET 118
+# define BIO_R_UNABLE_TO_LISTEN_SOCKET 119
+# define BIO_R_UNINITIALIZED 120
+# define BIO_R_UNSUPPORTED_METHOD 121
+# define BIO_R_WRITE_TO_READ_ONLY_BIO 126
+# define BIO_R_WSASTARTUP 122
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/bn.h b/openssl/bn.h
new file mode 120000
index 0000000..f2bdae5
--- /dev/null
+++ b/openssl/bn.h
@@ -0,0 +1 @@
+bn/bn.h
\ No newline at end of file
diff --git a/openssl/bn/Makefile b/openssl/bn/Makefile
new file mode 100644
index 0000000..fb5d419
--- /dev/null
+++ b/openssl/bn/Makefile
@@ -0,0 +1,80 @@
+# Copyright 2010 by Nest Labs, Inc. All rights reserved.
+#
+# This program is confidential and proprietary to Nest Labs, Inc.,
+# and may not be reproduced, published or disclosed to others without
+# company authorization.
+#
+
+DEPTH = ../../
+
+include $(DEPTH)Makefile.config
+
+OUTDIR = $(OBJ_DIR)
+SRCDIR = ./
+INCDIR = ./
+
+OBJECT_FILES = \
+ 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 \
+ bn_asm \
+ bn_recp \
+ bn_mont \
+ bn_mpi \
+ bn_exp2 \
+ bn_gf2m \
+ bn_nist \
+ bn_depr \
+ bn_const
+
+ifeq ($(BN_MONT_ASM_TYPE), arm)
+OBJECT_FILES += bn_mont_mul
+endif
+
+HEADER_FILES = \
+ bn_lcl \
+ bn_prime
+
+OBJECTS = $(OBJECT_FILES:%=$(OUTDIR)/%.o)
+HEADERS = $(HEADER_FILES:%=$(INCDIR)/%.h)
+
+all: $(OUTDIR) $(LIB_DIR)/libbn.a
+
+$(OUTDIR):
+ $(MKDIR) $(OUTDIR)
+
+clean:
+ $(RM) $(OUTDIR)
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.c $(HEADERS)
+ $(CC) $(CFLAGS) -O2 -c -o $@ $<
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.cpp $(HEADERS)
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.S $(HEADERS)
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+$(OUTDIR)/libbn.a: $(OBJECTS)
+ $(ARCHIVE) $@ $(OBJECTS)
+ $(RANLIB) $@
+
+$(LIB_DIR)/libbn.a: $(OUTDIR)/libbn.a
+ $(MKDIR) $(dir $@)
+ $(CP) $< $@
+
diff --git a/openssl/bn/bn.h b/openssl/bn/bn.h
new file mode 100644
index 0000000..7d57e98
--- /dev/null
+++ b/openssl/bn/bn.h
@@ -0,0 +1,952 @@
+/* crypto/bn/bn.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 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 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
+
+# include <openssl/e_os2.h>
+# ifndef OPENSSL_NO_FP_API
+# include <stdio.h> /* FILE */
+# endif
+# include <openssl/ossl_typ.h>
+# include <openssl/crypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * These preprocessor symbols control various aspects of the bignum headers
+ * and library code. They're not defined by any "normal" configuration, as
+ * they are intended for development and testing purposes. NB: defining all
+ * three can be useful for debugging application code as well as openssl
+ * itself. BN_DEBUG - turn on various debugging alterations to the bignum
+ * code BN_DEBUG_RAND - uses random poisoning of unused words to trip up
+ * mismanagement of bignum internals. You must also define BN_DEBUG.
+ */
+/* #define BN_DEBUG */
+/* #define BN_DEBUG_RAND */
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+# define BN_MUL_COMBA
+# define BN_SQR_COMBA
+# define BN_RECURSION
+# endif
+
+/*
+ * This next option uses the C libraries (2 word)/(1 word) function. If it is
+ * not defined, I use my C version (which is slower). The reason for this
+ * flag is that when the particular C compiler library routine is used, and
+ * the library is linked with a different compiler, the library is missing.
+ * This mostly happens when the library is built with gcc and then linked
+ * using normal cc. This would be a common occurrence because gcc normally
+ * produces code that is 2 times faster than system compilers for the big
+ * number stuff. For machines with only one compiler (or shared libraries),
+ * this should be on. Again this in only really a problem on machines using
+ * "long long's", are 32bit, and are not using my assembler code.
+ */
+# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \
+ defined(OPENSSL_SYS_WIN32) || defined(linux)
+# ifndef BN_DIV2W
+# define BN_DIV2W
+# endif
+# endif
+
+/*
+ * assuming long is 64bit - this is the DEC Alpha unsigned long long is only
+ * 64 bits :-(, don't define BN_LLONG for the DEC Alpha
+ */
+# ifdef SIXTY_FOUR_BIT_LONG
+# define BN_ULLONG unsigned long long
+# define BN_ULONG unsigned long
+# define BN_LONG long
+# define BN_BITS 128
+# define BN_BYTES 8
+# define BN_BITS2 64
+# define BN_BITS4 32
+# define BN_MASK (0xffffffffffffffffffffffffffffffffLL)
+# define BN_MASK2 (0xffffffffffffffffL)
+# define BN_MASK2l (0xffffffffL)
+# define BN_MASK2h (0xffffffff00000000L)
+# define BN_MASK2h1 (0xffffffff80000000L)
+# define BN_TBIT (0x8000000000000000L)
+# define BN_DEC_CONV (10000000000000000000UL)
+# define BN_DEC_FMT1 "%lu"
+# define BN_DEC_FMT2 "%019lu"
+# define BN_DEC_NUM 19
+# define BN_HEX_FMT1 "%lX"
+# define BN_HEX_FMT2 "%016lX"
+# endif
+
+/*
+ * This is where the long long data type is 64 bits, but long is 32. For
+ * machines where there are 64bit registers, this is the mode to use. IRIX,
+ * on R4000 and above should use this mode, along with the relevant assembler
+ * code :-). Do NOT define BN_LLONG.
+ */
+# ifdef SIXTY_FOUR_BIT
+# undef BN_LLONG
+# undef BN_ULLONG
+# define BN_ULONG unsigned long long
+# define BN_LONG long long
+# define BN_BITS 128
+# define BN_BYTES 8
+# define BN_BITS2 64
+# define BN_BITS4 32
+# define BN_MASK2 (0xffffffffffffffffLL)
+# define BN_MASK2l (0xffffffffL)
+# define BN_MASK2h (0xffffffff00000000LL)
+# define BN_MASK2h1 (0xffffffff80000000LL)
+# define BN_TBIT (0x8000000000000000LL)
+# define BN_DEC_CONV (10000000000000000000ULL)
+# define BN_DEC_FMT1 "%llu"
+# define BN_DEC_FMT2 "%019llu"
+# define BN_DEC_NUM 19
+# define BN_HEX_FMT1 "%llX"
+# define BN_HEX_FMT2 "%016llX"
+# endif
+
+# ifdef THIRTY_TWO_BIT
+# ifdef BN_LLONG
+# if defined(_WIN32) && !defined(__GNUC__)
+# define BN_ULLONG unsigned __int64
+# define BN_MASK (0xffffffffffffffffI64)
+# else
+# define BN_ULLONG unsigned long long
+# define BN_MASK (0xffffffffffffffffLL)
+# endif
+# endif
+# define BN_ULONG unsigned int
+# define BN_LONG int
+# define BN_BITS 64
+# define BN_BYTES 4
+# define BN_BITS2 32
+# define BN_BITS4 16
+# define BN_MASK2 (0xffffffffL)
+# define BN_MASK2l (0xffff)
+# define BN_MASK2h1 (0xffff8000L)
+# define BN_MASK2h (0xffff0000L)
+# define BN_TBIT (0x80000000L)
+# define BN_DEC_CONV (1000000000L)
+# define BN_DEC_FMT1 "%u"
+# define BN_DEC_FMT2 "%09u"
+# define BN_DEC_NUM 9
+# define BN_HEX_FMT1 "%X"
+# define BN_HEX_FMT2 "%08X"
+# endif
+
+/*
+ * 2011-02-22 SMS. In various places, a size_t variable or a type cast to
+ * size_t was used to perform integer-only operations on pointers. This
+ * failed on VMS with 64-bit pointers (CC /POINTER_SIZE = 64) because size_t
+ * is still only 32 bits. What's needed in these cases is an integer type
+ * with the same size as a pointer, which size_t is not certain to be. The
+ * only fix here is VMS-specific.
+ */
+# if defined(OPENSSL_SYS_VMS)
+# if __INITIAL_POINTER_SIZE == 64
+# define PTR_SIZE_INT long long
+# else /* __INITIAL_POINTER_SIZE == 64 */
+# define PTR_SIZE_INT int
+# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
+# else /* defined(OPENSSL_SYS_VMS) */
+# define PTR_SIZE_INT size_t
+# endif /* defined(OPENSSL_SYS_VMS) [else] */
+
+# define BN_DEFAULT_BITS 1280
+
+# define BN_FLG_MALLOCED 0x01
+# define BN_FLG_STATIC_DATA 0x02
+
+/*
+ * avoid leaking exponent information through timing,
+ * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime,
+ * BN_div() will call BN_div_no_branch,
+ * BN_mod_inverse() will call BN_mod_inverse_no_branch.
+ */
+# define BN_FLG_CONSTTIME 0x04
+
+# ifdef OPENSSL_NO_DEPRECATED
+/* deprecated name for the flag */
+# define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME
+/*
+ * avoid leaking exponent information through timings
+ * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime)
+ */
+# endif
+
+# ifndef OPENSSL_NO_DEPRECATED
+# define BN_FLG_FREE 0x8000
+ /* used for debuging */
+# endif
+# define BN_set_flags(b,n) ((b)->flags|=(n))
+# define BN_get_flags(b,n) ((b)->flags&(n))
+
+/*
+ * get a clone of a BIGNUM with changed flags, for *temporary* use only (the
+ * two BIGNUMs cannot not be used in parallel!)
+ */
+# define BN_with_flags(dest,b,n) ((dest)->d=(b)->d, \
+ (dest)->top=(b)->top, \
+ (dest)->dmax=(b)->dmax, \
+ (dest)->neg=(b)->neg, \
+ (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \
+ | ((b)->flags & ~BN_FLG_MALLOCED) \
+ | BN_FLG_STATIC_DATA \
+ | (n)))
+
+/* Already declared in ossl_typ.h */
+# if 0
+typedef struct bignum_st BIGNUM;
+/* Used for temp variables (declaration hidden in bn_lcl.h) */
+typedef struct bignum_ctx BN_CTX;
+typedef struct bn_blinding_st BN_BLINDING;
+typedef struct bn_mont_ctx_st BN_MONT_CTX;
+typedef struct bn_recp_ctx_st BN_RECP_CTX;
+typedef struct bn_gencb_st BN_GENCB;
+# endif
+
+struct bignum_st {
+ BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit
+ * chunks. */
+ int top; /* Index of last used d +1. */
+ /* The next are internal book keeping for bn_expand. */
+ int dmax; /* Size of the d array. */
+ int neg; /* one if the number is negative */
+ int flags;
+};
+
+/* Used for montgomery multiplication */
+struct bn_mont_ctx_st {
+ int ri; /* number of bits in R */
+ BIGNUM RR; /* used to convert to montgomery form */
+ BIGNUM N; /* The modulus */
+ BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 (Ni is only
+ * stored for bignum algorithm) */
+ BN_ULONG n0[2]; /* least significant word(s) of Ni; (type
+ * changed with 0.9.9, was "BN_ULONG n0;"
+ * before) */
+ int flags;
+};
+
+/*
+ * Used for reciprocal division/mod functions It cannot be shared between
+ * threads
+ */
+struct bn_recp_ctx_st {
+ BIGNUM N; /* the divisor */
+ BIGNUM Nr; /* the reciprocal */
+ int num_bits;
+ int shift;
+ int flags;
+};
+
+/* Used for slow "generation" functions. */
+struct bn_gencb_st {
+ unsigned int ver; /* To handle binary (in)compatibility */
+ void *arg; /* callback-specific data */
+ union {
+ /* if(ver==1) - handles old style callbacks */
+ void (*cb_1) (int, int, void *);
+ /* if(ver==2) - new callback style */
+ int (*cb_2) (int, int, BN_GENCB *);
+ } cb;
+};
+/* Wrapper function to make using BN_GENCB easier, */
+int BN_GENCB_call(BN_GENCB *cb, int a, int b);
+/* Macro to populate a BN_GENCB structure with an "old"-style callback */
+# define BN_GENCB_set_old(gencb, callback, cb_arg) { \
+ BN_GENCB *tmp_gencb = (gencb); \
+ tmp_gencb->ver = 1; \
+ tmp_gencb->arg = (cb_arg); \
+ tmp_gencb->cb.cb_1 = (callback); }
+/* Macro to populate a BN_GENCB structure with a "new"-style callback */
+# define BN_GENCB_set(gencb, callback, cb_arg) { \
+ BN_GENCB *tmp_gencb = (gencb); \
+ tmp_gencb->ver = 2; \
+ tmp_gencb->arg = (cb_arg); \
+ tmp_gencb->cb.cb_2 = (callback); }
+
+# define BN_prime_checks 0 /* default: select number of iterations based
+ * on the size of the number */
+
+/*
+ * number of Miller-Rabin iterations for an error rate of less than 2^-80 for
+ * random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook of
+ * Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
+ * original paper: Damgaard, Landrock, Pomerance: Average case error
+ * estimates for the strong probable prime test. -- Math. Comp. 61 (1993)
+ * 177-194)
+ */
+# define BN_prime_checks_for_size(b) ((b) >= 1300 ? 2 : \
+ (b) >= 850 ? 3 : \
+ (b) >= 650 ? 4 : \
+ (b) >= 550 ? 5 : \
+ (b) >= 450 ? 6 : \
+ (b) >= 400 ? 7 : \
+ (b) >= 350 ? 8 : \
+ (b) >= 300 ? 9 : \
+ (b) >= 250 ? 12 : \
+ (b) >= 200 ? 15 : \
+ (b) >= 150 ? 18 : \
+ /* b >= 100 */ 27)
+
+# define BN_num_bytes(a) ((BN_num_bits(a)+7)/8)
+
+/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */
+# define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \
+ (((w) == 0) && ((a)->top == 0)))
+# define BN_is_zero(a) ((a)->top == 0)
+# define BN_is_one(a) (BN_abs_is_word((a),1) && !(a)->neg)
+# define BN_is_word(a,w) (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg))
+# define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1))
+
+# define BN_one(a) (BN_set_word((a),1))
+# define BN_zero_ex(a) \
+ do { \
+ BIGNUM *_tmp_bn = (a); \
+ _tmp_bn->top = 0; \
+ _tmp_bn->neg = 0; \
+ } while(0)
+# ifdef OPENSSL_NO_DEPRECATED
+# define BN_zero(a) BN_zero_ex(a)
+# else
+# define BN_zero(a) (BN_set_word((a),0))
+# endif
+
+const BIGNUM *BN_value_one(void);
+char *BN_options(void);
+BN_CTX *BN_CTX_new(void);
+# ifndef OPENSSL_NO_DEPRECATED
+void BN_CTX_init(BN_CTX *c);
+# endif
+void BN_CTX_free(BN_CTX *c);
+void BN_CTX_start(BN_CTX *ctx);
+BIGNUM *BN_CTX_get(BN_CTX *ctx);
+void BN_CTX_end(BN_CTX *ctx);
+int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
+int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom);
+int BN_rand_range(BIGNUM *rnd, const BIGNUM *range);
+int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range);
+int BN_num_bits(const BIGNUM *a);
+int BN_num_bits_word(BN_ULONG);
+BIGNUM *BN_new(void);
+void BN_init(BIGNUM *);
+void BN_clear_free(BIGNUM *a);
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+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);
+BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret);
+int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
+/** BN_set_negative sets sign of a BIGNUM
+ * \param b pointer to the BIGNUM object
+ * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise
+ */
+void BN_set_negative(BIGNUM *b, int n);
+/** BN_is_negative returns 1 if the BIGNUM is negative
+ * \param a pointer to the BIGNUM object
+ * \return 1 if a < 0 and 0 otherwise
+ */
+# define BN_is_negative(a) ((a)->neg != 0)
+
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+ BN_CTX *ctx);
+# define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx))
+int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx);
+int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *m);
+int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx);
+int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *m);
+int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx);
+int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m);
+int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
+ BN_CTX *ctx);
+int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m);
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+int BN_mul_word(BIGNUM *a, BN_ULONG w);
+int BN_add_word(BIGNUM *a, BN_ULONG w);
+int BN_sub_word(BIGNUM *a, BN_ULONG w);
+int BN_set_word(BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_get_word(const BIGNUM *a);
+
+int BN_cmp(const BIGNUM *a, const BIGNUM *b);
+void BN_free(BIGNUM *a);
+int BN_is_bit_set(const BIGNUM *a, int n);
+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+int BN_lshift1(BIGNUM *r, const BIGNUM *a);
+int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+
+int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *in_mont);
+int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
+ const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
+ BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+
+int BN_mask_bits(BIGNUM *a, int n);
+# ifndef OPENSSL_NO_FP_API
+int BN_print_fp(FILE *fp, const BIGNUM *a);
+# endif
+# ifdef HEADER_BIO_H
+int BN_print(BIO *fp, const BIGNUM *a);
+# else
+int BN_print(void *fp, const BIGNUM *a);
+# endif
+int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx);
+int BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
+int BN_rshift1(BIGNUM *r, const BIGNUM *a);
+void BN_clear(BIGNUM *a);
+BIGNUM *BN_dup(const BIGNUM *a);
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+int BN_set_bit(BIGNUM *a, int n);
+int BN_clear_bit(BIGNUM *a, int n);
+char *BN_bn2hex(const BIGNUM *a);
+char *BN_bn2dec(const BIGNUM *a);
+int BN_hex2bn(BIGNUM **a, const char *str);
+int BN_dec2bn(BIGNUM **a, const char *str);
+int BN_asc2bn(BIGNUM **a, const char *str);
+int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); /* returns
+ * -2 for
+ * error */
+BIGNUM *BN_mod_inverse(BIGNUM *ret,
+ const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+BIGNUM *BN_mod_sqrt(BIGNUM *ret,
+ const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+
+void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords);
+
+/* Deprecated versions */
+# ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
+ const BIGNUM *add, const BIGNUM *rem,
+ void (*callback) (int, int, void *), void *cb_arg);
+int BN_is_prime(const BIGNUM *p, int nchecks,
+ void (*callback) (int, int, void *),
+ BN_CTX *ctx, void *cb_arg);
+int BN_is_prime_fasttest(const BIGNUM *p, int nchecks,
+ void (*callback) (int, int, void *), BN_CTX *ctx,
+ void *cb_arg, int do_trial_division);
+# endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* Newer versions */
+int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
+ const BIGNUM *rem, BN_GENCB *cb);
+int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb);
+int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx,
+ int do_trial_division, BN_GENCB *cb);
+
+int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx);
+
+int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+ const BIGNUM *Xp, const BIGNUM *Xp1,
+ const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx,
+ BN_GENCB *cb);
+int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, BIGNUM *Xp1,
+ BIGNUM *Xp2, const BIGNUM *Xp, const BIGNUM *e,
+ BN_CTX *ctx, BN_GENCB *cb);
+
+BN_MONT_CTX *BN_MONT_CTX_new(void);
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
+int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ BN_MONT_CTX *mont, BN_CTX *ctx);
+# define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\
+ (r),(a),&((mont)->RR),(mont),(ctx))
+int BN_from_montgomery(BIGNUM *r, const BIGNUM *a,
+ BN_MONT_CTX *mont, BN_CTX *ctx);
+void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx);
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from);
+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
+ const BIGNUM *mod, BN_CTX *ctx);
+
+/* BN_BLINDING flags */
+# define BN_BLINDING_NO_UPDATE 0x00000001
+# define BN_BLINDING_NO_RECREATE 0x00000002
+
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
+void BN_BLINDING_free(BN_BLINDING *b);
+int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
+int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
+ BN_CTX *);
+# ifndef OPENSSL_NO_DEPRECATED
+unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
+void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
+# endif
+CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *);
+unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
+void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
+BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
+ const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
+ int (*bn_mod_exp) (BIGNUM *r,
+ const BIGNUM *a,
+ const BIGNUM *p,
+ const BIGNUM *m,
+ BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx),
+ BN_MONT_CTX *m_ctx);
+
+# ifndef OPENSSL_NO_DEPRECATED
+void BN_set_params(int mul, int high, int low, int mont);
+int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */
+# endif
+
+void BN_RECP_CTX_init(BN_RECP_CTX *recp);
+BN_RECP_CTX *BN_RECP_CTX_new(void);
+void BN_RECP_CTX_free(BN_RECP_CTX *recp);
+int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx);
+int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+ BN_RECP_CTX *recp, BN_CTX *ctx);
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+ BN_RECP_CTX *recp, BN_CTX *ctx);
+
+# ifndef OPENSSL_NO_EC2M
+
+/*
+ * 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.
+ */
+
+/*
+ * r = a + b
+ */
+int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+# define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b)
+/*
+ * r=a mod p
+ */
+int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p);
+/* r = (a * b) mod p */
+int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *p, BN_CTX *ctx);
+/* r = (a * a) mod p */
+int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+/* r = (1 / b) mod p */
+int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx);
+/* r = (a / 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 = sqrt(a) mod p */
+int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ BN_CTX *ctx);
+/* r^2 + r = a mod p */
+int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ BN_CTX *ctx);
+# 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.
+ */
+/* r = a mod p */
+int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]);
+/* r = (a * b) mod p */
+int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const int p[], BN_CTX *ctx);
+/* r = (a * a) mod p */
+int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
+ BN_CTX *ctx);
+/* r = (1 / b) mod p */
+int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[],
+ BN_CTX *ctx);
+/* r = (a / b) mod p */
+int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const 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 int p[], BN_CTX *ctx);
+/* r = sqrt(a) mod p */
+int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
+ const int p[], BN_CTX *ctx);
+/* r^2 + r = a mod p */
+int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
+ const int p[], BN_CTX *ctx);
+int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max);
+int BN_GF2m_arr2poly(const int p[], BIGNUM *a);
+
+# endif
+
+/*
+ * 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)?\
+ (a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2))
+# define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
+BIGNUM *bn_expand2(BIGNUM *a, int words);
+# ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */
+# endif
+
+/*-
+ * Bignum consistency macros
+ * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
+ * bignum data after direct manipulations on the data. There is also an
+ * "internal" macro, bn_check_top(), for verifying that there are no leading
+ * zeroes. Unfortunately, some auditing is required due to the fact that
+ * bn_fix_top() has become an overabused duct-tape because bignum data is
+ * occasionally passed around in an inconsistent state. So the following
+ * changes have been made to sort this out;
+ * - bn_fix_top()s implementation has been moved to bn_correct_top()
+ * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and
+ * bn_check_top() is as before.
+ * - if BN_DEBUG *is* defined;
+ * - bn_check_top() tries to pollute unused words even if the bignum 'top' is
+ * consistent. (ed: only if BN_DEBUG_RAND is defined)
+ * - bn_fix_top() maps to bn_check_top() rather than "fixing" anything.
+ * The idea is to have debug builds flag up inconsistent bignums when they
+ * occur. If that occurs in a bn_fix_top(), we examine the code in question; if
+ * the use of bn_fix_top() was appropriate (ie. it follows directly after code
+ * that manipulates the bignum) it is converted to bn_correct_top(), and if it
+ * was not appropriate, we convert it permanently to bn_check_top() and track
+ * down the cause of the bug. Eventually, no internal code should be using the
+ * bn_fix_top() macro. External applications and libraries should try this with
+ * their own code too, both in terms of building against the openssl headers
+ * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it
+ * defined. This not only improves external code, it provides more test
+ * coverage for openssl's own code.
+ */
+
+# ifdef BN_DEBUG
+
+/* We only need assert() when debugging */
+# include <assert.h>
+
+# ifdef BN_DEBUG_RAND
+/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */
+# ifndef RAND_pseudo_bytes
+int RAND_pseudo_bytes(unsigned char *buf, int num);
+# define BN_DEBUG_TRIX
+# endif
+# define bn_pollute(a) \
+ do { \
+ const BIGNUM *_bnum1 = (a); \
+ if(_bnum1->top < _bnum1->dmax) { \
+ unsigned char _tmp_char; \
+ /* We cast away const without the compiler knowing, any \
+ * *genuinely* constant variables that aren't mutable \
+ * wouldn't be constructed with top!=dmax. */ \
+ BN_ULONG *_not_const; \
+ memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \
+ RAND_pseudo_bytes(&_tmp_char, 1); \
+ memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \
+ (_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \
+ } \
+ } while(0)
+# ifdef BN_DEBUG_TRIX
+# undef RAND_pseudo_bytes
+# endif
+# else
+# define bn_pollute(a)
+# endif
+# define bn_check_top(a) \
+ do { \
+ const BIGNUM *_bnum2 = (a); \
+ if (_bnum2 != NULL) { \
+ assert((_bnum2->top == 0) || \
+ (_bnum2->d[_bnum2->top - 1] != 0)); \
+ bn_pollute(_bnum2); \
+ } \
+ } while(0)
+
+# define bn_fix_top(a) bn_check_top(a)
+
+# define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2)
+# define bn_wcheck_size(bn, words) \
+ do { \
+ const BIGNUM *_bnum2 = (bn); \
+ assert((words) <= (_bnum2)->dmax && (words) >= (_bnum2)->top); \
+ /* avoid unused variable warning with NDEBUG */ \
+ (void)(_bnum2); \
+ } while(0)
+
+# else /* !BN_DEBUG */
+
+# define bn_pollute(a)
+# define bn_check_top(a)
+# define bn_fix_top(a) bn_correct_top(a)
+# define bn_check_size(bn, bits)
+# define bn_wcheck_size(bn, words)
+
+# endif
+
+# define bn_correct_top(a) \
+ { \
+ BN_ULONG *ftl; \
+ int tmp_top = (a)->top; \
+ if (tmp_top > 0) \
+ { \
+ for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \
+ if (*(ftl--)) break; \
+ (a)->top = tmp_top; \
+ } \
+ bn_pollute(a); \
+ }
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
+ BN_ULONG w);
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
+void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
+BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ int num);
+BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ int num);
+
+/* Primes from RFC 2409 */
+BIGNUM *get_rfc2409_prime_768(BIGNUM *bn);
+BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn);
+
+/* Primes from RFC 3526 */
+BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn);
+BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn);
+
+int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom);
+
+/* 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.
+ */
+void ERR_load_BN_strings(void);
+
+/* Error codes for the BN functions. */
+
+/* Function codes. */
+# define BN_F_BNRAND 127
+# define BN_F_BN_BLINDING_CONVERT_EX 100
+# define BN_F_BN_BLINDING_CREATE_PARAM 128
+# define BN_F_BN_BLINDING_INVERT_EX 101
+# define BN_F_BN_BLINDING_NEW 102
+# define BN_F_BN_BLINDING_UPDATE 103
+# define BN_F_BN_BN2DEC 104
+# define BN_F_BN_BN2HEX 105
+# define BN_F_BN_CTX_GET 116
+# define BN_F_BN_CTX_NEW 106
+# define BN_F_BN_CTX_START 129
+# define BN_F_BN_DIV 107
+# define BN_F_BN_DIV_NO_BRANCH 138
+# define BN_F_BN_DIV_RECP 130
+# define BN_F_BN_EXP 123
+# define BN_F_BN_EXPAND2 108
+# define BN_F_BN_EXPAND_INTERNAL 120
+# define BN_F_BN_GF2M_MOD 131
+# define BN_F_BN_GF2M_MOD_EXP 132
+# define BN_F_BN_GF2M_MOD_MUL 133
+# define BN_F_BN_GF2M_MOD_SOLVE_QUAD 134
+# define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135
+# define BN_F_BN_GF2M_MOD_SQR 136
+# define BN_F_BN_GF2M_MOD_SQRT 137
+# define BN_F_BN_MOD_EXP2_MONT 118
+# define BN_F_BN_MOD_EXP_MONT 109
+# define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124
+# define BN_F_BN_MOD_EXP_MONT_WORD 117
+# define BN_F_BN_MOD_EXP_RECP 125
+# define BN_F_BN_MOD_EXP_SIMPLE 126
+# define BN_F_BN_MOD_INVERSE 110
+# define BN_F_BN_MOD_INVERSE_NO_BRANCH 139
+# define BN_F_BN_MOD_LSHIFT_QUICK 119
+# define BN_F_BN_MOD_MUL_RECIPROCAL 111
+# define BN_F_BN_MOD_SQRT 121
+# define BN_F_BN_MPI2BN 112
+# define BN_F_BN_NEW 113
+# define BN_F_BN_RAND 114
+# define BN_F_BN_RAND_RANGE 122
+# define BN_F_BN_USUB 115
+
+/* Reason codes. */
+# define BN_R_ARG2_LT_ARG3 100
+# define BN_R_BAD_RECIPROCAL 101
+# define BN_R_BIGNUM_TOO_LONG 114
+# define BN_R_CALLED_WITH_EVEN_MODULUS 102
+# define BN_R_DIV_BY_ZERO 103
+# define BN_R_ENCODING_ERROR 104
+# define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105
+# define BN_R_INPUT_NOT_REDUCED 110
+# define BN_R_INVALID_LENGTH 106
+# define BN_R_INVALID_RANGE 115
+# define BN_R_NOT_A_SQUARE 111
+# define BN_R_NOT_INITIALIZED 107
+# define BN_R_NO_INVERSE 108
+# define BN_R_NO_SOLUTION 116
+# define BN_R_P_IS_NOT_PRIME 112
+# define BN_R_TOO_MANY_ITERATIONS 113
+# define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/bn/bn.mul b/openssl/bn/bn.mul
new file mode 100644
index 0000000..9728870
--- /dev/null
+++ b/openssl/bn/bn.mul
@@ -0,0 +1,19 @@
+We need
+
+* bn_mul_comba8
+* bn_mul_comba4
+* bn_mul_normal
+* bn_mul_recursive
+
+* bn_sqr_comba8
+* bn_sqr_comba4
+bn_sqr_normal -> BN_sqr
+* bn_sqr_recursive
+
+* bn_mul_low_recursive
+* bn_mul_low_normal
+* bn_mul_high
+
+* bn_mul_part_recursive # symetric but not power of 2
+
+bn_mul_asymetric_recursive # uneven, but do the chop up.
diff --git a/openssl/bn/bn_add.c b/openssl/bn/bn_add.c
new file mode 100644
index 0000000..2f3d110
--- /dev/null
+++ b/openssl/bn/bn_add.c
@@ -0,0 +1,313 @@
+/* crypto/bn/bn_add.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* r can == a or b */
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+ const BIGNUM *tmp;
+ int a_neg = a->neg, ret;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ /*-
+ * a + b a+b
+ * a + -b a-b
+ * -a + b b-a
+ * -a + -b -(a+b)
+ */
+ if (a_neg ^ b->neg) {
+ /* only one is negative */
+ if (a_neg) {
+ tmp = a;
+ a = b;
+ b = tmp;
+ }
+
+ /* we are now a - b */
+
+ if (BN_ucmp(a, b) < 0) {
+ if (!BN_usub(r, b, a))
+ return (0);
+ r->neg = 1;
+ } else {
+ if (!BN_usub(r, a, b))
+ return (0);
+ r->neg = 0;
+ }
+ return (1);
+ }
+
+ ret = BN_uadd(r, a, b);
+ r->neg = a_neg;
+ bn_check_top(r);
+ return ret;
+}
+
+/* unsigned add of b to a */
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+ int max, min, dif;
+ BN_ULONG *ap, *bp, *rp, carry, t1, t2;
+ const BIGNUM *tmp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (a->top < b->top) {
+ tmp = a;
+ a = b;
+ b = tmp;
+ }
+ max = a->top;
+ min = b->top;
+ dif = max - min;
+
+ if (bn_wexpand(r, max + 1) == NULL)
+ return 0;
+
+ r->top = max;
+
+ ap = a->d;
+ bp = b->d;
+ rp = r->d;
+
+ carry = bn_add_words(rp, ap, bp, min);
+ rp += min;
+ ap += min;
+ bp += min;
+
+ if (carry) {
+ while (dif) {
+ dif--;
+ t1 = *(ap++);
+ t2 = (t1 + 1) & BN_MASK2;
+ *(rp++) = t2;
+ if (t2) {
+ carry = 0;
+ break;
+ }
+ }
+ if (carry) {
+ /* carry != 0 => dif == 0 */
+ *rp = 1;
+ r->top++;
+ }
+ }
+ if (dif && rp != ap)
+ while (dif--)
+ /* copy remaining words if ap != rp */
+ *(rp++) = *(ap++);
+ r->neg = 0;
+ bn_check_top(r);
+ return 1;
+}
+
+/* unsigned subtraction of b from a, a must be larger than b. */
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+ int max, min, dif;
+ register BN_ULONG t1, t2, *ap, *bp, *rp;
+ int i, carry;
+#if defined(IRIX_CC_BUG) && !defined(LINT)
+ int dummy;
+#endif
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ max = a->top;
+ min = b->top;
+ dif = max - min;
+
+ if (dif < 0) { /* hmm... should not be happening */
+ BNerr(BN_F_BN_USUB, BN_R_ARG2_LT_ARG3);
+ return (0);
+ }
+
+ if (bn_wexpand(r, max) == NULL)
+ return (0);
+
+ ap = a->d;
+ bp = b->d;
+ rp = r->d;
+
+#if 1
+ carry = 0;
+ for (i = min; i != 0; i--) {
+ t1 = *(ap++);
+ t2 = *(bp++);
+ if (carry) {
+ carry = (t1 <= t2);
+ t1 = (t1 - t2 - 1) & BN_MASK2;
+ } else {
+ carry = (t1 < t2);
+ t1 = (t1 - t2) & BN_MASK2;
+ }
+# if defined(IRIX_CC_BUG) && !defined(LINT)
+ dummy = t1;
+# endif
+ *(rp++) = t1 & BN_MASK2;
+ }
+#else
+ carry = bn_sub_words(rp, ap, bp, min);
+ ap += min;
+ bp += min;
+ rp += min;
+#endif
+ if (carry) { /* subtracted */
+ if (!dif)
+ /* error: a < b */
+ return 0;
+ while (dif) {
+ dif--;
+ t1 = *(ap++);
+ t2 = (t1 - 1) & BN_MASK2;
+ *(rp++) = t2;
+ if (t1)
+ break;
+ }
+ }
+#if 0
+ memcpy(rp, ap, sizeof(*rp) * (max - i));
+#else
+ if (rp != ap) {
+ for (;;) {
+ if (!dif--)
+ break;
+ rp[0] = ap[0];
+ if (!dif--)
+ break;
+ rp[1] = ap[1];
+ if (!dif--)
+ break;
+ rp[2] = ap[2];
+ if (!dif--)
+ break;
+ rp[3] = ap[3];
+ rp += 4;
+ ap += 4;
+ }
+ }
+#endif
+
+ r->top = max;
+ r->neg = 0;
+ bn_correct_top(r);
+ return (1);
+}
+
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+ int max;
+ int add = 0, neg = 0;
+ const BIGNUM *tmp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ /*-
+ * a - b a-b
+ * a - -b a+b
+ * -a - b -(a+b)
+ * -a - -b b-a
+ */
+ if (a->neg) {
+ if (b->neg) {
+ tmp = a;
+ a = b;
+ b = tmp;
+ } else {
+ add = 1;
+ neg = 1;
+ }
+ } else {
+ if (b->neg) {
+ add = 1;
+ neg = 0;
+ }
+ }
+
+ if (add) {
+ if (!BN_uadd(r, a, b))
+ return (0);
+ r->neg = neg;
+ return (1);
+ }
+
+ /* We are actually doing a - b :-) */
+
+ max = (a->top > b->top) ? a->top : b->top;
+ if (bn_wexpand(r, max) == NULL)
+ return (0);
+ if (BN_ucmp(a, b) < 0) {
+ if (!BN_usub(r, b, a))
+ return (0);
+ r->neg = 1;
+ } else {
+ if (!BN_usub(r, a, b))
+ return (0);
+ r->neg = 0;
+ }
+ bn_check_top(r);
+ return (1);
+}
diff --git a/openssl/bn/bn_asm.c b/openssl/bn/bn_asm.c
new file mode 100644
index 0000000..e6a6976
--- /dev/null
+++ b/openssl/bn/bn_asm.c
@@ -0,0 +1,1098 @@
+/* crypto/bn/bn_asm.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [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"
+
+#ifdef OPENSSL_SMALL_FOOTPRINT
+#undef OPENSSL_SMALL_FOOTPRINT
+#endif
+
+#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
+ BN_ULONG w)
+{
+ BN_ULONG c1 = 0;
+
+ assert(num >= 0);
+ if (num <= 0)
+ return (c1);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ 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;
+ }
+# endif
+ while (num) {
+ mul_add(rp[0], ap[0], w, c1);
+ ap++;
+ rp++;
+ num--;
+ }
+
+ return (c1);
+}
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+{
+ BN_ULONG c1 = 0;
+
+ assert(num >= 0);
+ if (num <= 0)
+ return (c1);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ 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;
+ }
+# endif
+ while (num) {
+ mul(rp[0], ap[0], w, c1);
+ ap++;
+ rp++;
+ num--;
+ }
+ return (c1);
+}
+
+void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
+{
+ assert(n >= 0);
+ if (n <= 0)
+ return;
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ 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;
+ }
+# endif
+ while (n) {
+ sqr(r[0], r[1], a[0]);
+ a++;
+ r += 2;
+ n--;
+ }
+}
+
+#else /* !(defined(BN_LLONG) ||
+ * defined(BN_UMULT_HIGH)) */
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
+ BN_ULONG w)
+{
+ BN_ULONG c = 0;
+ BN_ULONG bl, bh;
+
+ assert(num >= 0);
+ if (num <= 0)
+ return ((BN_ULONG)0);
+
+ bl = LBITS(w);
+ bh = HBITS(w);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ while (num & ~3) {
+ mul_add(rp[0], ap[0], bl, bh, c);
+ mul_add(rp[1], ap[1], bl, bh, c);
+ mul_add(rp[2], ap[2], bl, bh, c);
+ mul_add(rp[3], ap[3], bl, bh, c);
+ ap += 4;
+ rp += 4;
+ num -= 4;
+ }
+# endif
+ while (num) {
+ mul_add(rp[0], ap[0], bl, bh, c);
+ ap++;
+ rp++;
+ num--;
+ }
+ return (c);
+}
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+{
+ BN_ULONG carry = 0;
+ BN_ULONG bl, bh;
+
+ assert(num >= 0);
+ if (num <= 0)
+ return ((BN_ULONG)0);
+
+ bl = LBITS(w);
+ bh = HBITS(w);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ while (num & ~3) {
+ mul(rp[0], ap[0], bl, bh, carry);
+ mul(rp[1], ap[1], bl, bh, carry);
+ mul(rp[2], ap[2], bl, bh, carry);
+ mul(rp[3], ap[3], bl, bh, carry);
+ ap += 4;
+ rp += 4;
+ num -= 4;
+ }
+# endif
+ while (num) {
+ mul(rp[0], ap[0], bl, bh, carry);
+ ap++;
+ rp++;
+ num--;
+ }
+ return (carry);
+}
+
+void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
+{
+ assert(n >= 0);
+ if (n <= 0)
+ return;
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ while (n & ~3) {
+ sqr64(r[0], r[1], a[0]);
+ sqr64(r[2], r[3], a[1]);
+ sqr64(r[4], r[5], a[2]);
+ sqr64(r[6], r[7], a[3]);
+ a += 4;
+ r += 8;
+ n -= 4;
+ }
+# endif
+ while (n) {
+ sqr64(r[0], r[1], a[0]);
+ a++;
+ r += 2;
+ n--;
+ }
+}
+
+#endif /* !(defined(BN_LLONG) ||
+ * defined(BN_UMULT_HIGH)) */
+
+#if defined(BN_LLONG) && defined(BN_DIV2W)
+
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+{
+ return ((BN_ULONG)(((((BN_ULLONG) h) << BN_BITS2) | l) / (BN_ULLONG) d));
+}
+
+#else
+
+/* Divide h,l by d and return the result. */
+/* I need to test this some more :-( */
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+{
+ BN_ULONG dh, dl, q, ret = 0, th, tl, t;
+ int i, count = 2;
+
+ if (d == 0)
+ return (BN_MASK2);
+
+ i = BN_num_bits_word(d);
+ assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
+
+ i = BN_BITS2 - i;
+ if (h >= d)
+ h -= d;
+
+ if (i) {
+ d <<= i;
+ h = (h << i) | (l >> (BN_BITS2 - i));
+ l <<= i;
+ }
+ dh = (d & BN_MASK2h) >> BN_BITS4;
+ dl = (d & BN_MASK2l);
+ for (;;) {
+ if ((h >> BN_BITS4) == dh)
+ q = BN_MASK2l;
+ else
+ q = h / dh;
+
+ th = q * dh;
+ tl = dl * q;
+ for (;;) {
+ t = h - th;
+ if ((t & BN_MASK2h) ||
+ ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4))))
+ break;
+ q--;
+ th -= dh;
+ tl -= dl;
+ }
+ t = (tl >> BN_BITS4);
+ tl = (tl << BN_BITS4) & BN_MASK2h;
+ th += t;
+
+ if (l < tl)
+ th++;
+ l -= tl;
+ if (h < th) {
+ h += d;
+ q--;
+ }
+ h -= th;
+
+ if (--count == 0)
+ break;
+
+ ret = q << BN_BITS4;
+ h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
+ l = (l & BN_MASK2l) << BN_BITS4;
+ }
+ ret |= q;
+ return (ret);
+}
+#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
+
+#ifdef BN_LLONG
+BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+ int n)
+{
+ BN_ULLONG ll = 0;
+
+ assert(n >= 0);
+ if (n <= 0)
+ return ((BN_ULONG)0);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ while (n & ~3) {
+ ll += (BN_ULLONG) a[0] + b[0];
+ r[0] = (BN_ULONG)ll & BN_MASK2;
+ ll >>= BN_BITS2;
+ ll += (BN_ULLONG) a[1] + b[1];
+ r[1] = (BN_ULONG)ll & BN_MASK2;
+ ll >>= BN_BITS2;
+ ll += (BN_ULLONG) a[2] + b[2];
+ r[2] = (BN_ULONG)ll & BN_MASK2;
+ ll >>= BN_BITS2;
+ ll += (BN_ULLONG) a[3] + b[3];
+ r[3] = (BN_ULONG)ll & BN_MASK2;
+ ll >>= BN_BITS2;
+ a += 4;
+ b += 4;
+ r += 4;
+ n -= 4;
+ }
+# endif
+ while (n) {
+ ll += (BN_ULLONG) a[0] + b[0];
+ r[0] = (BN_ULONG)ll & BN_MASK2;
+ ll >>= BN_BITS2;
+ a++;
+ b++;
+ r++;
+ n--;
+ }
+ return ((BN_ULONG)ll);
+}
+#else /* !BN_LLONG */
+BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+ int n)
+{
+ BN_ULONG c, l, t;
+
+ assert(n >= 0);
+ if (n <= 0)
+ return ((BN_ULONG)0);
+
+ c = 0;
+# ifndef OPENSSL_SMALL_FOOTPRINT
+ while (n & ~3) {
+ t = a[0];
+ t = (t + c) & BN_MASK2;
+ c = (t < c);
+ l = (t + b[0]) & BN_MASK2;
+ c += (l < t);
+ r[0] = l;
+ t = a[1];
+ t = (t + c) & BN_MASK2;
+ c = (t < c);
+ l = (t + b[1]) & BN_MASK2;
+ c += (l < t);
+ r[1] = l;
+ t = a[2];
+ t = (t + c) & BN_MASK2;
+ c = (t < c);
+ l = (t + b[2]) & BN_MASK2;
+ c += (l < t);
+ r[2] = l;
+ t = a[3];
+ t = (t + c) & BN_MASK2;
+ c = (t < c);
+ l = (t + b[3]) & BN_MASK2;
+ c += (l < t);
+ r[3] = l;
+ a += 4;
+ b += 4;
+ r += 4;
+ n -= 4;
+ }
+# endif
+ while (n) {
+ t = a[0];
+ t = (t + c) & BN_MASK2;
+ c = (t < c);
+ l = (t + b[0]) & BN_MASK2;
+ c += (l < t);
+ r[0] = l;
+ a++;
+ b++;
+ r++;
+ n--;
+ }
+ return ((BN_ULONG)c);
+}
+#endif /* !BN_LLONG */
+
+BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+ int n)
+{
+ BN_ULONG t1, t2;
+ int c = 0;
+
+ assert(n >= 0);
+ if (n <= 0)
+ return ((BN_ULONG)0);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+ while (n & ~3) {
+ t1 = a[0];
+ t2 = b[0];
+ r[0] = (t1 - t2 - c) & BN_MASK2;
+ if (t1 != t2)
+ c = (t1 < t2);
+ t1 = a[1];
+ t2 = b[1];
+ r[1] = (t1 - t2 - c) & BN_MASK2;
+ if (t1 != t2)
+ c = (t1 < t2);
+ t1 = a[2];
+ t2 = b[2];
+ r[2] = (t1 - t2 - c) & BN_MASK2;
+ if (t1 != t2)
+ c = (t1 < t2);
+ t1 = a[3];
+ t2 = b[3];
+ r[3] = (t1 - t2 - c) & BN_MASK2;
+ if (t1 != t2)
+ c = (t1 < t2);
+ a += 4;
+ b += 4;
+ r += 4;
+ n -= 4;
+ }
+#endif
+ while (n) {
+ t1 = a[0];
+ t2 = b[0];
+ r[0] = (t1 - t2 - c) & BN_MASK2;
+ if (t1 != t2)
+ c = (t1 < t2);
+ a++;
+ b++;
+ r++;
+ n--;
+ }
+ return (c);
+}
+
+#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT)
+
+# undef bn_mul_comba8
+# undef bn_mul_comba4
+# undef bn_sqr_comba8
+# undef bn_sqr_comba4
+
+/* 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)
+ */
+
+/*
+ * Keep in mind that carrying into high part of multiplication result
+ * can not overflow, because it cannot be all-ones.
+ */
+# ifdef BN_LLONG
+# define mul_add_c(a,b,c0,c1,c2) \
+ t=(BN_ULLONG)a*b; \
+ t1=(BN_ULONG)Lw(t); \
+ t2=(BN_ULONG)Hw(t); \
+ c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+# define mul_add_c2(a,b,c0,c1,c2) \
+ t=(BN_ULLONG)a*b; \
+ tt=(t+t)&BN_MASK; \
+ if (tt < t) c2++; \
+ t1=(BN_ULONG)Lw(tt); \
+ t2=(BN_ULONG)Hw(tt); \
+ c0=(c0+t1)&BN_MASK2; \
+ if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+# define sqr_add_c(a,i,c0,c1,c2) \
+ t=(BN_ULLONG)a[i]*a[i]; \
+ t1=(BN_ULONG)Lw(t); \
+ t2=(BN_ULONG)Hw(t); \
+ c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+# define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+# elif defined(BN_UMULT_LOHI)
+
+# define mul_add_c(a,b,c0,c1,c2) { \
+ BN_ULONG ta=(a),tb=(b); \
+ BN_UMULT_LOHI(t1,t2,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; \
+ BN_UMULT_LOHI(t0,t1,ta,tb); \
+ c0 += t0; t2 = t1+((c0<t0)?1:0);\
+ c1 += t2; c2 += (c1<t2)?1:0; \
+ c0 += t0; t1 += (c0<t0)?1:0; \
+ c1 += t1; c2 += (c1<t1)?1:0; \
+ }
+
+# define sqr_add_c(a,i,c0,c1,c2) { \
+ BN_ULONG ta=(a)[i]; \
+ BN_UMULT_LOHI(t1,t2,ta,ta); \
+ c0 += t1; t2 += (c0<t1)?1:0; \
+ c1 += t2; c2 += (c1<t2)?1:0; \
+ }
+
+# define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+# elif defined(BN_UMULT_HIGH)
+
+# 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; \
+ c0 += t0; t2 = t1+((c0<t0)?1:0);\
+ c1 += t2; c2 += (c1<t2)?1:0; \
+ c0 += t0; t1 += (c0<t0)?1:0; \
+ c1 += t1; c2 += (c1<t1)?1:0; \
+ }
+
+# define sqr_add_c(a,i,c0,c1,c2) { \
+ BN_ULONG ta=(a)[i]; \
+ t1 = ta * ta; \
+ t2 = BN_UMULT_HIGH(ta,ta); \
+ c0 += t1; t2 += (c0<t1)?1:0; \
+ c1 += t2; c2 += (c1<t2)?1:0; \
+ }
+
+# define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+# else /* !BN_LLONG */
+# define mul_add_c(a,b,c0,c1,c2) \
+ t1=LBITS(a); t2=HBITS(a); \
+ bl=LBITS(b); bh=HBITS(b); \
+ mul64(t1,t2,bl,bh); \
+ c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+# define mul_add_c2(a,b,c0,c1,c2) \
+ t1=LBITS(a); t2=HBITS(a); \
+ bl=LBITS(b); bh=HBITS(b); \
+ mul64(t1,t2,bl,bh); \
+ if (t2 & BN_TBIT) c2++; \
+ t2=(t2+t2)&BN_MASK2; \
+ if (t1 & BN_TBIT) t2++; \
+ t1=(t1+t1)&BN_MASK2; \
+ c0=(c0+t1)&BN_MASK2; \
+ if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+# define sqr_add_c(a,i,c0,c1,c2) \
+ sqr64(t1,t2,(a)[i]); \
+ c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
+ c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+
+# define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+# endif /* !BN_LLONG */
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+{
+# ifdef BN_LLONG
+ BN_ULLONG t;
+# else
+ BN_ULONG bl, bh;
+# endif
+ 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)
+{
+# ifdef BN_LLONG
+ BN_ULLONG t;
+# else
+ BN_ULONG bl, bh;
+# endif
+ 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, const BN_ULONG *a)
+{
+# ifdef BN_LLONG
+ BN_ULLONG t, tt;
+# else
+ BN_ULONG bl, bh;
+# endif
+ 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, const BN_ULONG *a)
+{
+# ifdef BN_LLONG
+ BN_ULLONG t, tt;
+# else
+ BN_ULONG bl, bh;
+# endif
+ 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;
+}
+
+# ifdef OPENSSL_NO_ASM
+# ifdef OPENSSL_BN_ASM_MONT
+# include <alloca.h>
+/*
+ * This is essentially reference implementation, which may or may not
+ * result in performance improvement. E.g. on IA-32 this routine was
+ * observed to give 40% faster rsa1024 private key operations and 10%
+ * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only
+ * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a
+ * reference implementation, one to be used as starting point for
+ * platform-specific assembler. Mentioned numbers apply to compiler
+ * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and
+ * can vary not only from platform to platform, but even for compiler
+ * versions. Assembler vs. assembler improvement coefficients can
+ * [and are known to] differ and are to be documented elsewhere.
+ */
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0p, int num)
+{
+ BN_ULONG c0, c1, ml, *tp, n0;
+# ifdef mul64
+ BN_ULONG mh;
+# endif
+ volatile BN_ULONG *vp;
+ int i = 0, j;
+
+# if 0 /* template for platform-specific
+ * implementation */
+ if (ap == bp)
+ return bn_sqr_mont(rp, ap, np, n0p, num);
+# endif
+ vp = tp = alloca((num + 2) * sizeof(BN_ULONG));
+
+ n0 = *n0p;
+
+ c0 = 0;
+ ml = bp[0];
+# ifdef mul64
+ mh = HBITS(ml);
+ ml = LBITS(ml);
+ for (j = 0; j < num; ++j)
+ mul(tp[j], ap[j], ml, mh, c0);
+# else
+ for (j = 0; j < num; ++j)
+ mul(tp[j], ap[j], ml, c0);
+# endif
+
+ tp[num] = c0;
+ tp[num + 1] = 0;
+ goto enter;
+
+ for (i = 0; i < num; i++) {
+ c0 = 0;
+ ml = bp[i];
+# ifdef mul64
+ mh = HBITS(ml);
+ ml = LBITS(ml);
+ for (j = 0; j < num; ++j)
+ mul_add(tp[j], ap[j], ml, mh, c0);
+# else
+ for (j = 0; j < num; ++j)
+ mul_add(tp[j], ap[j], ml, c0);
+# endif
+ c1 = (tp[num] + c0) & BN_MASK2;
+ tp[num] = c1;
+ tp[num + 1] = (c1 < c0 ? 1 : 0);
+ enter:
+ c1 = tp[0];
+ ml = (c1 * n0) & BN_MASK2;
+ c0 = 0;
+# ifdef mul64
+ mh = HBITS(ml);
+ ml = LBITS(ml);
+ mul_add(c1, np[0], ml, mh, c0);
+# else
+ mul_add(c1, ml, np[0], c0);
+# endif
+ for (j = 1; j < num; j++) {
+ c1 = tp[j];
+# ifdef mul64
+ mul_add(c1, np[j], ml, mh, c0);
+# else
+ mul_add(c1, ml, np[j], c0);
+# endif
+ tp[j - 1] = c1 & BN_MASK2;
+ }
+ c1 = (tp[num] + c0) & BN_MASK2;
+ tp[num - 1] = c1;
+ tp[num] = tp[num + 1] + (c1 < c0 ? 1 : 0);
+ }
+
+ if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) {
+ c0 = bn_sub_words(rp, tp, np, num);
+ if (tp[num] != 0 || c0 == 0) {
+ for (i = 0; i < num + 2; i++)
+ vp[i] = 0;
+ return 1;
+ }
+ }
+ for (i = 0; i < num; i++)
+ rp[i] = tp[i], vp[i] = 0;
+ vp[num] = 0;
+ vp[num + 1] = 0;
+ return 1;
+}
+# else
+/*
+ * Return value of 0 indicates that multiplication/convolution was not
+ * performed to signal the caller to fall down to alternative/original
+ * code-path.
+ */
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0, int num)
+{
+ return 0;
+}
+# endif /* OPENSSL_BN_ASM_MONT */
+# endif
+
+#else /* !BN_MUL_COMBA */
+
+/* hmm... is it faster just to do a multiply? */
+# undef bn_sqr_comba4
+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
+{
+ BN_ULONG t[8];
+ bn_sqr_normal(r, a, 4, t);
+}
+
+# undef bn_sqr_comba8
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
+{
+ BN_ULONG t[16];
+ bn_sqr_normal(r, a, 8, t);
+}
+
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+{
+ r[4] = bn_mul_words(&(r[0]), a, 4, b[0]);
+ r[5] = bn_mul_add_words(&(r[1]), a, 4, b[1]);
+ r[6] = bn_mul_add_words(&(r[2]), a, 4, b[2]);
+ r[7] = bn_mul_add_words(&(r[3]), a, 4, b[3]);
+}
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+{
+ r[8] = bn_mul_words(&(r[0]), a, 8, b[0]);
+ r[9] = bn_mul_add_words(&(r[1]), a, 8, b[1]);
+ r[10] = bn_mul_add_words(&(r[2]), a, 8, b[2]);
+ r[11] = bn_mul_add_words(&(r[3]), a, 8, b[3]);
+ r[12] = bn_mul_add_words(&(r[4]), a, 8, b[4]);
+ r[13] = bn_mul_add_words(&(r[5]), a, 8, b[5]);
+ r[14] = bn_mul_add_words(&(r[6]), a, 8, b[6]);
+ r[15] = bn_mul_add_words(&(r[7]), a, 8, b[7]);
+}
+
+# ifdef OPENSSL_NO_ASM
+# ifdef OPENSSL_BN_ASM_MONT
+# include <alloca.h>
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0p, int num)
+{
+ BN_ULONG c0, c1, *tp, n0 = *n0p;
+ volatile BN_ULONG *vp;
+ int i = 0, j;
+
+ vp = tp = alloca((num + 2) * sizeof(BN_ULONG));
+
+ for (i = 0; i <= num; i++)
+ tp[i] = 0;
+
+ for (i = 0; i < num; i++) {
+ c0 = bn_mul_add_words(tp, ap, num, bp[i]);
+ c1 = (tp[num] + c0) & BN_MASK2;
+ tp[num] = c1;
+ tp[num + 1] = (c1 < c0 ? 1 : 0);
+
+ c0 = bn_mul_add_words(tp, np, num, tp[0] * n0);
+ c1 = (tp[num] + c0) & BN_MASK2;
+ tp[num] = c1;
+ tp[num + 1] += (c1 < c0 ? 1 : 0);
+ for (j = 0; j <= num; j++)
+ tp[j] = tp[j + 1];
+ }
+
+ if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) {
+ c0 = bn_sub_words(rp, tp, np, num);
+ if (tp[num] != 0 || c0 == 0) {
+ for (i = 0; i < num + 2; i++)
+ vp[i] = 0;
+ return 1;
+ }
+ }
+ for (i = 0; i < num; i++)
+ rp[i] = tp[i], vp[i] = 0;
+ vp[num] = 0;
+ vp[num + 1] = 0;
+ return 1;
+}
+# else
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0, int num)
+{
+ return 0;
+}
+# endif /* OPENSSL_BN_ASM_MONT */
+# endif
+
+#endif /* !BN_MUL_COMBA */
diff --git a/openssl/bn/bn_blind.c b/openssl/bn/bn_blind.c
new file mode 100644
index 0000000..d448daa
--- /dev/null
+++ b/openssl/bn/bn_blind.c
@@ -0,0 +1,385 @@
+/* crypto/bn/bn_blind.c */
+/* ====================================================================
+ * Copyright (c) 1998-2006 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.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#define BN_BLINDING_COUNTER 32
+
+struct bn_blinding_st {
+ BIGNUM *A;
+ BIGNUM *Ai;
+ BIGNUM *e;
+ BIGNUM *mod; /* just a reference */
+#ifndef OPENSSL_NO_DEPRECATED
+ unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b; used
+ * only by crypto/rsa/rsa_eay.c, rsa_lib.c */
+#endif
+ CRYPTO_THREADID tid;
+ int counter;
+ unsigned long flags;
+ BN_MONT_CTX *m_ctx;
+ int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+};
+
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
+{
+ BN_BLINDING *ret = NULL;
+
+ bn_check_top(mod);
+
+ if ((ret = (BN_BLINDING *)OPENSSL_malloc(sizeof(BN_BLINDING))) == NULL) {
+ BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ memset(ret, 0, sizeof(BN_BLINDING));
+ if (A != NULL) {
+ if ((ret->A = BN_dup(A)) == NULL)
+ goto err;
+ }
+ if (Ai != NULL) {
+ if ((ret->Ai = BN_dup(Ai)) == NULL)
+ goto err;
+ }
+
+ /* save a copy of mod in the BN_BLINDING structure */
+ if ((ret->mod = BN_dup(mod)) == NULL)
+ goto err;
+ if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
+ BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
+
+ /*
+ * Set the counter to the special value -1 to indicate that this is
+ * never-used fresh blinding that does not need updating before first
+ * use.
+ */
+ ret->counter = -1;
+ CRYPTO_THREADID_current(&ret->tid);
+ return (ret);
+ err:
+ if (ret != NULL)
+ BN_BLINDING_free(ret);
+ return (NULL);
+}
+
+void BN_BLINDING_free(BN_BLINDING *r)
+{
+ if (r == NULL)
+ return;
+
+ if (r->A != NULL)
+ BN_free(r->A);
+ if (r->Ai != NULL)
+ BN_free(r->Ai);
+ if (r->e != NULL)
+ BN_free(r->e);
+ if (r->mod != NULL)
+ BN_free(r->mod);
+ OPENSSL_free(r);
+}
+
+int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
+{
+ int ret = 0;
+
+ if ((b->A == NULL) || (b->Ai == NULL)) {
+ BNerr(BN_F_BN_BLINDING_UPDATE, BN_R_NOT_INITIALIZED);
+ goto err;
+ }
+
+ if (b->counter == -1)
+ b->counter = 0;
+
+ if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL &&
+ !(b->flags & BN_BLINDING_NO_RECREATE)) {
+ /* re-create blinding parameters */
+ if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL))
+ goto err;
+ } else if (!(b->flags & BN_BLINDING_NO_UPDATE)) {
+ if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx))
+ goto err;
+ if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx))
+ goto err;
+ }
+
+ ret = 1;
+ err:
+ if (b->counter == BN_BLINDING_COUNTER)
+ b->counter = 0;
+ return (ret);
+}
+
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
+{
+ return BN_BLINDING_convert_ex(n, NULL, b, ctx);
+}
+
+int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
+{
+ int ret = 1;
+
+ bn_check_top(n);
+
+ if ((b->A == NULL) || (b->Ai == NULL)) {
+ BNerr(BN_F_BN_BLINDING_CONVERT_EX, BN_R_NOT_INITIALIZED);
+ return (0);
+ }
+
+ if (b->counter == -1)
+ /* Fresh blinding, doesn't need updating. */
+ b->counter = 0;
+ else if (!BN_BLINDING_update(b, ctx))
+ return (0);
+
+ if (r != NULL) {
+ if (!BN_copy(r, b->Ai))
+ ret = 0;
+ }
+
+ if (!BN_mod_mul(n, n, b->A, b->mod, ctx))
+ ret = 0;
+
+ return ret;
+}
+
+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
+{
+ return BN_BLINDING_invert_ex(n, NULL, b, ctx);
+}
+
+int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
+ BN_CTX *ctx)
+{
+ int ret;
+
+ bn_check_top(n);
+
+ if (r != NULL)
+ ret = BN_mod_mul(n, n, r, b->mod, ctx);
+ else {
+ if (b->Ai == NULL) {
+ BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED);
+ return (0);
+ }
+ ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
+ }
+
+ bn_check_top(n);
+ return (ret);
+}
+
+#ifndef OPENSSL_NO_DEPRECATED
+unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b)
+{
+ return b->thread_id;
+}
+
+void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n)
+{
+ b->thread_id = n;
+}
+#endif
+
+CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *b)
+{
+ return &b->tid;
+}
+
+unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
+{
+ return b->flags;
+}
+
+void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags)
+{
+ b->flags = flags;
+}
+
+BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
+ const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
+ int (*bn_mod_exp) (BIGNUM *r,
+ const BIGNUM *a,
+ const BIGNUM *p,
+ const BIGNUM *m,
+ BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx),
+ BN_MONT_CTX *m_ctx)
+{
+ int retry_counter = 32;
+ BN_BLINDING *ret = NULL;
+
+ if (b == NULL)
+ ret = BN_BLINDING_new(NULL, NULL, m);
+ else
+ ret = b;
+
+ if (ret == NULL)
+ goto err;
+
+ if (ret->A == NULL && (ret->A = BN_new()) == NULL)
+ goto err;
+ if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL)
+ goto err;
+
+ if (e != NULL) {
+ if (ret->e != NULL)
+ BN_free(ret->e);
+ ret->e = BN_dup(e);
+ }
+ if (ret->e == NULL)
+ goto err;
+
+ if (bn_mod_exp != NULL)
+ ret->bn_mod_exp = bn_mod_exp;
+ if (m_ctx != NULL)
+ ret->m_ctx = m_ctx;
+
+ do {
+ if (!BN_rand_range(ret->A, ret->mod))
+ goto err;
+ if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL) {
+ /*
+ * this should almost never happen for good RSA keys
+ */
+ unsigned long error = ERR_peek_last_error();
+ if (ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
+ if (retry_counter-- == 0) {
+ BNerr(BN_F_BN_BLINDING_CREATE_PARAM,
+ BN_R_TOO_MANY_ITERATIONS);
+ goto err;
+ }
+ ERR_clear_error();
+ } else
+ goto err;
+ } else
+ break;
+ } while (1);
+
+ if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) {
+ if (!ret->bn_mod_exp
+ (ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx))
+ goto err;
+ } else {
+ if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx))
+ goto err;
+ }
+
+ return ret;
+ err:
+ if (b == NULL && ret != NULL) {
+ BN_BLINDING_free(ret);
+ ret = NULL;
+ }
+
+ return ret;
+}
diff --git a/openssl/bn/bn_const.c b/openssl/bn/bn_const.c
new file mode 100644
index 0000000..12c3208
--- /dev/null
+++ b/openssl/bn/bn_const.c
@@ -0,0 +1,547 @@
+/* crypto/bn/knownprimes.c */
+/* Insert boilerplate */
+
+#include "bn.h"
+
+/*-
+ * "First Oakley Default Group" from RFC2409, section 6.1.
+ *
+ * The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 }
+ *
+ * RFC2409 specifies a generator of 2.
+ * RFC2412 specifies a generator of of 22.
+ */
+
+BIGNUM *get_rfc2409_prime_768(BIGNUM *bn)
+{
+ static const unsigned char RFC2409_PRIME_768[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x3A, 0x36, 0x20,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC2409_PRIME_768, sizeof(RFC2409_PRIME_768), bn);
+}
+
+/*-
+ * "Second Oakley Default Group" from RFC2409, section 6.2.
+ *
+ * The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
+ *
+ * RFC2409 specifies a generator of 2.
+ * RFC2412 specifies a generator of 22.
+ */
+
+BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn)
+{
+ static const unsigned char RFC2409_PRIME_1024[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC2409_PRIME_1024, sizeof(RFC2409_PRIME_1024), bn);
+}
+
+/*-
+ * "1536-bit MODP Group" from RFC3526, Section 2.
+ *
+ * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }
+ *
+ * RFC3526 specifies a generator of 2.
+ * RFC2312 specifies a generator of 22.
+ */
+
+BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn)
+{
+ static const unsigned char RFC3526_PRIME_1536[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), bn);
+}
+
+/*-
+ * "2048-bit MODP Group" from RFC3526, Section 3.
+ *
+ * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn)
+{
+ static const unsigned char RFC3526_PRIME_2048[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+ 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+ 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+ 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+ 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC3526_PRIME_2048, sizeof(RFC3526_PRIME_2048), bn);
+}
+
+/*-
+ * "3072-bit MODP Group" from RFC3526, Section 4.
+ *
+ * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn)
+{
+ static const unsigned char RFC3526_PRIME_3072[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+ 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+ 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+ 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+ 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+ 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+ 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+ 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+ 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+ 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+ 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+ 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+ 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+ 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+ 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+ 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+ 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+ 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+ 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+ 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+ 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC3526_PRIME_3072, sizeof(RFC3526_PRIME_3072), bn);
+}
+
+/*-
+ * "4096-bit MODP Group" from RFC3526, Section 5.
+ *
+ * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn)
+{
+ static const unsigned char RFC3526_PRIME_4096[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+ 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+ 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+ 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+ 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+ 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+ 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+ 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+ 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+ 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+ 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+ 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+ 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+ 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+ 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+ 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+ 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+ 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+ 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+ 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+ 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
+ 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+ 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
+ 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
+ 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+ 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
+ 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
+ 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+ 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
+ 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
+ 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+ 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
+ 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
+ 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+ 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
+ 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
+ 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC3526_PRIME_4096, sizeof(RFC3526_PRIME_4096), bn);
+}
+
+/*-
+ * "6144-bit MODP Group" from RFC3526, Section 6.
+ *
+ * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn)
+{
+ static const unsigned char RFC3526_PRIME_6144[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+ 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+ 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+ 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+ 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+ 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+ 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+ 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+ 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+ 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+ 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+ 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+ 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+ 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+ 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+ 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+ 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+ 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+ 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+ 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+ 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
+ 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+ 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
+ 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
+ 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+ 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
+ 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
+ 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+ 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
+ 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
+ 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+ 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
+ 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
+ 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+ 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
+ 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
+ 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
+ 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26,
+ 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE,
+ 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
+ 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E,
+ 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE,
+ 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
+ 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18,
+ 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED,
+ 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
+ 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B,
+ 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42,
+ 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
+ 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC,
+ 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03,
+ 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
+ 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82,
+ 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E,
+ 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
+ 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE,
+ 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5,
+ 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
+ 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8,
+ 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0,
+ 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
+ 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76,
+ 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0,
+ 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
+ 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32,
+ 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68,
+ 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
+ 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6,
+ 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xCC, 0x40, 0x24,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC3526_PRIME_6144, sizeof(RFC3526_PRIME_6144), bn);
+}
+
+/*-
+ * "8192-bit MODP Group" from RFC3526, Section 7.
+ *
+ * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn)
+{
+ static const unsigned char RFC3526_PRIME_8192[] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+ 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+ 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+ 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+ 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+ 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+ 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+ 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+ 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+ 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+ 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+ 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+ 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+ 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+ 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+ 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+ 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+ 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+ 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+ 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+ 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+ 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+ 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+ 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+ 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+ 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+ 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+ 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+ 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+ 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+ 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+ 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+ 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+ 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+ 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+ 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+ 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+ 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+ 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+ 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+ 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+ 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+ 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+ 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+ 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+ 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
+ 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+ 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
+ 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
+ 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+ 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
+ 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
+ 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+ 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
+ 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
+ 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+ 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
+ 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
+ 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+ 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
+ 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
+ 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
+ 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26,
+ 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE,
+ 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
+ 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E,
+ 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE,
+ 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
+ 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18,
+ 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED,
+ 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
+ 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B,
+ 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42,
+ 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
+ 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC,
+ 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03,
+ 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
+ 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82,
+ 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E,
+ 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
+ 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE,
+ 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5,
+ 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
+ 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8,
+ 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0,
+ 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
+ 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76,
+ 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0,
+ 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
+ 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32,
+ 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68,
+ 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
+ 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6,
+ 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xBE, 0x11, 0x59,
+ 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4,
+ 0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C,
+ 0xD8, 0xBE, 0xC4, 0xD0, 0x73, 0xB9, 0x31, 0xBA,
+ 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00,
+ 0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED,
+ 0x25, 0x76, 0xF6, 0x93, 0x6B, 0xA4, 0x24, 0x66,
+ 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68,
+ 0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78,
+ 0x23, 0x8F, 0x16, 0xCB, 0xE3, 0x9D, 0x65, 0x2D,
+ 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9,
+ 0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07,
+ 0x13, 0xEB, 0x57, 0xA8, 0x1A, 0x23, 0xF0, 0xC7,
+ 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B,
+ 0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD,
+ 0xFA, 0x9D, 0x4B, 0x7F, 0xA2, 0xC0, 0x87, 0xE8,
+ 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A,
+ 0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6,
+ 0x6D, 0x2A, 0x13, 0xF8, 0x3F, 0x44, 0xF8, 0x2D,
+ 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36,
+ 0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1,
+ 0x64, 0xF3, 0x1C, 0xC5, 0x08, 0x46, 0x85, 0x1D,
+ 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1,
+ 0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73,
+ 0xFA, 0xF3, 0x6B, 0xC3, 0x1E, 0xCF, 0xA2, 0x68,
+ 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92,
+ 0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7,
+ 0x88, 0x9A, 0x00, 0x2E, 0xD5, 0xEE, 0x38, 0x2B,
+ 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47,
+ 0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA,
+ 0x9E, 0x30, 0x50, 0xE2, 0x76, 0x56, 0x94, 0xDF,
+ 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71,
+ 0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ };
+ return BN_bin2bn(RFC3526_PRIME_8192, sizeof(RFC3526_PRIME_8192), bn);
+}
diff --git a/openssl/bn/bn_ctx.c b/openssl/bn/bn_ctx.c
new file mode 100644
index 0000000..526c6a0
--- /dev/null
+++ b/openssl/bn/bn_ctx.c
@@ -0,0 +1,448 @@
+/* crypto/bn/bn_ctx.c */
+/* Written by Ulf Moeller for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2004 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).
+ *
+ */
+
+#if !defined(BN_CTX_DEBUG) && !defined(BN_DEBUG)
+# ifndef NDEBUG
+# define NDEBUG
+# endif
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/*-
+ * TODO list
+ *
+ * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and
+ * check they can be safely removed.
+ * - Check +1 and other ugliness in BN_from_montgomery()
+ *
+ * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an
+ * appropriate 'block' size that will be honoured by bn_expand_internal() to
+ * prevent piddly little reallocations. OTOH, profiling bignum expansions in
+ * BN_CTX doesn't show this to be a big issue.
+ */
+
+/* How many bignums are in each "pool item"; */
+#define BN_CTX_POOL_SIZE 16
+/* The stack frame info is resizing, set a first-time expansion size; */
+#define BN_CTX_START_FRAMES 32
+
+/***********/
+/* BN_POOL */
+/***********/
+
+/* A bundle of bignums that can be linked with other bundles */
+typedef struct bignum_pool_item {
+ /* The bignum values */
+ BIGNUM vals[BN_CTX_POOL_SIZE];
+ /* Linked-list admin */
+ struct bignum_pool_item *prev, *next;
+} BN_POOL_ITEM;
+/* A linked-list of bignums grouped in bundles */
+typedef struct bignum_pool {
+ /* Linked-list admin */
+ BN_POOL_ITEM *head, *current, *tail;
+ /* Stack depth and allocation size */
+ unsigned used, size;
+} BN_POOL;
+static void BN_POOL_init(BN_POOL *);
+static void BN_POOL_finish(BN_POOL *);
+#ifndef OPENSSL_NO_DEPRECATED
+static void BN_POOL_reset(BN_POOL *);
+#endif
+static BIGNUM *BN_POOL_get(BN_POOL *);
+static void BN_POOL_release(BN_POOL *, unsigned int);
+
+/************/
+/* BN_STACK */
+/************/
+
+/* A wrapper to manage the "stack frames" */
+typedef struct bignum_ctx_stack {
+ /* Array of indexes into the bignum stack */
+ unsigned int *indexes;
+ /* Number of stack frames, and the size of the allocated array */
+ unsigned int depth, size;
+} BN_STACK;
+static void BN_STACK_init(BN_STACK *);
+static void BN_STACK_finish(BN_STACK *);
+#ifndef OPENSSL_NO_DEPRECATED
+static void BN_STACK_reset(BN_STACK *);
+#endif
+static int BN_STACK_push(BN_STACK *, unsigned int);
+static unsigned int BN_STACK_pop(BN_STACK *);
+
+/**********/
+/* BN_CTX */
+/**********/
+
+/* The opaque BN_CTX type */
+struct bignum_ctx {
+ /* The bignum bundles */
+ BN_POOL pool;
+ /* The "stack frames", if you will */
+ BN_STACK stack;
+ /* The number of bignums currently assigned */
+ unsigned int used;
+ /* Depth of stack overflow */
+ int err_stack;
+ /* Block "gets" until an "end" (compatibility behaviour) */
+ int too_many;
+};
+
+/* Enable this to find BN_CTX bugs */
+#ifdef BN_CTX_DEBUG
+static const char *ctxdbg_cur = NULL;
+static void ctxdbg(BN_CTX *ctx)
+{
+ unsigned int bnidx = 0, fpidx = 0;
+ BN_POOL_ITEM *item = ctx->pool.head;
+ BN_STACK *stack = &ctx->stack;
+ fprintf(stderr, "(%16p): ", ctx);
+ while (bnidx < ctx->used) {
+ fprintf(stderr, "%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);
+ if (!(bnidx % BN_CTX_POOL_SIZE))
+ item = item->next;
+ }
+ fprintf(stderr, "\n");
+ bnidx = 0;
+ fprintf(stderr, " : ");
+ while (fpidx < stack->depth) {
+ while (bnidx++ < stack->indexes[fpidx])
+ fprintf(stderr, " ");
+ fprintf(stderr, "^^^ ");
+ bnidx++;
+ fpidx++;
+ }
+ fprintf(stderr, "\n");
+}
+
+# define CTXDBG_ENTRY(str, ctx) do { \
+ ctxdbg_cur = (str); \
+ fprintf(stderr,"Starting %s\n", ctxdbg_cur); \
+ ctxdbg(ctx); \
+ } while(0)
+# define CTXDBG_EXIT(ctx) do { \
+ fprintf(stderr,"Ending %s\n", ctxdbg_cur); \
+ ctxdbg(ctx); \
+ } while(0)
+# define CTXDBG_RET(ctx,ret)
+#else
+# define CTXDBG_ENTRY(str, ctx)
+# define CTXDBG_EXIT(ctx)
+# define CTXDBG_RET(ctx,ret)
+#endif
+
+/*
+ * This function is an evil legacy and should not be used. This
+ * implementation is WYSIWYG, though I've done my best.
+ */
+#ifndef OPENSSL_NO_DEPRECATED
+void BN_CTX_init(BN_CTX *ctx)
+{
+ /*
+ * Assume the caller obtained the context via BN_CTX_new() and so is
+ * trying to reset it for use. Nothing else makes sense, least of all
+ * binary compatibility from a time when they could declare a static
+ * variable.
+ */
+ BN_POOL_reset(&ctx->pool);
+ BN_STACK_reset(&ctx->stack);
+ ctx->used = 0;
+ ctx->err_stack = 0;
+ ctx->too_many = 0;
+}
+#endif
+
+BN_CTX *BN_CTX_new(void)
+{
+ BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX));
+ if (!ret) {
+ BNerr(BN_F_BN_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ /* Initialise the structure */
+ BN_POOL_init(&ret->pool);
+ BN_STACK_init(&ret->stack);
+ ret->used = 0;
+ ret->err_stack = 0;
+ ret->too_many = 0;
+ return ret;
+}
+
+void BN_CTX_free(BN_CTX *ctx)
+{
+ if (ctx == NULL)
+ return;
+#ifdef BN_CTX_DEBUG
+ {
+ BN_POOL_ITEM *pool = ctx->pool.head;
+ fprintf(stderr, "BN_CTX_free, stack-size=%d, pool-bignums=%d\n",
+ ctx->stack.size, ctx->pool.size);
+ fprintf(stderr, "dmaxs: ");
+ while (pool) {
+ unsigned loop = 0;
+ while (loop < BN_CTX_POOL_SIZE)
+ fprintf(stderr, "%02x ", pool->vals[loop++].dmax);
+ pool = pool->next;
+ }
+ fprintf(stderr, "\n");
+ }
+#endif
+ BN_STACK_finish(&ctx->stack);
+ BN_POOL_finish(&ctx->pool);
+ OPENSSL_free(ctx);
+}
+
+void BN_CTX_start(BN_CTX *ctx)
+{
+ CTXDBG_ENTRY("BN_CTX_start", ctx);
+ /* If we're already overflowing ... */
+ if (ctx->err_stack || ctx->too_many)
+ ctx->err_stack++;
+ /* (Try to) get a new frame pointer */
+ else if (!BN_STACK_push(&ctx->stack, ctx->used)) {
+ BNerr(BN_F_BN_CTX_START, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+ ctx->err_stack++;
+ }
+ CTXDBG_EXIT(ctx);
+}
+
+void BN_CTX_end(BN_CTX *ctx)
+{
+ CTXDBG_ENTRY("BN_CTX_end", ctx);
+ if (ctx->err_stack)
+ ctx->err_stack--;
+ else {
+ unsigned int fp = BN_STACK_pop(&ctx->stack);
+ /* Does this stack frame have anything to release? */
+ if (fp < ctx->used)
+ BN_POOL_release(&ctx->pool, ctx->used - fp);
+ ctx->used = fp;
+ /* Unjam "too_many" in case "get" had failed */
+ ctx->too_many = 0;
+ }
+ CTXDBG_EXIT(ctx);
+}
+
+BIGNUM *BN_CTX_get(BN_CTX *ctx)
+{
+ BIGNUM *ret;
+ CTXDBG_ENTRY("BN_CTX_get", ctx);
+ if (ctx->err_stack || ctx->too_many)
+ return NULL;
+ if ((ret = BN_POOL_get(&ctx->pool)) == NULL) {
+ /*
+ * Setting too_many prevents repeated "get" attempts from cluttering
+ * the error stack.
+ */
+ ctx->too_many = 1;
+ BNerr(BN_F_BN_CTX_GET, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+ return NULL;
+ }
+ /* OK, make sure the returned bignum is "zero" */
+ BN_zero(ret);
+ ctx->used++;
+ CTXDBG_RET(ctx, ret);
+ return ret;
+}
+
+/************/
+/* BN_STACK */
+/************/
+
+static void BN_STACK_init(BN_STACK *st)
+{
+ st->indexes = NULL;
+ st->depth = st->size = 0;
+}
+
+static void BN_STACK_finish(BN_STACK *st)
+{
+ if (st->size)
+ OPENSSL_free(st->indexes);
+}
+
+#ifndef OPENSSL_NO_DEPRECATED
+static void BN_STACK_reset(BN_STACK *st)
+{
+ st->depth = 0;
+}
+#endif
+
+static int BN_STACK_push(BN_STACK *st, unsigned int idx)
+{
+ if (st->depth == st->size)
+ /* Need to expand */
+ {
+ unsigned int newsize = (st->size ?
+ (st->size * 3 / 2) : BN_CTX_START_FRAMES);
+ unsigned int *newitems = OPENSSL_malloc(newsize *
+ sizeof(unsigned int));
+ if (!newitems)
+ return 0;
+ if (st->depth)
+ memcpy(newitems, st->indexes, st->depth * sizeof(unsigned int));
+ if (st->size)
+ OPENSSL_free(st->indexes);
+ st->indexes = newitems;
+ st->size = newsize;
+ }
+ st->indexes[(st->depth)++] = idx;
+ return 1;
+}
+
+static unsigned int BN_STACK_pop(BN_STACK *st)
+{
+ return st->indexes[--(st->depth)];
+}
+
+/***********/
+/* BN_POOL */
+/***********/
+
+static void BN_POOL_init(BN_POOL *p)
+{
+ p->head = p->current = p->tail = NULL;
+ p->used = p->size = 0;
+}
+
+static void BN_POOL_finish(BN_POOL *p)
+{
+ while (p->head) {
+ unsigned int loop = 0;
+ BIGNUM *bn = p->head->vals;
+ while (loop++ < BN_CTX_POOL_SIZE) {
+ if (bn->d)
+ BN_clear_free(bn);
+ bn++;
+ }
+ p->current = p->head->next;
+ OPENSSL_free(p->head);
+ p->head = p->current;
+ }
+}
+
+#ifndef OPENSSL_NO_DEPRECATED
+static void BN_POOL_reset(BN_POOL *p)
+{
+ BN_POOL_ITEM *item = p->head;
+ while (item) {
+ unsigned int loop = 0;
+ BIGNUM *bn = item->vals;
+ while (loop++ < BN_CTX_POOL_SIZE) {
+ if (bn->d)
+ BN_clear(bn);
+ bn++;
+ }
+ item = item->next;
+ }
+ p->current = p->head;
+ p->used = 0;
+}
+#endif
+
+static BIGNUM *BN_POOL_get(BN_POOL *p)
+{
+ if (p->used == p->size) {
+ BIGNUM *bn;
+ unsigned int loop = 0;
+ BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(BN_POOL_ITEM));
+ if (!item)
+ return NULL;
+ /* Initialise the structure */
+ bn = item->vals;
+ while (loop++ < BN_CTX_POOL_SIZE)
+ BN_init(bn++);
+ item->prev = p->tail;
+ item->next = NULL;
+ /* Link it in */
+ if (!p->head)
+ p->head = p->current = p->tail = item;
+ else {
+ p->tail->next = item;
+ p->tail = item;
+ p->current = item;
+ }
+ p->size += BN_CTX_POOL_SIZE;
+ p->used++;
+ /* Return the first bignum from the new pool */
+ return item->vals;
+ }
+ if (!p->used)
+ p->current = p->head;
+ else if ((p->used % BN_CTX_POOL_SIZE) == 0)
+ p->current = p->current->next;
+ return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE);
+}
+
+static void BN_POOL_release(BN_POOL *p, unsigned int num)
+{
+ unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE;
+ p->used -= num;
+ while (num--) {
+ bn_check_top(p->current->vals + offset);
+ if (!offset) {
+ offset = BN_CTX_POOL_SIZE - 1;
+ p->current = p->current->prev;
+ } else
+ offset--;
+ }
+}
diff --git a/openssl/bn/bn_depr.c b/openssl/bn/bn_depr.c
new file mode 100644
index 0000000..34895f5
--- /dev/null
+++ b/openssl/bn/bn_depr.c
@@ -0,0 +1,115 @@
+/* crypto/bn/bn_depr.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).
+ *
+ */
+
+/*
+ * Support for deprecated functions goes here - static linkage will only
+ * slurp this code if applications are using them directly.
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+
+static void *dummy = &dummy;
+
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
+ const BIGNUM *add, const BIGNUM *rem,
+ void (*callback) (int, int, void *), void *cb_arg)
+{
+ BN_GENCB cb;
+ BIGNUM *rnd = NULL;
+ int found = 0;
+
+ BN_GENCB_set_old(&cb, callback, cb_arg);
+
+ if (ret == NULL) {
+ if ((rnd = BN_new()) == NULL)
+ goto err;
+ } else
+ rnd = ret;
+ if (!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb))
+ goto err;
+
+ /* we have a prime :-) */
+ found = 1;
+ err:
+ if (!found && (ret == NULL) && (rnd != NULL))
+ BN_free(rnd);
+ return (found ? rnd : NULL);
+}
+
+int BN_is_prime(const BIGNUM *a, int checks,
+ void (*callback) (int, int, void *), BN_CTX *ctx_passed,
+ void *cb_arg)
+{
+ BN_GENCB cb;
+ BN_GENCB_set_old(&cb, callback, cb_arg);
+ return BN_is_prime_ex(a, checks, ctx_passed, &cb);
+}
+
+int BN_is_prime_fasttest(const BIGNUM *a, int checks,
+ void (*callback) (int, int, void *),
+ BN_CTX *ctx_passed, void *cb_arg,
+ int do_trial_division)
+{
+ BN_GENCB cb;
+ BN_GENCB_set_old(&cb, callback, cb_arg);
+ return BN_is_prime_fasttest_ex(a, checks, ctx_passed,
+ do_trial_division, &cb);
+}
+#endif
diff --git a/openssl/bn/bn_div.c b/openssl/bn/bn_div.c
new file mode 100644
index 0000000..72e6ce3
--- /dev/null
+++ b/openssl/bn/bn_div.c
@@ -0,0 +1,477 @@
+/* crypto/bn/bn_div.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* The old slow way */
+#if 0
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+ BN_CTX *ctx)
+{
+ int i, nm, nd;
+ int ret = 0;
+ BIGNUM *D;
+
+ bn_check_top(m);
+ bn_check_top(d);
+ if (BN_is_zero(d)) {
+ BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO);
+ return (0);
+ }
+
+ if (BN_ucmp(m, d) < 0) {
+ if (rem != NULL) {
+ if (BN_copy(rem, m) == NULL)
+ return (0);
+ }
+ if (dv != NULL)
+ BN_zero(dv);
+ return (1);
+ }
+
+ BN_CTX_start(ctx);
+ D = BN_CTX_get(ctx);
+ if (dv == NULL)
+ dv = BN_CTX_get(ctx);
+ if (rem == NULL)
+ rem = BN_CTX_get(ctx);
+ if (D == NULL || dv == NULL || rem == NULL)
+ goto end;
+
+ nd = BN_num_bits(d);
+ nm = BN_num_bits(m);
+ if (BN_copy(D, d) == NULL)
+ goto end;
+ if (BN_copy(rem, m) == NULL)
+ goto end;
+
+ /*
+ * The next 2 are needed so we can do a dv->d[0]|=1 later since
+ * BN_lshift1 will only work once there is a value :-)
+ */
+ BN_zero(dv);
+ if (bn_wexpand(dv, 1) == NULL)
+ goto end;
+ dv->top = 1;
+
+ if (!BN_lshift(D, D, nm - nd))
+ goto end;
+ for (i = nm - nd; i >= 0; i--) {
+ if (!BN_lshift1(dv, dv))
+ goto end;
+ if (BN_ucmp(rem, D) >= 0) {
+ dv->d[0] |= 1;
+ if (!BN_usub(rem, rem, D))
+ goto end;
+ }
+/* CAN IMPROVE (and have now :=) */
+ if (!BN_rshift1(D, D))
+ goto end;
+ }
+ rem->neg = BN_is_zero(rem) ? 0 : m->neg;
+ dv->neg = m->neg ^ d->neg;
+ ret = 1;
+ end:
+ BN_CTX_end(ctx);
+ return (ret);
+}
+
+#else
+
+# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \
+ && !defined(PEDANTIC) && !defined(BN_DIV3W)
+# if defined(__GNUC__) && __GNUC__>=2
+# if defined(__i386) || defined (__i386__)
+ /*-
+ * There were two reasons for implementing this template:
+ * - GNU C generates a call to a function (__udivdi3 to be exact)
+ * in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
+ * understand why...);
+ * - divl doesn't only calculate quotient, but also leaves
+ * remainder in %edx which we can definitely use here:-)
+ *
+ * <appro@fy.chalmers.se>
+ */
+# undef bn_div_words
+# define bn_div_words(n0,n1,d0) \
+ ({ asm volatile ( \
+ "divl %4" \
+ : "=a"(q), "=d"(rem) \
+ : "a"(n1), "d"(n0), "g"(d0) \
+ : "cc"); \
+ 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>
+ */
+# undef bn_div_words
+# 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 */
+
+/*-
+ * BN_div computes dv := num / divisor, rounding towards
+ * zero, and sets up rm such that dv*divisor + rm = num holds.
+ * Thus:
+ * dv->neg == num->neg ^ divisor->neg (unless the result is zero)
+ * rm->neg == num->neg (unless the remainder is zero)
+ * If 'dv' or 'rm' is NULL, the respective value is not returned.
+ */
+int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
+ BN_CTX *ctx)
+{
+ int norm_shift, i, loop;
+ BIGNUM *tmp, wnum, *snum, *sdiv, *res;
+ BN_ULONG *resp, *wnump;
+ BN_ULONG d0, d1;
+ int num_n, div_n;
+ int no_branch = 0;
+
+ /*
+ * Invalid zero-padding would have particularly bad consequences so don't
+ * just rely on bn_check_top() here (bn_check_top() works only for
+ * BN_DEBUG builds)
+ */
+ if ((num->top > 0 && num->d[num->top - 1] == 0) ||
+ (divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) {
+ BNerr(BN_F_BN_DIV, BN_R_NOT_INITIALIZED);
+ return 0;
+ }
+
+ bn_check_top(num);
+ bn_check_top(divisor);
+
+ if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0)
+ || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0)) {
+ no_branch = 1;
+ }
+
+ bn_check_top(dv);
+ bn_check_top(rm);
+ /*- bn_check_top(num); *//*
+ * 'num' has been checked already
+ */
+ /*- bn_check_top(divisor); *//*
+ * 'divisor' has been checked already
+ */
+
+ if (BN_is_zero(divisor)) {
+ BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO);
+ return (0);
+ }
+
+ if (!no_branch && BN_ucmp(num, divisor) < 0) {
+ if (rm != NULL) {
+ if (BN_copy(rm, num) == NULL)
+ return (0);
+ }
+ if (dv != NULL)
+ BN_zero(dv);
+ return (1);
+ }
+
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+ snum = BN_CTX_get(ctx);
+ sdiv = BN_CTX_get(ctx);
+ if (dv == NULL)
+ res = BN_CTX_get(ctx);
+ else
+ res = dv;
+ if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL)
+ goto err;
+
+ /* First we normalise the numbers */
+ norm_shift = BN_BITS2 - ((BN_num_bits(divisor)) % BN_BITS2);
+ if (!(BN_lshift(sdiv, divisor, norm_shift)))
+ goto err;
+ sdiv->neg = 0;
+ norm_shift += BN_BITS2;
+ if (!(BN_lshift(snum, num, norm_shift)))
+ goto err;
+ snum->neg = 0;
+
+ if (no_branch) {
+ /*
+ * Since we don't know whether snum is larger than sdiv, we pad snum
+ * with enough zeroes without changing its value.
+ */
+ if (snum->top <= sdiv->top + 1) {
+ if (bn_wexpand(snum, sdiv->top + 2) == NULL)
+ goto err;
+ for (i = snum->top; i < sdiv->top + 2; i++)
+ snum->d[i] = 0;
+ snum->top = sdiv->top + 2;
+ } else {
+ if (bn_wexpand(snum, snum->top + 1) == NULL)
+ goto err;
+ snum->d[snum->top] = 0;
+ snum->top++;
+ }
+ }
+
+ div_n = sdiv->top;
+ num_n = snum->top;
+ loop = num_n - div_n;
+ /*
+ * Lets setup a 'window' into snum This is the part that corresponds to
+ * the current 'area' being divided
+ */
+ wnum.neg = 0;
+ wnum.d = &(snum->d[loop]);
+ wnum.top = div_n;
+ /*
+ * only needed when BN_ucmp messes up the values between top and max
+ */
+ wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */
+
+ /* Get the top 2 words of sdiv */
+ /* div_n=sdiv->top; */
+ d0 = sdiv->d[div_n - 1];
+ d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2];
+
+ /* pointer to the 'top' of snum */
+ wnump = &(snum->d[num_n - 1]);
+
+ /* Setup to 'res' */
+ res->neg = (num->neg ^ divisor->neg);
+ if (!bn_wexpand(res, (loop + 1)))
+ goto err;
+ res->top = loop - no_branch;
+ resp = &(res->d[loop - 1]);
+
+ /* space for temp */
+ if (!bn_wexpand(tmp, (div_n + 1)))
+ goto err;
+
+ if (!no_branch) {
+ if (BN_ucmp(&wnum, sdiv) >= 0) {
+ /*
+ * If BN_DEBUG_RAND is defined BN_ucmp changes (via bn_pollute)
+ * the const bignum arguments => clean the values between top and
+ * max again
+ */
+ bn_clear_top2max(&wnum);
+ bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n);
+ *resp = 1;
+ } else
+ res->top--;
+ }
+
+ /*
+ * if res->top == 0 then clear the neg value otherwise decrease the resp
+ * pointer
+ */
+ if (res->top == 0)
+ res->neg = 0;
+ else
+ resp--;
+
+ for (i = 0; i < loop - 1; i++, wnump--, resp--) {
+ BN_ULONG q, l0;
+ /*
+ * the first part of the loop uses the top two words of snum and sdiv
+ * to calculate a BN_ULONG q such that | wnum - sdiv * q | < sdiv
+ */
+# if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
+ BN_ULONG bn_div_3_words(BN_ULONG *, BN_ULONG, BN_ULONG);
+ q = bn_div_3_words(wnump, d1, d0);
+# else
+ BN_ULONG n0, n1, rem = 0;
+
+ n0 = wnump[0];
+ n1 = wnump[-1];
+ if (n0 == d0)
+ q = BN_MASK2;
+ else { /* n0 < d0 */
+
+# ifdef BN_LLONG
+ BN_ULLONG t2;
+
+# if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
+ 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
+ /*
+ * rem doesn't have to be BN_ULLONG. The least we
+ * know it's less that d0, isn't it?
+ */
+ rem = (n1 - q * d0) & BN_MASK2;
+# endif
+ t2 = (BN_ULLONG) d1 *q;
+
+ for (;;) {
+ if (t2 <= ((((BN_ULLONG) rem) << BN_BITS2) | wnump[-2]))
+ break;
+ q--;
+ rem += d0;
+ if (rem < d0)
+ break; /* don't let rem overflow */
+ t2 -= d1;
+ }
+# else /* !BN_LLONG */
+ BN_ULONG t2l, t2h;
+
+ 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)
+ t2l = d1 * q;
+ t2h = BN_UMULT_HIGH(d1, q);
+# else
+ {
+ BN_ULONG ql, qh;
+ t2l = LBITS(d1);
+ t2h = HBITS(d1);
+ ql = LBITS(q);
+ qh = HBITS(q);
+ mul64(t2l, t2h, ql, qh); /* t2=(BN_ULLONG)d1*q; */
+ }
+# endif
+
+ for (;;) {
+ if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2])))
+ break;
+ q--;
+ rem += d0;
+ if (rem < d0)
+ break; /* don't let rem overflow */
+ if (t2l < d1)
+ t2h--;
+ t2l -= d1;
+ }
+# endif /* !BN_LLONG */
+ }
+# endif /* !BN_DIV3W */
+
+ l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q);
+ tmp->d[div_n] = l0;
+ wnum.d--;
+ /*
+ * ingore top values of the bignums just sub the two BN_ULONG arrays
+ * with bn_sub_words
+ */
+ if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n + 1)) {
+ /*
+ * Note: As we have considered only the leading two BN_ULONGs in
+ * the calculation of q, sdiv * q might be greater than wnum (but
+ * then (q-1) * sdiv is less or equal than wnum)
+ */
+ q--;
+ if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
+ /*
+ * we can't have an overflow here (assuming that q != 0, but
+ * if q == 0 then tmp is zero anyway)
+ */
+ (*wnump)++;
+ }
+ /* store part of the result */
+ *resp = q;
+ }
+ bn_correct_top(snum);
+ if (rm != NULL) {
+ /*
+ * Keep a copy of the neg flag in num because if rm==num BN_rshift()
+ * will overwrite it.
+ */
+ int neg = num->neg;
+ BN_rshift(rm, snum, norm_shift);
+ if (!BN_is_zero(rm))
+ rm->neg = neg;
+ bn_check_top(rm);
+ }
+ if (no_branch)
+ bn_correct_top(res);
+ BN_CTX_end(ctx);
+ return (1);
+ err:
+ bn_check_top(rm);
+ BN_CTX_end(ctx);
+ return (0);
+}
+#endif
diff --git a/openssl/bn/bn_err.c b/openssl/bn/bn_err.c
new file mode 100644
index 0000000..faa7e22
--- /dev/null
+++ b/openssl/bn/bn_err.c
@@ -0,0 +1,150 @@
+/* crypto/bn/bn_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2007 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).
+ *
+ */
+
+/*
+ * NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BN,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BN,0,reason)
+
+static ERR_STRING_DATA BN_str_functs[] = {
+ {ERR_FUNC(BN_F_BNRAND), "BNRAND"},
+ {ERR_FUNC(BN_F_BN_BLINDING_CONVERT_EX), "BN_BLINDING_convert_ex"},
+ {ERR_FUNC(BN_F_BN_BLINDING_CREATE_PARAM), "BN_BLINDING_create_param"},
+ {ERR_FUNC(BN_F_BN_BLINDING_INVERT_EX), "BN_BLINDING_invert_ex"},
+ {ERR_FUNC(BN_F_BN_BLINDING_NEW), "BN_BLINDING_new"},
+ {ERR_FUNC(BN_F_BN_BLINDING_UPDATE), "BN_BLINDING_update"},
+ {ERR_FUNC(BN_F_BN_BN2DEC), "BN_bn2dec"},
+ {ERR_FUNC(BN_F_BN_BN2HEX), "BN_bn2hex"},
+ {ERR_FUNC(BN_F_BN_CTX_GET), "BN_CTX_get"},
+ {ERR_FUNC(BN_F_BN_CTX_NEW), "BN_CTX_new"},
+ {ERR_FUNC(BN_F_BN_CTX_START), "BN_CTX_start"},
+ {ERR_FUNC(BN_F_BN_DIV), "BN_div"},
+ {ERR_FUNC(BN_F_BN_DIV_NO_BRANCH), "BN_div_no_branch"},
+ {ERR_FUNC(BN_F_BN_DIV_RECP), "BN_div_recp"},
+ {ERR_FUNC(BN_F_BN_EXP), "BN_exp"},
+ {ERR_FUNC(BN_F_BN_EXPAND2), "bn_expand2"},
+ {ERR_FUNC(BN_F_BN_EXPAND_INTERNAL), "BN_EXPAND_INTERNAL"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD), "BN_GF2m_mod"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD_EXP), "BN_GF2m_mod_exp"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD_MUL), "BN_GF2m_mod_mul"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD), "BN_GF2m_mod_solve_quad"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR), "BN_GF2m_mod_solve_quad_arr"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD_SQR), "BN_GF2m_mod_sqr"},
+ {ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT), "BN_GF2m_mod_sqrt"},
+ {ERR_FUNC(BN_F_BN_MOD_EXP2_MONT), "BN_mod_exp2_mont"},
+ {ERR_FUNC(BN_F_BN_MOD_EXP_MONT), "BN_mod_exp_mont"},
+ {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME), "BN_mod_exp_mont_consttime"},
+ {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_WORD), "BN_mod_exp_mont_word"},
+ {ERR_FUNC(BN_F_BN_MOD_EXP_RECP), "BN_mod_exp_recp"},
+ {ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE), "BN_mod_exp_simple"},
+ {ERR_FUNC(BN_F_BN_MOD_INVERSE), "BN_mod_inverse"},
+ {ERR_FUNC(BN_F_BN_MOD_INVERSE_NO_BRANCH), "BN_mod_inverse_no_branch"},
+ {ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK), "BN_mod_lshift_quick"},
+ {ERR_FUNC(BN_F_BN_MOD_MUL_RECIPROCAL), "BN_mod_mul_reciprocal"},
+ {ERR_FUNC(BN_F_BN_MOD_SQRT), "BN_mod_sqrt"},
+ {ERR_FUNC(BN_F_BN_MPI2BN), "BN_mpi2bn"},
+ {ERR_FUNC(BN_F_BN_NEW), "BN_new"},
+ {ERR_FUNC(BN_F_BN_RAND), "BN_rand"},
+ {ERR_FUNC(BN_F_BN_RAND_RANGE), "BN_rand_range"},
+ {ERR_FUNC(BN_F_BN_USUB), "BN_usub"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA BN_str_reasons[] = {
+ {ERR_REASON(BN_R_ARG2_LT_ARG3), "arg2 lt arg3"},
+ {ERR_REASON(BN_R_BAD_RECIPROCAL), "bad reciprocal"},
+ {ERR_REASON(BN_R_BIGNUM_TOO_LONG), "bignum too long"},
+ {ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS), "called with even modulus"},
+ {ERR_REASON(BN_R_DIV_BY_ZERO), "div by zero"},
+ {ERR_REASON(BN_R_ENCODING_ERROR), "encoding error"},
+ {ERR_REASON(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA),
+ "expand on static bignum data"},
+ {ERR_REASON(BN_R_INPUT_NOT_REDUCED), "input not reduced"},
+ {ERR_REASON(BN_R_INVALID_LENGTH), "invalid length"},
+ {ERR_REASON(BN_R_INVALID_RANGE), "invalid range"},
+ {ERR_REASON(BN_R_NOT_A_SQUARE), "not a square"},
+ {ERR_REASON(BN_R_NOT_INITIALIZED), "not initialized"},
+ {ERR_REASON(BN_R_NO_INVERSE), "no inverse"},
+ {ERR_REASON(BN_R_NO_SOLUTION), "no solution"},
+ {ERR_REASON(BN_R_P_IS_NOT_PRIME), "p is not prime"},
+ {ERR_REASON(BN_R_TOO_MANY_ITERATIONS), "too many iterations"},
+ {ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES),
+ "too many temporary variables"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_BN_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(BN_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, BN_str_functs);
+ ERR_load_strings(0, BN_str_reasons);
+ }
+#endif
+}
diff --git a/openssl/bn/bn_exp.c b/openssl/bn/bn_exp.c
new file mode 100644
index 0000000..27146c8
--- /dev/null
+++ b/openssl/bn/bn_exp.c
@@ -0,0 +1,1120 @@
+/* crypto/bn/bn_exp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 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 "cryptlib.h"
+#include "bn_lcl.h"
+
+#include <stdlib.h>
+#ifdef _WIN32
+# include <malloc.h>
+# ifndef alloca
+# define alloca _alloca
+# endif
+#elif defined(__GNUC__)
+# ifndef alloca
+# define alloca(s) __builtin_alloca((s))
+# endif
+#endif
+
+/* maximum precomputation table size for *variable* sliding windows */
+#define TABLE_SIZE 32
+
+/* this one works - simple but works */
+int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+{
+ int i, bits, ret = 0;
+ BIGNUM *v, *rr;
+
+ if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+ /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+ BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
+
+ BN_CTX_start(ctx);
+ if ((r == a) || (r == p))
+ rr = BN_CTX_get(ctx);
+ else
+ rr = r;
+ v = BN_CTX_get(ctx);
+ if (rr == NULL || v == NULL)
+ goto err;
+
+ if (BN_copy(v, a) == NULL)
+ goto err;
+ bits = BN_num_bits(p);
+
+ if (BN_is_odd(p)) {
+ if (BN_copy(rr, a) == NULL)
+ goto err;
+ } else {
+ if (!BN_one(rr))
+ goto err;
+ }
+
+ for (i = 1; i < bits; i++) {
+ if (!BN_sqr(v, v, ctx))
+ goto err;
+ if (BN_is_bit_set(p, i)) {
+ if (!BN_mul(rr, rr, v, ctx))
+ goto err;
+ }
+ }
+ if (r != rr)
+ BN_copy(r, rr);
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(r);
+ return (ret);
+}
+
+int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+ BN_CTX *ctx)
+{
+ int ret;
+
+ bn_check_top(a);
+ bn_check_top(p);
+ bn_check_top(m);
+
+ /*-
+ * For even modulus m = 2^k*m_odd, it might make sense to compute
+ * a^p mod m_odd and a^p mod 2^k separately (with Montgomery
+ * exponentiation for the odd part), using appropriate exponent
+ * reductions, and combine the results using the CRT.
+ *
+ * For now, we use Montgomery only if the modulus is odd; otherwise,
+ * exponentiation using the reciprocal-based quick remaindering
+ * algorithm is used.
+ *
+ * (Timing obtained with expspeed.c [computations a^p mod m
+ * where a, p, m are of the same length: 256, 512, 1024, 2048,
+ * 4096, 8192 bits], compared to the running time of the
+ * standard algorithm:
+ *
+ * BN_mod_exp_mont 33 .. 40 % [AMD K6-2, Linux, debug configuration]
+ * 55 .. 77 % [UltraSparc processor, but
+ * debug-solaris-sparcv8-gcc conf.]
+ *
+ * BN_mod_exp_recp 50 .. 70 % [AMD K6-2, Linux, debug configuration]
+ * 62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
+ *
+ * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont
+ * at 2048 and more bits, but at 512 and 1024 bits, it was
+ * slower even than the standard algorithm!
+ *
+ * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]
+ * should be obtained when the new Montgomery reduction code
+ * has been integrated into OpenSSL.)
+ */
+
+#define MONT_MUL_MOD
+#define MONT_EXP_WORD
+#define RECP_MUL_MOD
+
+#ifdef MONT_MUL_MOD
+ /*
+ * I have finally been able to take out this pre-condition of the top bit
+ * being set. It was caused by an error in BN_div with negatives. There
+ * was also another problem when for a^b%m a >= m. eay 07-May-97
+ */
+ /* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
+
+ if (BN_is_odd(m)) {
+# ifdef MONT_EXP_WORD
+ if (a->top == 1 && !a->neg
+ && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) {
+ BN_ULONG A = a->d[0];
+ ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL);
+ } else
+# endif
+ ret = BN_mod_exp_mont(r, a, p, m, ctx, NULL);
+ } else
+#endif
+#ifdef RECP_MUL_MOD
+ {
+ ret = BN_mod_exp_recp(r, a, p, m, ctx);
+ }
+#else
+ {
+ ret = BN_mod_exp_simple(r, a, p, m, ctx);
+ }
+#endif
+
+ bn_check_top(r);
+ return (ret);
+}
+
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+{
+ int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+ int start = 1;
+ BIGNUM *aa;
+ /* Table of variables obtained from 'ctx' */
+ BIGNUM *val[TABLE_SIZE];
+ BN_RECP_CTX recp;
+
+ if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+ /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+ BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
+
+ bits = BN_num_bits(p);
+
+ if (bits == 0) {
+ ret = BN_one(r);
+ return ret;
+ }
+
+ BN_CTX_start(ctx);
+ aa = BN_CTX_get(ctx);
+ val[0] = BN_CTX_get(ctx);
+ if (!aa || !val[0])
+ goto err;
+
+ BN_RECP_CTX_init(&recp);
+ if (m->neg) {
+ /* ignore sign of 'm' */
+ if (!BN_copy(aa, m))
+ goto err;
+ aa->neg = 0;
+ if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0)
+ goto err;
+ } else {
+ if (BN_RECP_CTX_set(&recp, m, ctx) <= 0)
+ goto err;
+ }
+
+ if (!BN_nnmod(val[0], a, m, ctx))
+ goto err; /* 1 */
+ if (BN_is_zero(val[0])) {
+ BN_zero(r);
+ ret = 1;
+ goto err;
+ }
+
+ window = BN_window_bits_for_exponent_size(bits);
+ if (window > 1) {
+ if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx))
+ goto err; /* 2 */
+ j = 1 << (window - 1);
+ for (i = 1; i < j; i++) {
+ if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
+ !BN_mod_mul_reciprocal(val[i], val[i - 1], aa, &recp, ctx))
+ goto err;
+ }
+ }
+
+ start = 1; /* This is used to avoid multiplication etc
+ * when there is only the value '1' in the
+ * buffer. */
+ wvalue = 0; /* The 'value' of the window */
+ wstart = bits - 1; /* The top bit of the window */
+ wend = 0; /* The bottom bit of the window */
+
+ if (!BN_one(r))
+ goto err;
+
+ for (;;) {
+ if (BN_is_bit_set(p, wstart) == 0) {
+ if (!start)
+ if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx))
+ goto err;
+ if (wstart == 0)
+ break;
+ wstart--;
+ continue;
+ }
+ /*
+ * We now have wstart on a 'set' bit, we now need to work out how bit
+ * a window to do. To do this we need to scan forward until the last
+ * set bit before the end of the window
+ */
+ j = wstart;
+ wvalue = 1;
+ wend = 0;
+ for (i = 1; i < window; i++) {
+ if (wstart - i < 0)
+ break;
+ if (BN_is_bit_set(p, wstart - i)) {
+ wvalue <<= (i - wend);
+ wvalue |= 1;
+ wend = i;
+ }
+ }
+
+ /* wend is the size of the current window */
+ j = wend + 1;
+ /* add the 'bytes above' */
+ if (!start)
+ for (i = 0; i < j; i++) {
+ if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx))
+ goto err;
+ }
+
+ /* wvalue will be an odd number < 2^window */
+ if (!BN_mod_mul_reciprocal(r, r, val[wvalue >> 1], &recp, ctx))
+ goto err;
+
+ /* move the 'window' down further */
+ wstart -= wend + 1;
+ wvalue = 0;
+ start = 0;
+ if (wstart < 0)
+ break;
+ }
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ BN_RECP_CTX_free(&recp);
+ bn_check_top(r);
+ return (ret);
+}
+
+int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+ int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+ int start = 1;
+ BIGNUM *d, *r;
+ const BIGNUM *aa;
+ /* Table of variables obtained from 'ctx' */
+ BIGNUM *val[TABLE_SIZE];
+ BN_MONT_CTX *mont = NULL;
+
+ if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+ return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
+ }
+
+ bn_check_top(a);
+ bn_check_top(p);
+ bn_check_top(m);
+
+ if (!BN_is_odd(m)) {
+ BNerr(BN_F_BN_MOD_EXP_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);
+ return (0);
+ }
+ bits = BN_num_bits(p);
+ if (bits == 0) {
+ ret = BN_one(rr);
+ return ret;
+ }
+
+ BN_CTX_start(ctx);
+ d = BN_CTX_get(ctx);
+ r = BN_CTX_get(ctx);
+ val[0] = BN_CTX_get(ctx);
+ if (!d || !r || !val[0])
+ goto err;
+
+ /*
+ * If this is not done, things will break in the montgomery part
+ */
+
+ if (in_mont != NULL)
+ mont = in_mont;
+ else {
+ if ((mont = BN_MONT_CTX_new()) == NULL)
+ goto err;
+ if (!BN_MONT_CTX_set(mont, m, ctx))
+ goto err;
+ }
+
+ if (a->neg || BN_ucmp(a, m) >= 0) {
+ if (!BN_nnmod(val[0], a, m, ctx))
+ goto err;
+ aa = val[0];
+ } else
+ aa = a;
+ if (BN_is_zero(aa)) {
+ BN_zero(rr);
+ ret = 1;
+ goto err;
+ }
+ if (!BN_to_montgomery(val[0], aa, mont, ctx))
+ goto err; /* 1 */
+
+ window = BN_window_bits_for_exponent_size(bits);
+ if (window > 1) {
+ if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx))
+ goto err; /* 2 */
+ j = 1 << (window - 1);
+ for (i = 1; i < j; i++) {
+ if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
+ !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx))
+ goto err;
+ }
+ }
+
+ start = 1; /* This is used to avoid multiplication etc
+ * when there is only the value '1' in the
+ * buffer. */
+ wvalue = 0; /* The 'value' of the window */
+ wstart = bits - 1; /* The top bit of the window */
+ wend = 0; /* The bottom bit of the window */
+
+ if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
+ goto err;
+ for (;;) {
+ if (BN_is_bit_set(p, wstart) == 0) {
+ if (!start) {
+ if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+ goto err;
+ }
+ if (wstart == 0)
+ break;
+ wstart--;
+ continue;
+ }
+ /*
+ * We now have wstart on a 'set' bit, we now need to work out how bit
+ * a window to do. To do this we need to scan forward until the last
+ * set bit before the end of the window
+ */
+ j = wstart;
+ wvalue = 1;
+ wend = 0;
+ for (i = 1; i < window; i++) {
+ if (wstart - i < 0)
+ break;
+ if (BN_is_bit_set(p, wstart - i)) {
+ wvalue <<= (i - wend);
+ wvalue |= 1;
+ wend = i;
+ }
+ }
+
+ /* wend is the size of the current window */
+ j = wend + 1;
+ /* add the 'bytes above' */
+ if (!start)
+ for (i = 0; i < j; i++) {
+ if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+ goto err;
+ }
+
+ /* wvalue will be an odd number < 2^window */
+ if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx))
+ goto err;
+
+ /* move the 'window' down further */
+ wstart -= wend + 1;
+ wvalue = 0;
+ start = 0;
+ if (wstart < 0)
+ break;
+ }
+ if (!BN_from_montgomery(rr, r, mont, ctx))
+ goto err;
+ ret = 1;
+ err:
+ if ((in_mont == NULL) && (mont != NULL))
+ BN_MONT_CTX_free(mont);
+ BN_CTX_end(ctx);
+ bn_check_top(rr);
+ return (ret);
+}
+
+/*
+ * BN_mod_exp_mont_consttime() stores the precomputed powers in a specific
+ * layout so that accessing any of these table values shows the same access
+ * pattern as far as cache lines are concerned. The following functions are
+ * used to transfer a BIGNUM from/to that table.
+ */
+
+static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top,
+ unsigned char *buf, int idx,
+ int width)
+{
+ size_t i, j;
+
+ if (top > b->top)
+ top = b->top; /* this works because 'buf' is explicitly
+ * zeroed */
+ for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
+ buf[j] = ((unsigned char *)b->d)[i];
+ }
+
+ return 1;
+}
+
+static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
+ unsigned char *buf, int idx,
+ int width)
+{
+ size_t i, j;
+
+ if (bn_wexpand(b, top) == NULL)
+ return 0;
+
+ for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
+ ((unsigned char *)b->d)[i] = buf[j];
+ }
+
+ b->top = top;
+ bn_correct_top(b);
+ return 1;
+}
+
+/*
+ * Given a pointer value, compute the next address that is a cache line
+ * multiple.
+ */
+#define MOD_EXP_CTIME_ALIGN(x_) \
+ ((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK))))
+
+/*
+ * This variant of BN_mod_exp_mont() uses fixed windows and the special
+ * precomputation memory layout to limit data-dependency to a minimum to
+ * protect secret exponents (cf. the hyper-threading timing attacks pointed
+ * out by Colin Percival,
+ * http://www.daemong-consideredperthreading-considered-harmful/)
+ */
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *in_mont)
+{
+ int i, bits, ret = 0, window, wvalue;
+ int top;
+ BN_MONT_CTX *mont = NULL;
+
+ int numPowers;
+ unsigned char *powerbufFree = NULL;
+ int powerbufLen = 0;
+ unsigned char *powerbuf = NULL;
+ BIGNUM tmp, am;
+
+ bn_check_top(a);
+ bn_check_top(p);
+ bn_check_top(m);
+
+ top = m->top;
+
+ if (!(m->d[0] & 1)) {
+ BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME, BN_R_CALLED_WITH_EVEN_MODULUS);
+ return (0);
+ }
+ bits = BN_num_bits(p);
+ if (bits == 0) {
+ ret = BN_one(rr);
+ return ret;
+ }
+
+ BN_CTX_start(ctx);
+
+ /*
+ * Allocate a montgomery context if it was not supplied by the caller. If
+ * this is not done, things will break in the montgomery part.
+ */
+ if (in_mont != NULL)
+ mont = in_mont;
+ else {
+ if ((mont = BN_MONT_CTX_new()) == NULL)
+ goto err;
+ if (!BN_MONT_CTX_set(mont, m, ctx))
+ goto err;
+ }
+
+ /* Get the window size to use with size of p. */
+ window = BN_window_bits_for_ctime_exponent_size(bits);
+#if defined(OPENSSL_BN_ASM_MONT5)
+ if (window == 6 && bits <= 1024)
+ window = 5; /* ~5% improvement of 2048-bit RSA sign */
+#endif
+
+ /*
+ * Allocate a buffer large enough to hold all of the pre-computed powers
+ * of am, am itself and tmp.
+ */
+ numPowers = 1 << window;
+ powerbufLen = sizeof(m->d[0]) * (top * numPowers +
+ ((2 * top) >
+ numPowers ? (2 * top) : numPowers));
+#ifdef alloca
+ if (powerbufLen < 3072)
+ powerbufFree =
+ alloca(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH);
+ else
+#endif
+ if ((powerbufFree =
+ (unsigned char *)OPENSSL_malloc(powerbufLen +
+ MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH))
+ == NULL)
+ goto err;
+
+ powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
+ memset(powerbuf, 0, powerbufLen);
+
+#ifdef alloca
+ if (powerbufLen < 3072)
+ powerbufFree = NULL;
+#endif
+
+ /* lay down tmp and am right after powers table */
+ tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0]) * top * numPowers);
+ am.d = tmp.d + top;
+ tmp.top = am.top = 0;
+ tmp.dmax = am.dmax = top;
+ tmp.neg = am.neg = 0;
+ tmp.flags = am.flags = BN_FLG_STATIC_DATA;
+
+ /* prepare a^0 in Montgomery domain */
+#if 1
+ if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx))
+ goto err;
+#else
+ tmp.d[0] = (0 - m->d[0]) & BN_MASK2; /* 2^(top*BN_BITS2) - m */
+ for (i = 1; i < top; i++)
+ tmp.d[i] = (~m->d[i]) & BN_MASK2;
+ tmp.top = top;
+#endif
+
+ /* prepare a^1 in Montgomery domain */
+ if (a->neg || BN_ucmp(a, m) >= 0) {
+ if (!BN_mod(&am, a, m, ctx))
+ goto err;
+ if (!BN_to_montgomery(&am, &am, mont, ctx))
+ goto err;
+ } else if (!BN_to_montgomery(&am, a, mont, ctx))
+ goto err;
+
+#if defined(OPENSSL_BN_ASM_MONT5)
+ if (window == 5 && top > 1) {
+ /*
+ * This optimization uses ideas from http://eprint.iacr.org/2011/239,
+ * specifically optimization of cache-timing attack countermeasures
+ * and pre-computation optimization.
+ */
+
+ /*
+ * Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
+ * 512-bit RSA is hardly relevant, we omit it to spare size...
+ */
+ void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap,
+ const void *table, const BN_ULONG *np,
+ const BN_ULONG *n0, int num, int power);
+ void bn_scatter5(const BN_ULONG *inp, size_t num,
+ void *table, size_t power);
+ void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power);
+
+ BN_ULONG *np = mont->N.d, *n0 = mont->n0;
+
+ /*
+ * BN_to_montgomery can contaminate words above .top [in
+ * BN_DEBUG[_DEBUG] build]...
+ */
+ for (i = am.top; i < top; i++)
+ am.d[i] = 0;
+ for (i = tmp.top; i < top; i++)
+ tmp.d[i] = 0;
+
+ bn_scatter5(tmp.d, top, powerbuf, 0);
+ bn_scatter5(am.d, am.top, powerbuf, 1);
+ bn_mul_mont(tmp.d, am.d, am.d, np, n0, top);
+ bn_scatter5(tmp.d, top, powerbuf, 2);
+
+# if 0
+ for (i = 3; i < 32; i++) {
+ /* Calculate a^i = a^(i-1) * a */
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+ bn_scatter5(tmp.d, top, powerbuf, i);
+ }
+# else
+ /* same as above, but uses squaring for 1/2 of operations */
+ for (i = 4; i < 32; i *= 2) {
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_scatter5(tmp.d, top, powerbuf, i);
+ }
+ for (i = 3; i < 8; i += 2) {
+ int j;
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+ bn_scatter5(tmp.d, top, powerbuf, i);
+ for (j = 2 * i; j < 32; j *= 2) {
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_scatter5(tmp.d, top, powerbuf, j);
+ }
+ }
+ for (; i < 16; i += 2) {
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+ bn_scatter5(tmp.d, top, powerbuf, i);
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_scatter5(tmp.d, top, powerbuf, 2 * i);
+ }
+ for (; i < 32; i += 2) {
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+ bn_scatter5(tmp.d, top, powerbuf, i);
+ }
+# endif
+ bits--;
+ for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)
+ wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+ bn_gather5(tmp.d, top, powerbuf, wvalue);
+
+ /*
+ * Scan the exponent one window at a time starting from the most
+ * significant bits.
+ */
+ while (bits >= 0) {
+ for (wvalue = 0, i = 0; i < 5; i++, bits--)
+ wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+ bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
+ }
+
+ tmp.top = top;
+ bn_correct_top(&tmp);
+ } else
+#endif
+ {
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, numPowers))
+ goto err;
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, numPowers))
+ goto err;
+
+ /*
+ * If the window size is greater than 1, then calculate
+ * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1) (even
+ * powers could instead be computed as (a^(i/2))^2 to use the slight
+ * performance advantage of sqr over mul).
+ */
+ if (window > 1) {
+ if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
+ goto err;
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF
+ (&tmp, top, powerbuf, 2, numPowers))
+ goto err;
+ for (i = 3; i < numPowers; i++) {
+ /* Calculate a^i = a^(i-1) * a */
+ if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx))
+ goto err;
+ if (!MOD_EXP_CTIME_COPY_TO_PREBUF
+ (&tmp, top, powerbuf, i, numPowers))
+ goto err;
+ }
+ }
+
+ bits--;
+ for (wvalue = 0, i = bits % window; i >= 0; i--, bits--)
+ wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+ if (!MOD_EXP_CTIME_COPY_FROM_PREBUF
+ (&tmp, top, powerbuf, wvalue, numPowers))
+ goto err;
+
+ /*
+ * Scan the exponent one window at a time starting from the most
+ * significant bits.
+ */
+ while (bits >= 0) {
+ wvalue = 0; /* The 'value' of the window */
+
+ /* Scan the window, squaring the result as we go */
+ for (i = 0; i < window; i++, bits--) {
+ if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx))
+ goto err;
+ wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+ }
+
+ /*
+ * Fetch the appropriate pre-computed value from the pre-buf
+ */
+ if (!MOD_EXP_CTIME_COPY_FROM_PREBUF
+ (&am, top, powerbuf, wvalue, numPowers))
+ goto err;
+
+ /* Multiply the result into the intermediate result */
+ if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))
+ goto err;
+ }
+ }
+
+ /* Convert the final result from montgomery to standard format */
+ if (!BN_from_montgomery(rr, &tmp, mont, ctx))
+ goto err;
+ ret = 1;
+ err:
+ if ((in_mont == NULL) && (mont != NULL))
+ BN_MONT_CTX_free(mont);
+ if (powerbuf != NULL) {
+ OPENSSL_cleanse(powerbuf, powerbufLen);
+ if (powerbufFree)
+ OPENSSL_free(powerbufFree);
+ }
+ BN_CTX_end(ctx);
+ return (ret);
+}
+
+int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+ BN_MONT_CTX *mont = NULL;
+ int b, bits, ret = 0;
+ int r_is_one;
+ BN_ULONG w, next_w;
+ BIGNUM *d, *r, *t;
+ BIGNUM *swap_tmp;
+#define BN_MOD_MUL_WORD(r, w, m) \
+ (BN_mul_word(r, (w)) && \
+ (/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \
+ (BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))
+ /*
+ * BN_MOD_MUL_WORD is only used with 'w' large, so the BN_ucmp test is
+ * probably more overhead than always using BN_mod (which uses BN_copy if
+ * a similar test returns true).
+ */
+ /*
+ * We can use BN_mod and do not need BN_nnmod because our accumulator is
+ * never negative (the result of BN_mod does not depend on the sign of
+ * the modulus).
+ */
+#define BN_TO_MONTGOMERY_WORD(r, w, mont) \
+ (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
+
+ if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+ /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+ BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
+
+ bn_check_top(p);
+ bn_check_top(m);
+
+ if (!BN_is_odd(m)) {
+ BNerr(BN_F_BN_MOD_EXP_MONT_WORD, BN_R_CALLED_WITH_EVEN_MODULUS);
+ return (0);
+ }
+ if (m->top == 1)
+ a %= m->d[0]; /* make sure that 'a' is reduced */
+
+ bits = BN_num_bits(p);
+ if (bits == 0) {
+ /* x**0 mod 1 is still zero. */
+ if (BN_is_one(m)) {
+ ret = 1;
+ BN_zero(rr);
+ } else
+ ret = BN_one(rr);
+ return ret;
+ }
+ if (a == 0) {
+ BN_zero(rr);
+ ret = 1;
+ return ret;
+ }
+
+ BN_CTX_start(ctx);
+ d = BN_CTX_get(ctx);
+ r = BN_CTX_get(ctx);
+ t = BN_CTX_get(ctx);
+ if (d == NULL || r == NULL || t == NULL)
+ goto err;
+
+ if (in_mont != NULL)
+ mont = in_mont;
+ else {
+ if ((mont = BN_MONT_CTX_new()) == NULL)
+ goto err;
+ if (!BN_MONT_CTX_set(mont, m, ctx))
+ goto err;
+ }
+
+ r_is_one = 1; /* except for Montgomery factor */
+
+ /* bits-1 >= 0 */
+
+ /* The result is accumulated in the product r*w. */
+ w = a; /* bit 'bits-1' of 'p' is always set */
+ for (b = bits - 2; b >= 0; b--) {
+ /* First, square r*w. */
+ next_w = w * w;
+ if ((next_w / w) != w) { /* overflow */
+ if (r_is_one) {
+ if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
+ goto err;
+ r_is_one = 0;
+ } else {
+ if (!BN_MOD_MUL_WORD(r, w, m))
+ goto err;
+ }
+ next_w = 1;
+ }
+ w = next_w;
+ if (!r_is_one) {
+ if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+ goto err;
+ }
+
+ /* Second, multiply r*w by 'a' if exponent bit is set. */
+ if (BN_is_bit_set(p, b)) {
+ next_w = w * a;
+ if ((next_w / a) != w) { /* overflow */
+ if (r_is_one) {
+ if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
+ goto err;
+ r_is_one = 0;
+ } else {
+ if (!BN_MOD_MUL_WORD(r, w, m))
+ goto err;
+ }
+ next_w = a;
+ }
+ w = next_w;
+ }
+ }
+
+ /* Finally, set r:=r*w. */
+ if (w != 1) {
+ if (r_is_one) {
+ if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
+ goto err;
+ r_is_one = 0;
+ } else {
+ if (!BN_MOD_MUL_WORD(r, w, m))
+ goto err;
+ }
+ }
+
+ if (r_is_one) { /* can happen only if a == 1 */
+ if (!BN_one(rr))
+ goto err;
+ } else {
+ if (!BN_from_montgomery(rr, r, mont, ctx))
+ goto err;
+ }
+ ret = 1;
+ err:
+ if ((in_mont == NULL) && (mont != NULL))
+ BN_MONT_CTX_free(mont);
+ BN_CTX_end(ctx);
+ bn_check_top(rr);
+ return (ret);
+}
+
+/* The old fallback, simple version :-) */
+int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx)
+{
+ int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+ int start = 1;
+ BIGNUM *d;
+ /* Table of variables obtained from 'ctx' */
+ BIGNUM *val[TABLE_SIZE];
+
+ if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+ /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+ BNerr(BN_F_BN_MOD_EXP_SIMPLE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
+
+ bits = BN_num_bits(p);
+
+ if (bits == 0) {
+ ret = BN_one(r);
+ return ret;
+ }
+
+ BN_CTX_start(ctx);
+ d = BN_CTX_get(ctx);
+ val[0] = BN_CTX_get(ctx);
+ if (!d || !val[0])
+ goto err;
+
+ if (!BN_nnmod(val[0], a, m, ctx))
+ goto err; /* 1 */
+ if (BN_is_zero(val[0])) {
+ BN_zero(r);
+ ret = 1;
+ goto err;
+ }
+
+ window = BN_window_bits_for_exponent_size(bits);
+ if (window > 1) {
+ if (!BN_mod_mul(d, val[0], val[0], m, ctx))
+ goto err; /* 2 */
+ j = 1 << (window - 1);
+ for (i = 1; i < j; i++) {
+ if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
+ !BN_mod_mul(val[i], val[i - 1], d, m, ctx))
+ goto err;
+ }
+ }
+
+ start = 1; /* This is used to avoid multiplication etc
+ * when there is only the value '1' in the
+ * buffer. */
+ wvalue = 0; /* The 'value' of the window */
+ wstart = bits - 1; /* The top bit of the window */
+ wend = 0; /* The bottom bit of the window */
+
+ if (!BN_one(r))
+ goto err;
+
+ for (;;) {
+ if (BN_is_bit_set(p, wstart) == 0) {
+ if (!start)
+ if (!BN_mod_mul(r, r, r, m, ctx))
+ goto err;
+ if (wstart == 0)
+ break;
+ wstart--;
+ continue;
+ }
+ /*
+ * We now have wstart on a 'set' bit, we now need to work out how bit
+ * a window to do. To do this we need to scan forward until the last
+ * set bit before the end of the window
+ */
+ j = wstart;
+ wvalue = 1;
+ wend = 0;
+ for (i = 1; i < window; i++) {
+ if (wstart - i < 0)
+ break;
+ if (BN_is_bit_set(p, wstart - i)) {
+ wvalue <<= (i - wend);
+ wvalue |= 1;
+ wend = i;
+ }
+ }
+
+ /* wend is the size of the current window */
+ j = wend + 1;
+ /* add the 'bytes above' */
+ if (!start)
+ for (i = 0; i < j; i++) {
+ if (!BN_mod_mul(r, r, r, m, ctx))
+ goto err;
+ }
+
+ /* wvalue will be an odd number < 2^window */
+ if (!BN_mod_mul(r, r, val[wvalue >> 1], m, ctx))
+ goto err;
+
+ /* move the 'window' down further */
+ wstart -= wend + 1;
+ wvalue = 0;
+ start = 0;
+ if (wstart < 0)
+ break;
+ }
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(r);
+ return (ret);
+}
diff --git a/openssl/bn/bn_exp2.c b/openssl/bn/bn_exp2.c
new file mode 100644
index 0000000..43fd204
--- /dev/null
+++ b/openssl/bn/bn_exp2.c
@@ -0,0 +1,303 @@
+/* crypto/bn/bn_exp2.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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 <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#define TABLE_SIZE 32
+
+int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
+ const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
+ BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+ int i, j, bits, b, bits1, bits2, ret =
+ 0, wpos1, wpos2, window1, window2, wvalue1, wvalue2;
+ int r_is_one = 1;
+ BIGNUM *d, *r;
+ const BIGNUM *a_mod_m;
+ /* Tables of variables obtained from 'ctx' */
+ BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE];
+ BN_MONT_CTX *mont = NULL;
+
+ bn_check_top(a1);
+ bn_check_top(p1);
+ bn_check_top(a2);
+ bn_check_top(p2);
+ bn_check_top(m);
+
+ if (!(m->d[0] & 1)) {
+ BNerr(BN_F_BN_MOD_EXP2_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);
+ return (0);
+ }
+ bits1 = BN_num_bits(p1);
+ bits2 = BN_num_bits(p2);
+ if ((bits1 == 0) && (bits2 == 0)) {
+ ret = BN_one(rr);
+ return ret;
+ }
+
+ bits = (bits1 > bits2) ? bits1 : bits2;
+
+ BN_CTX_start(ctx);
+ d = BN_CTX_get(ctx);
+ r = BN_CTX_get(ctx);
+ val1[0] = BN_CTX_get(ctx);
+ val2[0] = BN_CTX_get(ctx);
+ if (!d || !r || !val1[0] || !val2[0])
+ goto err;
+
+ if (in_mont != NULL)
+ mont = in_mont;
+ else {
+ if ((mont = BN_MONT_CTX_new()) == NULL)
+ goto err;
+ if (!BN_MONT_CTX_set(mont, m, ctx))
+ goto err;
+ }
+
+ window1 = BN_window_bits_for_exponent_size(bits1);
+ window2 = BN_window_bits_for_exponent_size(bits2);
+
+ /*
+ * Build table for a1: val1[i] := a1^(2*i + 1) mod m for i = 0 .. 2^(window1-1)
+ */
+ if (a1->neg || BN_ucmp(a1, m) >= 0) {
+ if (!BN_mod(val1[0], a1, m, ctx))
+ goto err;
+ a_mod_m = val1[0];
+ } else
+ a_mod_m = a1;
+ if (BN_is_zero(a_mod_m)) {
+ BN_zero(rr);
+ ret = 1;
+ goto err;
+ }
+
+ if (!BN_to_montgomery(val1[0], a_mod_m, mont, ctx))
+ goto err;
+ if (window1 > 1) {
+ if (!BN_mod_mul_montgomery(d, val1[0], val1[0], mont, ctx))
+ goto err;
+
+ j = 1 << (window1 - 1);
+ for (i = 1; i < j; i++) {
+ if (((val1[i] = BN_CTX_get(ctx)) == NULL) ||
+ !BN_mod_mul_montgomery(val1[i], val1[i - 1], d, mont, ctx))
+ goto err;
+ }
+ }
+
+ /*
+ * Build table for a2: val2[i] := a2^(2*i + 1) mod m for i = 0 .. 2^(window2-1)
+ */
+ if (a2->neg || BN_ucmp(a2, m) >= 0) {
+ if (!BN_mod(val2[0], a2, m, ctx))
+ goto err;
+ a_mod_m = val2[0];
+ } else
+ a_mod_m = a2;
+ if (BN_is_zero(a_mod_m)) {
+ BN_zero(rr);
+ ret = 1;
+ goto err;
+ }
+ if (!BN_to_montgomery(val2[0], a_mod_m, mont, ctx))
+ goto err;
+ if (window2 > 1) {
+ if (!BN_mod_mul_montgomery(d, val2[0], val2[0], mont, ctx))
+ goto err;
+
+ j = 1 << (window2 - 1);
+ for (i = 1; i < j; i++) {
+ if (((val2[i] = BN_CTX_get(ctx)) == NULL) ||
+ !BN_mod_mul_montgomery(val2[i], val2[i - 1], d, mont, ctx))
+ goto err;
+ }
+ }
+
+ /* Now compute the power product, using independent windows. */
+ r_is_one = 1;
+ wvalue1 = 0; /* The 'value' of the first window */
+ wvalue2 = 0; /* The 'value' of the second window */
+ wpos1 = 0; /* If wvalue1 > 0, the bottom bit of the
+ * first window */
+ wpos2 = 0; /* If wvalue2 > 0, the bottom bit of the
+ * second window */
+
+ if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
+ goto err;
+ for (b = bits - 1; b >= 0; b--) {
+ if (!r_is_one) {
+ if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+ goto err;
+ }
+
+ if (!wvalue1)
+ if (BN_is_bit_set(p1, b)) {
+ /*
+ * consider bits b-window1+1 .. b for this window
+ */
+ i = b - window1 + 1;
+ while (!BN_is_bit_set(p1, i)) /* works for i<0 */
+ i++;
+ wpos1 = i;
+ wvalue1 = 1;
+ for (i = b - 1; i >= wpos1; i--) {
+ wvalue1 <<= 1;
+ if (BN_is_bit_set(p1, i))
+ wvalue1++;
+ }
+ }
+
+ if (!wvalue2)
+ if (BN_is_bit_set(p2, b)) {
+ /*
+ * consider bits b-window2+1 .. b for this window
+ */
+ i = b - window2 + 1;
+ while (!BN_is_bit_set(p2, i))
+ i++;
+ wpos2 = i;
+ wvalue2 = 1;
+ for (i = b - 1; i >= wpos2; i--) {
+ wvalue2 <<= 1;
+ if (BN_is_bit_set(p2, i))
+ wvalue2++;
+ }
+ }
+
+ if (wvalue1 && b == wpos1) {
+ /* wvalue1 is odd and < 2^window1 */
+ if (!BN_mod_mul_montgomery(r, r, val1[wvalue1 >> 1], mont, ctx))
+ goto err;
+ wvalue1 = 0;
+ r_is_one = 0;
+ }
+
+ if (wvalue2 && b == wpos2) {
+ /* wvalue2 is odd and < 2^window2 */
+ if (!BN_mod_mul_montgomery(r, r, val2[wvalue2 >> 1], mont, ctx))
+ goto err;
+ wvalue2 = 0;
+ r_is_one = 0;
+ }
+ }
+ if (!BN_from_montgomery(rr, r, mont, ctx))
+ goto err;
+ ret = 1;
+ err:
+ if ((in_mont == NULL) && (mont != NULL))
+ BN_MONT_CTX_free(mont);
+ BN_CTX_end(ctx);
+ bn_check_top(rr);
+ return (ret);
+}
diff --git a/openssl/bn/bn_gcd.c b/openssl/bn/bn_gcd.c
new file mode 100644
index 0000000..97c55ab
--- /dev/null
+++ b/openssl/bn/bn_gcd.c
@@ -0,0 +1,700 @@
+/* crypto/bn/bn_gcd.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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 "cryptlib.h"
+#include "bn_lcl.h"
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
+
+int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
+{
+ BIGNUM *a, *b, *t;
+ int ret = 0;
+
+ bn_check_top(in_a);
+ bn_check_top(in_b);
+
+ BN_CTX_start(ctx);
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ if (a == NULL || b == NULL)
+ goto err;
+
+ if (BN_copy(a, in_a) == NULL)
+ goto err;
+ if (BN_copy(b, in_b) == NULL)
+ goto err;
+ a->neg = 0;
+ b->neg = 0;
+
+ if (BN_cmp(a, b) < 0) {
+ t = a;
+ a = b;
+ b = t;
+ }
+ t = euclid(a, b);
+ if (t == NULL)
+ goto err;
+
+ if (BN_copy(r, t) == NULL)
+ goto err;
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(r);
+ return (ret);
+}
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
+{
+ BIGNUM *t;
+ int shifts = 0;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ /* 0 <= b <= a */
+ while (!BN_is_zero(b)) {
+ /* 0 < b <= a */
+
+ if (BN_is_odd(a)) {
+ if (BN_is_odd(b)) {
+ if (!BN_sub(a, a, b))
+ goto err;
+ if (!BN_rshift1(a, a))
+ goto err;
+ if (BN_cmp(a, b) < 0) {
+ t = a;
+ a = b;
+ b = t;
+ }
+ } else { /* a odd - b even */
+
+ if (!BN_rshift1(b, b))
+ goto err;
+ if (BN_cmp(a, b) < 0) {
+ t = a;
+ a = b;
+ b = t;
+ }
+ }
+ } else { /* a is even */
+
+ if (BN_is_odd(b)) {
+ if (!BN_rshift1(a, a))
+ goto err;
+ if (BN_cmp(a, b) < 0) {
+ t = a;
+ a = b;
+ b = t;
+ }
+ } else { /* a even - b even */
+
+ if (!BN_rshift1(a, a))
+ goto err;
+ if (!BN_rshift1(b, b))
+ goto err;
+ shifts++;
+ }
+ }
+ /* 0 <= b <= a */
+ }
+
+ if (shifts) {
+ if (!BN_lshift(a, a, shifts))
+ goto err;
+ }
+ bn_check_top(a);
+ return (a);
+ err:
+ return (NULL);
+}
+
+/* solves ax == 1 (mod n) */
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *ctx);
+
+BIGNUM *BN_mod_inverse(BIGNUM *in,
+ const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
+{
+ BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
+ BIGNUM *ret = NULL;
+ int sign;
+
+ if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0)
+ || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) {
+ return BN_mod_inverse_no_branch(in, a, n, ctx);
+ }
+
+ bn_check_top(a);
+ bn_check_top(n);
+
+ BN_CTX_start(ctx);
+ A = BN_CTX_get(ctx);
+ B = BN_CTX_get(ctx);
+ X = BN_CTX_get(ctx);
+ D = BN_CTX_get(ctx);
+ M = BN_CTX_get(ctx);
+ Y = BN_CTX_get(ctx);
+ T = BN_CTX_get(ctx);
+ if (T == NULL)
+ goto err;
+
+ if (in == NULL)
+ R = BN_new();
+ else
+ R = in;
+ if (R == NULL)
+ goto err;
+
+ BN_one(X);
+ BN_zero(Y);
+ if (BN_copy(B, a) == NULL)
+ goto err;
+ if (BN_copy(A, n) == NULL)
+ goto err;
+ A->neg = 0;
+ if (B->neg || (BN_ucmp(B, A) >= 0)) {
+ if (!BN_nnmod(B, B, A, ctx))
+ goto err;
+ }
+ sign = -1;
+ /*-
+ * From B = a mod |n|, A = |n| it follows that
+ *
+ * 0 <= B < A,
+ * -sign*X*a == B (mod |n|),
+ * sign*Y*a == A (mod |n|).
+ */
+
+ if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) {
+ /*
+ * Binary inversion algorithm; requires odd modulus. This is faster
+ * than the general algorithm if the modulus is sufficiently small
+ * (about 400 .. 500 bits on 32-bit sytems, but much more on 64-bit
+ * systems)
+ */
+ int shift;
+
+ while (!BN_is_zero(B)) {
+ /*-
+ * 0 < B < |n|,
+ * 0 < A <= |n|,
+ * (1) -sign*X*a == B (mod |n|),
+ * (2) sign*Y*a == A (mod |n|)
+ */
+
+ /*
+ * Now divide B by the maximum possible power of two in the
+ * integers, and divide X by the same value mod |n|. When we're
+ * done, (1) still holds.
+ */
+ shift = 0;
+ while (!BN_is_bit_set(B, shift)) { /* note that 0 < B */
+ shift++;
+
+ if (BN_is_odd(X)) {
+ if (!BN_uadd(X, X, n))
+ goto err;
+ }
+ /*
+ * now X is even, so we can easily divide it by two
+ */
+ if (!BN_rshift1(X, X))
+ goto err;
+ }
+ if (shift > 0) {
+ if (!BN_rshift(B, B, shift))
+ goto err;
+ }
+
+ /*
+ * Same for A and Y. Afterwards, (2) still holds.
+ */
+ shift = 0;
+ while (!BN_is_bit_set(A, shift)) { /* note that 0 < A */
+ shift++;
+
+ if (BN_is_odd(Y)) {
+ if (!BN_uadd(Y, Y, n))
+ goto err;
+ }
+ /* now Y is even */
+ if (!BN_rshift1(Y, Y))
+ goto err;
+ }
+ if (shift > 0) {
+ if (!BN_rshift(A, A, shift))
+ goto err;
+ }
+
+ /*-
+ * We still have (1) and (2).
+ * Both A and B are odd.
+ * The following computations ensure that
+ *
+ * 0 <= B < |n|,
+ * 0 < A < |n|,
+ * (1) -sign*X*a == B (mod |n|),
+ * (2) sign*Y*a == A (mod |n|),
+ *
+ * and that either A or B is even in the next iteration.
+ */
+ if (BN_ucmp(B, A) >= 0) {
+ /* -sign*(X + Y)*a == B - A (mod |n|) */
+ if (!BN_uadd(X, X, Y))
+ goto err;
+ /*
+ * NB: we could use BN_mod_add_quick(X, X, Y, n), but that
+ * actually makes the algorithm slower
+ */
+ if (!BN_usub(B, B, A))
+ goto err;
+ } else {
+ /* sign*(X + Y)*a == A - B (mod |n|) */
+ if (!BN_uadd(Y, Y, X))
+ goto err;
+ /*
+ * as above, BN_mod_add_quick(Y, Y, X, n) would slow things
+ * down
+ */
+ if (!BN_usub(A, A, B))
+ goto err;
+ }
+ }
+ } else {
+ /* general inversion algorithm */
+
+ while (!BN_is_zero(B)) {
+ BIGNUM *tmp;
+
+ /*-
+ * 0 < B < A,
+ * (*) -sign*X*a == B (mod |n|),
+ * sign*Y*a == A (mod |n|)
+ */
+
+ /* (D, M) := (A/B, A%B) ... */
+ if (BN_num_bits(A) == BN_num_bits(B)) {
+ if (!BN_one(D))
+ goto err;
+ if (!BN_sub(M, A, B))
+ goto err;
+ } else if (BN_num_bits(A) == BN_num_bits(B) + 1) {
+ /* A/B is 1, 2, or 3 */
+ if (!BN_lshift1(T, B))
+ goto err;
+ if (BN_ucmp(A, T) < 0) {
+ /* A < 2*B, so D=1 */
+ if (!BN_one(D))
+ goto err;
+ if (!BN_sub(M, A, B))
+ goto err;
+ } else {
+ /* A >= 2*B, so D=2 or D=3 */
+ if (!BN_sub(M, A, T))
+ goto err;
+ if (!BN_add(D, T, B))
+ goto err; /* use D (:= 3*B) as temp */
+ if (BN_ucmp(A, D) < 0) {
+ /* A < 3*B, so D=2 */
+ if (!BN_set_word(D, 2))
+ goto err;
+ /*
+ * M (= A - 2*B) already has the correct value
+ */
+ } else {
+ /* only D=3 remains */
+ if (!BN_set_word(D, 3))
+ goto err;
+ /*
+ * currently M = A - 2*B, but we need M = A - 3*B
+ */
+ if (!BN_sub(M, M, B))
+ goto err;
+ }
+ }
+ } else {
+ if (!BN_div(D, M, A, B, ctx))
+ goto err;
+ }
+
+ /*-
+ * Now
+ * A = D*B + M;
+ * thus we have
+ * (**) sign*Y*a == D*B + M (mod |n|).
+ */
+
+ tmp = A; /* keep the BIGNUM object, the value does not
+ * matter */
+
+ /* (A, B) := (B, A mod B) ... */
+ A = B;
+ B = M;
+ /* ... so we have 0 <= B < A again */
+
+ /*-
+ * Since the former M is now B and the former B is now A,
+ * (**) translates into
+ * sign*Y*a == D*A + B (mod |n|),
+ * i.e.
+ * sign*Y*a - D*A == B (mod |n|).
+ * Similarly, (*) translates into
+ * -sign*X*a == A (mod |n|).
+ *
+ * Thus,
+ * sign*Y*a + D*sign*X*a == B (mod |n|),
+ * i.e.
+ * sign*(Y + D*X)*a == B (mod |n|).
+ *
+ * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
+ * -sign*X*a == B (mod |n|),
+ * sign*Y*a == A (mod |n|).
+ * Note that X and Y stay non-negative all the time.
+ */
+
+ /*
+ * most of the time D is very small, so we can optimize tmp :=
+ * D*X+Y
+ */
+ if (BN_is_one(D)) {
+ if (!BN_add(tmp, X, Y))
+ goto err;
+ } else {
+ if (BN_is_word(D, 2)) {
+ if (!BN_lshift1(tmp, X))
+ goto err;
+ } else if (BN_is_word(D, 4)) {
+ if (!BN_lshift(tmp, X, 2))
+ goto err;
+ } else if (D->top == 1) {
+ if (!BN_copy(tmp, X))
+ goto err;
+ if (!BN_mul_word(tmp, D->d[0]))
+ goto err;
+ } else {
+ if (!BN_mul(tmp, D, X, ctx))
+ goto err;
+ }
+ if (!BN_add(tmp, tmp, Y))
+ goto err;
+ }
+
+ M = Y; /* keep the BIGNUM object, the value does not
+ * matter */
+ Y = X;
+ X = tmp;
+ sign = -sign;
+ }
+ }
+
+ /*-
+ * The while loop (Euclid's algorithm) ends when
+ * A == gcd(a,n);
+ * we have
+ * sign*Y*a == A (mod |n|),
+ * where Y is non-negative.
+ */
+
+ if (sign < 0) {
+ if (!BN_sub(Y, n, Y))
+ goto err;
+ }
+ /* Now Y*a == A (mod |n|). */
+
+ if (BN_is_one(A)) {
+ /* Y*a == 1 (mod |n|) */
+ if (!Y->neg && BN_ucmp(Y, n) < 0) {
+ if (!BN_copy(R, Y))
+ goto err;
+ } else {
+ if (!BN_nnmod(R, Y, n, ctx))
+ goto err;
+ }
+ } else {
+ BNerr(BN_F_BN_MOD_INVERSE, BN_R_NO_INVERSE);
+ goto err;
+ }
+ ret = R;
+ err:
+ if ((ret == NULL) && (in == NULL))
+ BN_free(R);
+ BN_CTX_end(ctx);
+ bn_check_top(ret);
+ return (ret);
+}
+
+/*
+ * BN_mod_inverse_no_branch is a special version of BN_mod_inverse. It does
+ * not contain branches that may leak sensitive information.
+ */
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *ctx)
+{
+ BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
+ BIGNUM local_A, local_B;
+ BIGNUM *pA, *pB;
+ BIGNUM *ret = NULL;
+ int sign;
+
+ bn_check_top(a);
+ bn_check_top(n);
+
+ BN_CTX_start(ctx);
+ A = BN_CTX_get(ctx);
+ B = BN_CTX_get(ctx);
+ X = BN_CTX_get(ctx);
+ D = BN_CTX_get(ctx);
+ M = BN_CTX_get(ctx);
+ Y = BN_CTX_get(ctx);
+ T = BN_CTX_get(ctx);
+ if (T == NULL)
+ goto err;
+
+ if (in == NULL)
+ R = BN_new();
+ else
+ R = in;
+ if (R == NULL)
+ goto err;
+
+ BN_one(X);
+ BN_zero(Y);
+ if (BN_copy(B, a) == NULL)
+ goto err;
+ if (BN_copy(A, n) == NULL)
+ goto err;
+ A->neg = 0;
+
+ if (B->neg || (BN_ucmp(B, A) >= 0)) {
+ /*
+ * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
+ * BN_div_no_branch will be called eventually.
+ */
+ pB = &local_B;
+ BN_with_flags(pB, B, BN_FLG_CONSTTIME);
+ if (!BN_nnmod(B, pB, A, ctx))
+ goto err;
+ }
+ sign = -1;
+ /*-
+ * From B = a mod |n|, A = |n| it follows that
+ *
+ * 0 <= B < A,
+ * -sign*X*a == B (mod |n|),
+ * sign*Y*a == A (mod |n|).
+ */
+
+ while (!BN_is_zero(B)) {
+ BIGNUM *tmp;
+
+ /*-
+ * 0 < B < A,
+ * (*) -sign*X*a == B (mod |n|),
+ * sign*Y*a == A (mod |n|)
+ */
+
+ /*
+ * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
+ * BN_div_no_branch will be called eventually.
+ */
+ pA = &local_A;
+ BN_with_flags(pA, A, BN_FLG_CONSTTIME);
+
+ /* (D, M) := (A/B, A%B) ... */
+ if (!BN_div(D, M, pA, B, ctx))
+ goto err;
+
+ /*-
+ * Now
+ * A = D*B + M;
+ * thus we have
+ * (**) sign*Y*a == D*B + M (mod |n|).
+ */
+
+ tmp = A; /* keep the BIGNUM object, the value does not
+ * matter */
+
+ /* (A, B) := (B, A mod B) ... */
+ A = B;
+ B = M;
+ /* ... so we have 0 <= B < A again */
+
+ /*-
+ * Since the former M is now B and the former B is now A,
+ * (**) translates into
+ * sign*Y*a == D*A + B (mod |n|),
+ * i.e.
+ * sign*Y*a - D*A == B (mod |n|).
+ * Similarly, (*) translates into
+ * -sign*X*a == A (mod |n|).
+ *
+ * Thus,
+ * sign*Y*a + D*sign*X*a == B (mod |n|),
+ * i.e.
+ * sign*(Y + D*X)*a == B (mod |n|).
+ *
+ * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
+ * -sign*X*a == B (mod |n|),
+ * sign*Y*a == A (mod |n|).
+ * Note that X and Y stay non-negative all the time.
+ */
+
+ if (!BN_mul(tmp, D, X, ctx))
+ goto err;
+ if (!BN_add(tmp, tmp, Y))
+ goto err;
+
+ M = Y; /* keep the BIGNUM object, the value does not
+ * matter */
+ Y = X;
+ X = tmp;
+ sign = -sign;
+ }
+
+ /*-
+ * The while loop (Euclid's algorithm) ends when
+ * A == gcd(a,n);
+ * we have
+ * sign*Y*a == A (mod |n|),
+ * where Y is non-negative.
+ */
+
+ if (sign < 0) {
+ if (!BN_sub(Y, n, Y))
+ goto err;
+ }
+ /* Now Y*a == A (mod |n|). */
+
+ if (BN_is_one(A)) {
+ /* Y*a == 1 (mod |n|) */
+ if (!Y->neg && BN_ucmp(Y, n) < 0) {
+ if (!BN_copy(R, Y))
+ goto err;
+ } else {
+ if (!BN_nnmod(R, Y, n, ctx))
+ goto err;
+ }
+ } else {
+ BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH, BN_R_NO_INVERSE);
+ goto err;
+ }
+ ret = R;
+ err:
+ if ((ret == NULL) && (in == NULL))
+ BN_free(R);
+ BN_CTX_end(ctx);
+ bn_check_top(ret);
+ return (ret);
+}
diff --git a/openssl/bn/bn_gf2m.c b/openssl/bn/bn_gf2m.c
new file mode 100644
index 0000000..aeee49a
--- /dev/null
+++ b/openssl/bn/bn_gf2m.c
@@ -0,0 +1,1293 @@
+/* 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"
+
+#ifndef OPENSSL_NO_EC2M
+
+/*
+ * 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
+
+# if !defined(OPENSSL_BN_ASM_GF2m)
+/*
+ * 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 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 & (0x1FFFFFFFFFFFFFFFULL);
+ 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; */
+}
+# else
+void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1,
+ BN_ULONG b0);
+# endif
+
+/*
+ * 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;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (a->top < b->top) {
+ at = b;
+ bt = a;
+ } else {
+ at = a;
+ bt = b;
+ }
+
+ if (bn_wexpand(r, at->top) == NULL)
+ return 0;
+
+ 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_correct_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 int p[])
+{
+ int j, k;
+ int n, dN, d0, d1;
+ BN_ULONG zz, *z;
+
+ bn_check_top(a);
+
+ if (!p[0]) {
+ /* reduction mod 1 => return 0 */
+ BN_zero(r);
+ return 1;
+ }
+
+ /*
+ * 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;
+
+ /* clear up the top d1 bits */
+ if (d0)
+ z[dN] = (z[dN] << d1) >> d1;
+ else
+ z[dN] = 0;
+ 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_correct_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)
+{
+ int ret = 0;
+ int arr[6];
+ bn_check_top(a);
+ bn_check_top(p);
+ ret = BN_GF2m_poly2arr(p, arr, sizeof(arr) / sizeof(arr[0]));
+ if (!ret || ret > (int)(sizeof(arr) / sizeof(arr[0]))) {
+ BNerr(BN_F_BN_GF2M_MOD, BN_R_INVALID_LENGTH);
+ return 0;
+ }
+ ret = BN_GF2m_mod_arr(r, a, arr);
+ bn_check_top(r);
+ 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 int p[], BN_CTX *ctx)
+{
+ int zlen, i, j, k, ret = 0;
+ BIGNUM *s;
+ BN_ULONG x1, x0, y1, y0, zz[4];
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ 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_correct_top(s);
+ if (BN_GF2m_mod_arr(r, s, p))
+ ret = 1;
+ bn_check_top(r);
+
+ 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)
+{
+ int ret = 0;
+ const int max = BN_num_bits(p) + 1;
+ int *arr = NULL;
+ bn_check_top(a);
+ bn_check_top(b);
+ bn_check_top(p);
+ if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL)
+ goto err;
+ ret = BN_GF2m_poly2arr(p, arr, max);
+ if (!ret || ret > 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);
+ bn_check_top(r);
+ 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 int p[],
+ BN_CTX *ctx)
+{
+ int i, ret = 0;
+ BIGNUM *s;
+
+ bn_check_top(a);
+ 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_correct_top(s);
+ if (!BN_GF2m_mod_arr(r, s, p))
+ goto err;
+ bn_check_top(r);
+ 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)
+{
+ int ret = 0;
+ const int max = BN_num_bits(p) + 1;
+ int *arr = NULL;
+
+ bn_check_top(a);
+ bn_check_top(p);
+ if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL)
+ goto err;
+ ret = BN_GF2m_poly2arr(p, arr, max);
+ if (!ret || ret > max) {
+ BNerr(BN_F_BN_GF2M_MOD_SQR, BN_R_INVALID_LENGTH);
+ goto err;
+ }
+ ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx);
+ bn_check_top(r);
+ 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 = NULL, *u = NULL, *v = NULL, *tmp;
+ int ret = 0;
+
+ bn_check_top(a);
+ bn_check_top(p);
+
+ BN_CTX_start(ctx);
+
+ if ((b = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if ((c = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if ((u = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if ((v = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ if (!BN_GF2m_mod(u, a, p))
+ goto err;
+ if (BN_is_zero(u))
+ goto err;
+
+ if (!BN_copy(v, p))
+ goto err;
+# if 0
+ if (!BN_one(b))
+ goto err;
+
+ while (1) {
+ while (!BN_is_odd(u)) {
+ if (BN_is_zero(u))
+ goto err;
+ 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_abs_is_word(u, 1))
+ 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;
+ }
+# else
+ {
+ int i, ubits = BN_num_bits(u), vbits = BN_num_bits(v), /* v is copy
+ * of p */
+ top = p->top;
+ BN_ULONG *udp, *bdp, *vdp, *cdp;
+
+ bn_wexpand(u, top);
+ udp = u->d;
+ for (i = u->top; i < top; i++)
+ udp[i] = 0;
+ u->top = top;
+ bn_wexpand(b, top);
+ bdp = b->d;
+ bdp[0] = 1;
+ for (i = 1; i < top; i++)
+ bdp[i] = 0;
+ b->top = top;
+ bn_wexpand(c, top);
+ cdp = c->d;
+ for (i = 0; i < top; i++)
+ cdp[i] = 0;
+ c->top = top;
+ vdp = v->d; /* It pays off to "cache" *->d pointers,
+ * because it allows optimizer to be more
+ * aggressive. But we don't have to "cache"
+ * p->d, because *p is declared 'const'... */
+ while (1) {
+ while (ubits && !(udp[0] & 1)) {
+ BN_ULONG u0, u1, b0, b1, mask;
+
+ u0 = udp[0];
+ b0 = bdp[0];
+ mask = (BN_ULONG)0 - (b0 & 1);
+ b0 ^= p->d[0] & mask;
+ for (i = 0; i < top - 1; i++) {
+ u1 = udp[i + 1];
+ udp[i] = ((u0 >> 1) | (u1 << (BN_BITS2 - 1))) & BN_MASK2;
+ u0 = u1;
+ b1 = bdp[i + 1] ^ (p->d[i + 1] & mask);
+ bdp[i] = ((b0 >> 1) | (b1 << (BN_BITS2 - 1))) & BN_MASK2;
+ b0 = b1;
+ }
+ udp[i] = u0 >> 1;
+ bdp[i] = b0 >> 1;
+ ubits--;
+ }
+
+ if (ubits <= BN_BITS2 && udp[0] == 1)
+ break;
+
+ if (ubits < vbits) {
+ i = ubits;
+ ubits = vbits;
+ vbits = i;
+ tmp = u;
+ u = v;
+ v = tmp;
+ tmp = b;
+ b = c;
+ c = tmp;
+ udp = vdp;
+ vdp = v->d;
+ bdp = cdp;
+ cdp = c->d;
+ }
+ for (i = 0; i < top; i++) {
+ udp[i] ^= vdp[i];
+ bdp[i] ^= cdp[i];
+ }
+ if (ubits == vbits) {
+ BN_ULONG ul;
+ int utop = (ubits - 1) / BN_BITS2;
+
+ while ((ul = udp[utop]) == 0 && utop)
+ utop--;
+ ubits = utop * BN_BITS2 + BN_num_bits_word(ul);
+ }
+ }
+ bn_correct_top(b);
+ }
+# endif
+
+ if (!BN_copy(r, b))
+ goto err;
+ bn_check_top(r);
+ ret = 1;
+
+ err:
+# ifdef BN_DEBUG /* BN_CTX_end would complain about the
+ * expanded form */
+ bn_correct_top(c);
+ bn_correct_top(u);
+ bn_correct_top(v);
+# endif
+ 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 int p[],
+ BN_CTX *ctx)
+{
+ BIGNUM *field;
+ int ret = 0;
+
+ bn_check_top(xx);
+ 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);
+ bn_check_top(r);
+
+ 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_check_top(y);
+ bn_check_top(x);
+ bn_check_top(p);
+
+ 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;
+ bn_check_top(r);
+ 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_check_top(y);
+ bn_check_top(x);
+ bn_check_top(p);
+
+ 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;
+
+ 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_abs_is_word(a, 1))
+ 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;
+ bn_check_top(r);
+ 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 int p[], BN_CTX *ctx)
+{
+ BIGNUM *field;
+ int ret = 0;
+
+ bn_check_top(yy);
+ bn_check_top(xx);
+
+ 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);
+ bn_check_top(r);
+
+ 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 int p[], BN_CTX *ctx)
+{
+ int ret = 0, i, n;
+ BIGNUM *u;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (BN_is_zero(b))
+ return (BN_one(r));
+
+ if (BN_abs_is_word(b, 1))
+ return (BN_copy(r, a) != NULL);
+
+ 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;
+ bn_check_top(r);
+ 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)
+{
+ int ret = 0;
+ const int max = BN_num_bits(p) + 1;
+ int *arr = NULL;
+ bn_check_top(a);
+ bn_check_top(b);
+ bn_check_top(p);
+ if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL)
+ goto err;
+ ret = BN_GF2m_poly2arr(p, arr, max);
+ if (!ret || ret > 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);
+ bn_check_top(r);
+ 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 int p[],
+ BN_CTX *ctx)
+{
+ int ret = 0;
+ BIGNUM *u;
+
+ bn_check_top(a);
+
+ if (!p[0]) {
+ /* reduction mod 1 => return 0 */
+ BN_zero(r);
+ return 1;
+ }
+
+ BN_CTX_start(ctx);
+ if ((u = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ if (!BN_set_bit(u, p[0] - 1))
+ goto err;
+ ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx);
+ bn_check_top(r);
+
+ 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)
+{
+ int ret = 0;
+ const int max = BN_num_bits(p) + 1;
+ int *arr = NULL;
+ bn_check_top(a);
+ bn_check_top(p);
+ if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL)
+ goto err;
+ ret = BN_GF2m_poly2arr(p, arr, max);
+ if (!ret || ret > max) {
+ BNerr(BN_F_BN_GF2M_MOD_SQRT, BN_R_INVALID_LENGTH);
+ goto err;
+ }
+ ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx);
+ bn_check_top(r);
+ 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 int p[],
+ BN_CTX *ctx)
+{
+ int ret = 0, count = 0, j;
+ BIGNUM *a, *z, *rho, *w, *w2, *tmp;
+
+ bn_check_top(a_);
+
+ if (!p[0]) {
+ /* reduction mod 1 => return 0 */
+ BN_zero(r);
+ return 1;
+ }
+
+ 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)) {
+ BN_zero(r);
+ ret = 1;
+ 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;
+ BN_zero(z);
+ 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)) {
+ BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION);
+ goto err;
+ }
+
+ if (!BN_copy(r, z))
+ goto err;
+ bn_check_top(r);
+
+ 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)
+{
+ int ret = 0;
+ const int max = BN_num_bits(p) + 1;
+ int *arr = NULL;
+ bn_check_top(a);
+ bn_check_top(p);
+ if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL)
+ goto err;
+ ret = BN_GF2m_poly2arr(p, arr, max);
+ if (!ret || ret > 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);
+ bn_check_top(r);
+ err:
+ if (arr)
+ OPENSSL_free(arr);
+ return ret;
+}
+
+/*
+ * Convert the bit-string representation of a polynomial ( \sum_{i=0}^n a_i *
+ * x^i) into an array of integers corresponding to the bits with non-zero
+ * coefficient. Array is terminated with -1. Up to max elements of the array
+ * will be filled. Return value is total number of array elements that would
+ * be filled if array was large enough.
+ */
+int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max)
+{
+ int i, j, k = 0;
+ BN_ULONG mask;
+
+ if (BN_is_zero(a))
+ return 0;
+
+ for (i = a->top - 1; i >= 0; i--) {
+ if (!a->d[i])
+ /* skip word if a->d[i] == 0 */
+ continue;
+ 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;
+ }
+ }
+
+ if (k < max) {
+ p[k] = -1;
+ k++;
+ }
+
+ return k;
+}
+
+/*
+ * Convert the coefficient array representation of a polynomial to a
+ * bit-string. The array must be terminated by -1.
+ */
+int BN_GF2m_arr2poly(const int p[], BIGNUM *a)
+{
+ int i;
+
+ bn_check_top(a);
+ BN_zero(a);
+ for (i = 0; p[i] != -1; i++) {
+ if (BN_set_bit(a, p[i]) == 0)
+ return 0;
+ }
+ bn_check_top(a);
+
+ return 1;
+}
+
+#endif
diff --git a/openssl/bn/bn_kron.c b/openssl/bn/bn_kron.c
new file mode 100644
index 0000000..88d731a
--- /dev/null
+++ b/openssl/bn/bn_kron.c
@@ -0,0 +1,186 @@
+/* crypto/bn/bn_kron.c */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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 "cryptlib.h"
+#include "bn_lcl.h"
+
+/* least significant word */
+#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0])
+
+/* Returns -2 for errors because both -1 and 0 are valid results. */
+int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+ int i;
+ int ret = -2; /* avoid 'uninitialized' warning */
+ int err = 0;
+ BIGNUM *A, *B, *tmp;
+ /*-
+ * In 'tab', only odd-indexed entries are relevant:
+ * For any odd BIGNUM n,
+ * tab[BN_lsw(n) & 7]
+ * is $(-1)^{(n^2-1)/8}$ (using TeX notation).
+ * Note that the sign of n does not matter.
+ */
+ static const int tab[8] = { 0, 1, 0, -1, 0, -1, 0, 1 };
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ BN_CTX_start(ctx);
+ A = BN_CTX_get(ctx);
+ B = BN_CTX_get(ctx);
+ if (B == NULL)
+ goto end;
+
+ err = !BN_copy(A, a);
+ if (err)
+ goto end;
+ err = !BN_copy(B, b);
+ if (err)
+ goto end;
+
+ /*
+ * Kronecker symbol, imlemented according to Henri Cohen,
+ * "A Course in Computational Algebraic Number Theory"
+ * (algorithm 1.4.10).
+ */
+
+ /* Cohen's step 1: */
+
+ if (BN_is_zero(B)) {
+ ret = BN_abs_is_word(A, 1);
+ goto end;
+ }
+
+ /* Cohen's step 2: */
+
+ if (!BN_is_odd(A) && !BN_is_odd(B)) {
+ ret = 0;
+ goto end;
+ }
+
+ /* now B is non-zero */
+ i = 0;
+ while (!BN_is_bit_set(B, i))
+ i++;
+ err = !BN_rshift(B, B, i);
+ if (err)
+ goto end;
+ if (i & 1) {
+ /* i is odd */
+ /* (thus B was even, thus A must be odd!) */
+
+ /* set 'ret' to $(-1)^{(A^2-1)/8}$ */
+ ret = tab[BN_lsw(A) & 7];
+ } else {
+ /* i is even */
+ ret = 1;
+ }
+
+ if (B->neg) {
+ B->neg = 0;
+ if (A->neg)
+ ret = -ret;
+ }
+
+ /*
+ * now B is positive and odd, so what remains to be done is to compute
+ * the Jacobi symbol (A/B) and multiply it by 'ret'
+ */
+
+ while (1) {
+ /* Cohen's step 3: */
+
+ /* B is positive and odd */
+
+ if (BN_is_zero(A)) {
+ ret = BN_is_one(B) ? ret : 0;
+ goto end;
+ }
+
+ /* now A is non-zero */
+ i = 0;
+ while (!BN_is_bit_set(A, i))
+ i++;
+ err = !BN_rshift(A, A, i);
+ if (err)
+ goto end;
+ if (i & 1) {
+ /* i is odd */
+ /* multiply 'ret' by $(-1)^{(B^2-1)/8}$ */
+ ret = ret * tab[BN_lsw(B) & 7];
+ }
+
+ /* Cohen's step 4: */
+ /* multiply 'ret' by $(-1)^{(A-1)(B-1)/4}$ */
+ if ((A->neg ? ~BN_lsw(A) : BN_lsw(A)) & BN_lsw(B) & 2)
+ ret = -ret;
+
+ /* (A, B) := (B mod |A|, |A|) */
+ err = !BN_nnmod(B, B, A, ctx);
+ if (err)
+ goto end;
+ tmp = A;
+ A = B;
+ B = tmp;
+ tmp->neg = 0;
+ }
+ end:
+ BN_CTX_end(ctx);
+ if (err)
+ return -2;
+ else
+ return ret;
+}
diff --git a/openssl/bn/bn_lcl.h b/openssl/bn/bn_lcl.h
new file mode 100644
index 0000000..1059d1d
--- /dev/null
+++ b/openssl/bn/bn_lcl.h
@@ -0,0 +1,510 @@
+/* crypto/bn/bn_lcl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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 HEADER_BN_LCL_H
+# define HEADER_BN_LCL_H
+
+# include <openssl/bn.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-
+ * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
+ *
+ *
+ * For window size 'w' (w >= 2) and a random 'b' bits exponent,
+ * the number of multiplications is a constant plus on average
+ *
+ * 2^(w-1) + (b-w)/(w+1);
+ *
+ * here 2^(w-1) is for precomputing the table (we actually need
+ * entries only for windows that have the lowest bit set), and
+ * (b-w)/(w+1) is an approximation for the expected number of
+ * w-bit windows, not counting the first one.
+ *
+ * Thus we should use
+ *
+ * w >= 6 if b > 671
+ * w = 5 if 671 > b > 239
+ * w = 4 if 239 > b > 79
+ * w = 3 if 79 > b > 23
+ * w <= 2 if 23 > b
+ *
+ * (with draws in between). Very small exponents are often selected
+ * with low Hamming weight, so we use w = 1 for b <= 23.
+ */
+# if 1
+# define BN_window_bits_for_exponent_size(b) \
+ ((b) > 671 ? 6 : \
+ (b) > 239 ? 5 : \
+ (b) > 79 ? 4 : \
+ (b) > 23 ? 3 : 1)
+# else
+/*
+ * Old SSLeay/OpenSSL table. Maximum window size was 5, so this table differs
+ * for b==1024; but it coincides for other interesting values (b==160,
+ * b==512).
+ */
+# define BN_window_bits_for_exponent_size(b) \
+ ((b) > 255 ? 5 : \
+ (b) > 127 ? 4 : \
+ (b) > 17 ? 3 : 1)
+# endif
+
+/*
+ * BN_mod_exp_mont_conttime is based on the assumption that the L1 data cache
+ * line width of the target processor is at least the following value.
+ */
+# define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH ( 64 )
+# define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1)
+
+/*
+ * Window sizes optimized for fixed window size modular exponentiation
+ * algorithm (BN_mod_exp_mont_consttime). To achieve the security goals of
+ * BN_mode_exp_mont_consttime, the maximum size of the window must not exceed
+ * log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). Window size thresholds are
+ * defined for cache line sizes of 32 and 64, cache line sizes where
+ * log_2(32)=5 and log_2(64)=6 respectively. A window size of 7 should only be
+ * used on processors that have a 128 byte or greater cache line size.
+ */
+# if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64
+
+# define BN_window_bits_for_ctime_exponent_size(b) \
+ ((b) > 937 ? 6 : \
+ (b) > 306 ? 5 : \
+ (b) > 89 ? 4 : \
+ (b) > 22 ? 3 : 1)
+# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (6)
+
+# elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32
+
+# define BN_window_bits_for_ctime_exponent_size(b) \
+ ((b) > 306 ? 5 : \
+ (b) > 89 ? 4 : \
+ (b) > 22 ? 3 : 1)
+# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (5)
+
+# endif
+
+/* Pentium pro 16,16,16,32,64 */
+/* Alpha 16,16,16,16.64 */
+# define BN_MULL_SIZE_NORMAL (16)/* 32 */
+# define BN_MUL_RECURSIVE_SIZE_NORMAL (16)/* 32 less than */
+# define BN_SQR_RECURSIVE_SIZE_NORMAL (16)/* 32 */
+# define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32)/* 32 */
+# define BN_MONT_CTX_SET_SIZE_WORD (64)/* 32 */
+
+# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
+/*
+ * BN_UMULT_HIGH section.
+ *
+ * No, I'm not trying to overwhelm you when stating that the
+ * product of N-bit numbers is 2*N bits wide:-) No, I don't expect
+ * you to be impressed when I say that if the compiler doesn't
+ * support 2*N integer type, then you have to replace every N*N
+ * multiplication with 4 (N/2)*(N/2) accompanied by some shifts
+ * and additions which unavoidably results in severe performance
+ * penalties. Of course provided that the hardware is capable of
+ * producing 2*N result... That's when you normally start
+ * considering assembler implementation. However! It should be
+ * pointed out that some CPUs (most notably Alpha, PowerPC and
+ * upcoming IA-64 family:-) provide *separate* instruction
+ * calculating the upper half of the product placing the result
+ * into a general purpose register. Now *if* the compiler supports
+ * inline assembler, then it's not impossible to implement the
+ * "bignum" routines (and have the compiler optimize 'em)
+ * exhibiting "native" performance in C. That's what BN_UMULT_HIGH
+ * macro is about:-)
+ *
+ * <appro@fy.chalmers.se>
+ */
+# if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
+# if defined(__DECC)
+# include <c_asm.h>
+# define BN_UMULT_HIGH(a,b) (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
+# elif defined(__GNUC__) && __GNUC__>=2
+# define BN_UMULT_HIGH(a,b) ({ \
+ register BN_ULONG ret; \
+ asm ("umulh %1,%2,%0" \
+ : "=r"(ret) \
+ : "r"(a), "r"(b)); \
+ ret; })
+# endif /* compiler */
+# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
+# if defined(__GNUC__) && __GNUC__>=2
+# define BN_UMULT_HIGH(a,b) ({ \
+ register BN_ULONG ret; \
+ asm ("mulhdu %0,%1,%2" \
+ : "=r"(ret) \
+ : "r"(a), "r"(b)); \
+ ret; })
+# endif /* compiler */
+# elif (defined(__x86_64) || defined(__x86_64__)) && \
+ (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
+# if defined(__GNUC__) && __GNUC__>=2
+# 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
+# elif (defined(_M_AMD64) || defined(_M_X64)) && defined(SIXTY_FOUR_BIT)
+# if defined(_MSC_VER) && _MSC_VER>=1400
+unsigned __int64 __umulh(unsigned __int64 a, unsigned __int64 b);
+unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b,
+ unsigned __int64 *h);
+# pragma intrinsic(__umulh,_umul128)
+# define BN_UMULT_HIGH(a,b) __umulh((a),(b))
+# define BN_UMULT_LOHI(low,high,a,b) ((low)=_umul128((a),(b),&(high)))
+# endif
+# elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG))
+# if defined(__GNUC__) && __GNUC__>=2
+# if __GNUC__>=4 && __GNUC_MINOR__>=4
+ /* "h" constraint is no more since 4.4 */
+# define BN_UMULT_HIGH(a,b) (((__uint128_t)(a)*(b))>>64)
+# define BN_UMULT_LOHI(low,high,a,b) ({ \
+ __uint128_t ret=(__uint128_t)(a)*(b); \
+ (high)=ret>>64; (low)=ret; })
+# else
+# define BN_UMULT_HIGH(a,b) ({ \
+ register BN_ULONG ret; \
+ asm ("dmultu %1,%2" \
+ : "=h"(ret) \
+ : "r"(a), "r"(b) : "l"); \
+ ret; })
+# define BN_UMULT_LOHI(low,high,a,b)\
+ asm ("dmultu %2,%3" \
+ : "=l"(low),"=h"(high) \
+ : "r"(a), "r"(b));
+# endif
+# endif
+# endif /* cpu */
+# endif /* OPENSSL_NO_ASM */
+
+/*************************************************************
+ * Using the long long type
+ */
+# define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
+# define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
+
+# ifdef BN_DEBUG_RAND
+# 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; \
+ }
+# else
+# define bn_clear_top2max(a)
+# endif
+
+# ifdef BN_LLONG
+# define mul_add(r,a,w,c) { \
+ BN_ULLONG t; \
+ t=(BN_ULLONG)w * (a) + (r) + (c); \
+ (r)= Lw(t); \
+ (c)= Hw(t); \
+ }
+
+# define mul(r,a,w,c) { \
+ BN_ULLONG t; \
+ t=(BN_ULLONG)w * (a) + (c); \
+ (r)= Lw(t); \
+ (c)= Hw(t); \
+ }
+
+# define sqr(r0,r1,a) { \
+ BN_ULLONG t; \
+ t=(BN_ULLONG)(a)*(a); \
+ (r0)=Lw(t); \
+ (r1)=Hw(t); \
+ }
+
+# elif defined(BN_UMULT_LOHI)
+# define mul_add(r,a,w,c) { \
+ BN_ULONG high,low,ret,tmp=(a); \
+ ret = (r); \
+ BN_UMULT_LOHI(low,high,w,tmp); \
+ ret += (c); \
+ (c) = (ret<(c))?1:0; \
+ (c) += high; \
+ ret += low; \
+ (c) += (ret<low)?1:0; \
+ (r) = ret; \
+ }
+
+# define mul(r,a,w,c) { \
+ BN_ULONG high,low,ret,ta=(a); \
+ BN_UMULT_LOHI(low,high,w,ta); \
+ ret = low + (c); \
+ (c) = high; \
+ (c) += (ret<low)?1:0; \
+ (r) = ret; \
+ }
+
+# define sqr(r0,r1,a) { \
+ BN_ULONG tmp=(a); \
+ BN_UMULT_LOHI(r0,r1,tmp,tmp); \
+ }
+
+# elif defined(BN_UMULT_HIGH)
+# define mul_add(r,a,w,c) { \
+ BN_ULONG high,low,ret,tmp=(a); \
+ ret = (r); \
+ high= BN_UMULT_HIGH(w,tmp); \
+ ret += (c); \
+ low = (w) * tmp; \
+ (c) = (ret<(c))?1:0; \
+ (c) += high; \
+ ret += low; \
+ (c) += (ret<low)?1:0; \
+ (r) = ret; \
+ }
+
+# define mul(r,a,w,c) { \
+ BN_ULONG high,low,ret,ta=(a); \
+ low = (w) * ta; \
+ high= BN_UMULT_HIGH(w,ta); \
+ ret = low + (c); \
+ (c) = high; \
+ (c) += (ret<low)?1:0; \
+ (r) = ret; \
+ }
+
+# define sqr(r0,r1,a) { \
+ BN_ULONG tmp=(a); \
+ (r0) = tmp * tmp; \
+ (r1) = BN_UMULT_HIGH(tmp,tmp); \
+ }
+
+# else
+/*************************************************************
+ * No long long type
+ */
+
+# define LBITS(a) ((a)&BN_MASK2l)
+# define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2l)
+# define L2HBITS(a) (((a)<<BN_BITS4)&BN_MASK2)
+
+# define LLBITS(a) ((a)&BN_MASKl)
+# define LHBITS(a) (((a)>>BN_BITS2)&BN_MASKl)
+# define LL2HBITS(a) ((BN_ULLONG)((a)&BN_MASKl)<<BN_BITS2)
+
+# define mul64(l,h,bl,bh) \
+ { \
+ BN_ULONG m,m1,lt,ht; \
+ \
+ lt=l; \
+ ht=h; \
+ m =(bh)*(lt); \
+ lt=(bl)*(lt); \
+ m1=(bl)*(ht); \
+ ht =(bh)*(ht); \
+ m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS((BN_ULONG)1); \
+ ht+=HBITS(m); \
+ m1=L2HBITS(m); \
+ lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \
+ (l)=lt; \
+ (h)=ht; \
+ }
+
+# define sqr64(lo,ho,in) \
+ { \
+ BN_ULONG l,h,m; \
+ \
+ h=(in); \
+ l=LBITS(h); \
+ h=HBITS(h); \
+ m =(l)*(h); \
+ l*=l; \
+ h*=h; \
+ h+=(m&BN_MASK2h1)>>(BN_BITS4-1); \
+ m =(m&BN_MASK2l)<<(BN_BITS4+1); \
+ l=(l+m)&BN_MASK2; if (l < m) h++; \
+ (lo)=l; \
+ (ho)=h; \
+ }
+
+# define mul_add(r,a,bl,bh,c) { \
+ BN_ULONG l,h; \
+ \
+ h= (a); \
+ l=LBITS(h); \
+ h=HBITS(h); \
+ mul64(l,h,(bl),(bh)); \
+ \
+ /* non-multiply part */ \
+ l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+ (c)=(r); \
+ l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+ (c)=h&BN_MASK2; \
+ (r)=l; \
+ }
+
+# define mul(r,a,bl,bh,c) { \
+ BN_ULONG l,h; \
+ \
+ h= (a); \
+ l=LBITS(h); \
+ h=HBITS(h); \
+ mul64(l,h,(bl),(bh)); \
+ \
+ /* non-multiply part */ \
+ l+=(c); if ((l&BN_MASK2) < (c)) h++; \
+ (c)=h&BN_MASK2; \
+ (r)=l&BN_MASK2; \
+ }
+# endif /* !BN_LLONG */
+
+# if defined(OPENSSL_DOING_MAKEDEPEND) && defined(OPENSSL_FIPS)
+# undef bn_div_words
+# endif
+
+void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb);
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
+void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp);
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a);
+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);
+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);
+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,
+ BN_ULONG *t);
+void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
+ BN_ULONG *t);
+BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+ int cl, int dl);
+BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+ int cl, int dl);
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+ const BN_ULONG *np, const BN_ULONG *n0, int num);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/bn/bn_lib.c b/openssl/bn/bn_lib.c
new file mode 100644
index 0000000..80105ff
--- /dev/null
+++ b/openssl/bn/bn_lib.c
@@ -0,0 +1,916 @@
+/* crypto/bn/bn_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+const char BN_version[] = "Big Number" OPENSSL_VERSION_PTEXT;
+
+/* This stuff appears to be completely unused, so is deprecated */
+#ifndef OPENSSL_NO_DEPRECATED
+/*-
+ * For a 32 bit machine
+ * 2 - 4 == 128
+ * 3 - 8 == 256
+ * 4 - 16 == 512
+ * 5 - 32 == 1024
+ * 6 - 64 == 2048
+ * 7 - 128 == 4096
+ * 8 - 256 == 8192
+ */
+static int bn_limit_bits = 0;
+static int bn_limit_num = 8; /* (1<<bn_limit_bits) */
+static int bn_limit_bits_low = 0;
+static int bn_limit_num_low = 8; /* (1<<bn_limit_bits_low) */
+static int bn_limit_bits_high = 0;
+static int bn_limit_num_high = 8; /* (1<<bn_limit_bits_high) */
+static int bn_limit_bits_mont = 0;
+static int bn_limit_num_mont = 8; /* (1<<bn_limit_bits_mont) */
+
+void BN_set_params(int mult, int high, int low, int mont)
+{
+ if (mult >= 0) {
+ if (mult > (int)(sizeof(int) * 8) - 1)
+ mult = sizeof(int) * 8 - 1;
+ bn_limit_bits = mult;
+ bn_limit_num = 1 << mult;
+ }
+ if (high >= 0) {
+ if (high > (int)(sizeof(int) * 8) - 1)
+ high = sizeof(int) * 8 - 1;
+ bn_limit_bits_high = high;
+ bn_limit_num_high = 1 << high;
+ }
+ if (low >= 0) {
+ if (low > (int)(sizeof(int) * 8) - 1)
+ low = sizeof(int) * 8 - 1;
+ bn_limit_bits_low = low;
+ bn_limit_num_low = 1 << low;
+ }
+ if (mont >= 0) {
+ if (mont > (int)(sizeof(int) * 8) - 1)
+ mont = sizeof(int) * 8 - 1;
+ bn_limit_bits_mont = mont;
+ bn_limit_num_mont = 1 << mont;
+ }
+}
+
+int BN_get_params(int which)
+{
+ if (which == 0)
+ return (bn_limit_bits);
+ else if (which == 1)
+ return (bn_limit_bits_high);
+ else if (which == 2)
+ return (bn_limit_bits_low);
+ else if (which == 3)
+ return (bn_limit_bits_mont);
+ else
+ return (0);
+}
+#endif
+
+const BIGNUM *BN_value_one(void)
+{
+ static const BN_ULONG data_one = 1L;
+ static const BIGNUM const_one =
+ { (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA };
+
+ return (&const_one);
+}
+
+int BN_num_bits_word(BN_ULONG l)
+{
+ static const unsigned char bits[256] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ };
+
+#if defined(SIXTY_FOUR_BIT_LONG)
+ if (l & 0xffffffff00000000L) {
+ if (l & 0xffff000000000000L) {
+ if (l & 0xff00000000000000L) {
+ return (bits[(int)(l >> 56)] + 56);
+ } else
+ return (bits[(int)(l >> 48)] + 48);
+ } else {
+ if (l & 0x0000ff0000000000L) {
+ return (bits[(int)(l >> 40)] + 40);
+ } else
+ return (bits[(int)(l >> 32)] + 32);
+ }
+ } else
+#else
+# ifdef SIXTY_FOUR_BIT
+ if (l & 0xffffffff00000000LL) {
+ if (l & 0xffff000000000000LL) {
+ if (l & 0xff00000000000000LL) {
+ return (bits[(int)(l >> 56)] + 56);
+ } else
+ return (bits[(int)(l >> 48)] + 48);
+ } else {
+ if (l & 0x0000ff0000000000LL) {
+ return (bits[(int)(l >> 40)] + 40);
+ } else
+ return (bits[(int)(l >> 32)] + 32);
+ }
+ } else
+# endif
+#endif
+ {
+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+ if (l & 0xffff0000L) {
+ if (l & 0xff000000L)
+ return (bits[(int)(l >> 24L)] + 24);
+ else
+ return (bits[(int)(l >> 16L)] + 16);
+ } else
+#endif
+ {
+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+ if (l & 0xff00L)
+ return (bits[(int)(l >> 8)] + 8);
+ else
+#endif
+ return (bits[(int)(l)]);
+ }
+ }
+}
+
+int BN_num_bits(const BIGNUM *a)
+{
+ int i = a->top - 1;
+ bn_check_top(a);
+
+ if (BN_is_zero(a))
+ return 0;
+ return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
+}
+
+void BN_clear_free(BIGNUM *a)
+{
+ int i;
+
+ if (a == NULL)
+ return;
+ bn_check_top(a);
+ if (a->d != NULL) {
+ OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0]));
+ if (!(BN_get_flags(a, BN_FLG_STATIC_DATA)))
+ OPENSSL_free(a->d);
+ }
+ i = BN_get_flags(a, BN_FLG_MALLOCED);
+ OPENSSL_cleanse(a, sizeof(BIGNUM));
+ if (i)
+ OPENSSL_free(a);
+}
+
+void BN_free(BIGNUM *a)
+{
+ if (a == NULL)
+ return;
+ bn_check_top(a);
+ if ((a->d != NULL) && !(BN_get_flags(a, BN_FLG_STATIC_DATA)))
+ OPENSSL_free(a->d);
+ if (a->flags & BN_FLG_MALLOCED)
+ OPENSSL_free(a);
+ else {
+#ifndef OPENSSL_NO_DEPRECATED
+ a->flags |= BN_FLG_FREE;
+#endif
+ a->d = NULL;
+ }
+}
+
+void BN_init(BIGNUM *a)
+{
+ memset(a, 0, sizeof(BIGNUM));
+ bn_check_top(a);
+}
+
+BIGNUM *BN_new(void)
+{
+ BIGNUM *ret;
+
+ if ((ret = (BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL) {
+ BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+ ret->flags = BN_FLG_MALLOCED;
+ ret->top = 0;
+ ret->neg = 0;
+ ret->dmax = 0;
+ ret->d = NULL;
+ bn_check_top(ret);
+ return (ret);
+}
+
+/* This is used both by bn_expand2() and bn_dup_expand() */
+/* The caller MUST check that words > b->dmax before calling this */
+static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
+{
+ BN_ULONG *A, *a = NULL;
+ const BN_ULONG *B;
+ int i;
+
+ bn_check_top(b);
+
+ if (words > (INT_MAX / (4 * BN_BITS2))) {
+ BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
+ return NULL;
+ }
+ if (BN_get_flags(b, BN_FLG_STATIC_DATA)) {
+ BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
+ return (NULL);
+ }
+ a = A = (BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG) * words);
+ if (A == NULL) {
+ BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+#ifdef PURIFY
+ /*
+ * Valgrind complains in BN_consttime_swap because we process the whole
+ * array even if it's not initialised yet. This doesn't matter in that
+ * function - what's important is constant time operation (we're not
+ * actually going to use the data)
+ */
+ memset(a, 0, sizeof(BN_ULONG) * words);
+#endif
+
+#if 1
+ B = b->d;
+ /* Check if the previous number needs to be copied */
+ if (B != NULL) {
+ for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
+ /*
+ * The fact that the loop is unrolled
+ * 4-wise is a tribute to Intel. It's
+ * the one that doesn't have enough
+ * registers to accomodate more data.
+ * I'd unroll it 8-wise otherwise:-)
+ *
+ * <appro@fy.chalmers.se>
+ */
+ 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;
+ }
+ /*
+ * workaround for ultrix cc: without 'case 0', the optimizer does
+ * the switch table by doing a=top&3; a--; goto jump_table[a];
+ * which fails for top== 0
+ */
+ switch (b->top & 3) {
+ case 3:
+ A[2] = B[2];
+ case 2:
+ A[1] = B[1];
+ case 1:
+ A[0] = B[0];
+ case 0:
+ ;
+ }
+ }
+#else
+ memset(A, 0, sizeof(BN_ULONG) * words);
+ memcpy(A, b->d, sizeof(b->d[0]) * b->top);
+#endif
+
+ return (a);
+}
+
+/*
+ * This is an internal function that can be used instead of bn_expand2() when
+ * there is a need to copy BIGNUMs instead of only expanding the data part,
+ * while still expanding them. Especially useful when needing to expand
+ * BIGNUMs that are declared 'const' and should therefore not be changed. The
+ * reason to use this instead of a BN_dup() followed by a bn_expand2() is
+ * memory allocation overhead. A BN_dup() followed by a bn_expand2() will
+ * allocate new memory for the BIGNUM data twice, and free it once, while
+ * bn_dup_expand() makes sure allocation is made only once.
+ */
+
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
+{
+ BIGNUM *r = NULL;
+
+ bn_check_top(b);
+
+ /*
+ * This function does not work if words <= b->dmax && top < words because
+ * BN_dup() does not preserve 'dmax'! (But bn_dup_expand() is not used
+ * anywhere yet.)
+ */
+
+ if (words > b->dmax) {
+ BN_ULONG *a = bn_expand_internal(b, words);
+
+ if (a) {
+ r = BN_new();
+ if (r) {
+ r->top = b->top;
+ r->dmax = words;
+ r->neg = b->neg;
+ r->d = a;
+ } else {
+ /* r == NULL, BN_new failure */
+ OPENSSL_free(a);
+ }
+ }
+ /*
+ * If a == NULL, there was an error in allocation in
+ * bn_expand_internal(), and NULL should be returned
+ */
+ } else {
+ r = BN_dup(b);
+ }
+
+ bn_check_top(r);
+ return r;
+}
+#endif
+
+/*
+ * This is an internal function that should not be used in applications. 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_check_top(b);
+
+ if (words > b->dmax) {
+ BN_ULONG *a = bn_expand_internal(b, words);
+ if (!a)
+ return NULL;
+ if (b->d)
+ OPENSSL_free(b->d);
+ b->d = a;
+ b->dmax = words;
+ }
+
+/* None of this should be necessary because of what b->top means! */
+#if 0
+ /*
+ * NB: bn_wexpand() calls this only if the BIGNUM really has to grow
+ */
+ if (b->top < b->dmax) {
+ int i;
+ BN_ULONG *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]));
+ }
+#endif
+ bn_check_top(b);
+ return b;
+}
+
+BIGNUM *BN_dup(const BIGNUM *a)
+{
+ BIGNUM *t;
+
+ if (a == NULL)
+ return NULL;
+ bn_check_top(a);
+
+ t = BN_new();
+ if (t == NULL)
+ return NULL;
+ if (!BN_copy(t, a)) {
+ BN_free(t);
+ return NULL;
+ }
+ bn_check_top(t);
+ return t;
+}
+
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
+{
+ int i;
+ BN_ULONG *A;
+ const BN_ULONG *B;
+
+ bn_check_top(b);
+
+ if (a == b)
+ return (a);
+ if (bn_wexpand(a, b->top) == NULL)
+ return (NULL);
+
+#if 1
+ A = a->d;
+ B = b->d;
+ for (i = b->top >> 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;
+ }
+ /* ultrix cc workaround, see comments in bn_expand_internal */
+ switch (b->top & 3) {
+ case 3:
+ A[2] = B[2];
+ case 2:
+ A[1] = B[1];
+ case 1:
+ A[0] = B[0];
+ case 0:;
+ }
+#else
+ memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
+#endif
+
+ a->top = b->top;
+ a->neg = b->neg;
+ bn_check_top(a);
+ return (a);
+}
+
+void BN_swap(BIGNUM *a, BIGNUM *b)
+{
+ int flags_old_a, flags_old_b;
+ BN_ULONG *tmp_d;
+ int tmp_top, tmp_dmax, tmp_neg;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ flags_old_a = a->flags;
+ flags_old_b = b->flags;
+
+ tmp_d = a->d;
+ tmp_top = a->top;
+ tmp_dmax = a->dmax;
+ tmp_neg = a->neg;
+
+ a->d = b->d;
+ a->top = b->top;
+ a->dmax = b->dmax;
+ a->neg = b->neg;
+
+ b->d = tmp_d;
+ b->top = tmp_top;
+ b->dmax = tmp_dmax;
+ b->neg = tmp_neg;
+
+ a->flags =
+ (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
+ b->flags =
+ (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
+ bn_check_top(a);
+ bn_check_top(b);
+}
+
+void BN_clear(BIGNUM *a)
+{
+ bn_check_top(a);
+ if (a->d != NULL)
+ memset(a->d, 0, a->dmax * sizeof(a->d[0]));
+ a->top = 0;
+ a->neg = 0;
+}
+
+BN_ULONG BN_get_word(const BIGNUM *a)
+{
+ if (a->top > 1)
+ return BN_MASK2;
+ else if (a->top == 1)
+ return a->d[0];
+ /* a->top == 0 */
+ return 0;
+}
+
+int BN_set_word(BIGNUM *a, BN_ULONG w)
+{
+ bn_check_top(a);
+ if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
+ return (0);
+ a->neg = 0;
+ a->d[0] = w;
+ a->top = (w ? 1 : 0);
+ bn_check_top(a);
+ return (1);
+}
+
+BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
+{
+ unsigned int i, m;
+ unsigned int n;
+ BN_ULONG l;
+ BIGNUM *bn = NULL;
+
+ if (ret == NULL)
+ ret = bn = BN_new();
+ if (ret == NULL)
+ return (NULL);
+ bn_check_top(ret);
+ l = 0;
+ n = len;
+ if (n == 0) {
+ ret->top = 0;
+ return (ret);
+ }
+ i = ((n - 1) / BN_BYTES) + 1;
+ m = ((n - 1) % (BN_BYTES));
+ if (bn_wexpand(ret, (int)i) == NULL) {
+ if (bn)
+ BN_free(bn);
+ return NULL;
+ }
+ ret->top = i;
+ ret->neg = 0;
+ while (n--) {
+ l = (l << 8L) | *(s++);
+ if (m-- == 0) {
+ ret->d[--i] = l;
+ l = 0;
+ m = BN_BYTES - 1;
+ }
+ }
+ /*
+ * need to call this due to clear byte at top if avoiding having the top
+ * bit set (-ve number)
+ */
+ bn_correct_top(ret);
+ return (ret);
+}
+
+/* ignore negative */
+int BN_bn2bin(const BIGNUM *a, unsigned char *to)
+{
+ int n, i;
+ BN_ULONG l;
+
+ bn_check_top(a);
+ n = i = BN_num_bytes(a);
+ while (i--) {
+ l = a->d[i / BN_BYTES];
+ *(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
+ }
+ return (n);
+}
+
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
+{
+ int i;
+ BN_ULONG t1, t2, *ap, *bp;
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ i = a->top - b->top;
+ if (i != 0)
+ return (i);
+ ap = a->d;
+ bp = b->d;
+ for (i = a->top - 1; i >= 0; i--) {
+ t1 = ap[i];
+ t2 = bp[i];
+ if (t1 != t2)
+ return ((t1 > t2) ? 1 : -1);
+ }
+ return (0);
+}
+
+int BN_cmp(const BIGNUM *a, const BIGNUM *b)
+{
+ int i;
+ int gt, lt;
+ BN_ULONG t1, t2;
+
+ if ((a == NULL) || (b == NULL)) {
+ if (a != NULL)
+ return (-1);
+ else if (b != NULL)
+ return (1);
+ else
+ return (0);
+ }
+
+ bn_check_top(a);
+ bn_check_top(b);
+
+ if (a->neg != b->neg) {
+ if (a->neg)
+ return (-1);
+ else
+ return (1);
+ }
+ if (a->neg == 0) {
+ gt = 1;
+ lt = -1;
+ } else {
+ gt = -1;
+ lt = 1;
+ }
+
+ if (a->top > b->top)
+ return (gt);
+ if (a->top < b->top)
+ return (lt);
+ for (i = a->top - 1; i >= 0; i--) {
+ t1 = a->d[i];
+ t2 = b->d[i];
+ if (t1 > t2)
+ return (gt);
+ if (t1 < t2)
+ return (lt);
+ }
+ return (0);
+}
+
+int BN_set_bit(BIGNUM *a, int n)
+{
+ int i, j, k;
+
+ if (n < 0)
+ return 0;
+
+ i = n / BN_BITS2;
+ j = n % BN_BITS2;
+ if (a->top <= i) {
+ if (bn_wexpand(a, i + 1) == NULL)
+ return (0);
+ for (k = a->top; k < i + 1; k++)
+ a->d[k] = 0;
+ a->top = i + 1;
+ }
+
+ a->d[i] |= (((BN_ULONG)1) << j);
+ bn_check_top(a);
+ return (1);
+}
+
+int BN_clear_bit(BIGNUM *a, int n)
+{
+ int i, j;
+
+ bn_check_top(a);
+ if (n < 0)
+ return 0;
+
+ i = n / BN_BITS2;
+ j = n % BN_BITS2;
+ if (a->top <= i)
+ return (0);
+
+ a->d[i] &= (~(((BN_ULONG)1) << j));
+ bn_correct_top(a);
+ return (1);
+}
+
+int BN_is_bit_set(const BIGNUM *a, int n)
+{
+ int i, j;
+
+ bn_check_top(a);
+ if (n < 0)
+ return 0;
+ i = n / BN_BITS2;
+ j = n % BN_BITS2;
+ if (a->top <= i)
+ return 0;
+ return (int)(((a->d[i]) >> j) & ((BN_ULONG)1));
+}
+
+int BN_mask_bits(BIGNUM *a, int n)
+{
+ int b, w;
+
+ bn_check_top(a);
+ if (n < 0)
+ return 0;
+
+ w = n / BN_BITS2;
+ b = n % BN_BITS2;
+ if (w >= a->top)
+ return 0;
+ if (b == 0)
+ a->top = w;
+ else {
+ a->top = w + 1;
+ a->d[w] &= ~(BN_MASK2 << b);
+ }
+ bn_correct_top(a);
+ return (1);
+}
+
+void BN_set_negative(BIGNUM *a, int b)
+{
+ if (b && !BN_is_zero(a))
+ a->neg = 1;
+ else
+ a->neg = 0;
+}
+
+int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
+{
+ int i;
+ BN_ULONG aa, bb;
+
+ aa = a[n - 1];
+ bb = b[n - 1];
+ if (aa != bb)
+ return ((aa > bb) ? 1 : -1);
+ for (i = n - 2; i >= 0; i--) {
+ aa = a[i];
+ bb = b[i];
+ if (aa != bb)
+ return ((aa > bb) ? 1 : -1);
+ }
+ return (0);
+}
+
+/*
+ * Here follows a specialised variants of bn_cmp_words(). It has the
+ * property of performing the operation 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...
+ */
+
+int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl)
+{
+ int n, i;
+ n = cl - 1;
+
+ if (dl < 0) {
+ for (i = dl; i < 0; i++) {
+ if (b[n - i] != 0)
+ return -1; /* a < b */
+ }
+ }
+ if (dl > 0) {
+ for (i = dl; i > 0; i--) {
+ if (a[n + i] != 0)
+ return 1; /* a > b */
+ }
+ }
+ return bn_cmp_words(a, b, cl);
+}
+
+/*
+ * Constant-time conditional swap of a and b.
+ * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set.
+ * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b,
+ * and that no more than nwords are used by either a or b.
+ * a and b cannot be the same number
+ */
+void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
+{
+ BN_ULONG t;
+ int i;
+
+ bn_wcheck_size(a, nwords);
+ bn_wcheck_size(b, nwords);
+
+ assert(a != b);
+ assert((condition & (condition - 1)) == 0);
+ assert(sizeof(BN_ULONG) >= sizeof(int));
+
+ condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
+
+ t = (a->top ^ b->top) & condition;
+ a->top ^= t;
+ b->top ^= t;
+
+#define BN_CONSTTIME_SWAP(ind) \
+ do { \
+ t = (a->d[ind] ^ b->d[ind]) & condition; \
+ a->d[ind] ^= t; \
+ b->d[ind] ^= t; \
+ } while (0)
+
+ switch (nwords) {
+ default:
+ for (i = 10; i < nwords; i++)
+ BN_CONSTTIME_SWAP(i);
+ /* Fallthrough */
+ case 10:
+ BN_CONSTTIME_SWAP(9); /* Fallthrough */
+ case 9:
+ BN_CONSTTIME_SWAP(8); /* Fallthrough */
+ case 8:
+ BN_CONSTTIME_SWAP(7); /* Fallthrough */
+ case 7:
+ BN_CONSTTIME_SWAP(6); /* Fallthrough */
+ case 6:
+ BN_CONSTTIME_SWAP(5); /* Fallthrough */
+ case 5:
+ BN_CONSTTIME_SWAP(4); /* Fallthrough */
+ case 4:
+ BN_CONSTTIME_SWAP(3); /* Fallthrough */
+ case 3:
+ BN_CONSTTIME_SWAP(2); /* Fallthrough */
+ case 2:
+ BN_CONSTTIME_SWAP(1); /* Fallthrough */
+ case 1:
+ BN_CONSTTIME_SWAP(0);
+ }
+#undef BN_CONSTTIME_SWAP
+}
diff --git a/openssl/bn/bn_mod.c b/openssl/bn/bn_mod.c
new file mode 100644
index 0000000..ffbce89
--- /dev/null
+++ b/openssl/bn/bn_mod.c
@@ -0,0 +1,316 @@
+/* crypto/bn/bn_mod.c */
+/*
+ * Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
+ * for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#if 0 /* now just a #define */
+int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+{
+ return (BN_div(NULL, rem, m, d, ctx));
+ /* note that rem->neg == m->neg (unless the remainder is zero) */
+}
+#endif
+
+int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+{
+ /*
+ * like BN_mod, but returns non-negative remainder (i.e., 0 <= r < |d|
+ * always holds)
+ */
+
+ if (!(BN_mod(r, m, d, ctx)))
+ return 0;
+ if (!r->neg)
+ return 1;
+ /* now -|d| < r < 0, so we have to set r := r + |d| */
+ return (d->neg ? BN_sub : BN_add) (r, r, d);
+}
+
+int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx)
+{
+ if (!BN_add(r, a, b))
+ return 0;
+ return BN_nnmod(r, r, m, ctx);
+}
+
+/*
+ * BN_mod_add variant that may be used if both a and b are non-negative and
+ * less than m
+ */
+int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *m)
+{
+ if (!BN_uadd(r, a, b))
+ return 0;
+ if (BN_ucmp(r, m) >= 0)
+ return BN_usub(r, r, m);
+ return 1;
+}
+
+int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx)
+{
+ if (!BN_sub(r, a, b))
+ return 0;
+ return BN_nnmod(r, r, m, ctx);
+}
+
+/*
+ * BN_mod_sub variant that may be used if both a and b are non-negative and
+ * less than m
+ */
+int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ const BIGNUM *m)
+{
+ if (!BN_sub(r, a, b))
+ return 0;
+ if (r->neg)
+ return BN_add(r, r, m);
+ return 1;
+}
+
+/* slow but works */
+int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx)
+{
+ BIGNUM *t;
+ int ret = 0;
+
+ bn_check_top(a);
+ bn_check_top(b);
+ bn_check_top(m);
+
+ BN_CTX_start(ctx);
+ if ((t = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if (a == b) {
+ if (!BN_sqr(t, a, ctx))
+ goto err;
+ } else {
+ if (!BN_mul(t, a, b, ctx))
+ goto err;
+ }
+ if (!BN_nnmod(r, t, m, ctx))
+ goto err;
+ bn_check_top(r);
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ return (ret);
+}
+
+int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
+{
+ if (!BN_sqr(r, a, ctx))
+ return 0;
+ /* r->neg == 0, thus we don't need BN_nnmod */
+ return BN_mod(r, r, m, ctx);
+}
+
+int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
+{
+ if (!BN_lshift1(r, a))
+ return 0;
+ bn_check_top(r);
+ return BN_nnmod(r, r, m, ctx);
+}
+
+/*
+ * BN_mod_lshift1 variant that may be used if a is non-negative and less than
+ * m
+ */
+int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
+{
+ if (!BN_lshift1(r, a))
+ return 0;
+ bn_check_top(r);
+ if (BN_cmp(r, m) >= 0)
+ return BN_sub(r, r, m);
+ return 1;
+}
+
+int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
+ BN_CTX *ctx)
+{
+ BIGNUM *abs_m = NULL;
+ int ret;
+
+ if (!BN_nnmod(r, a, m, ctx))
+ return 0;
+
+ if (m->neg) {
+ abs_m = BN_dup(m);
+ if (abs_m == NULL)
+ return 0;
+ abs_m->neg = 0;
+ }
+
+ ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
+ bn_check_top(r);
+
+ if (abs_m)
+ BN_free(abs_m);
+ return ret;
+}
+
+/*
+ * BN_mod_lshift variant that may be used if a is non-negative and less than
+ * m
+ */
+int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
+{
+ if (r != a) {
+ if (BN_copy(r, a) == NULL)
+ return 0;
+ }
+
+ while (n > 0) {
+ int max_shift;
+
+ /* 0 < r < m */
+ max_shift = BN_num_bits(m) - BN_num_bits(r);
+ /* max_shift >= 0 */
+
+ if (max_shift < 0) {
+ BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED);
+ return 0;
+ }
+
+ if (max_shift > n)
+ max_shift = n;
+
+ if (max_shift) {
+ if (!BN_lshift(r, r, max_shift))
+ return 0;
+ n -= max_shift;
+ } else {
+ if (!BN_lshift1(r, r))
+ return 0;
+ --n;
+ }
+
+ /* BN_num_bits(r) <= BN_num_bits(m) */
+
+ if (BN_cmp(r, m) >= 0) {
+ if (!BN_sub(r, r, m))
+ return 0;
+ }
+ }
+ bn_check_top(r);
+
+ return 1;
+}
diff --git a/openssl/bn/bn_mont.c b/openssl/bn/bn_mont.c
new file mode 100644
index 0000000..aadd5db
--- /dev/null
+++ b/openssl/bn/bn_mont.c
@@ -0,0 +1,555 @@
+/* crypto/bn/bn_mont.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 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).
+ *
+ */
+
+/*
+ * Details about Montgomery multiplication algorithms can be found at
+ * http://security.ece.orst.edu/publications.html, e.g.
+ * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and
+ * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+#define MONT_WORD /* use the faster word-based algorithm */
+
+#ifdef MONT_WORD
+static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
+#endif
+
+int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+ BN_MONT_CTX *mont, BN_CTX *ctx)
+{
+ BIGNUM *tmp;
+ int ret = 0;
+#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
+ int num = mont->N.top;
+
+ if (num > 1 && a->top == num && b->top == num) {
+ if (bn_wexpand(r, num) == NULL)
+ return (0);
+ if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {
+ r->neg = a->neg ^ b->neg;
+ r->top = num;
+ bn_correct_top(r);
+ return (1);
+ }
+ }
+#endif
+
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+ if (tmp == NULL)
+ goto err;
+
+ bn_check_top(tmp);
+ if (a == b) {
+ if (!BN_sqr(tmp, a, ctx))
+ goto err;
+ } else {
+ if (!BN_mul(tmp, a, b, ctx))
+ goto err;
+ }
+ /* reduce from aRR to aR */
+#ifdef MONT_WORD
+ if (!BN_from_montgomery_word(r, tmp, mont))
+ goto err;
+#else
+ if (!BN_from_montgomery(r, tmp, mont, ctx))
+ goto err;
+#endif
+ bn_check_top(r);
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ return (ret);
+}
+
+#ifdef MONT_WORD
+static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
+{
+ BIGNUM *n;
+ BN_ULONG *ap, *np, *rp, n0, v, carry;
+ int nl, max, i;
+
+ n = &(mont->N);
+ nl = n->top;
+ if (nl == 0) {
+ ret->top = 0;
+ return (1);
+ }
+
+ max = (2 * nl); /* carry is stored separately */
+ if (bn_wexpand(r, max) == NULL)
+ return (0);
+
+ r->neg ^= n->neg;
+ np = n->d;
+ rp = r->d;
+
+ /* clear the top words of T */
+# if 1
+ for (i = r->top; i < max; i++) /* memset? XXX */
+ rp[i] = 0;
+# else
+ memset(&(rp[r->top]), 0, (max - r->top) * sizeof(BN_ULONG));
+# endif
+
+ r->top = max;
+ n0 = mont->n0[0];
+
+# ifdef BN_COUNT
+ fprintf(stderr, "word BN_from_montgomery_word %d * %d\n", nl, nl);
+# endif
+ for (carry = 0, i = 0; i < nl; i++, rp++) {
+# ifdef __TANDEM
+ {
+ long long t1;
+ long long t2;
+ long long t3;
+ t1 = rp[0] * (n0 & 0177777);
+ t2 = 037777600000l;
+ t2 = n0 & t2;
+ t3 = rp[0] & 0177777;
+ t2 = (t3 * t2) & BN_MASK2;
+ t1 = t1 + t2;
+ v = bn_mul_add_words(rp, np, nl, (BN_ULONG)t1);
+ }
+# else
+ v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2);
+# endif
+ v = (v + carry + rp[nl]) & BN_MASK2;
+ carry |= (v != rp[nl]);
+ carry &= (v <= rp[nl]);
+ rp[nl] = v;
+ }
+
+ if (bn_wexpand(ret, nl) == NULL)
+ return (0);
+ ret->top = nl;
+ ret->neg = r->neg;
+
+ rp = ret->d;
+ ap = &(r->d[nl]);
+
+# define BRANCH_FREE 1
+# if BRANCH_FREE
+ {
+ BN_ULONG *nrp;
+ size_t m;
+
+ v = bn_sub_words(rp, ap, np, nl) - carry;
+ /*
+ * if subtraction result is real, then trick unconditional memcpy
+ * below to perform in-place "refresh" instead of actual copy.
+ */
+ m = (0 - (size_t)v);
+ nrp =
+ (BN_ULONG *)(((PTR_SIZE_INT) rp & ~m) | ((PTR_SIZE_INT) ap & m));
+
+ for (i = 0, nl -= 4; i < nl; i += 4) {
+ BN_ULONG t1, t2, t3, t4;
+
+ t1 = nrp[i + 0];
+ t2 = nrp[i + 1];
+ t3 = nrp[i + 2];
+ ap[i + 0] = 0;
+ t4 = nrp[i + 3];
+ ap[i + 1] = 0;
+ rp[i + 0] = t1;
+ ap[i + 2] = 0;
+ rp[i + 1] = t2;
+ ap[i + 3] = 0;
+ rp[i + 2] = t3;
+ rp[i + 3] = t4;
+ }
+ for (nl += 4; i < nl; i++)
+ rp[i] = nrp[i], ap[i] = 0;
+ }
+# else
+ if (bn_sub_words(rp, ap, np, nl) - carry)
+ memcpy(rp, ap, nl * sizeof(BN_ULONG));
+# endif
+ bn_correct_top(r);
+ bn_correct_top(ret);
+ bn_check_top(ret);
+
+ return (1);
+}
+#endif /* MONT_WORD */
+
+int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
+ BN_CTX *ctx)
+{
+ int retn = 0;
+#ifdef MONT_WORD
+ BIGNUM *t;
+
+ BN_CTX_start(ctx);
+ if ((t = BN_CTX_get(ctx)) && BN_copy(t, a))
+ retn = BN_from_montgomery_word(ret, t, mont);
+ BN_CTX_end(ctx);
+#else /* !MONT_WORD */
+ BIGNUM *t1, *t2;
+
+ BN_CTX_start(ctx);
+ t1 = BN_CTX_get(ctx);
+ t2 = BN_CTX_get(ctx);
+ if (t1 == NULL || t2 == NULL)
+ goto err;
+
+ if (!BN_copy(t1, a))
+ goto err;
+ BN_mask_bits(t1, mont->ri);
+
+ if (!BN_mul(t2, t1, &mont->Ni, ctx))
+ goto err;
+ BN_mask_bits(t2, mont->ri);
+
+ if (!BN_mul(t1, t2, &mont->N, ctx))
+ goto err;
+ if (!BN_add(t2, a, t1))
+ goto err;
+ if (!BN_rshift(ret, t2, mont->ri))
+ goto err;
+
+ if (BN_ucmp(ret, &(mont->N)) >= 0) {
+ if (!BN_usub(ret, ret, &(mont->N)))
+ goto err;
+ }
+ retn = 1;
+ bn_check_top(ret);
+ err:
+ BN_CTX_end(ctx);
+#endif /* MONT_WORD */
+ return (retn);
+}
+
+BN_MONT_CTX *BN_MONT_CTX_new(void)
+{
+ BN_MONT_CTX *ret;
+
+ if ((ret = (BN_MONT_CTX *)OPENSSL_malloc(sizeof(BN_MONT_CTX))) == NULL)
+ return (NULL);
+
+ BN_MONT_CTX_init(ret);
+ ret->flags = BN_FLG_MALLOCED;
+ return (ret);
+}
+
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
+{
+ ctx->ri = 0;
+ BN_init(&(ctx->RR));
+ BN_init(&(ctx->N));
+ BN_init(&(ctx->Ni));
+ ctx->n0[0] = ctx->n0[1] = 0;
+ ctx->flags = 0;
+}
+
+void BN_MONT_CTX_free(BN_MONT_CTX *mont)
+{
+ if (mont == NULL)
+ return;
+
+ BN_free(&(mont->RR));
+ BN_free(&(mont->N));
+ BN_free(&(mont->Ni));
+ if (mont->flags & BN_FLG_MALLOCED)
+ OPENSSL_free(mont);
+}
+
+int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
+{
+ int ret = 0;
+ BIGNUM *Ri, *R;
+
+ BN_CTX_start(ctx);
+ if ((Ri = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ R = &(mont->RR); /* grab RR as a temp */
+ if (!BN_copy(&(mont->N), mod))
+ goto err; /* Set N */
+ mont->N.neg = 0;
+
+#ifdef MONT_WORD
+ {
+ BIGNUM tmod;
+ BN_ULONG buf[2];
+
+ BN_init(&tmod);
+ tmod.d = buf;
+ tmod.dmax = 2;
+ tmod.neg = 0;
+
+ mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;
+
+# if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
+ /*
+ * Only certain BN_BITS2<=32 platforms actually make use of n0[1],
+ * and we could use the #else case (with a shorter R value) for the
+ * others. However, currently only the assembler files do know which
+ * is which.
+ */
+
+ BN_zero(R);
+ if (!(BN_set_bit(R, 2 * BN_BITS2)))
+ goto err;
+
+ tmod.top = 0;
+ if ((buf[0] = mod->d[0]))
+ tmod.top = 1;
+ if ((buf[1] = mod->top > 1 ? mod->d[1] : 0))
+ tmod.top = 2;
+
+ if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL)
+ goto err;
+ if (!BN_lshift(Ri, Ri, 2 * BN_BITS2))
+ goto err; /* R*Ri */
+ if (!BN_is_zero(Ri)) {
+ if (!BN_sub_word(Ri, 1))
+ goto err;
+ } else { /* if N mod word size == 1 */
+
+ if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL)
+ goto err;
+ /* Ri-- (mod double word size) */
+ Ri->neg = 0;
+ Ri->d[0] = BN_MASK2;
+ Ri->d[1] = BN_MASK2;
+ Ri->top = 2;
+ }
+ if (!BN_div(Ri, NULL, Ri, &tmod, ctx))
+ goto err;
+ /*
+ * Ni = (R*Ri-1)/N, keep only couple of least significant words:
+ */
+ mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
+ mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
+# else
+ BN_zero(R);
+ if (!(BN_set_bit(R, BN_BITS2)))
+ goto err; /* R */
+
+ buf[0] = mod->d[0]; /* tmod = N mod word size */
+ buf[1] = 0;
+ tmod.top = buf[0] != 0 ? 1 : 0;
+ /* Ri = R^-1 mod N */
+ if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL)
+ goto err;
+ if (!BN_lshift(Ri, Ri, BN_BITS2))
+ goto err; /* R*Ri */
+ if (!BN_is_zero(Ri)) {
+ if (!BN_sub_word(Ri, 1))
+ goto err;
+ } else { /* if N mod word size == 1 */
+
+ if (!BN_set_word(Ri, BN_MASK2))
+ goto err; /* Ri-- (mod word size) */
+ }
+ if (!BN_div(Ri, NULL, Ri, &tmod, ctx))
+ goto err;
+ /*
+ * Ni = (R*Ri-1)/N, keep only least significant word:
+ */
+ mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
+ mont->n0[1] = 0;
+# endif
+ }
+#else /* !MONT_WORD */
+ { /* bignum version */
+ mont->ri = BN_num_bits(&mont->N);
+ BN_zero(R);
+ if (!BN_set_bit(R, mont->ri))
+ goto err; /* R = 2^ri */
+ /* Ri = R^-1 mod N */
+ if ((BN_mod_inverse(Ri, R, &mont->N, ctx)) == NULL)
+ goto err;
+ if (!BN_lshift(Ri, Ri, mont->ri))
+ goto err; /* R*Ri */
+ if (!BN_sub_word(Ri, 1))
+ goto err;
+ /*
+ * Ni = (R*Ri-1) / N
+ */
+ if (!BN_div(&(mont->Ni), NULL, Ri, &mont->N, ctx))
+ goto err;
+ }
+#endif
+
+ /* setup RR for conversions */
+ BN_zero(&(mont->RR));
+ if (!BN_set_bit(&(mont->RR), mont->ri * 2))
+ goto err;
+ if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx))
+ goto err;
+
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ return ret;
+}
+
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
+{
+ if (to == from)
+ return (to);
+
+ if (!BN_copy(&(to->RR), &(from->RR)))
+ return NULL;
+ if (!BN_copy(&(to->N), &(from->N)))
+ return NULL;
+ if (!BN_copy(&(to->Ni), &(from->Ni)))
+ return NULL;
+ to->ri = from->ri;
+ to->n0[0] = from->n0[0];
+ to->n0[1] = from->n0[1];
+ return (to);
+}
+
+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
+ const BIGNUM *mod, BN_CTX *ctx)
+{
+ BN_MONT_CTX *ret;
+
+ CRYPTO_r_lock(lock);
+ ret = *pmont;
+ CRYPTO_r_unlock(lock);
+ if (ret)
+ return ret;
+
+ /*
+ * We don't want to serialise globally while doing our lazy-init math in
+ * BN_MONT_CTX_set. That punishes threads that are doing independent
+ * things. Instead, punish the case where more than one thread tries to
+ * lazy-init the same 'pmont', by having each do the lazy-init math work
+ * independently and only use the one from the thread that wins the race
+ * (the losers throw away the work they've done).
+ */
+ ret = BN_MONT_CTX_new();
+ if (!ret)
+ return NULL;
+ if (!BN_MONT_CTX_set(ret, mod, ctx)) {
+ BN_MONT_CTX_free(ret);
+ return NULL;
+ }
+
+ /* The locked compare-and-set, after the local work is done. */
+ CRYPTO_w_lock(lock);
+ if (*pmont) {
+ BN_MONT_CTX_free(ret);
+ ret = *pmont;
+ } else
+ *pmont = ret;
+ CRYPTO_w_unlock(lock);
+ return ret;
+}
diff --git a/openssl/bn/bn_mont_mul.S b/openssl/bn/bn_mont_mul.S
new file mode 100644
index 0000000..40abf63
--- /dev/null
+++ b/openssl/bn/bn_mont_mul.S
@@ -0,0 +1,155 @@
+.syntax unified
+.cpu cortex-m4
+
+.text
+
+.global bn_mul_mont
+.type bn_mul_mont,%function
+
+.align 2
+bn_mul_mont:
+ stmdb sp!,{r0,r2} @ sp points at argument block
+ ldr r0,[sp,#3*4] @ load num
+ cmp r0,#2
+ ittt lt @ if n < 2 return 0
+ movlt r0,#0
+ addlt sp,sp,#2*4
+ blt .Labrt
+
+ stmdb sp!,{r4-r12,lr} @ save 10 registers
+
+ mov r0,r0,lsl#2 @ rescale r0 for byte count
+ sub sp,sp,r0 @ alloca(4*num)
+ sub sp,sp,#4 @ +extra dword
+ sub r0,r0,#4 @ "num=num-1"
+ add r4,r2,r0 @ &bp[num-1]
+
+ add r0,sp,r0 @ r0 to point at &tp[num-1]
+ ldr r8,[r0,#14*4] @ &n0
+ ldr r2,[r2] @ bp[0]
+ ldr r5,[r1],#4 @ ap[0],ap++
+ ldr r6,[r3],#4 @ np[0],np++
+ ldr r8,[r8] @ *n0
+ str r4,[r0,#15*4] @ save &bp[num]
+
+ umull r10,r11,r5,r2 @ ap[0]*bp[0]
+ str r8,[r0,#14*4] @ save n0 value
+ mul r8,r10,r8 @ "tp[0]"*n0
+ mov r12,#0
+ umlal r10,r12,r6,r8 @ np[0]*n0+"t[0]"
+ mov r4,sp
+
+.L1st:
+ ldr r5,[r1],#4 @ ap[j],ap++
+ mov r10,r11
+ ldr r6,[r3],#4 @ np[j],np++
+ mov r11,#0
+ umlal r10,r11,r5,r2 @ ap[j]*bp[0]
+ mov r14,#0
+ umlal r12,r14,r6,r8 @ np[j]*n0
+ adds r12,r12,r10
+ str r12,[r4],#4 @ tp[j-1]=,tp++
+ adc r12,r14,#0
+ cmp r4,r0
+ bne .L1st
+
+ adds r12,r12,r11
+ ldr r4,[r0,#13*4] @ restore bp
+ mov r14,#0
+ ldr r8,[r0,#14*4] @ restore n0
+ adc r14,r14,#0
+ str r12,[r0] @ tp[num-1]=
+ str r14,[r0,#4] @ tp[num]=
+
+.Louter:
+ mov r5, sp @ mp: change
+ sub r7,r0, r5 @ "original" r0-1 value
+ sub r1,r1,r7 @ "rewind" ap to &ap[1]
+ ldr r2,[r4,#4]! @ *(++bp)
+ sub r3,r3,r7 @ "rewind" np to &np[1]
+ ldr r5,[r1,#-4] @ ap[0]
+ ldr r10,[sp] @ tp[0]
+ ldr r6,[r3,#-4] @ np[0]
+ ldr r7,[sp,#4] @ tp[1]
+
+ mov r11,#0
+ umlal r10,r11,r5,r2 @ ap[0]*bp[i]+tp[0]
+ str r4,[r0,#13*4] @ save bp
+ mul r8,r10,r8
+ mov r12,#0
+ umlal r10,r12,r6,r8 @ np[0]*n0+"tp[0]"
+ mov r4,sp
+
+.Linner:
+ ldr r5,[r1],#4 @ ap[j],ap++
+ adds r10,r11,r7 @ +=tp[j]
+ ldr r6,[r3],#4 @ np[j],np++
+ mov r11,#0
+ umlal r10,r11,r5,r2 @ ap[j]*bp[i]
+ mov r14,#0
+ umlal r12,r14,r6,r8 @ np[j]*n0
+ adc r11,r11,#0
+ ldr r7,[r4,#8] @ tp[j+1]
+ adds r12,r12,r10
+ str r12,[r4],#4 @ tp[j-1]=,tp++
+ adc r12,r14,#0
+ cmp r4,r0
+ bne .Linner
+
+ adds r12,r12,r11
+ mov r14,#0
+ ldr r4,[r0,#13*4] @ restore bp
+ adc r14,r14,#0
+ ldr r8,[r0,#14*4] @ restore n0
+ adds r12,r12,r7
+ ldr r7,[r0,#15*4] @ restore &bp[num]
+ adc r14,r14,#0
+ str r12,[r0] @ tp[num-1]=
+ str r14,[r0,#4] @ tp[num]=
+
+ cmp r4,r7
+ bne .Louter
+
+
+ ldr r2,[r0,#12*4] @ pull rp
+ add r0,r0,#4 @ r0 to point at &tp[num]
+ mov r5, sp @ mp: change
+ sub r5, r0, r5 @ "original" num value
+ mov r4,sp @ "rewind" r4
+ mov r1,r4 @ "borrow" r1
+ sub r3,r3,r5 @ "rewind" r3 to &np[0]
+
+ subs r7,r7,r7 @ "clear" carry flag
+.Lsub: ldr r7,[r4],#4
+ ldr r6,[r3],#4
+ sbcs r7,r7,r6 @ tp[j]-np[j]
+ str r7,[r2],#4 @ rp[j]=
+ teq r4,r0 @ preserve carry
+ bne .Lsub
+ sbcs r14,r14,#0 @ upmost carry
+ mov r4,sp @ "rewind" r4
+ sub r2,r2,r5 @ "rewind" r2
+
+ and r1,r4,r14
+ bic r3,r2,r14
+ orr r1,r1,r3 @ ap=borrow?tp:rp
+
+.Lcopy: ldr r7,[r1],#4 @ copy or in-place refresh
+ str sp,[r4],#4 @ zap tp
+ str r7,[r2],#4
+ cmp r4,r0
+ bne .Lcopy
+
+ add r0, r0, #4 @ mp: change
+ mov sp,r0 @ skip over tp[num+1]
+ ldmia sp!,{r4-r12,lr} @ restore registers
+ add sp,sp,#2*4 @ skip over {r0,r2}
+ mov r0,#1
+.Labrt:
+
+ bx lr
+.size bn_mul_mont,.-bn_mul_mont
+@.asciz "Montgomery multiplication for ARMv4, CRYPTOGAMS by <appro@openssl.org>"
+.align 2
+
+
diff --git a/openssl/bn/bn_mpi.c b/openssl/bn/bn_mpi.c
new file mode 100644
index 0000000..3bd40bb
--- /dev/null
+++ b/openssl/bn/bn_mpi.c
@@ -0,0 +1,128 @@
+/* crypto/bn/bn_mpi.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+int BN_bn2mpi(const BIGNUM *a, unsigned char *d)
+{
+ int bits;
+ int num = 0;
+ int ext = 0;
+ long l;
+
+ bits = BN_num_bits(a);
+ num = (bits + 7) / 8;
+ if (bits > 0) {
+ ext = ((bits & 0x07) == 0);
+ }
+ if (d == NULL)
+ return (num + 4 + ext);
+
+ l = num + ext;
+ d[0] = (unsigned char)(l >> 24) & 0xff;
+ d[1] = (unsigned char)(l >> 16) & 0xff;
+ d[2] = (unsigned char)(l >> 8) & 0xff;
+ d[3] = (unsigned char)(l) & 0xff;
+ if (ext)
+ d[4] = 0;
+ num = BN_bn2bin(a, &(d[4 + ext]));
+ if (a->neg)
+ d[4] |= 0x80;
+ return (num + 4 + ext);
+}
+
+BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *a)
+{
+ long len;
+ int neg = 0;
+
+ if (n < 4) {
+ BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH);
+ return (NULL);
+ }
+ len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) | (int)
+ d[3];
+ if ((len + 4) != n) {
+ BNerr(BN_F_BN_MPI2BN, BN_R_ENCODING_ERROR);
+ return (NULL);
+ }
+
+ if (a == NULL)
+ a = BN_new();
+ if (a == NULL)
+ return (NULL);
+
+ if (len == 0) {
+ a->neg = 0;
+ a->top = 0;
+ return (a);
+ }
+ d += 4;
+ if ((*d) & 0x80)
+ neg = 1;
+ if (BN_bin2bn(d, (int)len, a) == NULL)
+ return (NULL);
+ a->neg = neg;
+ if (neg) {
+ BN_clear_bit(a, BN_num_bits(a) - 1);
+ }
+ bn_check_top(a);
+ return (a);
+}
diff --git a/openssl/bn/bn_mul.c b/openssl/bn/bn_mul.c
new file mode 100644
index 0000000..b174850
--- /dev/null
+++ b/openssl/bn/bn_mul.c
@@ -0,0 +1,1164 @@
+/* crypto/bn/bn_mul.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [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(OPENSSL_BN_ASM_PART_WORDS)
+/*
+ * 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)
+ */
+
+/*-
+ * r is 2*n2 words in size,
+ * a and b are both n2 words in size.
+ * n2 must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n2 words in size
+ * We calculate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+/* dnX may not be positive, but n2/2+dnX has to be */
+void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+ 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
+ fprintf(stderr, " bn_mul_recursive %d%+d * %d%+d\n", n2, dna, n2, dnb);
+# endif
+# ifdef BN_MUL_COMBA
+# if 0
+ if (n2 == 4) {
+ bn_mul_comba4(r, a, b);
+ return;
+ }
+# endif
+ /*
+ * 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) {
+ 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_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_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_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:
+ case 0:
+ case 1:
+ zero = 1;
+ break;
+ case 2:
+ 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_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 && 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]));
+ else
+ memset(&(t[n2]), 0, 8 * sizeof(BN_ULONG));
+
+ bn_mul_comba4(r, a, b);
+ bn_mul_comba4(&(r[n2]), &(a[n]), &(b[n]));
+ } 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]));
+ else
+ memset(&(t[n2]), 0, 16 * sizeof(BN_ULONG));
+
+ bn_mul_comba8(r, a, b);
+ bn_mul_comba8(&(r[n2]), &(a[n]), &(b[n]));
+ } else
+# endif /* BN_MUL_COMBA */
+ {
+ p = &(t[n2 * 2]);
+ if (!zero)
+ 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, 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
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ */
+
+ c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
+
+ if (neg) { /* if t[32] is negative */
+ c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
+ } else {
+ /* Might have a carry */
+ c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
+ }
+
+ /*-
+ * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ * c1 holds the carry bits
+ */
+ c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
+ if (c1) {
+ p = &(r[n + n2]);
+ lo = *p;
+ ln = (lo + c1) & BN_MASK2;
+ *p = ln;
+
+ /*
+ * The overflow will stop before we over write words we should not
+ * overwrite
+ */
+ if (ln < (BN_ULONG)c1) {
+ do {
+ p++;
+ lo = *p;
+ ln = (lo + 1) & BN_MASK2;
+ *p = ln;
+ } while (ln == 0);
+ }
+ }
+}
+
+/*
+ * n+tn is the word length t needs to be n*4 is size, as does r
+ */
+/* tnX may not be negative but less than n */
+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;
+ int c1, c2, neg;
+ BN_ULONG ln, lo, *p;
+
+# ifdef BN_COUNT
+ fprintf(stderr, " bn_mul_part_recursive (%d%+d) * (%d%+d)\n",
+ n, tna, n, tnb);
+# endif
+ if (n < 8) {
+ bn_mul_normal(r, a, n + tna, b, n + tnb);
+ return;
+ }
+
+ /* r=(a[0]-a[1])*(b[1]-b[0]) */
+ c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
+ c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
+ neg = 0;
+ switch (c1 * 3 + c2) {
+ case -4:
+ 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:
+ /* break; */
+ case -2:
+ 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:
+ case 0:
+ case 1:
+ /* break; */
+ case 2:
+ 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:
+ /* break; */
+ case 4:
+ 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 would probably
+ * be negligible.
+ */
+# if 0
+ if (n == 4) {
+ bn_mul_comba4(&(t[n2]), t, &(t[n]));
+ bn_mul_comba4(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));
+ } else
+# endif
+ if (n == 8) {
+ bn_mul_comba8(&(t[n2]), t, &(t[n]));
+ bn_mul_comba8(r, a, b);
+ 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, 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
+ */
+ if (tna > tnb)
+ j = tna - i;
+ else
+ j = tnb - i;
+ if (j == 0) {
+ 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]),
+ 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 (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
+ && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) {
+ bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
+ } else {
+ for (;;) {
+ i /= 2;
+ /*
+ * these simplified conditions work exclusively because
+ * difference between tna and tnb is 1 or 0
+ */
+ if (i < tna || i < tnb) {
+ bn_mul_part_recursive(&(r[n2]),
+ &(a[n]), &(b[n]),
+ i, tna - i, tnb - i, p);
+ break;
+ } else if (i == tna || i == tnb) {
+ bn_mul_recursive(&(r[n2]),
+ &(a[n]), &(b[n]),
+ i, tna - i, tnb - i, p);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /*-
+ * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ */
+
+ c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
+
+ if (neg) { /* if t[32] is negative */
+ c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
+ } else {
+ /* Might have a carry */
+ c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
+ }
+
+ /*-
+ * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ * c1 holds the carry bits
+ */
+ c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
+ if (c1) {
+ p = &(r[n + n2]);
+ lo = *p;
+ ln = (lo + c1) & BN_MASK2;
+ *p = ln;
+
+ /*
+ * The overflow will stop before we over write words we should not
+ * overwrite
+ */
+ if (ln < (BN_ULONG)c1) {
+ do {
+ p++;
+ lo = *p;
+ ln = (lo + 1) & BN_MASK2;
+ *p = ln;
+ } while (ln == 0);
+ }
+ }
+}
+
+/*-
+ * a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ */
+void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+ BN_ULONG *t)
+{
+ int n = n2 / 2;
+
+# ifdef BN_COUNT
+ fprintf(stderr, " bn_mul_low_recursive %d * %d\n", n2, n2);
+# endif
+
+ 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]));
+ bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
+ bn_mul_low_recursive(&(t[0]), &(a[n]), &(b[0]), n, &(t[n2]));
+ bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
+ } else {
+ bn_mul_low_normal(&(t[0]), &(a[0]), &(b[n]), n);
+ bn_mul_low_normal(&(t[n]), &(a[n]), &(b[0]), n);
+ bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
+ bn_add_words(&(r[n]), &(r[n]), &(t[n]), n);
+ }
+}
+
+/*-
+ * a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ * l is the low words of the output.
+ * t needs to be n2*3
+ */
+void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
+ BN_ULONG *t)
+{
+ int i, n;
+ int c1, c2;
+ int neg, oneg, zero;
+ BN_ULONG ll, lc, *lp, *mp;
+
+# ifdef BN_COUNT
+ fprintf(stderr, " bn_mul_high %d * %d\n", n2, n2);
+# endif
+ n = n2 / 2;
+
+ /* Calculate (al-ah)*(bh-bl) */
+ neg = zero = 0;
+ c1 = bn_cmp_words(&(a[0]), &(a[n]), n);
+ c2 = bn_cmp_words(&(b[n]), &(b[0]), n);
+ switch (c1 * 3 + c2) {
+ case -4:
+ bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
+ bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
+ break;
+ case -3:
+ zero = 1;
+ break;
+ case -2:
+ bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
+ bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
+ neg = 1;
+ break;
+ case -1:
+ case 0:
+ case 1:
+ zero = 1;
+ break;
+ case 2:
+ bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
+ bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
+ neg = 1;
+ break;
+ case 3:
+ zero = 1;
+ break;
+ case 4:
+ bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
+ bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
+ break;
+ }
+
+ oneg = neg;
+ /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
+ /* r[10] = (a[1]*b[1]) */
+# ifdef BN_MUL_COMBA
+ if (n == 8) {
+ bn_mul_comba8(&(t[0]), &(r[0]), &(r[n]));
+ bn_mul_comba8(r, &(a[n]), &(b[n]));
+ } else
+# endif
+ {
+ 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)
+ * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
+ * We know s0 and s1 so the only unknown is high(al*bl)
+ * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
+ * high(al*bl) == s1 - (r[0]+l[0]+t[0])
+ */
+ if (l != NULL) {
+ lp = &(t[n2 + n]);
+ c1 = (int)(bn_add_words(lp, &(r[0]), &(l[0]), n));
+ } else {
+ c1 = 0;
+ lp = &(r[0]);
+ }
+
+ if (neg)
+ neg = (int)(bn_sub_words(&(t[n2]), lp, &(t[0]), n));
+ else {
+ bn_add_words(&(t[n2]), lp, &(t[0]), n);
+ neg = 0;
+ }
+
+ if (l != NULL) {
+ bn_sub_words(&(t[n2 + n]), &(l[n]), &(t[n2]), n);
+ } else {
+ lp = &(t[n2 + n]);
+ mp = &(t[n2]);
+ for (i = 0; i < n; i++)
+ lp[i] = ((~mp[i]) + 1) & BN_MASK2;
+ }
+
+ /*-
+ * s[0] = low(al*bl)
+ * t[3] = high(al*bl)
+ * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
+ * r[10] = (a[1]*b[1])
+ */
+ /*-
+ * R[10] = al*bl
+ * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
+ * R[32] = ah*bh
+ */
+ /*-
+ * R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
+ * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
+ * R[3]=r[1]+(carry/borrow)
+ */
+ if (l != NULL) {
+ lp = &(t[n2]);
+ c1 = (int)(bn_add_words(lp, &(t[n2 + n]), &(l[0]), n));
+ } else {
+ lp = &(t[n2 + n]);
+ c1 = 0;
+ }
+ c1 += (int)(bn_add_words(&(t[n2]), lp, &(r[0]), n));
+ if (oneg)
+ c1 -= (int)(bn_sub_words(&(t[n2]), &(t[n2]), &(t[0]), n));
+ else
+ c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), &(t[0]), n));
+
+ c2 = (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n2 + n]), n));
+ c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(r[n]), n));
+ if (oneg)
+ c2 -= (int)(bn_sub_words(&(r[0]), &(r[0]), &(t[n]), n));
+ else
+ c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n]), n));
+
+ if (c1 != 0) { /* Add starting at r[0], could be +ve or -ve */
+ i = 0;
+ if (c1 > 0) {
+ lc = c1;
+ do {
+ ll = (r[i] + lc) & BN_MASK2;
+ r[i++] = ll;
+ lc = (lc > ll);
+ } while (lc);
+ } else {
+ lc = -c1;
+ do {
+ ll = r[i];
+ r[i++] = (ll - lc) & BN_MASK2;
+ lc = (lc > ll);
+ } while (lc);
+ }
+ }
+ if (c2 != 0) { /* Add starting at r[1] */
+ i = n;
+ if (c2 > 0) {
+ lc = c2;
+ do {
+ ll = (r[i] + lc) & BN_MASK2;
+ r[i++] = ll;
+ lc = (lc > ll);
+ } while (lc);
+ } else {
+ lc = -c2;
+ do {
+ ll = r[i];
+ r[i++] = (ll - lc) & BN_MASK2;
+ lc = (lc > ll);
+ } while (lc);
+ }
+ }
+}
+#endif /* BN_RECURSION */
+
+int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+ int ret = 0;
+ int top, al, bl;
+ BIGNUM *rr;
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+ int i;
+#endif
+#ifdef BN_RECURSION
+ BIGNUM *t = NULL;
+ int j = 0, k;
+#endif
+
+#ifdef BN_COUNT
+ fprintf(stderr, "BN_mul %d * %d\n", a->top, b->top);
+#endif
+
+ bn_check_top(a);
+ bn_check_top(b);
+ bn_check_top(r);
+
+ al = a->top;
+ bl = b->top;
+
+ if ((al == 0) || (bl == 0)) {
+ BN_zero(r);
+ return (1);
+ }
+ top = al + bl;
+
+ BN_CTX_start(ctx);
+ if ((r == a) || (r == b)) {
+ if ((rr = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ } else
+ rr = r;
+ rr->neg = a->neg ^ b->neg;
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+ i = al - bl;
+#endif
+#ifdef BN_MUL_COMBA
+ if (i == 0) {
+# if 0
+ if (al == 4) {
+ if (bn_wexpand(rr, 8) == NULL)
+ goto err;
+ rr->top = 8;
+ bn_mul_comba4(rr->d, a->d, b->d);
+ goto end;
+ }
+# endif
+ if (al == 8) {
+ if (bn_wexpand(rr, 16) == NULL)
+ goto err;
+ rr->top = 16;
+ bn_mul_comba8(rr->d, a->d, b->d);
+ goto end;
+ }
+ }
+#endif /* BN_MUL_COMBA */
+#ifdef BN_RECURSION
+ if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
+ if (i >= -1 && i <= 1) {
+ /*
+ * 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);
+ }
+ j = 1 << (j - 1);
+ assert(j <= al || j <= bl);
+ k = j + j;
+ t = BN_CTX_get(ctx);
+ if (t == NULL)
+ goto err;
+ if (al > j || bl > j) {
+ 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,
+ j, al - j, bl - j, t->d);
+ } else { /* al <= j || bl <= j */
+
+ 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, 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)) {
+ BIGNUM *tmp_bn = (BIGNUM *)a;
+ if (bn_wexpand(tmp_bn, bl) == NULL)
+ goto err;
+ tmp_bn->d[al] = 0;
+ al++;
+ i++;
+ }
+ if (i == 0) {
+ /* symmetric and > 4 */
+ /* 16 or larger */
+ j = BN_num_bits_word((BN_ULONG)al);
+ j = 1 << (j - 1);
+ k = j + j;
+ t = BN_CTX_get(ctx);
+ if (al == j) { /* exact multiple */
+ 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);
+ } else {
+ 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 /* BN_RECURSION */
+ if (bn_wexpand(rr, top) == NULL)
+ goto err;
+ rr->top = top;
+ bn_mul_normal(rr->d, a->d, al, b->d, bl);
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+ end:
+#endif
+ bn_correct_top(rr);
+ if (r != rr)
+ BN_copy(r, rr);
+ ret = 1;
+ err:
+ bn_check_top(r);
+ BN_CTX_end(ctx);
+ return (ret);
+}
+
+void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
+{
+ BN_ULONG *rr;
+
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_mul_normal %d * %d\n", na, nb);
+#endif
+
+ if (na < nb) {
+ int itmp;
+ BN_ULONG *ltmp;
+
+ itmp = na;
+ na = nb;
+ nb = itmp;
+ ltmp = a;
+ a = b;
+ b = ltmp;
+
+ }
+ rr = &(r[na]);
+ if (nb <= 0) {
+ (void)bn_mul_words(r, a, na, 0);
+ return;
+ } else
+ rr[0] = bn_mul_words(r, a, na, b[0]);
+
+ for (;;) {
+ if (--nb <= 0)
+ return;
+ rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]);
+ if (--nb <= 0)
+ return;
+ rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]);
+ if (--nb <= 0)
+ return;
+ rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]);
+ if (--nb <= 0)
+ return;
+ rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]);
+ rr += 4;
+ r += 4;
+ b += 4;
+ }
+}
+
+void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+{
+#ifdef BN_COUNT
+ fprintf(stderr, " bn_mul_low_normal %d * %d\n", n, n);
+#endif
+ bn_mul_words(r, a, n, b[0]);
+
+ for (;;) {
+ if (--n <= 0)
+ return;
+ bn_mul_add_words(&(r[1]), a, n, b[1]);
+ if (--n <= 0)
+ return;
+ bn_mul_add_words(&(r[2]), a, n, b[2]);
+ if (--n <= 0)
+ return;
+ bn_mul_add_words(&(r[3]), a, n, b[3]);
+ if (--n <= 0)
+ return;
+ bn_mul_add_words(&(r[4]), a, n, b[4]);
+ r += 4;
+ b += 4;
+ }
+}
diff --git a/openssl/bn/bn_nist.c b/openssl/bn/bn_nist.c
new file mode 100644
index 0000000..4a45404
--- /dev/null
+++ b/openssl/bn/bn_nist.c
@@ -0,0 +1,1262 @@
+/* crypto/bn/bn_nist.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 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
+
+/* pre-computed tables are "carry-less" values of modulus*(i+1) */
+#if BN_BITS2 == 64
+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
+ {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFFULL},
+ {0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL},
+ {0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFCULL, 0xFFFFFFFFFFFFFFFFULL}
+};
+
+static const BN_ULONG _nist_p_192_sqr[] = {
+ 0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000001ULL,
+ 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL
+};
+
+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
+ {0x0000000000000001ULL, 0xFFFFFFFF00000000ULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL},
+ {0x0000000000000002ULL, 0xFFFFFFFE00000000ULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFFULL} /* this one is
+ * "carry-full" */
+};
+
+static const BN_ULONG _nist_p_224_sqr[] = {
+ 0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0x0000000200000000ULL,
+ 0x0000000000000000ULL, 0xFFFFFFFFFFFFFFFEULL,
+ 0xFFFFFFFFFFFFFFFFULL
+};
+
+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
+ {0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL,
+ 0x0000000000000000ULL, 0xFFFFFFFF00000001ULL},
+ {0xFFFFFFFFFFFFFFFEULL, 0x00000001FFFFFFFFULL,
+ 0x0000000000000000ULL, 0xFFFFFFFE00000002ULL},
+ {0xFFFFFFFFFFFFFFFDULL, 0x00000002FFFFFFFFULL,
+ 0x0000000000000000ULL, 0xFFFFFFFD00000003ULL},
+ {0xFFFFFFFFFFFFFFFCULL, 0x00000003FFFFFFFFULL,
+ 0x0000000000000000ULL, 0xFFFFFFFC00000004ULL},
+ {0xFFFFFFFFFFFFFFFBULL, 0x00000004FFFFFFFFULL,
+ 0x0000000000000000ULL, 0xFFFFFFFB00000005ULL},
+};
+
+static const BN_ULONG _nist_p_256_sqr[] = {
+ 0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFEULL,
+ 0x00000001FFFFFFFEULL, 0x00000001FFFFFFFEULL,
+ 0xFFFFFFFE00000001ULL, 0xFFFFFFFE00000002ULL
+};
+
+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
+ {0x00000000FFFFFFFFULL, 0xFFFFFFFF00000000ULL, 0xFFFFFFFFFFFFFFFEULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+ {0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+ {0x00000002FFFFFFFDULL, 0xFFFFFFFD00000000ULL, 0xFFFFFFFFFFFFFFFCULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+ {0x00000003FFFFFFFCULL, 0xFFFFFFFC00000000ULL, 0xFFFFFFFFFFFFFFFBULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+ {0x00000004FFFFFFFBULL, 0xFFFFFFFB00000000ULL, 0xFFFFFFFFFFFFFFFAULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+};
+
+static const BN_ULONG _nist_p_384_sqr[] = {
+ 0xFFFFFFFE00000001ULL, 0x0000000200000000ULL, 0xFFFFFFFE00000000ULL,
+ 0x0000000200000000ULL, 0x0000000000000001ULL, 0x0000000000000000ULL,
+ 0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
+};
+
+static const BN_ULONG _nist_p_521[] =
+ { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+ 0x00000000000001FFULL
+};
+
+static const BN_ULONG _nist_p_521_sqr[] = {
+ 0x0000000000000001ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
+ 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
+ 0x0000000000000000ULL, 0x0000000000000000ULL, 0xFFFFFFFFFFFFFC00ULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+ 0xFFFFFFFFFFFFFFFFULL, 0x000000000003FFFFULL
+};
+#elif BN_BITS2 == 32
+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
+ {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
+};
+
+static const BN_ULONG _nist_p_192_sqr[] = {
+ 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000,
+ 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
+ {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
+};
+
+static const BN_ULONG _nist_p_224_sqr[] = {
+ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000002,
+ 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
+ {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
+ {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE},
+ {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD},
+ {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
+ 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC},
+ {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004,
+ 0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB},
+};
+
+static const BN_ULONG _nist_p_256_sqr[] = {
+ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001,
+ 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001,
+ 0x00000001, 0xFFFFFFFE, 0x00000002, 0xFFFFFFFE
+};
+
+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
+ {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFB, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+ {0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB, 0xFFFFFFFA, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+};
+
+static const BN_ULONG _nist_p_384_sqr[] = {
+ 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
+ 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static const BN_ULONG _nist_p_521[] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0x000001FF
+};
+
+static const BN_ULONG _nist_p_521_sqr[] = {
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFC00, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x0003FFFF
+};
+#else
+# error "unsupported BN_BITS2"
+#endif
+
+static const BIGNUM _bignum_nist_p_192 = {
+ (BN_ULONG *)_nist_p_192[0],
+ BN_NIST_192_TOP,
+ BN_NIST_192_TOP,
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_224 = {
+ (BN_ULONG *)_nist_p_224[0],
+ BN_NIST_224_TOP,
+ BN_NIST_224_TOP,
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_256 = {
+ (BN_ULONG *)_nist_p_256[0],
+ BN_NIST_256_TOP,
+ BN_NIST_256_TOP,
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_384 = {
+ (BN_ULONG *)_nist_p_384[0],
+ BN_NIST_384_TOP,
+ BN_NIST_384_TOP,
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_521 = {
+ (BN_ULONG *)_nist_p_521,
+ BN_NIST_521_TOP,
+ BN_NIST_521_TOP,
+ 0,
+ BN_FLG_STATIC_DATA
+};
+
+const BIGNUM *BN_get0_nist_prime_192(void)
+{
+ return &_bignum_nist_p_192;
+}
+
+const BIGNUM *BN_get0_nist_prime_224(void)
+{
+ return &_bignum_nist_p_224;
+}
+
+const BIGNUM *BN_get0_nist_prime_256(void)
+{
+ return &_bignum_nist_p_256;
+}
+
+const BIGNUM *BN_get0_nist_prime_384(void)
+{
+ return &_bignum_nist_p_384;
+}
+
+const BIGNUM *BN_get0_nist_prime_521(void)
+{
+ return &_bignum_nist_p_521;
+}
+
+static void nist_cp_bn_0(BN_ULONG *dst, const BN_ULONG *src, int top, int max)
+{
+ int i;
+
+#ifdef BN_DEBUG
+ OPENSSL_assert(top <= max);
+#endif
+ for (i = 0; i < top; i++)
+ dst[i] = src[i];
+ for (; i < max; i++)
+ dst[i] = 0;
+}
+
+static void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top)
+{
+ int i;
+
+ for (i = 0; i < top; i++)
+ dst[i] = src[i];
+}
+
+#if BN_BITS2 == 64
+# define bn_cp_64(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0;
+# define bn_64_set_0(to, n) (to)[n] = (BN_ULONG)0;
+/*
+ * two following macros are implemented under assumption that they
+ * are called in a sequence with *ascending* n, i.e. as they are...
+ */
+# define bn_cp_32_naked(to, n, from, m) (((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\
+ :(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l)))
+# define bn_32_set_0(to, n) (((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0));
+# define bn_cp_32(to,n,from,m) ((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n)
+# if defined(L_ENDIAN)
+# if defined(__arch64__)
+# define NIST_INT64 long
+# else
+# define NIST_INT64 long long
+# endif
+# endif
+#else
+# define bn_cp_64(to, n, from, m) \
+ { \
+ bn_cp_32(to, (n)*2, from, (m)*2); \
+ bn_cp_32(to, (n)*2+1, from, (m)*2+1); \
+ }
+# define bn_64_set_0(to, n) \
+ { \
+ bn_32_set_0(to, (n)*2); \
+ bn_32_set_0(to, (n)*2+1); \
+ }
+# define bn_cp_32(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0;
+# define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0;
+# if defined(_WIN32) && !defined(__GNUC__)
+# define NIST_INT64 __int64
+# elif defined(BN_LLONG)
+# define NIST_INT64 long long
+# endif
+#endif /* BN_BITS2 != 64 */
+
+#define nist_set_192(to, from, a1, a2, a3) \
+ { \
+ bn_cp_64(to, 0, from, (a3) - 3) \
+ bn_cp_64(to, 1, from, (a2) - 3) \
+ bn_cp_64(to, 2, from, (a1) - 3) \
+ }
+
+int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+ BN_CTX *ctx)
+{
+ int top = a->top, i;
+ int carry;
+ register BN_ULONG *r_d, *a_d = a->d;
+ union {
+ BN_ULONG bn[BN_NIST_192_TOP];
+ unsigned int ui[BN_NIST_192_TOP * sizeof(BN_ULONG) /
+ sizeof(unsigned int)];
+ } buf;
+ BN_ULONG c_d[BN_NIST_192_TOP], *res;
+ PTR_SIZE_INT mask;
+ static const BIGNUM _bignum_nist_p_192_sqr = {
+ (BN_ULONG *)_nist_p_192_sqr,
+ sizeof(_nist_p_192_sqr) / sizeof(_nist_p_192_sqr[0]),
+ sizeof(_nist_p_192_sqr) / sizeof(_nist_p_192_sqr[0]),
+ 0, BN_FLG_STATIC_DATA
+ };
+
+ field = &_bignum_nist_p_192; /* just to make sure */
+
+ if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_192_sqr) >= 0)
+ return BN_nnmod(r, a, field, ctx);
+
+ i = BN_ucmp(field, a);
+ if (i == 0) {
+ BN_zero(r);
+ return 1;
+ } else if (i > 0)
+ return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+ if (r != a) {
+ if (!bn_wexpand(r, BN_NIST_192_TOP))
+ return 0;
+ r_d = r->d;
+ nist_cp_bn(r_d, a_d, BN_NIST_192_TOP);
+ } else
+ r_d = a_d;
+
+ nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP,
+ BN_NIST_192_TOP);
+
+#if defined(NIST_INT64)
+ {
+ NIST_INT64 acc; /* accumulator */
+ unsigned int *rp = (unsigned int *)r_d;
+ const unsigned int *bp = (const unsigned int *)buf.ui;
+
+ acc = rp[0];
+ acc += bp[3 * 2 - 6];
+ acc += bp[5 * 2 - 6];
+ rp[0] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[1];
+ acc += bp[3 * 2 - 5];
+ acc += bp[5 * 2 - 5];
+ rp[1] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[2];
+ acc += bp[3 * 2 - 6];
+ acc += bp[4 * 2 - 6];
+ acc += bp[5 * 2 - 6];
+ rp[2] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[3];
+ acc += bp[3 * 2 - 5];
+ acc += bp[4 * 2 - 5];
+ acc += bp[5 * 2 - 5];
+ rp[3] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[4];
+ acc += bp[4 * 2 - 6];
+ acc += bp[5 * 2 - 6];
+ rp[4] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[5];
+ acc += bp[4 * 2 - 5];
+ acc += bp[5 * 2 - 5];
+ rp[5] = (unsigned int)acc;
+
+ carry = (int)(acc >> 32);
+ }
+#else
+ {
+ BN_ULONG t_d[BN_NIST_192_TOP];
+
+ nist_set_192(t_d, buf.bn, 0, 3, 3);
+ carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+ nist_set_192(t_d, buf.bn, 4, 4, 0);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+ nist_set_192(t_d, buf.bn, 5, 5, 5)
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+ }
+#endif
+ if (carry > 0)
+ carry =
+ (int)bn_sub_words(r_d, r_d, _nist_p_192[carry - 1],
+ BN_NIST_192_TOP);
+ else
+ carry = 1;
+
+ /*
+ * we need 'if (carry==0 || result>=modulus) result-=modulus;'
+ * as comparison implies subtraction, we can write
+ * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;'
+ * this is what happens below, but without explicit if:-) a.
+ */
+ mask =
+ 0 - (PTR_SIZE_INT) bn_sub_words(c_d, r_d, _nist_p_192[0],
+ BN_NIST_192_TOP);
+ mask &= 0 - (PTR_SIZE_INT) carry;
+ res = c_d;
+ res = (BN_ULONG *)
+ (((PTR_SIZE_INT) res & ~mask) | ((PTR_SIZE_INT) r_d & mask));
+ nist_cp_bn(r_d, res, BN_NIST_192_TOP);
+ r->top = BN_NIST_192_TOP;
+ bn_correct_top(r);
+
+ return 1;
+}
+
+typedef BN_ULONG (*bn_addsub_f) (BN_ULONG *, const BN_ULONG *,
+ const BN_ULONG *, int);
+
+#define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \
+ { \
+ bn_cp_32(to, 0, from, (a7) - 7) \
+ bn_cp_32(to, 1, from, (a6) - 7) \
+ bn_cp_32(to, 2, from, (a5) - 7) \
+ bn_cp_32(to, 3, from, (a4) - 7) \
+ bn_cp_32(to, 4, from, (a3) - 7) \
+ bn_cp_32(to, 5, from, (a2) - 7) \
+ bn_cp_32(to, 6, from, (a1) - 7) \
+ }
+
+int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+ BN_CTX *ctx)
+{
+ int top = a->top, i;
+ int carry;
+ BN_ULONG *r_d, *a_d = a->d;
+ union {
+ BN_ULONG bn[BN_NIST_224_TOP];
+ unsigned int ui[BN_NIST_224_TOP * sizeof(BN_ULONG) /
+ sizeof(unsigned int)];
+ } buf;
+ BN_ULONG c_d[BN_NIST_224_TOP], *res;
+ PTR_SIZE_INT mask;
+ union {
+ bn_addsub_f f;
+ PTR_SIZE_INT p;
+ } u;
+ static const BIGNUM _bignum_nist_p_224_sqr = {
+ (BN_ULONG *)_nist_p_224_sqr,
+ sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]),
+ sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]),
+ 0, BN_FLG_STATIC_DATA
+ };
+
+ field = &_bignum_nist_p_224; /* just to make sure */
+
+ if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_224_sqr) >= 0)
+ return BN_nnmod(r, a, field, ctx);
+
+ i = BN_ucmp(field, a);
+ if (i == 0) {
+ BN_zero(r);
+ return 1;
+ } else if (i > 0)
+ return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+ if (r != a) {
+ if (!bn_wexpand(r, BN_NIST_224_TOP))
+ return 0;
+ r_d = r->d;
+ nist_cp_bn(r_d, a_d, BN_NIST_224_TOP);
+ } else
+ r_d = a_d;
+
+#if BN_BITS2==64
+ /* copy upper 256 bits of 448 bit number ... */
+ nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP - 1),
+ top - (BN_NIST_224_TOP - 1), BN_NIST_224_TOP);
+ /* ... and right shift by 32 to obtain upper 224 bits */
+ nist_set_224(buf.bn, c_d, 14, 13, 12, 11, 10, 9, 8);
+ /* truncate lower part to 224 bits too */
+ r_d[BN_NIST_224_TOP - 1] &= BN_MASK2l;
+#else
+ nist_cp_bn_0(buf.bn, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP,
+ BN_NIST_224_TOP);
+#endif
+
+#if defined(NIST_INT64) && BN_BITS2!=64
+ {
+ NIST_INT64 acc; /* accumulator */
+ unsigned int *rp = (unsigned int *)r_d;
+ const unsigned int *bp = (const unsigned int *)buf.ui;
+
+ acc = rp[0];
+ acc -= bp[7 - 7];
+ acc -= bp[11 - 7];
+ rp[0] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[1];
+ acc -= bp[8 - 7];
+ acc -= bp[12 - 7];
+ rp[1] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[2];
+ acc -= bp[9 - 7];
+ acc -= bp[13 - 7];
+ rp[2] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[3];
+ acc += bp[7 - 7];
+ acc += bp[11 - 7];
+ acc -= bp[10 - 7];
+ rp[3] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[4];
+ acc += bp[8 - 7];
+ acc += bp[12 - 7];
+ acc -= bp[11 - 7];
+ rp[4] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[5];
+ acc += bp[9 - 7];
+ acc += bp[13 - 7];
+ acc -= bp[12 - 7];
+ rp[5] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[6];
+ acc += bp[10 - 7];
+ acc -= bp[13 - 7];
+ rp[6] = (unsigned int)acc;
+
+ carry = (int)(acc >> 32);
+# if BN_BITS2==64
+ rp[7] = carry;
+# endif
+ }
+#else
+ {
+ BN_ULONG t_d[BN_NIST_224_TOP];
+
+ nist_set_224(t_d, buf.bn, 10, 9, 8, 7, 0, 0, 0);
+ carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+ nist_set_224(t_d, buf.bn, 0, 13, 12, 11, 0, 0, 0);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+ nist_set_224(t_d, buf.bn, 13, 12, 11, 10, 9, 8, 7);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+ nist_set_224(t_d, buf.bn, 0, 0, 0, 0, 13, 12, 11);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+
+# if BN_BITS2==64
+ carry = (int)(r_d[BN_NIST_224_TOP - 1] >> 32);
+# endif
+ }
+#endif
+ u.f = bn_sub_words;
+ if (carry > 0) {
+ carry =
+ (int)bn_sub_words(r_d, r_d, _nist_p_224[carry - 1],
+ BN_NIST_224_TOP);
+#if BN_BITS2==64
+ carry = (int)(~(r_d[BN_NIST_224_TOP - 1] >> 32)) & 1;
+#endif
+ } else if (carry < 0) {
+ /*
+ * it's a bit more comlicated logic in this case. if bn_add_words
+ * yields no carry, then result has to be adjusted by unconditionally
+ * *adding* the modulus. but if it does, then result has to be
+ * compared to the modulus and conditionally adjusted by
+ * *subtracting* the latter.
+ */
+ carry =
+ (int)bn_add_words(r_d, r_d, _nist_p_224[-carry - 1],
+ BN_NIST_224_TOP);
+ mask = 0 - (PTR_SIZE_INT) carry;
+ u.p = ((PTR_SIZE_INT) bn_sub_words & mask) |
+ ((PTR_SIZE_INT) bn_add_words & ~mask);
+ } else
+ carry = 1;
+
+ /* otherwise it's effectively same as in BN_nist_mod_192... */
+ mask =
+ 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_224[0], BN_NIST_224_TOP);
+ mask &= 0 - (PTR_SIZE_INT) carry;
+ res = c_d;
+ res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
+ ((PTR_SIZE_INT) r_d & mask));
+ nist_cp_bn(r_d, res, BN_NIST_224_TOP);
+ r->top = BN_NIST_224_TOP;
+ bn_correct_top(r);
+
+ return 1;
+}
+
+#define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \
+ { \
+ bn_cp_32(to, 0, from, (a8) - 8) \
+ bn_cp_32(to, 1, from, (a7) - 8) \
+ bn_cp_32(to, 2, from, (a6) - 8) \
+ bn_cp_32(to, 3, from, (a5) - 8) \
+ bn_cp_32(to, 4, from, (a4) - 8) \
+ bn_cp_32(to, 5, from, (a3) - 8) \
+ bn_cp_32(to, 6, from, (a2) - 8) \
+ bn_cp_32(to, 7, from, (a1) - 8) \
+ }
+
+int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+ BN_CTX *ctx)
+{
+ int i, top = a->top;
+ int carry = 0;
+ register BN_ULONG *a_d = a->d, *r_d;
+ union {
+ BN_ULONG bn[BN_NIST_256_TOP];
+ unsigned int ui[BN_NIST_256_TOP * sizeof(BN_ULONG) /
+ sizeof(unsigned int)];
+ } buf;
+ BN_ULONG c_d[BN_NIST_256_TOP], *res;
+ PTR_SIZE_INT mask;
+ union {
+ bn_addsub_f f;
+ PTR_SIZE_INT p;
+ } u;
+ static const BIGNUM _bignum_nist_p_256_sqr = {
+ (BN_ULONG *)_nist_p_256_sqr,
+ sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]),
+ sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]),
+ 0, BN_FLG_STATIC_DATA
+ };
+
+ field = &_bignum_nist_p_256; /* just to make sure */
+
+ if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_256_sqr) >= 0)
+ return BN_nnmod(r, a, field, ctx);
+
+ i = BN_ucmp(field, a);
+ if (i == 0) {
+ BN_zero(r);
+ return 1;
+ } else if (i > 0)
+ return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+ if (r != a) {
+ if (!bn_wexpand(r, BN_NIST_256_TOP))
+ return 0;
+ r_d = r->d;
+ nist_cp_bn(r_d, a_d, BN_NIST_256_TOP);
+ } else
+ r_d = a_d;
+
+ nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP,
+ BN_NIST_256_TOP);
+
+#if defined(NIST_INT64)
+ {
+ NIST_INT64 acc; /* accumulator */
+ unsigned int *rp = (unsigned int *)r_d;
+ const unsigned int *bp = (const unsigned int *)buf.ui;
+
+ acc = rp[0];
+ acc += bp[8 - 8];
+ acc += bp[9 - 8];
+ acc -= bp[11 - 8];
+ acc -= bp[12 - 8];
+ acc -= bp[13 - 8];
+ acc -= bp[14 - 8];
+ rp[0] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[1];
+ acc += bp[9 - 8];
+ acc += bp[10 - 8];
+ acc -= bp[12 - 8];
+ acc -= bp[13 - 8];
+ acc -= bp[14 - 8];
+ acc -= bp[15 - 8];
+ rp[1] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[2];
+ acc += bp[10 - 8];
+ acc += bp[11 - 8];
+ acc -= bp[13 - 8];
+ acc -= bp[14 - 8];
+ acc -= bp[15 - 8];
+ rp[2] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[3];
+ acc += bp[11 - 8];
+ acc += bp[11 - 8];
+ acc += bp[12 - 8];
+ acc += bp[12 - 8];
+ acc += bp[13 - 8];
+ acc -= bp[15 - 8];
+ acc -= bp[8 - 8];
+ acc -= bp[9 - 8];
+ rp[3] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[4];
+ acc += bp[12 - 8];
+ acc += bp[12 - 8];
+ acc += bp[13 - 8];
+ acc += bp[13 - 8];
+ acc += bp[14 - 8];
+ acc -= bp[9 - 8];
+ acc -= bp[10 - 8];
+ rp[4] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[5];
+ acc += bp[13 - 8];
+ acc += bp[13 - 8];
+ acc += bp[14 - 8];
+ acc += bp[14 - 8];
+ acc += bp[15 - 8];
+ acc -= bp[10 - 8];
+ acc -= bp[11 - 8];
+ rp[5] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[6];
+ acc += bp[14 - 8];
+ acc += bp[14 - 8];
+ acc += bp[15 - 8];
+ acc += bp[15 - 8];
+ acc += bp[14 - 8];
+ acc += bp[13 - 8];
+ acc -= bp[8 - 8];
+ acc -= bp[9 - 8];
+ rp[6] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[7];
+ acc += bp[15 - 8];
+ acc += bp[15 - 8];
+ acc += bp[15 - 8];
+ acc += bp[8 - 8];
+ acc -= bp[10 - 8];
+ acc -= bp[11 - 8];
+ acc -= bp[12 - 8];
+ acc -= bp[13 - 8];
+ rp[7] = (unsigned int)acc;
+
+ carry = (int)(acc >> 32);
+ }
+#else
+ {
+ BN_ULONG t_d[BN_NIST_256_TOP];
+
+ /*
+ * S1
+ */
+ nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0);
+ /*
+ * S2
+ */
+ nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0);
+ carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
+ /* left shift */
+ {
+ register BN_ULONG *ap, t, c;
+ ap = t_d;
+ c = 0;
+ for (i = BN_NIST_256_TOP; i != 0; --i) {
+ t = *ap;
+ *(ap++) = ((t << 1) | c) & BN_MASK2;
+ c = (t & BN_TBIT) ? 1 : 0;
+ }
+ carry <<= 1;
+ carry |= c;
+ }
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+ /*
+ * S3
+ */
+ nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+ /*
+ * S4
+ */
+ nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+ /*
+ * D1
+ */
+ nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+ /*
+ * D2
+ */
+ nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+ /*
+ * D3
+ */
+ nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+ /*
+ * D4
+ */
+ nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+
+ }
+#endif
+ /* see BN_nist_mod_224 for explanation */
+ u.f = bn_sub_words;
+ if (carry > 0)
+ carry =
+ (int)bn_sub_words(r_d, r_d, _nist_p_256[carry - 1],
+ BN_NIST_256_TOP);
+ else if (carry < 0) {
+ carry =
+ (int)bn_add_words(r_d, r_d, _nist_p_256[-carry - 1],
+ BN_NIST_256_TOP);
+ mask = 0 - (PTR_SIZE_INT) carry;
+ u.p = ((PTR_SIZE_INT) bn_sub_words & mask) |
+ ((PTR_SIZE_INT) bn_add_words & ~mask);
+ } else
+ carry = 1;
+
+ mask =
+ 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_256[0], BN_NIST_256_TOP);
+ mask &= 0 - (PTR_SIZE_INT) carry;
+ res = c_d;
+ res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
+ ((PTR_SIZE_INT) r_d & mask));
+ nist_cp_bn(r_d, res, BN_NIST_256_TOP);
+ r->top = BN_NIST_256_TOP;
+ bn_correct_top(r);
+
+ return 1;
+}
+
+#define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
+ { \
+ bn_cp_32(to, 0, from, (a12) - 12) \
+ bn_cp_32(to, 1, from, (a11) - 12) \
+ bn_cp_32(to, 2, from, (a10) - 12) \
+ bn_cp_32(to, 3, from, (a9) - 12) \
+ bn_cp_32(to, 4, from, (a8) - 12) \
+ bn_cp_32(to, 5, from, (a7) - 12) \
+ bn_cp_32(to, 6, from, (a6) - 12) \
+ bn_cp_32(to, 7, from, (a5) - 12) \
+ bn_cp_32(to, 8, from, (a4) - 12) \
+ bn_cp_32(to, 9, from, (a3) - 12) \
+ bn_cp_32(to, 10, from, (a2) - 12) \
+ bn_cp_32(to, 11, from, (a1) - 12) \
+ }
+
+int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+ BN_CTX *ctx)
+{
+ int i, top = a->top;
+ int carry = 0;
+ register BN_ULONG *r_d, *a_d = a->d;
+ union {
+ BN_ULONG bn[BN_NIST_384_TOP];
+ unsigned int ui[BN_NIST_384_TOP * sizeof(BN_ULONG) /
+ sizeof(unsigned int)];
+ } buf;
+ BN_ULONG c_d[BN_NIST_384_TOP], *res;
+ PTR_SIZE_INT mask;
+ union {
+ bn_addsub_f f;
+ PTR_SIZE_INT p;
+ } u;
+ static const BIGNUM _bignum_nist_p_384_sqr = {
+ (BN_ULONG *)_nist_p_384_sqr,
+ sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]),
+ sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]),
+ 0, BN_FLG_STATIC_DATA
+ };
+
+ field = &_bignum_nist_p_384; /* just to make sure */
+
+ if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_384_sqr) >= 0)
+ return BN_nnmod(r, a, field, ctx);
+
+ i = BN_ucmp(field, a);
+ if (i == 0) {
+ BN_zero(r);
+ return 1;
+ } else if (i > 0)
+ return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+ if (r != a) {
+ if (!bn_wexpand(r, BN_NIST_384_TOP))
+ return 0;
+ r_d = r->d;
+ nist_cp_bn(r_d, a_d, BN_NIST_384_TOP);
+ } else
+ r_d = a_d;
+
+ nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP,
+ BN_NIST_384_TOP);
+
+#if defined(NIST_INT64)
+ {
+ NIST_INT64 acc; /* accumulator */
+ unsigned int *rp = (unsigned int *)r_d;
+ const unsigned int *bp = (const unsigned int *)buf.ui;
+
+ acc = rp[0];
+ acc += bp[12 - 12];
+ acc += bp[21 - 12];
+ acc += bp[20 - 12];
+ acc -= bp[23 - 12];
+ rp[0] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[1];
+ acc += bp[13 - 12];
+ acc += bp[22 - 12];
+ acc += bp[23 - 12];
+ acc -= bp[12 - 12];
+ acc -= bp[20 - 12];
+ rp[1] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[2];
+ acc += bp[14 - 12];
+ acc += bp[23 - 12];
+ acc -= bp[13 - 12];
+ acc -= bp[21 - 12];
+ rp[2] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[3];
+ acc += bp[15 - 12];
+ acc += bp[12 - 12];
+ acc += bp[20 - 12];
+ acc += bp[21 - 12];
+ acc -= bp[14 - 12];
+ acc -= bp[22 - 12];
+ acc -= bp[23 - 12];
+ rp[3] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[4];
+ acc += bp[21 - 12];
+ acc += bp[21 - 12];
+ acc += bp[16 - 12];
+ acc += bp[13 - 12];
+ acc += bp[12 - 12];
+ acc += bp[20 - 12];
+ acc += bp[22 - 12];
+ acc -= bp[15 - 12];
+ acc -= bp[23 - 12];
+ acc -= bp[23 - 12];
+ rp[4] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[5];
+ acc += bp[22 - 12];
+ acc += bp[22 - 12];
+ acc += bp[17 - 12];
+ acc += bp[14 - 12];
+ acc += bp[13 - 12];
+ acc += bp[21 - 12];
+ acc += bp[23 - 12];
+ acc -= bp[16 - 12];
+ rp[5] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[6];
+ acc += bp[23 - 12];
+ acc += bp[23 - 12];
+ acc += bp[18 - 12];
+ acc += bp[15 - 12];
+ acc += bp[14 - 12];
+ acc += bp[22 - 12];
+ acc -= bp[17 - 12];
+ rp[6] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[7];
+ acc += bp[19 - 12];
+ acc += bp[16 - 12];
+ acc += bp[15 - 12];
+ acc += bp[23 - 12];
+ acc -= bp[18 - 12];
+ rp[7] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[8];
+ acc += bp[20 - 12];
+ acc += bp[17 - 12];
+ acc += bp[16 - 12];
+ acc -= bp[19 - 12];
+ rp[8] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[9];
+ acc += bp[21 - 12];
+ acc += bp[18 - 12];
+ acc += bp[17 - 12];
+ acc -= bp[20 - 12];
+ rp[9] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[10];
+ acc += bp[22 - 12];
+ acc += bp[19 - 12];
+ acc += bp[18 - 12];
+ acc -= bp[21 - 12];
+ rp[10] = (unsigned int)acc;
+ acc >>= 32;
+
+ acc += rp[11];
+ acc += bp[23 - 12];
+ acc += bp[20 - 12];
+ acc += bp[19 - 12];
+ acc -= bp[22 - 12];
+ rp[11] = (unsigned int)acc;
+
+ carry = (int)(acc >> 32);
+ }
+#else
+ {
+ BN_ULONG t_d[BN_NIST_384_TOP];
+
+ /*
+ * S1
+ */
+ nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23 - 4, 22 - 4, 21 - 4);
+ /* left shift */
+ {
+ register BN_ULONG *ap, t, c;
+ ap = t_d;
+ c = 0;
+ for (i = 3; i != 0; --i) {
+ t = *ap;
+ *(ap++) = ((t << 1) | c) & BN_MASK2;
+ c = (t & BN_TBIT) ? 1 : 0;
+ }
+ *ap = c;
+ }
+ carry =
+ (int)bn_add_words(r_d + (128 / BN_BITS2), r_d + (128 / BN_BITS2),
+ t_d, BN_NIST_256_TOP);
+ /*
+ * S2
+ */
+ carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP);
+ /*
+ * S3
+ */
+ nist_set_384(t_d, buf.bn, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22,
+ 21);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+ /*
+ * S4
+ */
+ nist_set_384(t_d, buf.bn, 19, 18, 17, 16, 15, 14, 13, 12, 20, 0, 23,
+ 0);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+ /*
+ * S5
+ */
+ nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 23, 22, 21, 20, 0, 0, 0, 0);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+ /*
+ * S6
+ */
+ nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 23, 22, 21, 0, 0, 20);
+ carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+ /*
+ * D1
+ */
+ nist_set_384(t_d, buf.bn, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
+ 23);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+ /*
+ * D2
+ */
+ nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 22, 21, 20, 0);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+ /*
+ * D3
+ */
+ nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0);
+ carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+
+ }
+#endif
+ /* see BN_nist_mod_224 for explanation */
+ u.f = bn_sub_words;
+ if (carry > 0)
+ carry =
+ (int)bn_sub_words(r_d, r_d, _nist_p_384[carry - 1],
+ BN_NIST_384_TOP);
+ else if (carry < 0) {
+ carry =
+ (int)bn_add_words(r_d, r_d, _nist_p_384[-carry - 1],
+ BN_NIST_384_TOP);
+ mask = 0 - (PTR_SIZE_INT) carry;
+ u.p = ((PTR_SIZE_INT) bn_sub_words & mask) |
+ ((PTR_SIZE_INT) bn_add_words & ~mask);
+ } else
+ carry = 1;
+
+ mask =
+ 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_384[0], BN_NIST_384_TOP);
+ mask &= 0 - (PTR_SIZE_INT) carry;
+ res = c_d;
+ res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
+ ((PTR_SIZE_INT) r_d & mask));
+ nist_cp_bn(r_d, res, BN_NIST_384_TOP);
+ r->top = BN_NIST_384_TOP;
+ bn_correct_top(r);
+
+ return 1;
+}
+
+#define BN_NIST_521_RSHIFT (521%BN_BITS2)
+#define BN_NIST_521_LSHIFT (BN_BITS2-BN_NIST_521_RSHIFT)
+#define BN_NIST_521_TOP_MASK ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
+
+int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+ BN_CTX *ctx)
+{
+ int top = a->top, i;
+ BN_ULONG *r_d, *a_d = a->d, t_d[BN_NIST_521_TOP], val, tmp, *res;
+ PTR_SIZE_INT mask;
+ static const BIGNUM _bignum_nist_p_521_sqr = {
+ (BN_ULONG *)_nist_p_521_sqr,
+ sizeof(_nist_p_521_sqr) / sizeof(_nist_p_521_sqr[0]),
+ sizeof(_nist_p_521_sqr) / sizeof(_nist_p_521_sqr[0]),
+ 0, BN_FLG_STATIC_DATA
+ };
+
+ field = &_bignum_nist_p_521; /* just to make sure */
+
+ if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_521_sqr) >= 0)
+ return BN_nnmod(r, a, field, ctx);
+
+ i = BN_ucmp(field, a);
+ if (i == 0) {
+ BN_zero(r);
+ return 1;
+ } else if (i > 0)
+ return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+ if (r != a) {
+ if (!bn_wexpand(r, BN_NIST_521_TOP))
+ return 0;
+ r_d = r->d;
+ nist_cp_bn(r_d, a_d, BN_NIST_521_TOP);
+ } else
+ r_d = a_d;
+
+ /* upper 521 bits, copy ... */
+ nist_cp_bn_0(t_d, a_d + (BN_NIST_521_TOP - 1),
+ top - (BN_NIST_521_TOP - 1), BN_NIST_521_TOP);
+ /* ... and right shift */
+ for (val = t_d[0], i = 0; i < BN_NIST_521_TOP - 1; i++) {
+ t_d[i] = (val >> BN_NIST_521_RSHIFT |
+ (tmp = t_d[i + 1]) << BN_NIST_521_LSHIFT) & BN_MASK2;
+ val = tmp;
+ }
+ t_d[i] = val >> BN_NIST_521_RSHIFT;
+ /* lower 521 bits */
+ r_d[i] &= BN_NIST_521_TOP_MASK;
+
+ bn_add_words(r_d, r_d, t_d, BN_NIST_521_TOP);
+ mask =
+ 0 - (PTR_SIZE_INT) bn_sub_words(t_d, r_d, _nist_p_521,
+ BN_NIST_521_TOP);
+ res = t_d;
+ res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
+ ((PTR_SIZE_INT) r_d & mask));
+ nist_cp_bn(r_d, res, BN_NIST_521_TOP);
+ r->top = BN_NIST_521_TOP;
+ bn_correct_top(r);
+
+ return 1;
+}
diff --git a/openssl/bn/bn_prime.c b/openssl/bn/bn_prime.c
new file mode 100644
index 0000000..1d25687
--- /dev/null
+++ b/openssl/bn/bn_prime.c
@@ -0,0 +1,515 @@
+/* crypto/bn/bn_prime.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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 <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+
+/*
+ * NB: these functions have been "upgraded", the deprecated versions (which
+ * are compatibility wrappers using these functions) are in bn_depr.c. -
+ * Geoff
+ */
+
+/*
+ * The quick sieve algorithm approach to weeding out primes is Philip
+ * Zimmermann's, as implemented in PGP. I have had a read of his comments
+ * and implemented my own version.
+ */
+#include "bn_prime.h"
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+ const BIGNUM *a1_odd, int k, BN_CTX *ctx,
+ BN_MONT_CTX *mont);
+static int probable_prime(BIGNUM *rnd, int bits);
+static int probable_prime_dh(BIGNUM *rnd, int bits,
+ const BIGNUM *add, const BIGNUM *rem,
+ BN_CTX *ctx);
+static int probable_prime_dh_safe(BIGNUM *rnd, int bits, const BIGNUM *add,
+ const BIGNUM *rem, BN_CTX *ctx);
+
+int BN_GENCB_call(BN_GENCB *cb, int a, int b)
+{
+ /* No callback means continue */
+ if (!cb)
+ return 1;
+ switch (cb->ver) {
+ case 1:
+ /* Deprecated-style callbacks */
+ if (!cb->cb.cb_1)
+ return 1;
+ cb->cb.cb_1(a, b, cb->arg);
+ return 1;
+ case 2:
+ /* New-style callbacks */
+ return cb->cb.cb_2(a, b, cb);
+ default:
+ break;
+ }
+ /* Unrecognised callback type */
+ return 0;
+}
+
+int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
+ const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb)
+{
+ BIGNUM *t;
+ int found = 0;
+ int i, j, c1 = 0;
+ BN_CTX *ctx;
+ int checks = BN_prime_checks_for_size(bits);
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ t = BN_CTX_get(ctx);
+ if (!t)
+ goto err;
+ loop:
+ /* make a random number and set the top and bottom bits */
+ if (add == NULL) {
+ if (!probable_prime(ret, bits))
+ goto err;
+ } else {
+ if (safe) {
+ if (!probable_prime_dh_safe(ret, bits, add, rem, ctx))
+ goto err;
+ } else {
+ if (!probable_prime_dh(ret, bits, add, rem, ctx))
+ goto err;
+ }
+ }
+ /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */
+ if (!BN_GENCB_call(cb, 0, c1++))
+ /* aborted */
+ goto err;
+
+ if (!safe) {
+ i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb);
+ if (i == -1)
+ goto err;
+ if (i == 0)
+ goto loop;
+ } else {
+ /*
+ * for "safe prime" generation, check that (p-1)/2 is prime. Since a
+ * prime is odd, We just need to divide by 2
+ */
+ if (!BN_rshift1(t, ret))
+ goto err;
+
+ for (i = 0; i < checks; i++) {
+ j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb);
+ if (j == -1)
+ goto err;
+ if (j == 0)
+ goto loop;
+
+ j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb);
+ if (j == -1)
+ goto err;
+ if (j == 0)
+ goto loop;
+
+ if (!BN_GENCB_call(cb, 2, c1 - 1))
+ goto err;
+ /* We have a safe prime test pass */
+ }
+ }
+ /* we have a prime :-) */
+ found = 1;
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ bn_check_top(ret);
+ return found;
+}
+
+int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
+ BN_GENCB *cb)
+{
+ return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
+}
+
+int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
+ int do_trial_division, BN_GENCB *cb)
+{
+ int i, j, ret = -1;
+ int k;
+ BN_CTX *ctx = NULL;
+ BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
+ BN_MONT_CTX *mont = NULL;
+ const BIGNUM *A = NULL;
+
+ if (BN_cmp(a, BN_value_one()) <= 0)
+ return 0;
+
+ if (checks == BN_prime_checks)
+ checks = BN_prime_checks_for_size(BN_num_bits(a));
+
+ /* first look for small factors */
+ if (!BN_is_odd(a))
+ /* a is even => a is prime if and only if a == 2 */
+ return BN_is_word(a, 2);
+ if (do_trial_division) {
+ for (i = 1; i < NUMPRIMES; i++)
+ if (BN_mod_word(a, primes[i]) == 0)
+ return 0;
+ if (!BN_GENCB_call(cb, 1, -1))
+ goto err;
+ }
+
+ if (ctx_passed != NULL)
+ ctx = ctx_passed;
+ else if ((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+
+ /* A := abs(a) */
+ if (a->neg) {
+ BIGNUM *t;
+ if ((t = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ BN_copy(t, a);
+ t->neg = 0;
+ A = t;
+ } else
+ A = a;
+ A1 = BN_CTX_get(ctx);
+ A1_odd = BN_CTX_get(ctx);
+ check = BN_CTX_get(ctx);
+ if (check == NULL)
+ goto err;
+
+ /* compute A1 := A - 1 */
+ if (!BN_copy(A1, A))
+ goto err;
+ if (!BN_sub_word(A1, 1))
+ goto err;
+ if (BN_is_zero(A1)) {
+ ret = 0;
+ goto err;
+ }
+
+ /* write A1 as A1_odd * 2^k */
+ k = 1;
+ while (!BN_is_bit_set(A1, k))
+ k++;
+ if (!BN_rshift(A1_odd, A1, k))
+ goto err;
+
+ /* Montgomery setup for computations mod A */
+ mont = BN_MONT_CTX_new();
+ if (mont == NULL)
+ goto err;
+ if (!BN_MONT_CTX_set(mont, A, ctx))
+ goto err;
+
+ for (i = 0; i < checks; i++) {
+ if (!BN_pseudo_rand_range(check, A1))
+ goto err;
+ if (!BN_add_word(check, 1))
+ goto err;
+ /* now 1 <= check < A */
+
+ j = witness(check, A, A1, A1_odd, k, ctx, mont);
+ if (j == -1)
+ goto err;
+ if (j) {
+ ret = 0;
+ goto err;
+ }
+ if (!BN_GENCB_call(cb, 1, i))
+ goto err;
+ }
+ ret = 1;
+ err:
+ if (ctx != NULL) {
+ BN_CTX_end(ctx);
+ if (ctx_passed == NULL)
+ BN_CTX_free(ctx);
+ }
+ if (mont != NULL)
+ BN_MONT_CTX_free(mont);
+
+ return (ret);
+}
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+ const BIGNUM *a1_odd, int k, BN_CTX *ctx,
+ BN_MONT_CTX *mont)
+{
+ if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
+ return -1;
+ if (BN_is_one(w))
+ return 0; /* probably prime */
+ if (BN_cmp(w, a1) == 0)
+ return 0; /* w == -1 (mod a), 'a' is probably prime */
+ while (--k) {
+ if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
+ return -1;
+ if (BN_is_one(w))
+ return 1; /* 'a' is composite, otherwise a previous 'w'
+ * would have been == -1 (mod 'a') */
+ if (BN_cmp(w, a1) == 0)
+ return 0; /* w == -1 (mod a), 'a' is probably prime */
+ }
+ /*
+ * If we get here, 'w' is the (a-1)/2-th power of the original 'w', and
+ * it is neither -1 nor +1 -- so 'a' cannot be prime
+ */
+ bn_check_top(w);
+ return 1;
+}
+
+static int probable_prime(BIGNUM *rnd, int bits)
+{
+ int i;
+ prime_t mods[NUMPRIMES];
+ BN_ULONG delta, maxdelta;
+
+ again:
+ if (!BN_rand(rnd, bits, 1, 1))
+ return (0);
+ /* we now have a random number 'rand' to test. */
+ for (i = 1; i < NUMPRIMES; i++)
+ mods[i] = (prime_t) BN_mod_word(rnd, (BN_ULONG)primes[i]);
+ maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
+ delta = 0;
+ loop:for (i = 1; i < NUMPRIMES; i++) {
+ /*
+ * check that rnd is not a prime and also that gcd(rnd-1,primes) == 1
+ * (except for 2)
+ */
+ if (((mods[i] + delta) % primes[i]) <= 1) {
+ delta += 2;
+ if (delta > maxdelta)
+ goto again;
+ goto loop;
+ }
+ }
+ if (!BN_add_word(rnd, delta))
+ return (0);
+ bn_check_top(rnd);
+ return (1);
+}
+
+static int probable_prime_dh(BIGNUM *rnd, int bits,
+ const BIGNUM *add, const BIGNUM *rem,
+ BN_CTX *ctx)
+{
+ int i, ret = 0;
+ BIGNUM *t1;
+
+ BN_CTX_start(ctx);
+ if ((t1 = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ if (!BN_rand(rnd, bits, 0, 1))
+ goto err;
+
+ /* we need ((rnd-rem) % add) == 0 */
+
+ if (!BN_mod(t1, rnd, add, ctx))
+ goto err;
+ if (!BN_sub(rnd, rnd, t1))
+ goto err;
+ if (rem == NULL) {
+ if (!BN_add_word(rnd, 1))
+ goto err;
+ } else {
+ if (!BN_add(rnd, rnd, rem))
+ goto err;
+ }
+
+ /* we now have a random number 'rand' to test. */
+
+ loop:for (i = 1; i < NUMPRIMES; i++) {
+ /* check that rnd is a prime */
+ if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) {
+ if (!BN_add(rnd, rnd, add))
+ goto err;
+ goto loop;
+ }
+ }
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(rnd);
+ return (ret);
+}
+
+static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
+ const BIGNUM *rem, BN_CTX *ctx)
+{
+ int i, ret = 0;
+ BIGNUM *t1, *qadd, *q;
+
+ bits--;
+ BN_CTX_start(ctx);
+ t1 = BN_CTX_get(ctx);
+ q = BN_CTX_get(ctx);
+ qadd = BN_CTX_get(ctx);
+ if (qadd == NULL)
+ goto err;
+
+ if (!BN_rshift1(qadd, padd))
+ goto err;
+
+ if (!BN_rand(q, bits, 0, 1))
+ goto err;
+
+ /* we need ((rnd-rem) % add) == 0 */
+ if (!BN_mod(t1, q, qadd, ctx))
+ goto err;
+ if (!BN_sub(q, q, t1))
+ goto err;
+ if (rem == NULL) {
+ if (!BN_add_word(q, 1))
+ goto err;
+ } else {
+ if (!BN_rshift1(t1, rem))
+ goto err;
+ if (!BN_add(q, q, t1))
+ goto err;
+ }
+
+ /* we now have a random number 'rand' to test. */
+ if (!BN_lshift1(p, q))
+ goto err;
+ if (!BN_add_word(p, 1))
+ goto err;
+
+ loop:for (i = 1; i < NUMPRIMES; i++) {
+ /* check that p and q are prime */
+ /*
+ * check that for p and q gcd(p-1,primes) == 1 (except for 2)
+ */
+ if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) ||
+ (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) {
+ if (!BN_add(p, p, padd))
+ goto err;
+ if (!BN_add(q, q, qadd))
+ goto err;
+ goto loop;
+ }
+ }
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(p);
+ return (ret);
+}
diff --git a/openssl/bn/bn_prime.h b/openssl/bn/bn_prime.h
new file mode 100644
index 0000000..5cf0de1
--- /dev/null
+++ b/openssl/bn/bn_prime.h
@@ -0,0 +1,326 @@
+/* Auto generated by bn_prime.pl */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef EIGHT_BIT
+# define NUMPRIMES 2048
+typedef unsigned short prime_t;
+#else
+# define NUMPRIMES 54
+typedef unsigned char prime_t;
+#endif
+static const prime_t primes[NUMPRIMES] = {
+ 2, 3, 5, 7, 11, 13, 17, 19,
+ 23, 29, 31, 37, 41, 43, 47, 53,
+ 59, 61, 67, 71, 73, 79, 83, 89,
+ 97, 101, 103, 107, 109, 113, 127, 131,
+ 137, 139, 149, 151, 157, 163, 167, 173,
+ 179, 181, 191, 193, 197, 199, 211, 223,
+ 227, 229, 233, 239, 241, 251,
+#ifndef EIGHT_BIT
+ 257, 263,
+ 269, 271, 277, 281, 283, 293, 307, 311,
+ 313, 317, 331, 337, 347, 349, 353, 359,
+ 367, 373, 379, 383, 389, 397, 401, 409,
+ 419, 421, 431, 433, 439, 443, 449, 457,
+ 461, 463, 467, 479, 487, 491, 499, 503,
+ 509, 521, 523, 541, 547, 557, 563, 569,
+ 571, 577, 587, 593, 599, 601, 607, 613,
+ 617, 619, 631, 641, 643, 647, 653, 659,
+ 661, 673, 677, 683, 691, 701, 709, 719,
+ 727, 733, 739, 743, 751, 757, 761, 769,
+ 773, 787, 797, 809, 811, 821, 823, 827,
+ 829, 839, 853, 857, 859, 863, 877, 881,
+ 883, 887, 907, 911, 919, 929, 937, 941,
+ 947, 953, 967, 971, 977, 983, 991, 997,
+ 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049,
+ 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097,
+ 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163,
+ 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
+ 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283,
+ 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321,
+ 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423,
+ 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459,
+ 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
+ 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571,
+ 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619,
+ 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693,
+ 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747,
+ 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
+ 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877,
+ 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949,
+ 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003,
+ 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069,
+ 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129,
+ 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203,
+ 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267,
+ 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311,
+ 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377,
+ 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423,
+ 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503,
+ 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579,
+ 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657,
+ 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693,
+ 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741,
+ 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801,
+ 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861,
+ 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939,
+ 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011,
+ 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,
+ 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167,
+ 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221,
+ 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301,
+ 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347,
+ 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413,
+ 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491,
+ 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541,
+ 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607,
+ 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671,
+ 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727,
+ 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797,
+ 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863,
+ 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923,
+ 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003,
+ 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057,
+ 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129,
+ 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211,
+ 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259,
+ 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337,
+ 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409,
+ 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481,
+ 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547,
+ 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621,
+ 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673,
+ 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751,
+ 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813,
+ 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909,
+ 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967,
+ 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011,
+ 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087,
+ 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167,
+ 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233,
+ 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309,
+ 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399,
+ 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443,
+ 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507,
+ 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573,
+ 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653,
+ 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711,
+ 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791,
+ 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849,
+ 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897,
+ 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007,
+ 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073,
+ 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133,
+ 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211,
+ 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271,
+ 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329,
+ 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379,
+ 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473,
+ 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563,
+ 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637,
+ 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701,
+ 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779,
+ 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,
+ 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907,
+ 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971,
+ 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027,
+ 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121,
+ 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207,
+ 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253,
+ 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349,
+ 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457,
+ 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517,
+ 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561,
+ 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621,
+ 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691,
+ 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757,
+ 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853,
+ 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919,
+ 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009,
+ 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087,
+ 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161,
+ 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231,
+ 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291,
+ 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369,
+ 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443,
+ 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537,
+ 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609,
+ 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677,
+ 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731,
+ 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803,
+ 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861,
+ 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941,
+ 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011,
+ 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091,
+ 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161,
+ 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227,
+ 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311,
+ 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377,
+ 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433,
+ 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491,
+ 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587,
+ 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649,
+ 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733,
+ 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791,
+ 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857,
+ 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929,
+ 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037,
+ 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099,
+ 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163,
+ 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247,
+ 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303,
+ 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369,
+ 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459,
+ 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531,
+ 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627,
+ 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691,
+ 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771,
+ 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859,
+ 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937,
+ 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003,
+ 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087,
+ 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161,
+ 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251,
+ 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317,
+ 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399,
+ 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483,
+ 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551,
+ 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657,
+ 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731,
+ 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813,
+ 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887,
+ 11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941,
+ 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011,
+ 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101,
+ 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161,
+ 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251,
+ 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323,
+ 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401,
+ 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473,
+ 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527,
+ 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589,
+ 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653,
+ 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739,
+ 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821,
+ 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907,
+ 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967,
+ 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033,
+ 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109,
+ 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177,
+ 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259,
+ 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337,
+ 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421,
+ 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499,
+ 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597,
+ 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681,
+ 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723,
+ 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799,
+ 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879,
+ 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933,
+ 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033,
+ 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143,
+ 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221,
+ 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323,
+ 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407,
+ 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461,
+ 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549,
+ 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627,
+ 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699,
+ 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753,
+ 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821,
+ 14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887,
+ 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957,
+ 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073,
+ 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137,
+ 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217,
+ 15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277,
+ 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331,
+ 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401,
+ 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473,
+ 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569,
+ 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643,
+ 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727,
+ 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773,
+ 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859,
+ 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919,
+ 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007,
+ 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087,
+ 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183,
+ 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249,
+ 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349,
+ 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427,
+ 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493,
+ 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603,
+ 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661,
+ 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747,
+ 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843,
+ 16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927,
+ 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993,
+ 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053,
+ 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159,
+ 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231,
+ 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327,
+ 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389,
+ 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467,
+ 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519,
+ 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599,
+ 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683,
+ 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783,
+ 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863,
+#endif
+};
diff --git a/openssl/bn/bn_prime.pl b/openssl/bn/bn_prime.pl
new file mode 100644
index 0000000..3fafb6f
--- /dev/null
+++ b/openssl/bn/bn_prime.pl
@@ -0,0 +1,119 @@
+#!/usr/local/bin/perl
+# bn_prime.pl
+
+$num=2048;
+$num=$ARGV[0] if ($#ARGV >= 0);
+
+push(@primes,2);
+$p=1;
+loop: while ($#primes < $num-1)
+ {
+ $p+=2;
+ $s=int(sqrt($p));
+
+ for ($i=0; defined($primes[$i]) && $primes[$i]<=$s; $i++)
+ {
+ next loop if (($p%$primes[$i]) == 0);
+ }
+ push(@primes,$p);
+ }
+
+# print <<"EOF";
+# /* Auto generated by bn_prime.pl */
+# /* Copyright (C) 1995-1997 Eric Young (eay\@mincom.oz.au).
+# * All rights reserved.
+# * Copyright remains Eric Young's, and as such any Copyright notices in
+# * the code are not to be removed.
+# * See the COPYRIGHT file in the SSLeay distribution for more details.
+# */
+#
+# EOF
+
+print <<\EOF;
+/* Auto generated by bn_prime.pl */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+EOF
+
+for ($i=0; $i <= $#primes; $i++)
+ {
+ if ($primes[$i] > 256)
+ {
+ $eight=$i;
+ last;
+ }
+ }
+
+printf "#ifndef EIGHT_BIT\n";
+printf "#define NUMPRIMES %d\n",$num;
+printf "typedef unsigned short prime_t;\n";
+printf "#else\n";
+printf "#define NUMPRIMES %d\n",$eight;
+printf "typedef unsigned char prime_t;\n";
+printf "#endif\n";
+print "static const prime_t primes[NUMPRIMES]=\n\t{\n\t";
+$init=0;
+for ($i=0; $i <= $#primes; $i++)
+ {
+ printf "\n#ifndef EIGHT_BIT\n\t" if ($primes[$i] > 256) && !($init++);
+ printf("\n\t") if (($i%8) == 0) && ($i != 0);
+ printf("%4d,",$primes[$i]);
+ }
+print "\n#endif\n\t};\n";
+
+
diff --git a/openssl/bn/bn_print.c b/openssl/bn/bn_print.c
new file mode 100644
index 0000000..4dcaae3
--- /dev/null
+++ b/openssl/bn/bn_print.c
@@ -0,0 +1,383 @@
+/* crypto/bn/bn_print.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include "bn_lcl.h"
+
+static const char Hex[] = "0123456789ABCDEF";
+
+/* Must 'OPENSSL_free' the returned data */
+char *BN_bn2hex(const BIGNUM *a)
+{
+ int i, j, v, z = 0;
+ char *buf;
+ char *p;
+
+ buf = (char *)OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
+ if (buf == NULL) {
+ BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ p = buf;
+ if (a->neg)
+ *(p++) = '-';
+ if (BN_is_zero(a))
+ *(p++) = '0';
+ for (i = a->top - 1; i >= 0; i--) {
+ for (j = BN_BITS2 - 8; j >= 0; j -= 8) {
+ /* strip leading zeros */
+ v = ((int)(a->d[i] >> (long)j)) & 0xff;
+ if (z || (v != 0)) {
+ *(p++) = Hex[v >> 4];
+ *(p++) = Hex[v & 0x0f];
+ z = 1;
+ }
+ }
+ }
+ *p = '\0';
+ err:
+ return (buf);
+}
+
+/* Must 'OPENSSL_free' the returned data */
+char *BN_bn2dec(const BIGNUM *a)
+{
+ int i = 0, num, ok = 0;
+ char *buf = NULL;
+ char *p;
+ BIGNUM *t = NULL;
+ BN_ULONG *bn_data = NULL, *lp;
+
+ /*-
+ * get an upper bound for the length of the decimal integer
+ * num <= (BN_num_bits(a) + 1) * log(2)
+ * <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1 (rounding error)
+ * <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1
+ */
+ i = BN_num_bits(a) * 3;
+ num = (i / 10 + i / 1000 + 1) + 1;
+ bn_data =
+ (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
+ buf = (char *)OPENSSL_malloc(num + 3);
+ if ((buf == NULL) || (bn_data == NULL)) {
+ BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if ((t = BN_dup(a)) == NULL)
+ goto err;
+
+#define BUF_REMAIN (num+3 - (size_t)(p - buf))
+ p = buf;
+ lp = bn_data;
+ if (BN_is_zero(t)) {
+ *(p++) = '0';
+ *(p++) = '\0';
+ } else {
+ if (BN_is_negative(t))
+ *p++ = '-';
+
+ i = 0;
+ while (!BN_is_zero(t)) {
+ *lp = BN_div_word(t, BN_DEC_CONV);
+ lp++;
+ }
+ lp--;
+ /*
+ * We now have a series of blocks, BN_DEC_NUM chars in length, where
+ * the last one needs truncation. The blocks need to be reversed in
+ * order.
+ */
+ BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT1, *lp);
+ while (*p)
+ p++;
+ while (lp != bn_data) {
+ lp--;
+ BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT2, *lp);
+ while (*p)
+ p++;
+ }
+ }
+ ok = 1;
+ err:
+ if (bn_data != NULL)
+ OPENSSL_free(bn_data);
+ if (t != NULL)
+ BN_free(t);
+ if (!ok && buf) {
+ OPENSSL_free(buf);
+ buf = NULL;
+ }
+
+ return (buf);
+}
+
+int BN_hex2bn(BIGNUM **bn, const char *a)
+{
+ BIGNUM *ret = NULL;
+ BN_ULONG l = 0;
+ int neg = 0, h, m, i, j, k, c;
+ int num;
+
+ if ((a == NULL) || (*a == '\0'))
+ return (0);
+
+ if (*a == '-') {
+ neg = 1;
+ a++;
+ }
+
+ for (i = 0; isxdigit((unsigned char)a[i]); i++) ;
+
+ num = i + neg;
+ if (bn == NULL)
+ return (num);
+
+ /* a is the start of the hex digits, and it is 'i' long */
+ if (*bn == NULL) {
+ if ((ret = BN_new()) == NULL)
+ return (0);
+ } else {
+ ret = *bn;
+ BN_zero(ret);
+ }
+
+ /* i is the number of hex digests; */
+ if (bn_expand(ret, i * 4) == NULL)
+ goto err;
+
+ j = i; /* least significant 'hex' */
+ m = 0;
+ h = 0;
+ while (j > 0) {
+ m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j;
+ l = 0;
+ for (;;) {
+ c = a[j - m];
+ if ((c >= '0') && (c <= '9'))
+ k = c - '0';
+ else if ((c >= 'a') && (c <= 'f'))
+ k = c - 'a' + 10;
+ else if ((c >= 'A') && (c <= 'F'))
+ k = c - 'A' + 10;
+ else
+ k = 0; /* paranoia */
+ l = (l << 4) | k;
+
+ if (--m <= 0) {
+ ret->d[h++] = l;
+ break;
+ }
+ }
+ j -= (BN_BYTES * 2);
+ }
+ ret->top = h;
+ bn_correct_top(ret);
+ ret->neg = neg;
+
+ *bn = ret;
+ bn_check_top(ret);
+ return (num);
+ err:
+ if (*bn == NULL)
+ BN_free(ret);
+ return (0);
+}
+
+int BN_dec2bn(BIGNUM **bn, const char *a)
+{
+ BIGNUM *ret = NULL;
+ BN_ULONG l = 0;
+ int neg = 0, i, j;
+ int num;
+
+ if ((a == NULL) || (*a == '\0'))
+ return (0);
+ if (*a == '-') {
+ neg = 1;
+ a++;
+ }
+
+ for (i = 0; isdigit((unsigned char)a[i]); i++) ;
+
+ num = i + neg;
+ if (bn == NULL)
+ return (num);
+
+ /*
+ * a is the start of the digits, and it is 'i' long. We chop it into
+ * BN_DEC_NUM digits at a time
+ */
+ if (*bn == NULL) {
+ if ((ret = BN_new()) == NULL)
+ return (0);
+ } else {
+ ret = *bn;
+ BN_zero(ret);
+ }
+
+ /* i is the number of digests, a bit of an over expand; */
+ if (bn_expand(ret, i * 4) == NULL)
+ goto err;
+
+ j = BN_DEC_NUM - (i % BN_DEC_NUM);
+ if (j == BN_DEC_NUM)
+ j = 0;
+ l = 0;
+ while (*a) {
+ l *= 10;
+ l += *a - '0';
+ a++;
+ if (++j == BN_DEC_NUM) {
+ BN_mul_word(ret, BN_DEC_CONV);
+ BN_add_word(ret, l);
+ l = 0;
+ j = 0;
+ }
+ }
+ ret->neg = neg;
+
+ bn_correct_top(ret);
+ *bn = ret;
+ bn_check_top(ret);
+ return (num);
+ err:
+ if (*bn == NULL)
+ BN_free(ret);
+ return (0);
+}
+
+int BN_asc2bn(BIGNUM **bn, const char *a)
+{
+ const char *p = a;
+ if (*p == '-')
+ p++;
+
+ if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x')) {
+ if (!BN_hex2bn(bn, p + 2))
+ return 0;
+ } else {
+ if (!BN_dec2bn(bn, p))
+ return 0;
+ }
+ if (*a == '-')
+ (*bn)->neg = 1;
+ return 1;
+}
+
+#ifndef OPENSSL_NO_BIO
+# ifndef OPENSSL_NO_FP_API
+int BN_print_fp(FILE *fp, const BIGNUM *a)
+{
+ BIO *b;
+ int ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL)
+ return (0);
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = BN_print(b, a);
+ BIO_free(b);
+ return (ret);
+}
+# endif
+
+int BN_print(BIO *bp, const BIGNUM *a)
+{
+ int i, j, v, z = 0;
+ int ret = 0;
+
+ if ((a->neg) && (BIO_write(bp, "-", 1) != 1))
+ goto end;
+ if (BN_is_zero(a) && (BIO_write(bp, "0", 1) != 1))
+ goto end;
+ for (i = a->top - 1; i >= 0; i--) {
+ for (j = BN_BITS2 - 4; j >= 0; j -= 4) {
+ /* strip leading zeros */
+ v = ((int)(a->d[i] >> (long)j)) & 0x0f;
+ if (z || (v != 0)) {
+ if (BIO_write(bp, &(Hex[v]), 1) != 1)
+ goto end;
+ z = 1;
+ }
+ }
+ }
+ ret = 1;
+ end:
+ return (ret);
+}
+#endif
+
+char *BN_options(void)
+{
+ static int init = 0;
+ static char data[16];
+
+ if (!init) {
+ init++;
+#ifdef BN_LLONG
+ BIO_snprintf(data, sizeof data, "bn(%d,%d)",
+ (int)sizeof(BN_ULLONG) * 8, (int)sizeof(BN_ULONG) * 8);
+#else
+ BIO_snprintf(data, sizeof data, "bn(%d,%d)",
+ (int)sizeof(BN_ULONG) * 8, (int)sizeof(BN_ULONG) * 8);
+#endif
+ }
+ return (data);
+}
diff --git a/openssl/bn/bn_rand.c b/openssl/bn/bn_rand.c
new file mode 100644
index 0000000..0d0a926
--- /dev/null
+++ b/openssl/bn/bn_rand.c
@@ -0,0 +1,291 @@
+/* crypto/bn/bn_rand.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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 <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+
+static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
+{
+ unsigned char *buf = NULL;
+ int ret = 0, bit, bytes, mask;
+ time_t tim;
+
+ if (bits == 0) {
+ BN_zero(rnd);
+ return 1;
+ }
+
+ bytes = (bits + 7) / 8;
+ bit = (bits - 1) % 8;
+ mask = 0xff << (bit + 1);
+
+ buf = (unsigned char *)OPENSSL_malloc(bytes);
+ if (buf == NULL) {
+ BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* make a random number and set the top and bottom bits */
+#ifndef NO_TIME_BN_RAND
+ time(&tim);
+ RAND_add(&tim, sizeof(tim), 0.0);
+#endif /* NO_TIME_BN_RAND */
+
+ if (pseudorand) {
+ if (RAND_pseudo_bytes(buf, bytes) == -1)
+ goto err;
+ } else {
+ if (RAND_bytes(buf, bytes) <= 0)
+ goto err;
+ }
+
+#if 1
+ if (pseudorand == 2) {
+ /*
+ * generate patterns that are more likely to trigger BN library bugs
+ */
+ int i;
+ unsigned char c;
+
+ for (i = 0; i < bytes; i++) {
+ RAND_pseudo_bytes(&c, 1);
+ if (c >= 128 && i > 0)
+ buf[i] = buf[i - 1];
+ else if (c < 42)
+ buf[i] = 0;
+ else if (c < 84)
+ buf[i] = 255;
+ }
+ }
+#endif
+
+ if (top != -1) {
+ if (top) {
+ if (bit == 0) {
+ buf[0] = 1;
+ buf[1] |= 0x80;
+ } else {
+ buf[0] |= (3 << (bit - 1));
+ }
+ } else {
+ buf[0] |= (1 << bit);
+ }
+ }
+ buf[0] &= ~mask;
+ if (bottom) /* set bottom bit if requested */
+ buf[bytes - 1] |= 1;
+ if (!BN_bin2bn(buf, bytes, rnd))
+ goto err;
+ ret = 1;
+ err:
+ if (buf != NULL) {
+ OPENSSL_cleanse(buf, bytes);
+ OPENSSL_free(buf);
+ }
+ bn_check_top(rnd);
+ return (ret);
+}
+
+int BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
+{
+ return bnrand(0, rnd, bits, top, bottom);
+}
+
+int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
+{
+ return bnrand(1, rnd, bits, top, bottom);
+}
+
+#if 1
+int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom)
+{
+ return bnrand(2, rnd, bits, top, bottom);
+}
+#endif
+
+/* random number r: 0 <= r < range */
+static int bn_rand_range(int pseudo, BIGNUM *r, const 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)) {
+ BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE);
+ return 0;
+ }
+
+ n = BN_num_bits(range); /* n > 0 */
+
+ /* BN_is_bit_set(range, n - 1) always holds */
+
+ if (n == 1)
+ BN_zero(r);
+ else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) {
+ /*
+ * range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer
+ * than range
+ */
+ do {
+ if (!bn_rand(r, n + 1, -1, 0))
+ return 0;
+ /*
+ * If r < 3*range, use r := r MOD range (which is either r, r -
+ * range, or r - 2*range). Otherwise, iterate once more. Since
+ * 3*range = 11..._2, each iteration succeeds with probability >=
+ * .75.
+ */
+ if (BN_cmp(r, range) >= 0) {
+ if (!BN_sub(r, r, range))
+ return 0;
+ 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);
+ } else {
+ do {
+ /* 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);
+ }
+
+ bn_check_top(r);
+ return 1;
+}
+
+int BN_rand_range(BIGNUM *r, const BIGNUM *range)
+{
+ return bn_rand_range(0, r, range);
+}
+
+int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range)
+{
+ return bn_rand_range(1, r, range);
+}
diff --git a/openssl/bn/bn_recp.c b/openssl/bn/bn_recp.c
new file mode 100644
index 0000000..6826f93
--- /dev/null
+++ b/openssl/bn/bn_recp.c
@@ -0,0 +1,249 @@
+/* crypto/bn/bn_recp.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+void BN_RECP_CTX_init(BN_RECP_CTX *recp)
+{
+ BN_init(&(recp->N));
+ BN_init(&(recp->Nr));
+ recp->num_bits = 0;
+ recp->flags = 0;
+}
+
+BN_RECP_CTX *BN_RECP_CTX_new(void)
+{
+ BN_RECP_CTX *ret;
+
+ if ((ret = (BN_RECP_CTX *)OPENSSL_malloc(sizeof(BN_RECP_CTX))) == NULL)
+ return (NULL);
+
+ BN_RECP_CTX_init(ret);
+ ret->flags = BN_FLG_MALLOCED;
+ return (ret);
+}
+
+void BN_RECP_CTX_free(BN_RECP_CTX *recp)
+{
+ if (recp == NULL)
+ return;
+
+ BN_free(&(recp->N));
+ BN_free(&(recp->Nr));
+ if (recp->flags & BN_FLG_MALLOCED)
+ OPENSSL_free(recp);
+}
+
+int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
+{
+ if (!BN_copy(&(recp->N), d))
+ return 0;
+ BN_zero(&(recp->Nr));
+ recp->num_bits = BN_num_bits(d);
+ recp->shift = 0;
+ return (1);
+}
+
+int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+ BN_RECP_CTX *recp, BN_CTX *ctx)
+{
+ int ret = 0;
+ BIGNUM *a;
+ const BIGNUM *ca;
+
+ BN_CTX_start(ctx);
+ if ((a = BN_CTX_get(ctx)) == NULL)
+ goto err;
+ if (y != NULL) {
+ if (x == y) {
+ if (!BN_sqr(a, x, ctx))
+ goto err;
+ } else {
+ if (!BN_mul(a, x, y, ctx))
+ goto err;
+ }
+ ca = a;
+ } else
+ ca = x; /* Just do the mod */
+
+ ret = BN_div_recp(NULL, r, ca, recp, ctx);
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(r);
+ return (ret);
+}
+
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+ BN_RECP_CTX *recp, BN_CTX *ctx)
+{
+ int i, j, ret = 0;
+ BIGNUM *a, *b, *d, *r;
+
+ BN_CTX_start(ctx);
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ if (dv != NULL)
+ d = dv;
+ else
+ d = BN_CTX_get(ctx);
+ if (rem != NULL)
+ r = rem;
+ else
+ r = BN_CTX_get(ctx);
+ if (a == NULL || b == NULL || d == NULL || r == NULL)
+ goto err;
+
+ if (BN_ucmp(m, &(recp->N)) < 0) {
+ BN_zero(d);
+ if (!BN_copy(r, m))
+ return 0;
+ BN_CTX_end(ctx);
+ return (1);
+ }
+
+ /*
+ * We want the remainder Given input of ABCDEF / ab we need multiply
+ * ABCDEF by 3 digests of the reciprocal of ab
+ */
+
+ /* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */
+ i = BN_num_bits(m);
+ j = recp->num_bits << 1;
+ if (j > i)
+ i = j;
+
+ /* Nr := round(2^i / N) */
+ if (i != recp->shift)
+ recp->shift = BN_reciprocal(&(recp->Nr), &(recp->N), i, ctx);
+ /* BN_reciprocal could have returned -1 for an error */
+ if (recp->shift == -1)
+ goto err;
+
+ /*-
+ * d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))|
+ * = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))|
+ * <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)|
+ * = |m/N|
+ */
+ if (!BN_rshift(a, m, recp->num_bits))
+ goto err;
+ if (!BN_mul(b, a, &(recp->Nr), ctx))
+ goto err;
+ if (!BN_rshift(d, b, i - recp->num_bits))
+ goto err;
+ d->neg = 0;
+
+ if (!BN_mul(b, &(recp->N), d, ctx))
+ goto err;
+ if (!BN_usub(r, m, b))
+ goto err;
+ r->neg = 0;
+
+#if 1
+ j = 0;
+ while (BN_ucmp(r, &(recp->N)) >= 0) {
+ if (j++ > 2) {
+ BNerr(BN_F_BN_DIV_RECP, BN_R_BAD_RECIPROCAL);
+ goto err;
+ }
+ if (!BN_usub(r, r, &(recp->N)))
+ goto err;
+ if (!BN_add_word(d, 1))
+ goto err;
+ }
+#endif
+
+ r->neg = BN_is_zero(r) ? 0 : m->neg;
+ d->neg = m->neg ^ recp->N.neg;
+ ret = 1;
+ err:
+ BN_CTX_end(ctx);
+ bn_check_top(dv);
+ bn_check_top(rem);
+ return (ret);
+}
+
+/*
+ * len is the expected size of the result We actually calculate with an extra
+ * word of precision, so we can do faster division if the remainder is not
+ * required.
+ */
+/* r := 2^len / m */
+int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
+{
+ int ret = -1;
+ BIGNUM *t;
+
+ BN_CTX_start(ctx);
+ if ((t = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ if (!BN_set_bit(t, len))
+ goto err;
+
+ if (!BN_div(r, NULL, t, m, ctx))
+ goto err;
+
+ ret = len;
+ err:
+ bn_check_top(r);
+ BN_CTX_end(ctx);
+ return (ret);
+}
diff --git a/openssl/bn/bn_shift.c b/openssl/bn/bn_shift.c
new file mode 100644
index 0000000..4f3e8ff
--- /dev/null
+++ b/openssl/bn/bn_shift.c
@@ -0,0 +1,214 @@
+/* crypto/bn/bn_shift.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+int BN_lshift1(BIGNUM *r, const BIGNUM *a)
+{
+ register BN_ULONG *ap, *rp, t, c;
+ int i;
+
+ bn_check_top(r);
+ bn_check_top(a);
+
+ if (r != a) {
+ r->neg = a->neg;
+ if (bn_wexpand(r, a->top + 1) == NULL)
+ return (0);
+ r->top = a->top;
+ } else {
+ if (bn_wexpand(r, a->top + 1) == NULL)
+ return (0);
+ }
+ ap = a->d;
+ rp = r->d;
+ c = 0;
+ for (i = 0; i < a->top; i++) {
+ t = *(ap++);
+ *(rp++) = ((t << 1) | c) & BN_MASK2;
+ c = (t & BN_TBIT) ? 1 : 0;
+ }
+ if (c) {
+ *rp = 1;
+ r->top++;
+ }
+ bn_check_top(r);
+ return (1);
+}
+
+int BN_rshift1(BIGNUM *r, const BIGNUM *a)
+{
+ BN_ULONG *ap, *rp, t, c;
+ int i, j;
+
+ bn_check_top(r);
+ bn_check_top(a);
+
+ if (BN_is_zero(a)) {
+ BN_zero(r);
+ return (1);
+ }
+ i = a->top;
+ ap = a->d;
+ j = i - (ap[i - 1] == 1);
+ if (a != r) {
+ if (bn_wexpand(r, j) == NULL)
+ return (0);
+ r->neg = a->neg;
+ }
+ rp = r->d;
+ t = ap[--i];
+ c = (t & 1) ? BN_TBIT : 0;
+ if (t >>= 1)
+ rp[i] = t;
+ while (i > 0) {
+ t = ap[--i];
+ rp[i] = ((t >> 1) & BN_MASK2) | c;
+ c = (t & 1) ? BN_TBIT : 0;
+ }
+ r->top = j;
+ bn_check_top(r);
+ return (1);
+}
+
+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
+{
+ int i, nw, lb, rb;
+ BN_ULONG *t, *f;
+ BN_ULONG l;
+
+ bn_check_top(r);
+ bn_check_top(a);
+
+ r->neg = a->neg;
+ nw = n / BN_BITS2;
+ if (bn_wexpand(r, a->top + nw + 1) == NULL)
+ return (0);
+ lb = n % BN_BITS2;
+ rb = BN_BITS2 - lb;
+ f = a->d;
+ t = r->d;
+ t[a->top + nw] = 0;
+ if (lb == 0)
+ for (i = a->top - 1; i >= 0; i--)
+ t[nw + i] = f[i];
+ else
+ for (i = a->top - 1; i >= 0; i--) {
+ l = f[i];
+ t[nw + i + 1] |= (l >> rb) & BN_MASK2;
+ t[nw + i] = (l << lb) & BN_MASK2;
+ }
+ memset(t, 0, nw * sizeof(t[0]));
+ /*
+ * for (i=0; i<nw; i++) t[i]=0;
+ */
+ r->top = a->top + nw + 1;
+ bn_correct_top(r);
+ bn_check_top(r);
+ return (1);
+}
+
+int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
+{
+ int i, j, nw, lb, rb;
+ BN_ULONG *t, *f;
+ BN_ULONG l, tmp;
+
+ bn_check_top(r);
+ bn_check_top(a);
+
+ nw = n / BN_BITS2;
+ rb = n % BN_BITS2;
+ lb = BN_BITS2 - rb;
+ if (nw >= a->top || a->top == 0) {
+ BN_zero(r);
+ return (1);
+ }
+ i = (BN_num_bits(a) - n + (BN_BITS2 - 1)) / BN_BITS2;
+ if (r != a) {
+ r->neg = a->neg;
+ if (bn_wexpand(r, i) == NULL)
+ return (0);
+ } else {
+ if (n == 0)
+ return 1; /* or the copying loop will go berserk */
+ }
+
+ f = &(a->d[nw]);
+ t = r->d;
+ j = a->top - nw;
+ r->top = i;
+
+ if (rb == 0) {
+ for (i = j; i != 0; i--)
+ *(t++) = *(f++);
+ } else {
+ l = *(f++);
+ for (i = j - 1; i != 0; i--) {
+ tmp = (l >> rb) & BN_MASK2;
+ l = *(f++);
+ *(t++) = (tmp | (l << lb)) & BN_MASK2;
+ }
+ if ((l = (l >> rb) & BN_MASK2))
+ *(t) = l;
+ }
+ bn_check_top(r);
+ return (1);
+}
diff --git a/openssl/bn/bn_sqr.c b/openssl/bn/bn_sqr.c
new file mode 100644
index 0000000..3ca6987
--- /dev/null
+++ b/openssl/bn/bn_sqr.c
@@ -0,0 +1,290 @@
+/* crypto/bn/bn_sqr.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* r must not be a */
+/*
+ * I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96
+ */
+int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
+{
+ int max, al;
+ int ret = 0;
+ BIGNUM *tmp, *rr;
+
+#ifdef BN_COUNT
+ fprintf(stderr, "BN_sqr %d * %d\n", a->top, a->top);
+#endif
+ bn_check_top(a);
+
+ al = a->top;
+ if (al <= 0) {
+ r->top = 0;
+ r->neg = 0;
+ return 1;
+ }
+
+ BN_CTX_start(ctx);
+ rr = (a != r) ? r : BN_CTX_get(ctx);
+ tmp = BN_CTX_get(ctx);
+ if (!rr || !tmp)
+ goto err;
+
+ max = 2 * al; /* Non-zero (from above) */
+ if (bn_wexpand(rr, max) == NULL)
+ goto err;
+
+ if (al == 4) {
+#ifndef BN_SQR_COMBA
+ BN_ULONG t[8];
+ bn_sqr_normal(rr->d, a->d, 4, t);
+#else
+ bn_sqr_comba4(rr->d, a->d);
+#endif
+ } else if (al == 8) {
+#ifndef BN_SQR_COMBA
+ BN_ULONG t[16];
+ bn_sqr_normal(rr->d, a->d, 8, t);
+#else
+ bn_sqr_comba8(rr->d, a->d);
+#endif
+ } else {
+#if defined(BN_RECURSION)
+ if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) {
+ BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL * 2];
+ bn_sqr_normal(rr->d, a->d, al, t);
+ } else {
+ int j, k;
+
+ j = BN_num_bits_word((BN_ULONG)al);
+ j = 1 << (j - 1);
+ k = j + j;
+ if (al == j) {
+ if (bn_wexpand(tmp, k * 2) == NULL)
+ goto err;
+ bn_sqr_recursive(rr->d, a->d, al, tmp->d);
+ } else {
+ if (bn_wexpand(tmp, max) == NULL)
+ goto err;
+ bn_sqr_normal(rr->d, a->d, al, tmp->d);
+ }
+ }
+#else
+ if (bn_wexpand(tmp, max) == NULL)
+ goto err;
+ bn_sqr_normal(rr->d, a->d, al, tmp->d);
+#endif
+ }
+
+ rr->neg = 0;
+ /*
+ * If the most-significant half of the top word of 'a' is zero, then the
+ * square of 'a' will max-1 words.
+ */
+ if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
+ rr->top = max - 1;
+ else
+ rr->top = max;
+ if (rr != r)
+ BN_copy(r, rr);
+ ret = 1;
+ err:
+ bn_check_top(rr);
+ bn_check_top(tmp);
+ BN_CTX_end(ctx);
+ return (ret);
+}
+
+/* tmp must have 2*n words */
+void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
+{
+ int i, j, max;
+ const BN_ULONG *ap;
+ BN_ULONG *rp;
+
+ max = n * 2;
+ ap = a;
+ rp = r;
+ rp[0] = rp[max - 1] = 0;
+ rp++;
+ j = n;
+
+ if (--j > 0) {
+ ap++;
+ rp[j] = bn_mul_words(rp, ap, j, ap[-1]);
+ rp += 2;
+ }
+
+ for (i = n - 2; i > 0; i--) {
+ j--;
+ ap++;
+ rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);
+ rp += 2;
+ }
+
+ bn_add_words(r, r, r, max);
+
+ /* There will not be a carry */
+
+ bn_sqr_words(tmp, a, n);
+
+ bn_add_words(r, r, tmp, max);
+}
+
+#ifdef BN_RECURSION
+/*-
+ * r is 2*n words in size,
+ * a and b are both n words in size. (There's not actually a 'b' here ...)
+ * n must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n words in size
+ * We calculate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t)
+{
+ int n = n2 / 2;
+ int zero, c1;
+ BN_ULONG ln, lo, *p;
+
+# ifdef BN_COUNT
+ fprintf(stderr, " bn_sqr_recursive %d * %d\n", n2, n2);
+# endif
+ if (n2 == 4) {
+# ifndef BN_SQR_COMBA
+ bn_sqr_normal(r, a, 4, t);
+# else
+ bn_sqr_comba4(r, a);
+# endif
+ return;
+ } else if (n2 == 8) {
+# ifndef BN_SQR_COMBA
+ bn_sqr_normal(r, a, 8, t);
+# else
+ bn_sqr_comba8(r, a);
+# endif
+ return;
+ }
+ if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) {
+ bn_sqr_normal(r, a, n2, t);
+ return;
+ }
+ /* r=(a[0]-a[1])*(a[1]-a[0]) */
+ c1 = bn_cmp_words(a, &(a[n]), n);
+ zero = 0;
+ if (c1 > 0)
+ bn_sub_words(t, a, &(a[n]), n);
+ else if (c1 < 0)
+ bn_sub_words(t, &(a[n]), a, n);
+ else
+ zero = 1;
+
+ /* The result will always be negative unless it is zero */
+ p = &(t[n2 * 2]);
+
+ if (!zero)
+ bn_sqr_recursive(&(t[n2]), t, n, p);
+ else
+ memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG));
+ bn_sqr_recursive(r, a, n, p);
+ bn_sqr_recursive(&(r[n2]), &(a[n]), n, p);
+
+ /*-
+ * t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
+ * r[10] holds (a[0]*b[0])
+ * r[32] holds (b[1]*b[1])
+ */
+
+ c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
+
+ /* t[32] is negative */
+ c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
+
+ /*-
+ * t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
+ * r[10] holds (a[0]*a[0])
+ * r[32] holds (a[1]*a[1])
+ * c1 holds the carry bits
+ */
+ c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
+ if (c1) {
+ p = &(r[n + n2]);
+ lo = *p;
+ ln = (lo + c1) & BN_MASK2;
+ *p = ln;
+
+ /*
+ * The overflow will stop before we over write words we should not
+ * overwrite
+ */
+ if (ln < (BN_ULONG)c1) {
+ do {
+ p++;
+ lo = *p;
+ ln = (lo + 1) & BN_MASK2;
+ *p = ln;
+ } while (ln == 0);
+ }
+ }
+}
+#endif
diff --git a/openssl/bn/bn_sqrt.c b/openssl/bn/bn_sqrt.c
new file mode 100644
index 0000000..232af99
--- /dev/null
+++ b/openssl/bn/bn_sqrt.c
@@ -0,0 +1,409 @@
+/* crypto/bn/bn_sqrt.c */
+/*
+ * Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> and Bodo
+ * Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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 "cryptlib.h"
+#include "bn_lcl.h"
+
+BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+/*
+ * Returns 'ret' such that ret^2 == a (mod p), using the Tonelli/Shanks
+ * algorithm (cf. Henri Cohen, "A Course in Algebraic Computational Number
+ * Theory", algorithm 1.5.1). 'p' must be prime!
+ */
+{
+ BIGNUM *ret = in;
+ int err = 1;
+ int r;
+ BIGNUM *A, *b, *q, *t, *x, *y;
+ int e, i, j;
+
+ if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) {
+ if (BN_abs_is_word(p, 2)) {
+ if (ret == NULL)
+ ret = BN_new();
+ if (ret == NULL)
+ goto end;
+ if (!BN_set_word(ret, BN_is_bit_set(a, 0))) {
+ if (ret != in)
+ BN_free(ret);
+ return NULL;
+ }
+ bn_check_top(ret);
+ return ret;
+ }
+
+ BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+ return (NULL);
+ }
+
+ if (BN_is_zero(a) || BN_is_one(a)) {
+ if (ret == NULL)
+ ret = BN_new();
+ if (ret == NULL)
+ goto end;
+ if (!BN_set_word(ret, BN_is_one(a))) {
+ if (ret != in)
+ BN_free(ret);
+ return NULL;
+ }
+ bn_check_top(ret);
+ return ret;
+ }
+
+ BN_CTX_start(ctx);
+ A = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ q = BN_CTX_get(ctx);
+ t = BN_CTX_get(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (y == NULL)
+ goto end;
+
+ if (ret == NULL)
+ 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))
+ e++;
+ /* we'll set q later (if needed) */
+
+ if (e == 1) {
+ /*-
+ * The easy case: (|p|-1)/2 is odd, so 2 has an inverse
+ * modulo (|p|-1)/2, and square roots can be computed
+ * directly by modular exponentiation.
+ * We have
+ * 2 * (|p|+1)/4 == 1 (mod (|p|-1)/2),
+ * so we can use exponent (|p|+1)/4, i.e. (|p|-3)/4 + 1.
+ */
+ 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;
+ err = 0;
+ goto vrfy;
+ }
+
+ if (e == 2) {
+ /*-
+ * |p| == 5 (mod 8)
+ *
+ * In this case 2 is always a non-square since
+ * Legendre(2,p) = (-1)^((p^2-1)/8) for any odd prime.
+ * So if a really is a square, then 2*a is a non-square.
+ * Thus for
+ * b := (2*a)^((|p|-5)/8),
+ * i := (2*a)*b^2
+ * we have
+ * i^2 = (2*a)^((1 + (|p|-5)/4)*2)
+ * = (2*a)^((p-1)/2)
+ * = -1;
+ * so if we set
+ * x := a*b*(i-1),
+ * then
+ * x^2 = a^2 * b^2 * (i^2 - 2*i + 1)
+ * = a^2 * b^2 * (-2*i)
+ * = a*(-i)*(2*a*b^2)
+ * = a*(-i)*i
+ * = a.
+ *
+ * (This is due to A.O.L. Atkin,
+ * <URL: http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>,
+ * November 1992.)
+ */
+
+ /* t := 2*a */
+ if (!BN_mod_lshift1_quick(t, A, p))
+ goto end;
+
+ /* b := (2*a)^((|p|-5)/8) */
+ if (!BN_rshift(q, p, 3))
+ goto end;
+ q->neg = 0;
+ if (!BN_mod_exp(b, t, q, p, ctx))
+ goto end;
+
+ /* y := b^2 */
+ if (!BN_mod_sqr(y, b, p, ctx))
+ goto end;
+
+ /* t := (2*a)*b^2 - 1 */
+ if (!BN_mod_mul(t, t, y, p, ctx))
+ goto end;
+ 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, x, t, p, ctx))
+ goto end;
+
+ if (!BN_copy(ret, x))
+ goto end;
+ err = 0;
+ goto vrfy;
+ }
+
+ /*
+ * e > 2, so we really have to use the Tonelli/Shanks algorithm. First,
+ * find some y that is not a square.
+ */
+ if (!BN_copy(q, p))
+ goto end; /* use 'q' as temp */
+ q->neg = 0;
+ i = 2;
+ do {
+ /*
+ * For efficiency, try small numbers first; if this fails, try random
+ * numbers.
+ */
+ if (i < 22) {
+ if (!BN_set_word(y, i))
+ goto end;
+ } else {
+ if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0))
+ goto end;
+ if (BN_ucmp(y, p) >= 0) {
+ if (!(p->neg ? BN_add : BN_sub) (y, y, p))
+ goto end;
+ }
+ /* now 0 <= y < |p| */
+ if (BN_is_zero(y))
+ if (!BN_set_word(y, i))
+ goto end;
+ }
+
+ r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */
+ if (r < -1)
+ goto end;
+ if (r == 0) {
+ /* m divides p */
+ BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+ goto end;
+ }
+ }
+ while (r == 1 && ++i < 82);
+
+ if (r != -1) {
+ /*
+ * Many rounds and still no non-square -- this is more likely a bug
+ * than just bad luck. Even if p is not prime, we should have found
+ * some y such that r == -1.
+ */
+ BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS);
+ goto end;
+ }
+
+ /* Here's our actual 'q': */
+ if (!BN_rshift(q, q, e))
+ goto end;
+
+ /*
+ * Now that we have some non-square, we can find an element of order 2^e
+ * by computing its q'th power.
+ */
+ if (!BN_mod_exp(y, y, q, p, ctx))
+ goto end;
+ if (BN_is_one(y)) {
+ BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+ goto end;
+ }
+
+ /*-
+ * Now we know that (if p is indeed prime) there is an integer
+ * k, 0 <= k < 2^e, such that
+ *
+ * a^q * y^k == 1 (mod p).
+ *
+ * As a^q is a square and y is not, k must be even.
+ * q+1 is even, too, so there is an element
+ *
+ * X := a^((q+1)/2) * y^(k/2),
+ *
+ * and it satisfies
+ *
+ * X^2 = a^q * a * y^k
+ * = a,
+ *
+ * so it is the square root that we are looking for.
+ */
+
+ /* t := (q-1)/2 (note that q is odd) */
+ if (!BN_rshift1(t, q))
+ goto end;
+
+ /* 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_is_zero(t)) {
+ /* special case: a == 0 (mod p) */
+ BN_zero(ret);
+ err = 0;
+ goto end;
+ } else if (!BN_one(x))
+ goto end;
+ } else {
+ if (!BN_mod_exp(x, A, t, p, ctx))
+ goto end;
+ if (BN_is_zero(x)) {
+ /* special case: a == 0 (mod p) */
+ BN_zero(ret);
+ err = 0;
+ goto end;
+ }
+ }
+
+ /* 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;
+
+ /* x := a*x (= a^((q+1)/2)) */
+ if (!BN_mod_mul(x, x, A, p, ctx))
+ goto end;
+
+ while (1) {
+ /*-
+ * Now b is a^q * y^k for some even k (0 <= k < 2^E
+ * where E refers to the original value of e, which we
+ * don't keep in a variable), and x is a^((q+1)/2) * y^(k/2).
+ *
+ * We have a*b = x^2,
+ * y^2^(e-1) = -1,
+ * b^2^(e-1) = 1.
+ */
+
+ if (BN_is_one(b)) {
+ if (!BN_copy(ret, x))
+ goto end;
+ err = 0;
+ goto vrfy;
+ }
+
+ /* find smallest i such that b^(2^i) = 1 */
+ i = 1;
+ if (!BN_mod_sqr(t, b, p, ctx))
+ goto end;
+ while (!BN_is_one(t)) {
+ i++;
+ if (i == e) {
+ BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
+ goto end;
+ }
+ if (!BN_mod_mul(t, t, t, p, ctx))
+ goto end;
+ }
+
+ /* t := y^2^(e - i - 1) */
+ if (!BN_copy(t, y))
+ goto end;
+ for (j = e - i - 1; j > 0; j--) {
+ if (!BN_mod_sqr(t, t, p, ctx))
+ goto end;
+ }
+ if (!BN_mod_mul(y, t, t, p, ctx))
+ goto end;
+ if (!BN_mod_mul(x, x, t, p, ctx))
+ goto end;
+ if (!BN_mod_mul(b, b, y, p, ctx))
+ goto end;
+ 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) {
+ if (ret != NULL && ret != in) {
+ BN_clear_free(ret);
+ }
+ ret = NULL;
+ }
+ BN_CTX_end(ctx);
+ bn_check_top(ret);
+ return ret;
+}
diff --git a/openssl/bn/bn_word.c b/openssl/bn/bn_word.c
new file mode 100644
index 0000000..b031a60
--- /dev/null
+++ b/openssl/bn/bn_word.c
@@ -0,0 +1,227 @@
+/* crypto/bn/bn_word.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
+{
+#ifndef BN_LLONG
+ BN_ULONG ret = 0;
+#else
+ BN_ULLONG ret = 0;
+#endif
+ int i;
+
+ if (w == 0)
+ return (BN_ULONG)-1;
+
+ bn_check_top(a);
+ w &= BN_MASK2;
+ for (i = a->top - 1; i >= 0; i--) {
+#ifndef BN_LLONG
+ ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w;
+ ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
+#else
+ ret = (BN_ULLONG) (((ret << (BN_ULLONG) BN_BITS2) | a->d[i]) %
+ (BN_ULLONG) w);
+#endif
+ }
+ return ((BN_ULONG)ret);
+}
+
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
+{
+ BN_ULONG ret = 0;
+ int i, j;
+
+ bn_check_top(a);
+ w &= BN_MASK2;
+
+ if (!w)
+ /* actually this an error (division by zero) */
+ return (BN_ULONG)-1;
+ if (a->top == 0)
+ return 0;
+
+ /* normalize input (so bn_div_words doesn't complain) */
+ j = BN_BITS2 - BN_num_bits_word(w);
+ w <<= j;
+ if (!BN_lshift(a, a, j))
+ return (BN_ULONG)-1;
+
+ for (i = a->top - 1; i >= 0; i--) {
+ BN_ULONG l, d;
+
+ l = a->d[i];
+ d = bn_div_words(ret, l, w);
+ ret = (l - ((d * w) & BN_MASK2)) & BN_MASK2;
+ a->d[i] = d;
+ }
+ if ((a->top > 0) && (a->d[a->top - 1] == 0))
+ a->top--;
+ ret >>= j;
+ bn_check_top(a);
+ return (ret);
+}
+
+int BN_add_word(BIGNUM *a, BN_ULONG w)
+{
+ BN_ULONG l;
+ int i;
+
+ bn_check_top(a);
+ w &= BN_MASK2;
+
+ /* degenerate case: w is zero */
+ if (!w)
+ return 1;
+ /* degenerate case: a is zero */
+ if (BN_is_zero(a))
+ return BN_set_word(a, w);
+ /* handle 'a' when negative */
+ if (a->neg) {
+ a->neg = 0;
+ i = BN_sub_word(a, w);
+ if (!BN_is_zero(a))
+ a->neg = !(a->neg);
+ return (i);
+ }
+ for (i = 0; w != 0 && i < a->top; i++) {
+ a->d[i] = l = (a->d[i] + w) & BN_MASK2;
+ w = (w > l) ? 1 : 0;
+ }
+ if (w && i == a->top) {
+ if (bn_wexpand(a, a->top + 1) == NULL)
+ return 0;
+ a->top++;
+ a->d[i] = w;
+ }
+ bn_check_top(a);
+ return (1);
+}
+
+int BN_sub_word(BIGNUM *a, BN_ULONG w)
+{
+ int i;
+
+ bn_check_top(a);
+ w &= BN_MASK2;
+
+ /* degenerate case: w is zero */
+ if (!w)
+ return 1;
+ /* degenerate case: a is zero */
+ if (BN_is_zero(a)) {
+ i = BN_set_word(a, w);
+ if (i != 0)
+ BN_set_negative(a, 1);
+ return i;
+ }
+ /* handle 'a' when negative */
+ if (a->neg) {
+ a->neg = 0;
+ i = BN_add_word(a, w);
+ a->neg = 1;
+ return (i);
+ }
+
+ if ((a->top == 1) && (a->d[0] < w)) {
+ a->d[0] = w - a->d[0];
+ a->neg = 1;
+ return (1);
+ }
+ i = 0;
+ for (;;) {
+ if (a->d[i] >= w) {
+ a->d[i] -= w;
+ break;
+ } else {
+ a->d[i] = (a->d[i] - w) & BN_MASK2;
+ i++;
+ w = 1;
+ }
+ }
+ if ((a->d[i] == 0) && (i == (a->top - 1)))
+ a->top--;
+ bn_check_top(a);
+ return (1);
+}
+
+int BN_mul_word(BIGNUM *a, BN_ULONG w)
+{
+ BN_ULONG ll;
+
+ bn_check_top(a);
+ w &= BN_MASK2;
+ if (a->top) {
+ if (w == 0)
+ BN_zero(a);
+ else {
+ ll = bn_mul_words(a->d, a->d, a->top, w);
+ if (ll) {
+ if (bn_wexpand(a, a->top + 1) == NULL)
+ return (0);
+ a->d[a->top++] = ll;
+ }
+ }
+ }
+ bn_check_top(a);
+ return (1);
+}
diff --git a/openssl/bn/bn_x931p.c b/openssl/bn/bn_x931p.c
new file mode 100644
index 0000000..6d76b12
--- /dev/null
+++ b/openssl/bn/bn_x931p.c
@@ -0,0 +1,274 @@
+/* bn_x931p.c */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 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 <stdio.h>
+#include <openssl/bn.h>
+
+/* X9.31 routines for prime derivation */
+
+/*
+ * X9.31 prime derivation. This is used to generate the primes pi (p1, p2,
+ * q1, q2) from a parameter Xpi by checking successive odd integers.
+ */
+
+static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx,
+ BN_GENCB *cb)
+{
+ int i = 0;
+ if (!BN_copy(pi, Xpi))
+ return 0;
+ if (!BN_is_odd(pi) && !BN_add_word(pi, 1))
+ return 0;
+ for (;;) {
+ i++;
+ BN_GENCB_call(cb, 0, i);
+ /* NB 27 MR is specificed in X9.31 */
+ if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb))
+ break;
+ if (!BN_add_word(pi, 2))
+ return 0;
+ }
+ BN_GENCB_call(cb, 2, i);
+ return 1;
+}
+
+/*
+ * This is the main X9.31 prime derivation function. From parameters Xp1, Xp2
+ * and Xp derive the prime p. If the parameters p1 or p2 are not NULL they
+ * will be returned too: this is needed for testing.
+ */
+
+int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+ const BIGNUM *Xp, const BIGNUM *Xp1,
+ const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx,
+ BN_GENCB *cb)
+{
+ int ret = 0;
+
+ BIGNUM *t, *p1p2, *pm1;
+
+ /* Only even e supported */
+ if (!BN_is_odd(e))
+ return 0;
+
+ BN_CTX_start(ctx);
+ if (!p1)
+ p1 = BN_CTX_get(ctx);
+
+ if (!p2)
+ p2 = BN_CTX_get(ctx);
+
+ t = BN_CTX_get(ctx);
+
+ p1p2 = BN_CTX_get(ctx);
+
+ pm1 = BN_CTX_get(ctx);
+
+ if (!bn_x931_derive_pi(p1, Xp1, ctx, cb))
+ goto err;
+
+ if (!bn_x931_derive_pi(p2, Xp2, ctx, cb))
+ goto err;
+
+ if (!BN_mul(p1p2, p1, p2, ctx))
+ goto err;
+
+ /* First set p to value of Rp */
+
+ if (!BN_mod_inverse(p, p2, p1, ctx))
+ goto err;
+
+ if (!BN_mul(p, p, p2, ctx))
+ goto err;
+
+ if (!BN_mod_inverse(t, p1, p2, ctx))
+ goto err;
+
+ if (!BN_mul(t, t, p1, ctx))
+ goto err;
+
+ if (!BN_sub(p, p, t))
+ goto err;
+
+ if (p->neg && !BN_add(p, p, p1p2))
+ goto err;
+
+ /* p now equals Rp */
+
+ if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
+ goto err;
+
+ if (!BN_add(p, p, Xp))
+ goto err;
+
+ /* p now equals Yp0 */
+
+ for (;;) {
+ int i = 1;
+ BN_GENCB_call(cb, 0, i++);
+ if (!BN_copy(pm1, p))
+ goto err;
+ if (!BN_sub_word(pm1, 1))
+ goto err;
+ if (!BN_gcd(t, pm1, e, ctx))
+ goto err;
+ if (BN_is_one(t)
+ /*
+ * X9.31 specifies 8 MR and 1 Lucas test or any prime test
+ * offering similar or better guarantees 50 MR is considerably
+ * better.
+ */
+ && BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb))
+ break;
+ if (!BN_add(p, p, p1p2))
+ goto err;
+ }
+
+ BN_GENCB_call(cb, 3, 0);
+
+ ret = 1;
+
+ err:
+
+ BN_CTX_end(ctx);
+
+ return ret;
+}
+
+/*
+ * Generate pair of paramters Xp, Xq for X9.31 prime generation. Note: nbits
+ * paramter is sum of number of bits in both.
+ */
+
+int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx)
+{
+ BIGNUM *t;
+ int i;
+ /*
+ * Number of bits for each prime is of the form 512+128s for s = 0, 1,
+ * ...
+ */
+ if ((nbits < 1024) || (nbits & 0xff))
+ return 0;
+ nbits >>= 1;
+ /*
+ * The random value Xp must be between sqrt(2) * 2^(nbits-1) and 2^nbits
+ * - 1. By setting the top two bits we ensure that the lower bound is
+ * exceeded.
+ */
+ if (!BN_rand(Xp, nbits, 1, 0))
+ return 0;
+
+ BN_CTX_start(ctx);
+ t = BN_CTX_get(ctx);
+
+ for (i = 0; i < 1000; i++) {
+ if (!BN_rand(Xq, nbits, 1, 0))
+ return 0;
+ /* Check that |Xp - Xq| > 2^(nbits - 100) */
+ BN_sub(t, Xp, Xq);
+ if (BN_num_bits(t) > (nbits - 100))
+ break;
+ }
+
+ BN_CTX_end(ctx);
+
+ if (i < 1000)
+ return 1;
+
+ return 0;
+
+}
+
+/*
+ * Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1 and
+ * Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL the
+ * relevant parameter will be stored in it. Due to the fact that |Xp - Xq| >
+ * 2^(nbits - 100) must be satisfied Xp and Xq are generated using the
+ * previous function and supplied as input.
+ */
+
+int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+ BIGNUM *Xp1, BIGNUM *Xp2,
+ const BIGNUM *Xp,
+ const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb)
+{
+ int ret = 0;
+
+ BN_CTX_start(ctx);
+ if (!Xp1)
+ Xp1 = BN_CTX_get(ctx);
+ if (!Xp2)
+ Xp2 = BN_CTX_get(ctx);
+
+ if (!BN_rand(Xp1, 101, 0, 0))
+ goto error;
+ if (!BN_rand(Xp2, 101, 0, 0))
+ goto error;
+ if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb))
+ goto error;
+
+ ret = 1;
+
+ error:
+ BN_CTX_end(ctx);
+
+ return ret;
+
+}
diff --git a/openssl/bn/bnspeed.c b/openssl/bn/bnspeed.c
new file mode 100644
index 0000000..e387fdf
--- /dev/null
+++ b/openssl/bn/bnspeed.c
@@ -0,0 +1,232 @@
+/* unused */
+
+/* crypto/bn/bnspeed.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* most of this code has been pilfered from my libdes speed.c program */
+
+#define BASENUM 1000000
+#undef PROG
+#define PROG bnspeed_main
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
+# define TIMES
+#endif
+
+#ifndef _IRIX
+# include <time.h>
+#endif
+#ifdef TIMES
+# include <sys/types.h>
+# include <sys/times.h>
+#endif
+
+/*
+ * Depending on the VMS version, the tms structure is perhaps defined. The
+ * __TMS macro will show if it was. If it wasn't defined, we should undefine
+ * TIMES, since that tells the rest of the program how things should be
+ * handled. -- Richard Levitte
+ */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+# undef TIMES
+#endif
+
+#ifndef TIMES
+# include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+# define _POSIX_SOURCE
+# include <limits.h>
+# include <sys/param.h>
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+
+/* The following if from times(3) man page. It may need to be changed */
+#ifndef HZ
+# ifndef CLK_TCK
+# ifndef _BSD_CLK_TCK_ /* FreeBSD hack */
+# define HZ 100.0
+# else /* _BSD_CLK_TCK_ */
+# define HZ ((double)_BSD_CLK_TCK_)
+# endif
+# else /* CLK_TCK */
+# define HZ ((double)CLK_TCK)
+# endif
+#endif
+
+#undef BUFSIZE
+#define BUFSIZE ((long)1024*8)
+int run = 0;
+
+static double Time_F(int s);
+#define START 0
+#define STOP 1
+
+static double Time_F(int s)
+{
+ double ret;
+#ifdef TIMES
+ static struct tms tstart, tend;
+
+ if (s == START) {
+ times(&tstart);
+ return (0);
+ } else {
+ times(&tend);
+ ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ;
+ return ((ret < 1e-3) ? 1e-3 : ret);
+ }
+#else /* !times() */
+ static struct timeb tstart, tend;
+ long i;
+
+ if (s == START) {
+ ftime(&tstart);
+ return (0);
+ } else {
+ ftime(&tend);
+ i = (long)tend.millitm - (long)tstart.millitm;
+ ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1000.0;
+ return ((ret < 0.001) ? 0.001 : ret);
+ }
+#endif
+}
+
+#define NUM_SIZES 5
+static int sizes[NUM_SIZES] = { 128, 256, 512, 1024, 2048 };
+
+/*
+ * static int sizes[NUM_SIZES]={59,179,299,419,539};
+ */
+
+void do_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+
+int main(int argc, char **argv)
+{
+ BN_CTX *ctx;
+ BIGNUM a, b, c;
+
+ ctx = BN_CTX_new();
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+
+ do_mul(&a, &b, &c, ctx);
+}
+
+void do_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+{
+ int i, j, k;
+ double tm;
+ long num;
+
+ for (i = 0; i < NUM_SIZES; i++) {
+ num = BASENUM;
+ if (i)
+ num /= (i * 3);
+ BN_rand(a, sizes[i], 1, 0);
+ for (j = i; j < NUM_SIZES; j++) {
+ BN_rand(b, sizes[j], 1, 0);
+ Time_F(START);
+ for (k = 0; k < num; k++)
+ BN_mul(r, b, a, ctx);
+ tm = Time_F(STOP);
+ printf("mul %4d x %4d -> %8.3fms\n", sizes[i], sizes[j],
+ tm * 1000.0 / num);
+ }
+ }
+
+ for (i = 0; i < NUM_SIZES; i++) {
+ num = BASENUM;
+ if (i)
+ num /= (i * 3);
+ BN_rand(a, sizes[i], 1, 0);
+ Time_F(START);
+ for (k = 0; k < num; k++)
+ BN_sqr(r, a, ctx);
+ tm = Time_F(STOP);
+ printf("sqr %4d x %4d -> %8.3fms\n", sizes[i], sizes[i],
+ tm * 1000.0 / num);
+ }
+
+ for (i = 0; i < NUM_SIZES; i++) {
+ num = BASENUM / 10;
+ if (i)
+ num /= (i * 3);
+ BN_rand(a, sizes[i] - 1, 1, 0);
+ for (j = i; j < NUM_SIZES; j++) {
+ BN_rand(b, sizes[j], 1, 0);
+ Time_F(START);
+ for (k = 0; k < 100000; k++)
+ BN_div(r, NULL, b, a, ctx);
+ tm = Time_F(STOP);
+ printf("div %4d / %4d -> %8.3fms\n", sizes[j], sizes[i] - 1,
+ tm * 1000.0 / num);
+ }
+ }
+}
diff --git a/openssl/bn/bntest.c b/openssl/bn/bntest.c
new file mode 100644
index 0000000..06662c5
--- /dev/null
+++ b/openssl/bn/bntest.c
@@ -0,0 +1,2085 @@
+/* crypto/bn/bntest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * 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.
+ *
+ */
+
+/*
+ * Until the key-gen callbacks are modified to use newer prototypes, we allow
+ * deprecated functions for openssl-internal code
+ */
+#ifdef OPENSSL_NO_DEPRECATED
+# undef OPENSSL_NO_DEPRECATED
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "e_os.h"
+
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+
+const int num0 = 100; /* number of tests */
+const int num1 = 50; /* additional tests for some functions */
+const int num2 = 5; /* number of tests for slow functions */
+
+int test_add(BIO *bp);
+int test_sub(BIO *bp);
+int test_lshift1(BIO *bp);
+int test_lshift(BIO *bp, BN_CTX *ctx, BIGNUM *a_);
+int test_rshift1(BIO *bp);
+int test_rshift(BIO *bp, BN_CTX *ctx);
+int test_div(BIO *bp, BN_CTX *ctx);
+int test_div_word(BIO *bp);
+int test_div_recp(BIO *bp, BN_CTX *ctx);
+int test_mul(BIO *bp);
+int test_sqr(BIO *bp, BN_CTX *ctx);
+int test_mont(BIO *bp, BN_CTX *ctx);
+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_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx);
+int test_mod_exp_mont5(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);
+static int results = 0;
+
+static unsigned char lst[] =
+ "\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
+ "\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0";
+
+static const char rnd_seed[] =
+ "string to make the random number generator think it has entropy";
+
+static void message(BIO *out, char *m)
+{
+ fprintf(stderr, "test %s\n", m);
+ BIO_puts(out, "print \"test ");
+ BIO_puts(out, m);
+ BIO_puts(out, "\\n\"\n");
+}
+
+int main(int argc, char *argv[])
+{
+ BN_CTX *ctx;
+ BIO *out;
+ char *outfile = NULL;
+
+ results = 0;
+
+ RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
+
+ argc--;
+ argv++;
+ while (argc >= 1) {
+ if (strcmp(*argv, "-results") == 0)
+ results = 1;
+ else if (strcmp(*argv, "-out") == 0) {
+ if (--argc < 1)
+ break;
+ outfile = *(++argv);
+ }
+ argc--;
+ argv++;
+ }
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ EXIT(1);
+
+ out = BIO_new(BIO_s_file());
+ if (out == NULL)
+ EXIT(1);
+ if (outfile == NULL) {
+ BIO_set_fp(out, stdout, BIO_NOCLOSE);
+ } else {
+ if (!BIO_write_filename(out, outfile)) {
+ perror(outfile);
+ EXIT(1);
+ }
+ }
+
+ if (!results)
+ BIO_puts(out, "obase=16\nibase=16\n");
+
+ message(out, "BN_add");
+ if (!test_add(out))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_sub");
+ if (!test_sub(out))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_lshift1");
+ if (!test_lshift1(out))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_lshift (fixed)");
+ if (!test_lshift(out, ctx, BN_bin2bn(lst, sizeof(lst) - 1, NULL)))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_lshift");
+ if (!test_lshift(out, ctx, NULL))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_rshift1");
+ if (!test_rshift1(out))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_rshift");
+ if (!test_rshift(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_sqr");
+ if (!test_sqr(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_mul");
+ if (!test_mul(out))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_div");
+ if (!test_div(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_div_word");
+ if (!test_div_word(out))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_div_recp");
+ if (!test_div_recp(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_mod");
+ if (!test_mod(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_mod_mul");
+ if (!test_mod_mul(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_mont");
+ if (!test_mont(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_mod_exp");
+ if (!test_mod_exp(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_mod_exp_mont_consttime");
+ if (!test_mod_exp_mont_consttime(out, ctx))
+ goto err;
+ if (!test_mod_exp_mont5(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_exp");
+ if (!test_exp(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_kronecker");
+ if (!test_kron(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_mod_sqrt");
+ if (!test_sqrt(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+#ifndef OPENSSL_NO_EC2M
+ message(out, "BN_GF2m_add");
+ if (!test_gf2m_add(out))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_GF2m_mod");
+ if (!test_gf2m_mod(out))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_GF2m_mod_mul");
+ if (!test_gf2m_mod_mul(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_GF2m_mod_sqr");
+ if (!test_gf2m_mod_sqr(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_GF2m_mod_inv");
+ if (!test_gf2m_mod_inv(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_GF2m_mod_div");
+ if (!test_gf2m_mod_div(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_GF2m_mod_exp");
+ if (!test_gf2m_mod_exp(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_GF2m_mod_sqrt");
+ if (!test_gf2m_mod_sqrt(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+
+ message(out, "BN_GF2m_mod_solve_quad");
+ if (!test_gf2m_mod_solve_quad(out, ctx))
+ goto err;
+ (void)BIO_flush(out);
+#endif
+ BN_CTX_free(ctx);
+ BIO_free(out);
+
+ EXIT(0);
+ err:
+ BIO_puts(out, "1\n"); /* make sure the Perl script fed by bc
+ * notices the failure, see test_bn in
+ * test/Makefile.ssl */
+ (void)BIO_flush(out);
+ ERR_load_crypto_strings();
+ ERR_print_errors_fp(stderr);
+ EXIT(1);
+ return (1);
+}
+
+int test_add(BIO *bp)
+{
+ BIGNUM a, b, c;
+ int i;
+
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+
+ BN_bntest_rand(&a, 512, 0, 0);
+ for (i = 0; i < num0; i++) {
+ BN_bntest_rand(&b, 450 + i, 0, 0);
+ a.neg = rand_neg();
+ b.neg = rand_neg();
+ BN_add(&c, &a, &b);
+ 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");
+ }
+ a.neg = !a.neg;
+ b.neg = !b.neg;
+ BN_add(&c, &c, &b);
+ BN_add(&c, &c, &a);
+ if (!BN_is_zero(&c)) {
+ fprintf(stderr, "Add test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(&a);
+ BN_free(&b);
+ BN_free(&c);
+ return (1);
+}
+
+int test_sub(BIO *bp)
+{
+ BIGNUM a, b, c;
+ int i;
+
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+
+ for (i = 0; i < num0 + num1; i++) {
+ if (i < num1) {
+ BN_bntest_rand(&a, 512, 0, 0);
+ BN_copy(&b, &a);
+ if (BN_set_bit(&a, i) == 0)
+ return (0);
+ BN_add_word(&b, i);
+ } else {
+ BN_bntest_rand(&b, 400 + i - num1, 0, 0);
+ a.neg = rand_neg();
+ b.neg = rand_neg();
+ }
+ BN_sub(&c, &a, &b);
+ 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");
+ }
+ BN_add(&c, &c, &b);
+ BN_sub(&c, &c, &a);
+ if (!BN_is_zero(&c)) {
+ fprintf(stderr, "Subtract test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(&a);
+ BN_free(&b);
+ BN_free(&c);
+ return (1);
+}
+
+int test_div(BIO *bp, BN_CTX *ctx)
+{
+ BIGNUM a, b, c, d, e;
+ int i;
+
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+ BN_init(&d);
+ BN_init(&e);
+
+ for (i = 0; i < num0 + num1; i++) {
+ if (i < num1) {
+ BN_bntest_rand(&a, 400, 0, 0);
+ BN_copy(&b, &a);
+ BN_lshift(&a, &a, i);
+ BN_add_word(&a, i);
+ } else
+ BN_bntest_rand(&b, 50 + 3 * (i - num1), 0, 0);
+ a.neg = rand_neg();
+ b.neg = rand_neg();
+ BN_div(&d, &c, &a, &b, ctx);
+ if (bp != NULL) {
+ if (!results) {
+ BN_print(bp, &a);
+ BIO_puts(bp, " / ");
+ BN_print(bp, &b);
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, &d);
+ BIO_puts(bp, "\n");
+
+ if (!results) {
+ BN_print(bp, &a);
+ BIO_puts(bp, " % ");
+ BN_print(bp, &b);
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, &c);
+ BIO_puts(bp, "\n");
+ }
+ BN_mul(&e, &d, &b, ctx);
+ BN_add(&d, &e, &c);
+ BN_sub(&d, &d, &a);
+ if (!BN_is_zero(&d)) {
+ fprintf(stderr, "Division test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(&a);
+ BN_free(&b);
+ BN_free(&c);
+ BN_free(&d);
+ BN_free(&e);
+ return (1);
+}
+
+static void print_word(BIO *bp, BN_ULONG w)
+{
+#ifdef SIXTY_FOUR_BIT
+ if (sizeof(w) > sizeof(unsigned long)) {
+ unsigned long h = (unsigned long)(w >> 32), l = (unsigned long)(w);
+
+ if (h)
+ BIO_printf(bp, "%lX%08lX", h, l);
+ else
+ BIO_printf(bp, "%lX", l);
+ return;
+ }
+#endif
+ BIO_printf(bp, BN_HEX_FMT1, w);
+}
+
+int test_div_word(BIO *bp)
+{
+ BIGNUM a, b;
+ BN_ULONG r, s;
+ int i;
+
+ BN_init(&a);
+ BN_init(&b);
+
+ for (i = 0; i < num0; i++) {
+ do {
+ BN_bntest_rand(&a, 512, -1, 0);
+ BN_bntest_rand(&b, BN_BITS2, -1, 0);
+ s = b.d[0];
+ } while (!s);
+
+ BN_copy(&b, &a);
+ r = BN_div_word(&b, s);
+
+ if (bp != NULL) {
+ if (!results) {
+ BN_print(bp, &a);
+ BIO_puts(bp, " / ");
+ print_word(bp, s);
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, &b);
+ BIO_puts(bp, "\n");
+
+ if (!results) {
+ BN_print(bp, &a);
+ BIO_puts(bp, " % ");
+ print_word(bp, s);
+ BIO_puts(bp, " - ");
+ }
+ print_word(bp, r);
+ BIO_puts(bp, "\n");
+ }
+ BN_mul_word(&b, s);
+ BN_add_word(&b, r);
+ BN_sub(&b, &a, &b);
+ if (!BN_is_zero(&b)) {
+ fprintf(stderr, "Division (word) test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(&a);
+ BN_free(&b);
+ return (1);
+}
+
+int test_div_recp(BIO *bp, BN_CTX *ctx)
+{
+ BIGNUM a, b, c, d, e;
+ BN_RECP_CTX recp;
+ int i;
+
+ BN_RECP_CTX_init(&recp);
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+ BN_init(&d);
+ BN_init(&e);
+
+ for (i = 0; i < num0 + num1; i++) {
+ if (i < num1) {
+ BN_bntest_rand(&a, 400, 0, 0);
+ BN_copy(&b, &a);
+ BN_lshift(&a, &a, i);
+ BN_add_word(&a, i);
+ } else
+ BN_bntest_rand(&b, 50 + 3 * (i - num1), 0, 0);
+ a.neg = rand_neg();
+ b.neg = rand_neg();
+ BN_RECP_CTX_set(&recp, &b, ctx);
+ BN_div_recp(&d, &c, &a, &recp, ctx);
+ if (bp != NULL) {
+ if (!results) {
+ BN_print(bp, &a);
+ BIO_puts(bp, " / ");
+ BN_print(bp, &b);
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, &d);
+ BIO_puts(bp, "\n");
+
+ if (!results) {
+ BN_print(bp, &a);
+ BIO_puts(bp, " % ");
+ BN_print(bp, &b);
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, &c);
+ BIO_puts(bp, "\n");
+ }
+ BN_mul(&e, &d, &b, ctx);
+ BN_add(&d, &e, &c);
+ BN_sub(&d, &d, &a);
+ if (!BN_is_zero(&d)) {
+ fprintf(stderr, "Reciprocal division test failed!\n");
+ fprintf(stderr, "a=");
+ BN_print_fp(stderr, &a);
+ fprintf(stderr, "\nb=");
+ BN_print_fp(stderr, &b);
+ fprintf(stderr, "\n");
+ return 0;
+ }
+ }
+ BN_free(&a);
+ BN_free(&b);
+ BN_free(&c);
+ BN_free(&d);
+ BN_free(&e);
+ BN_RECP_CTX_free(&recp);
+ return (1);
+}
+
+int test_mul(BIO *bp)
+{
+ BIGNUM a, b, c, d, e;
+ int i;
+ BN_CTX *ctx;
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ EXIT(1);
+
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+ BN_init(&d);
+ BN_init(&e);
+
+ for (i = 0; i < num0 + num1; i++) {
+ if (i <= num1) {
+ BN_bntest_rand(&a, 100, 0, 0);
+ BN_bntest_rand(&b, 100, 0, 0);
+ } else
+ BN_bntest_rand(&b, i - num1, 0, 0);
+ a.neg = rand_neg();
+ b.neg = rand_neg();
+ BN_mul(&c, &a, &b, ctx);
+ 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");
+ }
+ BN_div(&d, &e, &c, &a, ctx);
+ BN_sub(&d, &d, &b);
+ if (!BN_is_zero(&d) || !BN_is_zero(&e)) {
+ fprintf(stderr, "Multiplication test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(&a);
+ BN_free(&b);
+ BN_free(&c);
+ BN_free(&d);
+ BN_free(&e);
+ BN_CTX_free(ctx);
+ return (1);
+}
+
+int test_sqr(BIO *bp, BN_CTX *ctx)
+{
+ BIGNUM *a, *c, *d, *e;
+ int i, ret = 0;
+
+ a = BN_new();
+ c = BN_new();
+ d = BN_new();
+ e = BN_new();
+ if (a == NULL || c == NULL || d == NULL || e == NULL) {
+ goto err;
+ }
+
+ for (i = 0; i < num0; i++) {
+ BN_bntest_rand(a, 40 + i * 10, 0, 0);
+ a->neg = rand_neg();
+ BN_sqr(c, a, ctx);
+ if (bp != NULL) {
+ if (!results) {
+ BN_print(bp, a);
+ BIO_puts(bp, " * ");
+ BN_print(bp, a);
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, c);
+ BIO_puts(bp, "\n");
+ }
+ BN_div(d, e, c, a, ctx);
+ BN_sub(d, d, a);
+ if (!BN_is_zero(d) || !BN_is_zero(e)) {
+ fprintf(stderr, "Square test failed!\n");
+ goto err;
+ }
+ }
+
+ /* Regression test for a BN_sqr overflow bug. */
+ BN_hex2bn(&a,
+ "80000000000000008000000000000001"
+ "FFFFFFFFFFFFFFFE0000000000000000");
+ BN_sqr(c, a, ctx);
+ if (bp != NULL) {
+ if (!results) {
+ BN_print(bp, a);
+ BIO_puts(bp, " * ");
+ BN_print(bp, a);
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, c);
+ BIO_puts(bp, "\n");
+ }
+ BN_mul(d, a, a, ctx);
+ if (BN_cmp(c, d)) {
+ fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
+ "different results!\n");
+ goto err;
+ }
+
+ /* Regression test for a BN_sqr overflow bug. */
+ BN_hex2bn(&a,
+ "80000000000000000000000080000001"
+ "FFFFFFFE000000000000000000000000");
+ BN_sqr(c, a, ctx);
+ if (bp != NULL) {
+ if (!results) {
+ BN_print(bp, a);
+ BIO_puts(bp, " * ");
+ BN_print(bp, a);
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, c);
+ BIO_puts(bp, "\n");
+ }
+ BN_mul(d, a, a, ctx);
+ if (BN_cmp(c, d)) {
+ fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce "
+ "different results!\n");
+ goto err;
+ }
+ ret = 1;
+ err:
+ if (a != NULL)
+ BN_free(a);
+ if (c != NULL)
+ BN_free(c);
+ if (d != NULL)
+ BN_free(d);
+ if (e != NULL)
+ BN_free(e);
+ return ret;
+}
+
+int test_mont(BIO *bp, BN_CTX *ctx)
+{
+ BIGNUM a, b, c, d, A, B;
+ BIGNUM n;
+ int i;
+ BN_MONT_CTX *mont;
+
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+ BN_init(&d);
+ BN_init(&A);
+ BN_init(&B);
+ BN_init(&n);
+
+ mont = BN_MONT_CTX_new();
+ if (mont == NULL)
+ return 0;
+
+ BN_bntest_rand(&a, 100, 0, 0);
+ BN_bntest_rand(&b, 100, 0, 0);
+ for (i = 0; i < num2; i++) {
+ int bits = (200 * (i + 1)) / num2;
+
+ if (bits == 0)
+ continue;
+ BN_bntest_rand(&n, bits, 0, 1);
+ BN_MONT_CTX_set(mont, &n, ctx);
+
+ BN_nnmod(&a, &a, &n, ctx);
+ BN_nnmod(&b, &b, &n, ctx);
+
+ BN_to_montgomery(&A, &a, mont, ctx);
+ BN_to_montgomery(&B, &b, mont, ctx);
+
+ BN_mod_mul_montgomery(&c, &A, &B, mont, ctx);
+ BN_from_montgomery(&A, &c, mont, ctx);
+ if (bp != NULL) {
+ if (!results) {
+#ifdef undef
+ fprintf(stderr, "%d * %d %% %d\n",
+ BN_num_bits(&a),
+ BN_num_bits(&b), BN_num_bits(mont->N));
+#endif
+ BN_print(bp, &a);
+ BIO_puts(bp, " * ");
+ BN_print(bp, &b);
+ BIO_puts(bp, " % ");
+ BN_print(bp, &(mont->N));
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, &A);
+ BIO_puts(bp, "\n");
+ }
+ BN_mod_mul(&d, &a, &b, &n, ctx);
+ BN_sub(&d, &d, &A);
+ if (!BN_is_zero(&d)) {
+ fprintf(stderr, "Montgomery multiplication test failed!\n");
+ return 0;
+ }
+ }
+ BN_MONT_CTX_free(mont);
+ BN_free(&a);
+ BN_free(&b);
+ BN_free(&c);
+ BN_free(&d);
+ BN_free(&A);
+ BN_free(&B);
+ BN_free(&n);
+ return (1);
+}
+
+int test_mod(BIO *bp, BN_CTX *ctx)
+{
+ BIGNUM *a, *b, *c, *d, *e;
+ int i;
+
+ a = BN_new();
+ b = BN_new();
+ c = BN_new();
+ d = BN_new();
+ e = BN_new();
+
+ BN_bntest_rand(a, 1024, 0, 0);
+ for (i = 0; i < num0; i++) {
+ BN_bntest_rand(b, 450 + i * 10, 0, 0);
+ a->neg = rand_neg();
+ b->neg = rand_neg();
+ BN_mod(c, a, b, ctx);
+ 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");
+ }
+ BN_div(d, e, a, b, ctx);
+ BN_sub(e, e, c);
+ if (!BN_is_zero(e)) {
+ fprintf(stderr, "Modulo test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ return (1);
+}
+
+int test_mod_mul(BIO *bp, BN_CTX *ctx)
+{
+ BIGNUM *a, *b, *c, *d, *e;
+ int i, j;
+
+ a = BN_new();
+ b = BN_new();
+ c = BN_new();
+ d = BN_new();
+ e = BN_new();
+
+ for (j = 0; j < 3; j++) {
+ BN_bntest_rand(c, 1024, 0, 0);
+ for (i = 0; i < num0; i++) {
+ BN_bntest_rand(a, 475 + i * 10, 0, 0);
+ BN_bntest_rand(b, 425 + i * 11, 0, 0);
+ a->neg = rand_neg();
+ b->neg = rand_neg();
+ if (!BN_mod_mul(e, a, b, c, ctx)) {
+ unsigned long l;
+
+ while ((l = ERR_get_error()))
+ fprintf(stderr, "ERROR:%s\n", ERR_error_string(l, NULL));
+ EXIT(1);
+ }
+ if (bp != NULL) {
+ if (!results) {
+ BN_print(bp, a);
+ BIO_puts(bp, " * ");
+ BN_print(bp, b);
+ BIO_puts(bp, " % ");
+ BN_print(bp, c);
+ if ((a->neg ^ b->neg) && !BN_is_zero(e)) {
+ /*
+ * If (a*b) % c is negative, c must be added in order
+ * to obtain the normalized remainder (new with
+ * OpenSSL 0.9.7, previous versions of BN_mod_mul
+ * could generate negative results)
+ */
+ BIO_puts(bp, " + ");
+ BN_print(bp, c);
+ }
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, e);
+ BIO_puts(bp, "\n");
+ }
+ BN_mul(d, a, b, ctx);
+ BN_sub(d, d, e);
+ BN_div(a, b, d, c, ctx);
+ if (!BN_is_zero(b)) {
+ fprintf(stderr, "Modulo multiply test failed!\n");
+ ERR_print_errors_fp(stderr);
+ return 0;
+ }
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ return (1);
+}
+
+int test_mod_exp(BIO *bp, BN_CTX *ctx)
+{
+ BIGNUM *a, *b, *c, *d, *e;
+ int i;
+
+ a = BN_new();
+ b = BN_new();
+ c = BN_new();
+ d = BN_new();
+ e = BN_new();
+
+ BN_bntest_rand(c, 30, 0, 1); /* must be odd for montgomery */
+ for (i = 0; i < num2; i++) {
+ BN_bntest_rand(a, 20 + i * 5, 0, 0);
+ BN_bntest_rand(b, 2 + i, 0, 0);
+
+ if (!BN_mod_exp(d, a, b, c, ctx))
+ return (0);
+
+ 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, " - ");
+ }
+ BN_print(bp, d);
+ BIO_puts(bp, "\n");
+ }
+ BN_exp(e, a, b, ctx);
+ BN_sub(e, e, d);
+ BN_div(a, b, e, c, ctx);
+ if (!BN_is_zero(b)) {
+ fprintf(stderr, "Modulo exponentiation test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ return (1);
+}
+
+int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
+{
+ BIGNUM *a, *b, *c, *d, *e;
+ int i;
+
+ a = BN_new();
+ b = BN_new();
+ c = BN_new();
+ d = BN_new();
+ e = BN_new();
+
+ BN_bntest_rand(c, 30, 0, 1); /* must be odd for montgomery */
+ for (i = 0; i < num2; i++) {
+ BN_bntest_rand(a, 20 + i * 5, 0, 0);
+ BN_bntest_rand(b, 2 + i, 0, 0);
+
+ if (!BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL))
+ return (00);
+
+ 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, " - ");
+ }
+ BN_print(bp, d);
+ BIO_puts(bp, "\n");
+ }
+ BN_exp(e, a, b, ctx);
+ BN_sub(e, e, d);
+ BN_div(a, b, e, c, ctx);
+ if (!BN_is_zero(b)) {
+ fprintf(stderr, "Modulo exponentiation test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ return (1);
+}
+
+/*
+ * Test constant-time modular exponentiation with 1024-bit inputs, which on
+ * x86_64 cause a different code branch to be taken.
+ */
+int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx)
+{
+ BIGNUM *a, *p, *m, *d, *e;
+
+ BN_MONT_CTX *mont;
+
+ a = BN_new();
+ p = BN_new();
+ m = BN_new();
+ d = BN_new();
+ e = BN_new();
+
+ mont = BN_MONT_CTX_new();
+
+ BN_bntest_rand(m, 1024, 0, 1); /* must be odd for montgomery */
+ /* Zero exponent */
+ BN_bntest_rand(a, 1024, 0, 0);
+ BN_zero(p);
+ if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL))
+ return 0;
+ if (!BN_is_one(d)) {
+ fprintf(stderr, "Modular exponentiation test failed!\n");
+ return 0;
+ }
+ /* Zero input */
+ BN_bntest_rand(p, 1024, 0, 0);
+ BN_zero(a);
+ if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL))
+ return 0;
+ if (!BN_is_zero(d)) {
+ fprintf(stderr, "Modular exponentiation test failed!\n");
+ return 0;
+ }
+ /*
+ * Craft an input whose Montgomery representation is 1, i.e., shorter
+ * than the modulus m, in order to test the const time precomputation
+ * scattering/gathering.
+ */
+ BN_one(a);
+ BN_MONT_CTX_set(mont, m, ctx);
+ if (!BN_from_montgomery(e, a, mont, ctx))
+ return 0;
+ if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL))
+ return 0;
+ if (!BN_mod_exp_simple(a, e, p, m, ctx))
+ return 0;
+ if (BN_cmp(a, d) != 0) {
+ fprintf(stderr, "Modular exponentiation test failed!\n");
+ return 0;
+ }
+ /* Finally, some regular test vectors. */
+ BN_bntest_rand(e, 1024, 0, 0);
+ if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL))
+ return 0;
+ if (!BN_mod_exp_simple(a, e, p, m, ctx))
+ return 0;
+ if (BN_cmp(a, d) != 0) {
+ fprintf(stderr, "Modular exponentiation test failed!\n");
+ return 0;
+ }
+ BN_free(a);
+ BN_free(p);
+ BN_free(m);
+ BN_free(d);
+ BN_free(e);
+ return (1);
+}
+
+int test_exp(BIO *bp, BN_CTX *ctx)
+{
+ BIGNUM *a, *b, *d, *e, *one;
+ int i;
+
+ a = BN_new();
+ b = BN_new();
+ d = BN_new();
+ e = BN_new();
+ one = BN_new();
+ BN_one(one);
+
+ for (i = 0; i < num2; i++) {
+ BN_bntest_rand(a, 20 + i * 5, 0, 0);
+ BN_bntest_rand(b, 2 + i, 0, 0);
+
+ if (BN_exp(d, a, b, ctx) <= 0)
+ return (0);
+
+ if (bp != NULL) {
+ if (!results) {
+ BN_print(bp, a);
+ BIO_puts(bp, " ^ ");
+ BN_print(bp, b);
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, d);
+ BIO_puts(bp, "\n");
+ }
+ BN_one(e);
+ for (; !BN_is_zero(b); BN_sub(b, b, one))
+ BN_mul(e, e, a, ctx);
+ BN_sub(e, e, d);
+ if (!BN_is_zero(e)) {
+ fprintf(stderr, "Exponentiation test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(d);
+ BN_free(e);
+ BN_free(one);
+ return (1);
+}
+
+#ifndef OPENSSL_NO_EC2M
+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;
+ int p0[] = { 163, 7, 6, 3, 0, -1 };
+ int p1[] = { 193, 15, 0, -1 };
+
+ 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;
+ int p0[] = { 163, 7, 6, 3, 0, -1 };
+ int p1[] = { 193, 15, 0, -1 };
+
+ 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;
+ int p0[] = { 163, 7, 6, 3, 0, -1 };
+ int p1[] = { 193, 15, 0, -1 };
+
+ 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;
+ int p0[] = { 163, 7, 6, 3, 0, -1 };
+ int p1[] = { 193, 15, 0, -1 };
+
+ 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;
+ int p0[] = { 163, 7, 6, 3, 0, -1 };
+ int p1[] = { 193, 15, 0, -1 };
+
+ 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;
+ int p0[] = { 163, 7, 6, 3, 0, -1 };
+ int p1[] = { 193, 15, 0, -1 };
+
+ 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;
+ int p0[] = { 163, 7, 6, 3, 0, -1 };
+ int p1[] = { 193, 15, 0, -1 };
+
+ 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;
+ int p0[] = { 163, 7, 6, 3, 0, -1 };
+ int p1[] = { 193, 15, 0, -1 };
+
+ 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;
+}
+#endif
+static int genprime_cb(int p, int n, BN_GENCB *arg)
+{
+ char c = '*';
+
+ if (p == 0)
+ c = '.';
+ if (p == 1)
+ c = '+';
+ if (p == 2)
+ c = '*';
+ if (p == 3)
+ c = '\n';
+ putc(c, stderr);
+ fflush(stderr);
+ return 1;
+}
+
+int test_kron(BIO *bp, BN_CTX *ctx)
+{
+ BN_GENCB cb;
+ BIGNUM *a, *b, *r, *t;
+ int i;
+ int legendre, kronecker;
+ int ret = 0;
+
+ a = BN_new();
+ b = BN_new();
+ r = BN_new();
+ t = BN_new();
+ if (a == NULL || b == NULL || r == NULL || t == NULL)
+ goto err;
+
+ BN_GENCB_set(&cb, genprime_cb, NULL);
+
+ /*
+ * We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol). In
+ * this case we know that if b is prime, then BN_kronecker(a, b, ctx) is
+ * congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol). So we
+ * generate a random prime b and compare these values for a number of
+ * random a's. (That is, we run the Solovay-Strassen primality test to
+ * confirm that b is prime, except that we don't want to test whether b
+ * is prime but whether BN_kronecker works.)
+ */
+
+ if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, &cb))
+ goto err;
+ b->neg = rand_neg();
+ putc('\n', stderr);
+
+ for (i = 0; i < num0; i++) {
+ if (!BN_bntest_rand(a, 512, 0, 0))
+ goto err;
+ a->neg = rand_neg();
+
+ /* t := (|b|-1)/2 (note that b is odd) */
+ if (!BN_copy(t, b))
+ goto err;
+ t->neg = 0;
+ if (!BN_sub_word(t, 1))
+ goto err;
+ if (!BN_rshift1(t, t))
+ goto err;
+ /* r := a^t mod b */
+ b->neg = 0;
+
+ if (!BN_mod_exp_recp(r, a, t, b, ctx))
+ goto err;
+ b->neg = 1;
+
+ if (BN_is_word(r, 1))
+ legendre = 1;
+ else if (BN_is_zero(r))
+ legendre = 0;
+ else {
+ if (!BN_add_word(r, 1))
+ goto err;
+ if (0 != BN_ucmp(r, b)) {
+ fprintf(stderr, "Legendre symbol computation failed\n");
+ goto err;
+ }
+ legendre = -1;
+ }
+
+ kronecker = BN_kronecker(a, b, ctx);
+ if (kronecker < -1)
+ goto err;
+ /* we actually need BN_kronecker(a, |b|) */
+ if (a->neg && b->neg)
+ kronecker = -kronecker;
+
+ if (legendre != kronecker) {
+ fprintf(stderr, "legendre != kronecker; a = ");
+ BN_print_fp(stderr, a);
+ fprintf(stderr, ", b = ");
+ BN_print_fp(stderr, b);
+ fprintf(stderr, "\n");
+ goto err;
+ }
+
+ putc('.', stderr);
+ fflush(stderr);
+ }
+
+ putc('\n', stderr);
+ fflush(stderr);
+ ret = 1;
+ err:
+ if (a != NULL)
+ BN_free(a);
+ if (b != NULL)
+ BN_free(b);
+ if (r != NULL)
+ BN_free(r);
+ if (t != NULL)
+ BN_free(t);
+ return ret;
+}
+
+int test_sqrt(BIO *bp, BN_CTX *ctx)
+{
+ BN_GENCB cb;
+ BIGNUM *a, *p, *r;
+ int i, j;
+ int ret = 0;
+
+ a = BN_new();
+ p = BN_new();
+ r = BN_new();
+ if (a == NULL || p == NULL || r == NULL)
+ goto err;
+
+ BN_GENCB_set(&cb, genprime_cb, NULL);
+
+ for (i = 0; i < 16; i++) {
+ if (i < 8) {
+ unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
+
+ if (!BN_set_word(p, primes[i]))
+ goto err;
+ } else {
+ if (!BN_set_word(a, 32))
+ goto err;
+ if (!BN_set_word(r, 2 * i + 1))
+ goto err;
+
+ if (!BN_generate_prime_ex(p, 256, 0, a, r, &cb))
+ goto err;
+ putc('\n', stderr);
+ }
+ p->neg = rand_neg();
+
+ for (j = 0; j < num2; j++) {
+ /*
+ * construct 'a' such that it is a square modulo p, but in
+ * general not a proper square and not reduced modulo p
+ */
+ if (!BN_bntest_rand(r, 256, 0, 3))
+ goto err;
+ if (!BN_nnmod(r, r, p, ctx))
+ goto err;
+ if (!BN_mod_sqr(r, r, p, ctx))
+ goto err;
+ if (!BN_bntest_rand(a, 256, 0, 3))
+ goto err;
+ if (!BN_nnmod(a, a, p, ctx))
+ goto err;
+ if (!BN_mod_sqr(a, a, p, ctx))
+ goto err;
+ if (!BN_mul(a, a, r, ctx))
+ goto err;
+ if (rand_neg())
+ if (!BN_sub(a, a, p))
+ goto err;
+
+ if (!BN_mod_sqrt(r, a, p, ctx))
+ goto err;
+ if (!BN_mod_sqr(r, r, p, ctx))
+ goto err;
+
+ if (!BN_nnmod(a, a, p, ctx))
+ goto err;
+
+ if (BN_cmp(a, r) != 0) {
+ fprintf(stderr, "BN_mod_sqrt failed: a = ");
+ BN_print_fp(stderr, a);
+ fprintf(stderr, ", r = ");
+ BN_print_fp(stderr, r);
+ fprintf(stderr, ", p = ");
+ BN_print_fp(stderr, p);
+ fprintf(stderr, "\n");
+ goto err;
+ }
+
+ putc('.', stderr);
+ fflush(stderr);
+ }
+
+ putc('\n', stderr);
+ fflush(stderr);
+ }
+ ret = 1;
+ err:
+ if (a != NULL)
+ BN_free(a);
+ if (p != NULL)
+ BN_free(p);
+ if (r != NULL)
+ BN_free(r);
+ return ret;
+}
+
+int test_lshift(BIO *bp, BN_CTX *ctx, BIGNUM *a_)
+{
+ BIGNUM *a, *b, *c, *d;
+ int i;
+
+ b = BN_new();
+ c = BN_new();
+ d = BN_new();
+ BN_one(c);
+
+ if (a_)
+ a = a_;
+ else {
+ a = BN_new();
+ BN_bntest_rand(a, 200, 0, 0);
+ a->neg = rand_neg();
+ }
+ for (i = 0; i < num0; i++) {
+ BN_lshift(b, a, i + 1);
+ BN_add(c, c, c);
+ if (bp != NULL) {
+ if (!results) {
+ BN_print(bp, a);
+ BIO_puts(bp, " * ");
+ BN_print(bp, c);
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, b);
+ BIO_puts(bp, "\n");
+ }
+ BN_mul(d, a, c, ctx);
+ BN_sub(d, d, b);
+ if (!BN_is_zero(d)) {
+ fprintf(stderr, "Left shift test failed!\n");
+ fprintf(stderr, "a=");
+ BN_print_fp(stderr, a);
+ fprintf(stderr, "\nb=");
+ BN_print_fp(stderr, b);
+ fprintf(stderr, "\nc=");
+ BN_print_fp(stderr, c);
+ fprintf(stderr, "\nd=");
+ BN_print_fp(stderr, d);
+ fprintf(stderr, "\n");
+ return 0;
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ BN_free(d);
+ return (1);
+}
+
+int test_lshift1(BIO *bp)
+{
+ BIGNUM *a, *b, *c;
+ int i;
+
+ a = BN_new();
+ b = BN_new();
+ c = BN_new();
+
+ BN_bntest_rand(a, 200, 0, 0);
+ a->neg = rand_neg();
+ for (i = 0; i < num0; i++) {
+ BN_lshift1(b, a);
+ if (bp != NULL) {
+ if (!results) {
+ BN_print(bp, a);
+ BIO_puts(bp, " * 2");
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, b);
+ BIO_puts(bp, "\n");
+ }
+ BN_add(c, a, a);
+ BN_sub(a, b, c);
+ if (!BN_is_zero(a)) {
+ fprintf(stderr, "Left shift one test failed!\n");
+ return 0;
+ }
+
+ BN_copy(a, b);
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ return (1);
+}
+
+int test_rshift(BIO *bp, BN_CTX *ctx)
+{
+ BIGNUM *a, *b, *c, *d, *e;
+ int i;
+
+ a = BN_new();
+ b = BN_new();
+ c = BN_new();
+ d = BN_new();
+ e = BN_new();
+ BN_one(c);
+
+ BN_bntest_rand(a, 200, 0, 0);
+ a->neg = rand_neg();
+ for (i = 0; i < num0; i++) {
+ BN_rshift(b, a, i + 1);
+ BN_add(c, c, c);
+ if (bp != NULL) {
+ if (!results) {
+ BN_print(bp, a);
+ BIO_puts(bp, " / ");
+ BN_print(bp, c);
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, b);
+ BIO_puts(bp, "\n");
+ }
+ BN_div(d, e, a, c, ctx);
+ BN_sub(d, d, b);
+ if (!BN_is_zero(d)) {
+ fprintf(stderr, "Right shift test failed!\n");
+ return 0;
+ }
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ BN_free(d);
+ BN_free(e);
+ return (1);
+}
+
+int test_rshift1(BIO *bp)
+{
+ BIGNUM *a, *b, *c;
+ int i;
+
+ a = BN_new();
+ b = BN_new();
+ c = BN_new();
+
+ BN_bntest_rand(a, 200, 0, 0);
+ a->neg = rand_neg();
+ for (i = 0; i < num0; i++) {
+ BN_rshift1(b, a);
+ if (bp != NULL) {
+ if (!results) {
+ BN_print(bp, a);
+ BIO_puts(bp, " / 2");
+ BIO_puts(bp, " - ");
+ }
+ BN_print(bp, b);
+ BIO_puts(bp, "\n");
+ }
+ BN_sub(c, a, b);
+ BN_sub(c, c, b);
+ if (!BN_is_zero(c) && !BN_abs_is_word(c, 1)) {
+ fprintf(stderr, "Right shift one test failed!\n");
+ return 0;
+ }
+ BN_copy(a, b);
+ }
+ BN_free(a);
+ BN_free(b);
+ BN_free(c);
+ return (1);
+}
+
+int rand_neg(void)
+{
+ static unsigned int neg = 0;
+ static int sign[8] = { 0, 0, 0, 1, 1, 0, 1, 1 };
+
+ return (sign[(neg++) % 8]);
+}
diff --git a/openssl/bn/divtest.c b/openssl/bn/divtest.c
new file mode 100644
index 0000000..2590b45
--- /dev/null
+++ b/openssl/bn/divtest.c
@@ -0,0 +1,42 @@
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+
+static int Rand(n)
+{
+ unsigned char x[2];
+ RAND_pseudo_bytes(x, 2);
+ return (x[0] + 2 * x[1]);
+}
+
+static void bug(char *m, BIGNUM *a, BIGNUM *b)
+{
+ printf("%s!\na=", m);
+ BN_print_fp(stdout, a);
+ printf("\nb=");
+ BN_print_fp(stdout, b);
+ printf("\n");
+ fflush(stdout);
+}
+
+main()
+{
+ BIGNUM *a = BN_new(), *b = BN_new(), *c = BN_new(), *d = BN_new(),
+ *C = BN_new(), *D = BN_new();
+ BN_RECP_CTX *recp = BN_RECP_CTX_new();
+ BN_CTX *ctx = BN_CTX_new();
+
+ for (;;) {
+ BN_pseudo_rand(a, Rand(), 0, 0);
+ BN_pseudo_rand(b, Rand(), 0, 0);
+ if (BN_is_zero(b))
+ continue;
+
+ BN_RECP_CTX_set(recp, b, ctx);
+ if (BN_div(C, D, a, b, ctx) != 1)
+ bug("BN_div failed", a, b);
+ if (BN_div_recp(c, d, a, recp, ctx) != 1)
+ bug("BN_div_recp failed", a, b);
+ else if (BN_cmp(c, C) != 0 || BN_cmp(c, C) != 0)
+ bug("mismatch", a, b);
+ }
+}
diff --git a/openssl/bn/exp.c b/openssl/bn/exp.c
new file mode 100644
index 0000000..fbce28c
--- /dev/null
+++ b/openssl/bn/exp.c
@@ -0,0 +1,61 @@
+/* unused */
+
+#include <stdio.h>
+#include <openssl/tmdiff.h>
+#include "bn_lcl.h"
+
+#define SIZE 256
+#define NUM (8*8*8)
+#define MOD (8*8*8*8*8)
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ BN_CTX ctx;
+ BIGNUM a, b, c, r, rr, t, l;
+ int j, i, size = SIZE, num = NUM, mod = MOD;
+ char *start, *end;
+ BN_MONT_CTX mont;
+ double d, md;
+
+ BN_MONT_CTX_init(&mont);
+ BN_CTX_init(&ctx);
+ BN_init(&a);
+ BN_init(&b);
+ BN_init(&c);
+ BN_init(&r);
+
+ start = ms_time_new();
+ end = ms_time_new();
+ while (size <= 1024 * 8) {
+ BN_rand(&a, size, 0, 0);
+ BN_rand(&b, size, 1, 0);
+ BN_rand(&c, size, 0, 1);
+
+ BN_mod(&a, &a, &c, &ctx);
+
+ ms_time_get(start);
+ for (i = 0; i < 10; i++)
+ BN_MONT_CTX_set(&mont, &c, &ctx);
+ ms_time_get(end);
+ md = ms_time_diff(start, end);
+
+ ms_time_get(start);
+ for (i = 0; i < num; i++) {
+ /* bn_mull(&r,&a,&b,&ctx); */
+ /* BN_sqr(&r,&a,&ctx); */
+ BN_mod_exp_mont(&r, &a, &b, &c, &ctx, &mont);
+ }
+ ms_time_get(end);
+ d = ms_time_diff(start, end) /* *50/33 */ ;
+ printf("%5d bit:%6.2f %6d %6.4f %4d m_set(%5.4f)\n", size,
+ d, num, d / num, (int)((d / num) * mod), md / 10.0);
+ num /= 8;
+ mod /= 8;
+ if (num <= 0)
+ num = 1;
+ size *= 2;
+ }
+
+}
diff --git a/openssl/bn/expspeed.c b/openssl/bn/expspeed.c
new file mode 100644
index 0000000..513a568
--- /dev/null
+++ b/openssl/bn/expspeed.c
@@ -0,0 +1,381 @@
+/* unused */
+
+/* crypto/bn/expspeed.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* most of this code has been pilfered from my libdes speed.c program */
+
+#define BASENUM 5000
+#define NUM_START 0
+
+/*
+ * determine timings for modexp, modmul, modsqr, gcd, Kronecker symbol,
+ * modular inverse, or modular square roots
+ */
+#define TEST_EXP
+#undef TEST_MUL
+#undef TEST_SQR
+#undef TEST_GCD
+#undef TEST_KRON
+#undef TEST_INV
+#undef TEST_SQRT
+#define P_MOD_64 9 /* least significant 6 bits for prime to be
+ * used for BN_sqrt timings */
+
+#if defined(TEST_EXP) + defined(TEST_MUL) + defined(TEST_SQR) + defined(TEST_GCD) + defined(TEST_KRON) + defined(TEST_INV) +defined(TEST_SQRT) != 1
+# error "choose one test"
+#endif
+
+#if defined(TEST_INV) || defined(TEST_SQRT)
+# define C_PRIME
+static void genprime_cb(int p, int n, void *arg);
+#endif
+
+#undef PROG
+#define PROG bnspeed_main
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
+# define TIMES
+#endif
+
+#ifndef _IRIX
+# include <time.h>
+#endif
+#ifdef TIMES
+# include <sys/types.h>
+# include <sys/times.h>
+#endif
+
+/*
+ * Depending on the VMS version, the tms structure is perhaps defined. The
+ * __TMS macro will show if it was. If it wasn't defined, we should undefine
+ * TIMES, since that tells the rest of the program how things should be
+ * handled. -- Richard Levitte
+ */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
+# undef TIMES
+#endif
+
+#ifndef TIMES
+# include <sys/timeb.h>
+#endif
+
+#if defined(sun) || defined(__ultrix)
+# define _POSIX_SOURCE
+# include <limits.h>
+# include <sys/param.h>
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+
+/* The following if from times(3) man page. It may need to be changed */
+#ifndef HZ
+# ifndef CLK_TCK
+# ifndef _BSD_CLK_TCK_ /* FreeBSD hack */
+# define HZ 100.0
+# else /* _BSD_CLK_TCK_ */
+# define HZ ((double)_BSD_CLK_TCK_)
+# endif
+# else /* CLK_TCK */
+# define HZ ((double)CLK_TCK)
+# endif
+#endif
+
+#undef BUFSIZE
+#define BUFSIZE ((long)1024*8)
+int run = 0;
+
+static double Time_F(int s);
+#define START 0
+#define STOP 1
+
+static double Time_F(int s)
+{
+ double ret;
+#ifdef TIMES
+ static struct tms tstart, tend;
+
+ if (s == START) {
+ times(&tstart);
+ return (0);
+ } else {
+ times(&tend);
+ ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ;
+ return ((ret < 1e-3) ? 1e-3 : ret);
+ }
+#else /* !times() */
+ static struct timeb tstart, tend;
+ long i;
+
+ if (s == START) {
+ ftime(&tstart);
+ return (0);
+ } else {
+ ftime(&tend);
+ i = (long)tend.millitm - (long)tstart.millitm;
+ ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1000.0;
+ return ((ret < 0.001) ? 0.001 : ret);
+ }
+#endif
+}
+
+#define NUM_SIZES 7
+#if NUM_START > NUM_SIZES
+# error "NUM_START > NUM_SIZES"
+#endif
+static int sizes[NUM_SIZES] = { 128, 256, 512, 1024, 2048, 4096, 8192 };
+
+static int mul_c[NUM_SIZES] =
+ { 8 * 8 * 8 * 8 * 8 * 8, 8 * 8 * 8 * 8 * 8, 8 * 8 * 8 * 8, 8 * 8 * 8,
+ 8 * 8, 8, 1
+};
+
+/*
+ * static int sizes[NUM_SIZES]={59,179,299,419,539};
+ */
+
+#define RAND_SEED(string) { const char str[] = string; RAND_seed(string, sizeof str); }
+
+void do_mul_exp(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx);
+
+int main(int argc, char **argv)
+{
+ BN_CTX *ctx;
+ BIGNUM *a, *b, *c, *r;
+
+#if 1
+ if (!CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0))
+ abort();
+#endif
+
+ ctx = BN_CTX_new();
+ a = BN_new();
+ b = BN_new();
+ c = BN_new();
+ r = BN_new();
+
+ while (!RAND_status())
+ /* not enough bits */
+ RAND_SEED("I demand a manual recount!");
+
+ do_mul_exp(r, a, b, c, ctx);
+ return 0;
+}
+
+void do_mul_exp(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx)
+{
+ int i, k;
+ double tm;
+ long num;
+
+ num = BASENUM;
+ for (i = NUM_START; i < NUM_SIZES; i++) {
+#ifdef C_PRIME
+# ifdef TEST_SQRT
+ if (!BN_set_word(a, 64))
+ goto err;
+ if (!BN_set_word(b, P_MOD_64))
+ goto err;
+# define ADD a
+# define REM b
+# else
+# define ADD NULL
+# define REM NULL
+# endif
+ if (!BN_generate_prime(c, sizes[i], 0, ADD, REM, genprime_cb, NULL))
+ goto err;
+ putc('\n', stderr);
+ fflush(stderr);
+#endif
+
+ for (k = 0; k < num; k++) {
+ if (k % 50 == 0) { /* Average over num/50 different choices of
+ * random numbers. */
+ if (!BN_pseudo_rand(a, sizes[i], 1, 0))
+ goto err;
+
+ if (!BN_pseudo_rand(b, sizes[i], 1, 0))
+ goto err;
+
+#ifndef C_PRIME
+ if (!BN_pseudo_rand(c, sizes[i], 1, 1))
+ goto err;
+#endif
+
+#ifdef TEST_SQRT
+ if (!BN_mod_sqr(a, a, c, ctx))
+ goto err;
+ if (!BN_mod_sqr(b, b, c, ctx))
+ goto err;
+#else
+ if (!BN_nnmod(a, a, c, ctx))
+ goto err;
+ if (!BN_nnmod(b, b, c, ctx))
+ goto err;
+#endif
+
+ if (k == 0)
+ Time_F(START);
+ }
+#if defined(TEST_EXP)
+ if (!BN_mod_exp(r, a, b, c, ctx))
+ goto err;
+#elif defined(TEST_MUL)
+ {
+ int i = 0;
+ for (i = 0; i < 50; i++)
+ if (!BN_mod_mul(r, a, b, c, ctx))
+ goto err;
+ }
+#elif defined(TEST_SQR)
+ {
+ int i = 0;
+ for (i = 0; i < 50; i++) {
+ if (!BN_mod_sqr(r, a, c, ctx))
+ goto err;
+ if (!BN_mod_sqr(r, b, c, ctx))
+ goto err;
+ }
+ }
+#elif defined(TEST_GCD)
+ if (!BN_gcd(r, a, b, ctx))
+ goto err;
+ if (!BN_gcd(r, b, c, ctx))
+ goto err;
+ if (!BN_gcd(r, c, a, ctx))
+ goto err;
+#elif defined(TEST_KRON)
+ if (-2 == BN_kronecker(a, b, ctx))
+ goto err;
+ if (-2 == BN_kronecker(b, c, ctx))
+ goto err;
+ if (-2 == BN_kronecker(c, a, ctx))
+ goto err;
+#elif defined(TEST_INV)
+ if (!BN_mod_inverse(r, a, c, ctx))
+ goto err;
+ if (!BN_mod_inverse(r, b, c, ctx))
+ goto err;
+#else /* TEST_SQRT */
+ if (!BN_mod_sqrt(r, a, c, ctx))
+ goto err;
+ if (!BN_mod_sqrt(r, b, c, ctx))
+ goto err;
+#endif
+ }
+ tm = Time_F(STOP);
+ printf(
+#if defined(TEST_EXP)
+ "modexp %4d ^ %4d %% %4d"
+#elif defined(TEST_MUL)
+ "50*modmul %4d %4d %4d"
+#elif defined(TEST_SQR)
+ "100*modsqr %4d %4d %4d"
+#elif defined(TEST_GCD)
+ "3*gcd %4d %4d %4d"
+#elif defined(TEST_KRON)
+ "3*kronecker %4d %4d %4d"
+#elif defined(TEST_INV)
+ "2*inv %4d %4d mod %4d"
+#else /* TEST_SQRT */
+ "2*sqrt [prime == %d (mod 64)] %4d %4d mod %4d"
+#endif
+ " -> %8.6fms %5.1f (%ld)\n",
+#ifdef TEST_SQRT
+ P_MOD_64,
+#endif
+ sizes[i], sizes[i], sizes[i], tm * 1000.0 / num,
+ tm * mul_c[i] / num, num);
+ num /= 7;
+ if (num <= 0)
+ num = 1;
+ }
+ return;
+
+ err:
+ ERR_print_errors_fp(stderr);
+}
+
+#ifdef C_PRIME
+static void genprime_cb(int p, int n, void *arg)
+{
+ char c = '*';
+
+ if (p == 0)
+ c = '.';
+ if (p == 1)
+ c = '+';
+ if (p == 2)
+ c = '*';
+ if (p == 3)
+ c = '\n';
+ putc(c, stderr);
+ fflush(stderr);
+ (void)n;
+ (void)arg;
+}
+#endif
diff --git a/openssl/bn/exptest.c b/openssl/bn/exptest.c
new file mode 100644
index 0000000..8b3a4ba
--- /dev/null
+++ b/openssl/bn/exptest.c
@@ -0,0 +1,249 @@
+/* crypto/bn/exptest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+#define NUM_BITS (BN_BITS*2)
+
+static const char rnd_seed[] =
+ "string to make the random number generator think it has entropy";
+
+/*
+ * test_exp_mod_zero tests that x**0 mod 1 == 0. It returns zero on success.
+ */
+static int test_exp_mod_zero()
+{
+ BIGNUM a, p, m;
+ BIGNUM r;
+ BN_CTX *ctx = BN_CTX_new();
+ int ret = 1;
+
+ BN_init(&m);
+ BN_one(&m);
+
+ BN_init(&a);
+ BN_one(&a);
+
+ BN_init(&p);
+ BN_zero(&p);
+
+ BN_init(&r);
+ BN_mod_exp(&r, &a, &p, &m, ctx);
+ BN_CTX_free(ctx);
+
+ if (BN_is_zero(&r))
+ ret = 0;
+ else {
+ printf("1**0 mod 1 = ");
+ BN_print_fp(stdout, &r);
+ printf(", should be 0\n");
+ }
+
+ BN_free(&r);
+ BN_free(&a);
+ BN_free(&p);
+ BN_free(&m);
+
+ return ret;
+}
+
+int main(int argc, char *argv[])
+{
+ BN_CTX *ctx;
+ BIO *out = NULL;
+ int i, ret;
+ unsigned char c;
+ BIGNUM *r_mont, *r_mont_const, *r_recp, *r_simple, *a, *b, *m;
+
+ RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we
+ * don't even check its return
+ * value (which we should) */
+
+ ERR_load_BN_strings();
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL)
+ EXIT(1);
+ r_mont = BN_new();
+ r_mont_const = BN_new();
+ r_recp = BN_new();
+ r_simple = BN_new();
+ a = BN_new();
+ b = BN_new();
+ m = BN_new();
+ if ((r_mont == NULL) || (r_recp == NULL) || (a == NULL) || (b == NULL))
+ goto err;
+
+ out = BIO_new(BIO_s_file());
+
+ if (out == NULL)
+ EXIT(1);
+ BIO_set_fp(out, stdout, BIO_NOCLOSE);
+
+ for (i = 0; i < 200; i++) {
+ RAND_bytes(&c, 1);
+ c = (c % BN_BITS) - BN_BITS2;
+ BN_rand(a, NUM_BITS + c, 0, 0);
+
+ RAND_bytes(&c, 1);
+ c = (c % BN_BITS) - BN_BITS2;
+ BN_rand(b, NUM_BITS + c, 0, 0);
+
+ RAND_bytes(&c, 1);
+ c = (c % BN_BITS) - BN_BITS2;
+ BN_rand(m, NUM_BITS + c, 0, 1);
+
+ BN_mod(a, a, m, ctx);
+ BN_mod(b, b, m, ctx);
+
+ ret = BN_mod_exp_mont(r_mont, a, b, m, ctx, NULL);
+ if (ret <= 0) {
+ printf("BN_mod_exp_mont() problems\n");
+ ERR_print_errors(out);
+ EXIT(1);
+ }
+
+ ret = BN_mod_exp_recp(r_recp, a, b, m, ctx);
+ if (ret <= 0) {
+ printf("BN_mod_exp_recp() problems\n");
+ ERR_print_errors(out);
+ EXIT(1);
+ }
+
+ ret = BN_mod_exp_simple(r_simple, a, b, m, ctx);
+ if (ret <= 0) {
+ printf("BN_mod_exp_simple() problems\n");
+ ERR_print_errors(out);
+ EXIT(1);
+ }
+
+ ret = BN_mod_exp_mont_consttime(r_mont_const, a, b, m, ctx, NULL);
+ if (ret <= 0) {
+ printf("BN_mod_exp_mont_consttime() problems\n");
+ ERR_print_errors(out);
+ EXIT(1);
+ }
+
+ if (BN_cmp(r_simple, r_mont) == 0
+ && BN_cmp(r_simple, r_recp) == 0
+ && BN_cmp(r_simple, r_mont_const) == 0) {
+ printf(".");
+ fflush(stdout);
+ } else {
+ if (BN_cmp(r_simple, r_mont) != 0)
+ printf("\nsimple and mont results differ\n");
+ if (BN_cmp(r_simple, r_mont_const) != 0)
+ printf("\nsimple and mont const time results differ\n");
+ if (BN_cmp(r_simple, r_recp) != 0)
+ printf("\nsimple and recp results differ\n");
+
+ printf("a (%3d) = ", BN_num_bits(a));
+ BN_print(out, a);
+ printf("\nb (%3d) = ", BN_num_bits(b));
+ BN_print(out, b);
+ printf("\nm (%3d) = ", BN_num_bits(m));
+ BN_print(out, m);
+ printf("\nsimple =");
+ BN_print(out, r_simple);
+ printf("\nrecp =");
+ BN_print(out, r_recp);
+ printf("\nmont =");
+ BN_print(out, r_mont);
+ printf("\nmont_ct =");
+ BN_print(out, r_mont_const);
+ printf("\n");
+ EXIT(1);
+ }
+ }
+ BN_free(r_mont);
+ BN_free(r_mont_const);
+ BN_free(r_recp);
+ BN_free(r_simple);
+ BN_free(a);
+ BN_free(b);
+ BN_free(m);
+ BN_CTX_free(ctx);
+ ERR_remove_thread_state(NULL);
+ CRYPTO_mem_leaks(out);
+ BIO_free(out);
+ printf("\n");
+
+ if (test_exp_mod_zero() != 0)
+ goto err;
+
+ printf("done\n");
+
+ EXIT(0);
+ err:
+ ERR_load_crypto_strings();
+ ERR_print_errors(out);
+#ifdef OPENSSL_SYS_NETWARE
+ printf("ERROR\n");
+#endif
+ EXIT(1);
+ return (1);
+}
diff --git a/openssl/bn/todo b/openssl/bn/todo
new file mode 100644
index 0000000..e47e381
--- /dev/null
+++ b/openssl/bn/todo
@@ -0,0 +1,3 @@
+Cache RECP_CTX values
+make the result argument independant of the inputs.
+split up the _exp_ functions
diff --git a/openssl/bn/vms-helper.c b/openssl/bn/vms-helper.c
new file mode 100644
index 0000000..f342e90
--- /dev/null
+++ b/openssl/bn/vms-helper.c
@@ -0,0 +1,68 @@
+/* vms-helper.c */
+/* ====================================================================
+ * Copyright (c) 1999 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 <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+bn_div_words_abort(int i)
+{
+#ifdef BN_DEBUG
+# if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
+ fprintf(stderr, "Division would overflow (%d)\n", i);
+# endif
+ abort();
+#endif
+}
diff --git a/openssl/buffer.h b/openssl/buffer.h
new file mode 120000
index 0000000..cb180d0
--- /dev/null
+++ b/openssl/buffer.h
@@ -0,0 +1 @@
+buffer/buffer.h
\ No newline at end of file
diff --git a/openssl/buffer/buffer.h b/openssl/buffer/buffer.h
new file mode 100644
index 0000000..632df93
--- /dev/null
+++ b/openssl/buffer/buffer.h
@@ -0,0 +1,118 @@
+/* crypto/buffer/buffer.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BUFFER_H
+# define HEADER_BUFFER_H
+
+# include <openssl/ossl_typ.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# include <stddef.h>
+
+# if !defined(NO_SYS_TYPES_H)
+# include <sys/types.h>
+# endif
+
+/* Already declared in ossl_typ.h */
+/* typedef struct buf_mem_st BUF_MEM; */
+
+struct buf_mem_st {
+ size_t length; /* current number of bytes */
+ char *data;
+ size_t max; /* size of buffer */
+};
+
+BUF_MEM *BUF_MEM_new(void);
+void BUF_MEM_free(BUF_MEM *a);
+int BUF_MEM_grow(BUF_MEM *str, size_t len);
+int BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
+char *BUF_strdup(const char *str);
+char *BUF_strndup(const char *str, size_t siz);
+void *BUF_memdup(const void *data, size_t siz);
+void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz);
+
+/* safe string functions */
+size_t BUF_strlcpy(char *dst, const char *src, size_t siz);
+size_t BUF_strlcat(char *dst, const char *src, size_t siz);
+
+/* 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.
+ */
+void ERR_load_BUF_strings(void);
+
+/* Error codes for the BUF functions. */
+
+/* Function codes. */
+# define BUF_F_BUF_MEMDUP 103
+# define BUF_F_BUF_MEM_GROW 100
+# define BUF_F_BUF_MEM_GROW_CLEAN 105
+# define BUF_F_BUF_MEM_NEW 101
+# define BUF_F_BUF_STRDUP 102
+# define BUF_F_BUF_STRNDUP 104
+
+/* Reason codes. */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/crypto.h b/openssl/crypto.h
new file mode 100644
index 0000000..c450d7a
--- /dev/null
+++ b/openssl/crypto.h
@@ -0,0 +1,661 @@
+/* crypto/crypto.h */
+/* ====================================================================
+ * Copyright (c) 1998-2006 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.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * 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
+
+# include <stdlib.h>
+
+# include <openssl/e_os2.h>
+
+# ifndef OPENSSL_NO_FP_API
+# include <stdio.h>
+# endif
+
+# include <openssl/stack.h>
+# include <openssl/safestack.h>
+# include <openssl/opensslv.h>
+# include <openssl/ossl_typ.h>
+
+# ifdef CHARSET_EBCDIC
+# include <openssl/ebcdic.h>
+# endif
+
+/*
+ * Resolve problems on some operating systems with symbol names that clash
+ * one way or another
+ */
+# include <openssl/symhacks.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Backward compatibility to SSLeay */
+/*
+ * This is more to be used to check the correct DLL is being used in the MS
+ * world.
+ */
+# define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER
+# define SSLEAY_VERSION 0
+/* #define SSLEAY_OPTIONS 1 no longer supported */
+# define SSLEAY_CFLAGS 2
+# define SSLEAY_BUILT_ON 3
+# define SSLEAY_PLATFORM 4
+# define SSLEAY_DIR 5
+
+/* Already declared in ossl_typ.h */
+# if 0
+typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
+/* Called when a new object is created */
+typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+ int idx, long argl, void *argp);
+/* Called when an object is free()ed */
+typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+ int idx, long argl, void *argp);
+/* Called when we need to dup an object */
+typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from,
+ void *from_d, int idx, long argl, void *argp);
+# endif
+
+/* A generic structure to pass assorted data in a expandable way */
+typedef struct openssl_item_st {
+ int code;
+ void *value; /* Not used for flag attributes */
+ size_t value_size; /* Max size of value for output, length for
+ * input */
+ size_t *value_length; /* Returned length of value for output */
+} OPENSSL_ITEM;
+
+/*
+ * When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock
+ * 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_X509_CRL 6
+# define CRYPTO_LOCK_X509_REQ 7
+# define CRYPTO_LOCK_DSA 8
+# define CRYPTO_LOCK_RSA 9
+# define CRYPTO_LOCK_EVP_PKEY 10
+# define CRYPTO_LOCK_X509_STORE 11
+# define CRYPTO_LOCK_SSL_CTX 12
+# define CRYPTO_LOCK_SSL_CERT 13
+# define CRYPTO_LOCK_SSL_SESSION 14
+# define CRYPTO_LOCK_SSL_SESS_CERT 15
+# define CRYPTO_LOCK_SSL 16
+# define CRYPTO_LOCK_SSL_METHOD 17
+# define CRYPTO_LOCK_RAND 18
+# define CRYPTO_LOCK_RAND2 19
+# define CRYPTO_LOCK_MALLOC 20
+# define CRYPTO_LOCK_BIO 21
+# define CRYPTO_LOCK_GETHOSTBYNAME 22
+# define CRYPTO_LOCK_GETSERVBYNAME 23
+# define CRYPTO_LOCK_READDIR 24
+# define CRYPTO_LOCK_RSA_BLINDING 25
+# define CRYPTO_LOCK_DH 26
+# define CRYPTO_LOCK_MALLOC2 27
+# define CRYPTO_LOCK_DSO 28
+# define CRYPTO_LOCK_DYNLOCK 29
+# define CRYPTO_LOCK_ENGINE 30
+# define CRYPTO_LOCK_UI 31
+# define CRYPTO_LOCK_ECDSA 32
+# define CRYPTO_LOCK_EC 33
+# define CRYPTO_LOCK_ECDH 34
+# define CRYPTO_LOCK_BN 35
+# define CRYPTO_LOCK_EC_PRE_COMP 36
+# define CRYPTO_LOCK_STORE 37
+# define CRYPTO_LOCK_COMP 38
+# define CRYPTO_LOCK_FIPS 39
+# define CRYPTO_LOCK_FIPS2 40
+# define CRYPTO_NUM_LOCKS 41
+
+# define CRYPTO_LOCK 1
+# define CRYPTO_UNLOCK 2
+# define CRYPTO_READ 4
+# define CRYPTO_WRITE 8
+
+# ifndef OPENSSL_NO_LOCKING
+# ifndef CRYPTO_w_lock
+# define CRYPTO_w_lock(type) \
+ CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+# define CRYPTO_w_unlock(type) \
+ CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+# define CRYPTO_r_lock(type) \
+ CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+# define CRYPTO_r_unlock(type) \
+ CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+# define CRYPTO_add(addr,amount,type) \
+ CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
+# endif
+# else
+# define CRYPTO_w_lock(a)
+# define CRYPTO_w_unlock(a)
+# define CRYPTO_r_lock(a)
+# define CRYPTO_r_unlock(a)
+# define CRYPTO_add(a,b,c) ((*(a))+=(b))
+# endif
+
+/*
+ * Some applications as well as some parts of OpenSSL need to allocate and
+ * deallocate locks in a dynamic fashion. The following typedef makes this
+ * possible in a type-safe manner.
+ */
+/* struct CRYPTO_dynlock_value has to be defined by the application. */
+typedef struct {
+ int references;
+ struct CRYPTO_dynlock_value *data;
+} CRYPTO_dynlock;
+
+/*
+ * The following can be used to detect memory leaks in the SSLeay library. It
+ * used, it turns on malloc checking
+ */
+
+# define CRYPTO_MEM_CHECK_OFF 0x0/* an enume */
+# define CRYPTO_MEM_CHECK_ON 0x1/* a bit */
+# define CRYPTO_MEM_CHECK_ENABLE 0x2/* a bit */
+# define CRYPTO_MEM_CHECK_DISABLE 0x3/* an enume */
+
+/*
+ * The following are bit values to turn on or off options connected to the
+ * malloc checking functionality
+ */
+
+/* Adds time to the memory checking information */
+# define V_CRYPTO_MDEBUG_TIME 0x1/* a bit */
+/* Adds thread number to the memory checking information */
+# define V_CRYPTO_MDEBUG_THREAD 0x2/* a bit */
+
+# define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD)
+
+/* predec of the BIO type */
+typedef struct bio_st BIO_dummy;
+
+struct crypto_ex_data_st {
+ STACK_OF(void) *sk;
+ /* gcc is screwing up this data structure :-( */
+ int dummy;
+};
+DECLARE_STACK_OF(void)
+
+/*
+ * This stuff is basically class callback functions The current classes are
+ * SSL_CTX, SSL, SSL_SESSION, and a few more
+ */
+
+typedef struct crypto_ex_data_func_st {
+ long argl; /* Arbitary long */
+ void *argp; /* Arbitary void * */
+ CRYPTO_EX_new *new_func;
+ CRYPTO_EX_free *free_func;
+ CRYPTO_EX_dup *dup_func;
+} CRYPTO_EX_DATA_FUNCS;
+
+DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS)
+
+/*
+ * Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA
+ * entry.
+ */
+
+# define CRYPTO_EX_INDEX_BIO 0
+# define CRYPTO_EX_INDEX_SSL 1
+# define CRYPTO_EX_INDEX_SSL_CTX 2
+# define CRYPTO_EX_INDEX_SSL_SESSION 3
+# define CRYPTO_EX_INDEX_X509_STORE 4
+# define CRYPTO_EX_INDEX_X509_STORE_CTX 5
+# define CRYPTO_EX_INDEX_RSA 6
+# define CRYPTO_EX_INDEX_DSA 7
+# define CRYPTO_EX_INDEX_DH 8
+# 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
+# define CRYPTO_EX_INDEX_STORE 15
+
+/*
+ * Dynamically assigned indexes start from this value (don't use directly,
+ * use via CRYPTO_ex_data_new_class).
+ */
+# define CRYPTO_EX_INDEX_USER 100
+
+/*
+ * This is the default callbacks, but we can have others as well: this is
+ * needed in Win32 where the application malloc and the library malloc may
+ * not be the same.
+ */
+# define CRYPTO_malloc_init() CRYPTO_set_mem_functions(\
+ malloc, realloc, free)
+
+# if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD
+# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */
+# define CRYPTO_MDEBUG
+# endif
+# endif
+
+/*
+ * Set standard debugging functions (not done by default unless CRYPTO_MDEBUG
+ * is defined)
+ */
+# define CRYPTO_malloc_debug_init() do {\
+ CRYPTO_set_mem_debug_functions(\
+ CRYPTO_dbg_malloc,\
+ CRYPTO_dbg_realloc,\
+ CRYPTO_dbg_free,\
+ CRYPTO_dbg_set_options,\
+ CRYPTO_dbg_get_options);\
+ } while(0)
+
+int CRYPTO_mem_ctrl(int mode);
+int CRYPTO_is_mem_check_on(void);
+
+/* for applications */
+# define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON)
+# define MemCheck_stop() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF)
+
+/* for library-internal use */
+# define MemCheck_on() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE)
+# define MemCheck_off() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE)
+# define is_MemCheck_on() CRYPTO_is_mem_check_on()
+
+# define OPENSSL_malloc(num) CRYPTO_malloc((int)num,__FILE__,__LINE__)
+# define OPENSSL_strdup(str) CRYPTO_strdup((str),__FILE__,__LINE__)
+# define OPENSSL_realloc(addr,num) \
+ CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__)
+# define OPENSSL_realloc_clean(addr,old_num,num) \
+ CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__)
+# define OPENSSL_remalloc(addr,num) \
+ CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__)
+# define OPENSSL_freeFunc CRYPTO_free
+# define OPENSSL_free(addr) CRYPTO_free(addr)
+
+# define OPENSSL_malloc_locked(num) \
+ CRYPTO_malloc_locked((int)num,__FILE__,__LINE__)
+# define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr)
+
+const char *SSLeay_version(int type);
+unsigned long SSLeay(void);
+
+int OPENSSL_issetugid(void);
+
+/* An opaque type representing an implementation of "ex_data" support */
+typedef struct st_CRYPTO_EX_DATA_IMPL CRYPTO_EX_DATA_IMPL;
+/* Return an opaque pointer to the current "ex_data" implementation */
+const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void);
+/* Sets the "ex_data" implementation to be used (if it's not too late) */
+int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i);
+/* Get a new "ex_data" class, and return the corresponding "class_index" */
+int CRYPTO_ex_data_new_class(void);
+/* Within a given class, get/register a new index */
+int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
+ CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func);
+/*
+ * Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a
+ * given class (invokes whatever per-class callbacks are applicable)
+ */
+int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+ CRYPTO_EX_DATA *from);
+void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+/*
+ * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular
+ * index (relative to the class type involved)
+ */
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
+void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx);
+/*
+ * This function cleans up all "ex_data" state. It mustn't be called under
+ * potential race-conditions.
+ */
+void CRYPTO_cleanup_all_ex_data(void);
+
+int CRYPTO_get_new_lockid(char *name);
+
+int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */
+void CRYPTO_lock(int mode, int type, const char *file, int line);
+void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
+ const char *file, int line));
+void (*CRYPTO_get_locking_callback(void)) (int mode, int type,
+ const char *file, int line);
+void CRYPTO_set_add_lock_callback(int (*func)
+ (int *num, int mount, int type,
+ const char *file, int line));
+int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type,
+ const char *file, int line);
+
+/* Don't use this structure directly. */
+typedef struct crypto_threadid_st {
+ void *ptr;
+ unsigned long val;
+} CRYPTO_THREADID;
+/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
+void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
+void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
+int CRYPTO_THREADID_set_callback(void (*threadid_func) (CRYPTO_THREADID *));
+void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *);
+void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
+int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b);
+void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src);
+unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
+# ifndef OPENSSL_NO_DEPRECATED
+void CRYPTO_set_id_callback(unsigned long (*func) (void));
+unsigned long (*CRYPTO_get_id_callback(void)) (void);
+unsigned long CRYPTO_thread_id(void);
+# endif
+
+const char *CRYPTO_get_lock_name(int type);
+int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
+ int line);
+
+int CRYPTO_get_new_dynlockid(void);
+void CRYPTO_destroy_dynlockid(int i);
+struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i);
+void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value
+ *(*dyn_create_function) (const char
+ *file,
+ int line));
+void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)
+ (int mode,
+ struct CRYPTO_dynlock_value *l,
+ const char *file, int line));
+void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)
+ (struct CRYPTO_dynlock_value *l,
+ const char *file, int line));
+struct CRYPTO_dynlock_value
+*(*CRYPTO_get_dynlock_create_callback(void)) (const char *file, int line);
+void (*CRYPTO_get_dynlock_lock_callback(void)) (int mode,
+ struct CRYPTO_dynlock_value
+ *l, const char *file,
+ int line);
+void (*CRYPTO_get_dynlock_destroy_callback(void)) (struct CRYPTO_dynlock_value
+ *l, const char *file,
+ int line);
+
+/*
+ * CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions -- call
+ * the latter last if you need different functions
+ */
+int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t),
+ void (*f) (void *));
+int CRYPTO_set_locked_mem_functions(void *(*m) (size_t),
+ void (*free_func) (void *));
+int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
+ void *(*r) (void *, size_t, const char *,
+ int), void (*f) (void *));
+int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int),
+ void (*free_func) (void *));
+int CRYPTO_set_mem_debug_functions(void (*m)
+ (void *, int, const char *, int, int),
+ void (*r) (void *, void *, int,
+ const char *, int, int),
+ void (*f) (void *, int), void (*so) (long),
+ long (*go) (void));
+void CRYPTO_get_mem_functions(void *(**m) (size_t),
+ void *(**r) (void *, size_t),
+ void (**f) (void *));
+void CRYPTO_get_locked_mem_functions(void *(**m) (size_t),
+ void (**f) (void *));
+void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int),
+ void *(**r) (void *, size_t, const char *,
+ int), void (**f) (void *));
+void CRYPTO_get_locked_mem_ex_functions(void
+ *(**m) (size_t, const char *, int),
+ void (**f) (void *));
+void CRYPTO_get_mem_debug_functions(void (**m)
+ (void *, int, const char *, int, int),
+ void (**r) (void *, void *, int,
+ const char *, int, int),
+ void (**f) (void *, int),
+ void (**so) (long), long (**go) (void));
+
+void *CRYPTO_malloc_locked(int num, const char *file, int line);
+void CRYPTO_free_locked(void *ptr);
+void *CRYPTO_malloc(int num, const char *file, int line);
+char *CRYPTO_strdup(const char *str, const char *file, int line);
+void CRYPTO_free(void *ptr);
+void *CRYPTO_realloc(void *addr, int num, const char *file, int line);
+void *CRYPTO_realloc_clean(void *addr, int old_num, int num, const char *file,
+ int line);
+void *CRYPTO_remalloc(void *addr, int num, const char *file, int line);
+
+void OPENSSL_cleanse(void *ptr, size_t len);
+
+void CRYPTO_set_mem_debug_options(long bits);
+long CRYPTO_get_mem_debug_options(void);
+
+# define CRYPTO_push_info(info) \
+ CRYPTO_push_info_(info, __FILE__, __LINE__);
+int CRYPTO_push_info_(const char *info, const char *file, int line);
+int CRYPTO_pop_info(void);
+int CRYPTO_remove_all_info(void);
+
+/*
+ * Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro;
+ * used as default in CRYPTO_MDEBUG compilations):
+ */
+/*-
+ * The last argument has the following significance:
+ *
+ * 0: called before the actual memory allocation has taken place
+ * 1: called after the actual memory allocation has taken place
+ */
+void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
+ int before_p);
+void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, const char *file,
+ int line, int before_p);
+void CRYPTO_dbg_free(void *addr, int before_p);
+/*-
+ * Tell the debugging code about options. By default, the following values
+ * apply:
+ *
+ * 0: Clear all options.
+ * V_CRYPTO_MDEBUG_TIME (1): Set the "Show Time" option.
+ * V_CRYPTO_MDEBUG_THREAD (2): Set the "Show Thread Number" option.
+ * V_CRYPTO_MDEBUG_ALL (3): 1 + 2
+ */
+void CRYPTO_dbg_set_options(long bits);
+long CRYPTO_dbg_get_options(void);
+
+# ifndef OPENSSL_NO_FP_API
+void CRYPTO_mem_leaks_fp(FILE *);
+# endif
+void CRYPTO_mem_leaks(struct bio_st *bio);
+/* unsigned long order, char *file, int line, int num_bytes, char *addr */
+typedef void *CRYPTO_MEM_LEAK_CB (unsigned long, const char *, int, int,
+ void *);
+void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb);
+
+/* die if we have to */
+void OpenSSLDie(const char *file, int line, const char *assertion);
+# define OPENSSL_assert(e) (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1))
+
+unsigned long *OPENSSL_ia32cap_loc(void);
+# define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc()))
+int OPENSSL_isservice(void);
+
+int FIPS_mode(void);
+int FIPS_mode_set(int r);
+
+void OPENSSL_init(void);
+
+# define fips_md_init(alg) fips_md_init_ctx(alg, alg)
+
+# ifdef OPENSSL_FIPS
+# define fips_md_init_ctx(alg, cx) \
+ int alg##_Init(cx##_CTX *c) \
+ { \
+ if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
+ "Low level API call to digest " #alg " forbidden in FIPS mode!"); \
+ return private_##alg##_Init(c); \
+ } \
+ int private_##alg##_Init(cx##_CTX *c)
+
+# define fips_cipher_abort(alg) \
+ if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \
+ "Low level API call to cipher " #alg " forbidden in FIPS mode!")
+
+# else
+# define fips_md_init_ctx(alg, cx) \
+ int alg##_Init(cx##_CTX *c)
+# define fips_cipher_abort(alg) while(0)
+# endif
+
+/*
+ * CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal.
+ * It takes an amount of time dependent on |len|, but independent of the
+ * contents of |a| and |b|. Unlike memcmp, it cannot be used to put elements
+ * into a defined order as the return value when a != b is undefined, other
+ * than to be non-zero.
+ */
+int CRYPTO_memcmp(const void *a, const void *b, size_t len);
+
+/* 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.
+ */
+void ERR_load_CRYPTO_strings(void);
+
+/* Error codes for the CRYPTO functions. */
+
+/* Function codes. */
+# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100
+# define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID 103
+# define CRYPTO_F_CRYPTO_GET_NEW_LOCKID 101
+# define CRYPTO_F_CRYPTO_SET_EX_DATA 102
+# define CRYPTO_F_DEF_ADD_INDEX 104
+# define CRYPTO_F_DEF_GET_CLASS 105
+# define CRYPTO_F_FIPS_MODE_SET 109
+# define CRYPTO_F_INT_DUP_EX_DATA 106
+# define CRYPTO_F_INT_FREE_EX_DATA 107
+# define CRYPTO_F_INT_NEW_EX_DATA 108
+
+/* Reason codes. */
+# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101
+# define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/dh.h b/openssl/dh.h
new file mode 120000
index 0000000..0015870
--- /dev/null
+++ b/openssl/dh.h
@@ -0,0 +1 @@
+dh/dh.h
\ No newline at end of file
diff --git a/openssl/dh/dh.h b/openssl/dh/dh.h
new file mode 100644
index 0000000..4cbaa97
--- /dev/null
+++ b/openssl/dh/dh.h
@@ -0,0 +1,287 @@
+/* crypto/dh/dh.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_DH_H
+# define HEADER_DH_H
+
+# include <openssl/e_os2.h>
+
+# ifdef OPENSSL_NO_DH
+# error DH is disabled.
+# endif
+
+# ifndef OPENSSL_NO_BIO
+# include <openssl/bio.h>
+# endif
+# include <openssl/ossl_typ.h>
+# ifndef OPENSSL_NO_DEPRECATED
+# include <openssl/bn.h>
+# endif
+
+# ifndef OPENSSL_DH_MAX_MODULUS_BITS
+# define OPENSSL_DH_MAX_MODULUS_BITS 10000
+# endif
+
+# define DH_FLAG_CACHE_MONT_P 0x01
+
+/*
+ * new with 0.9.7h; the built-in DH
+ * implementation now uses constant time
+ * modular exponentiation for secret exponents
+ * by default. This flag causes the
+ * faster variable sliding window method to
+ * be used for all exponents.
+ */
+# define DH_FLAG_NO_EXP_CONSTTIME 0x02
+
+/*
+ * If this flag is set the DH method is FIPS compliant and can be used in
+ * FIPS mode. This is set in the validated module method. If an application
+ * sets this flag in its own methods it is its reposibility to ensure the
+ * result is compliant.
+ */
+
+# define DH_FLAG_FIPS_METHOD 0x0400
+
+/*
+ * If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+# define DH_FLAG_NON_FIPS_ALLOW 0x0400
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct dh_st DH; */
+/* typedef struct dh_method DH_METHOD; */
+
+struct dh_method {
+ const char *name;
+ /* Methods here */
+ int (*generate_key) (DH *dh);
+ int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh);
+ /* Can be null */
+ int (*bn_mod_exp) (const DH *dh, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx);
+ int (*init) (DH *dh);
+ int (*finish) (DH *dh);
+ int flags;
+ char *app_data;
+ /* If this is non-NULL, it will be used to generate parameters */
+ int (*generate_params) (DH *dh, int prime_len, int generator,
+ BN_GENCB *cb);
+};
+
+struct dh_st {
+ /*
+ * This first argument is used to pick up errors when a DH is passed
+ * instead of a EVP_PKEY
+ */
+ int pad;
+ int version;
+ BIGNUM *p;
+ BIGNUM *g;
+ long length; /* optional */
+ BIGNUM *pub_key; /* g^x */
+ BIGNUM *priv_key; /* x */
+ int flags;
+ BN_MONT_CTX *method_mont_p;
+ /* Place holders if we want to do X9.42 DH */
+ BIGNUM *q;
+ BIGNUM *j;
+ unsigned char *seed;
+ int seedlen;
+ BIGNUM *counter;
+ int references;
+ CRYPTO_EX_DATA ex_data;
+ const DH_METHOD *meth;
+ ENGINE *engine;
+};
+
+# define DH_GENERATOR_2 2
+/* #define DH_GENERATOR_3 3 */
+# define DH_GENERATOR_5 5
+
+/* DH_check error codes */
+# define DH_CHECK_P_NOT_PRIME 0x01
+# define DH_CHECK_P_NOT_SAFE_PRIME 0x02
+# define DH_UNABLE_TO_CHECK_GENERATOR 0x04
+# define DH_NOT_SUITABLE_GENERATOR 0x08
+
+/* DH_check_pub_key error codes */
+# define DH_CHECK_PUBKEY_TOO_SMALL 0x01
+# define DH_CHECK_PUBKEY_TOO_LARGE 0x02
+
+/*
+ * primes p where (p-1)/2 is prime too are called "safe"; we define this for
+ * backward compatibility:
+ */
+# define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME
+
+# define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
+ (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x))
+# define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \
+ (unsigned char *)(x))
+# define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x)
+# define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
+
+DH *DHparams_dup(DH *);
+
+const DH_METHOD *DH_OpenSSL(void);
+
+void DH_set_default_method(const DH_METHOD *meth);
+const DH_METHOD *DH_get_default_method(void);
+int DH_set_method(DH *dh, const DH_METHOD *meth);
+DH *DH_new_method(ENGINE *engine);
+
+DH *DH_new(void);
+void DH_free(DH *dh);
+int DH_up_ref(DH *dh);
+int DH_size(const DH *dh);
+int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int DH_set_ex_data(DH *d, int idx, void *arg);
+void *DH_get_ex_data(DH *d, int idx);
+
+/* Deprecated version */
+# ifndef OPENSSL_NO_DEPRECATED
+DH *DH_generate_parameters(int prime_len, int generator,
+ void (*callback) (int, int, void *), void *cb_arg);
+# endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int DH_generate_parameters_ex(DH *dh, int prime_len, int generator,
+ BN_GENCB *cb);
+
+int DH_check(const DH *dh, int *codes);
+int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes);
+int DH_generate_key(DH *dh);
+int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
+DH *d2i_DHparams(DH **a, const unsigned char **pp, long length);
+int i2d_DHparams(const DH *a, unsigned char **pp);
+# ifndef OPENSSL_NO_FP_API
+int DHparams_print_fp(FILE *fp, const DH *x);
+# endif
+# ifndef OPENSSL_NO_BIO
+int DHparams_print(BIO *bp, const DH *x);
+# else
+int DHparams_print(char *bp, const DH *x);
+# endif
+
+# define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \
+ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+ EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL)
+
+# define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \
+ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+ EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL)
+
+# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1)
+# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2)
+
+/* 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.
+ */
+void ERR_load_DH_strings(void);
+
+/* Error codes for the DH functions. */
+
+/* Function codes. */
+# define DH_F_COMPUTE_KEY 102
+# define DH_F_DHPARAMS_PRINT_FP 101
+# define DH_F_DH_BUILTIN_GENPARAMS 106
+# define DH_F_DH_COMPUTE_KEY 114
+# define DH_F_DH_GENERATE_KEY 115
+# define DH_F_DH_GENERATE_PARAMETERS_EX 116
+# define DH_F_DH_NEW_METHOD 105
+# define DH_F_DH_PARAM_DECODE 107
+# define DH_F_DH_PRIV_DECODE 110
+# define DH_F_DH_PRIV_ENCODE 111
+# define DH_F_DH_PUB_DECODE 108
+# define DH_F_DH_PUB_ENCODE 109
+# define DH_F_DO_DH_PRINT 100
+# define DH_F_GENERATE_KEY 103
+# define DH_F_GENERATE_PARAMETERS 104
+# define DH_F_PKEY_DH_DERIVE 112
+# define DH_F_PKEY_DH_KEYGEN 113
+
+/* Reason codes. */
+# define DH_R_BAD_GENERATOR 101
+# define DH_R_BN_DECODE_ERROR 109
+# define DH_R_BN_ERROR 106
+# define DH_R_DECODE_ERROR 104
+# define DH_R_INVALID_PUBKEY 102
+# define DH_R_KEYS_NOT_SET 108
+# define DH_R_KEY_SIZE_TOO_SMALL 110
+# define DH_R_MODULUS_TOO_LARGE 103
+# define DH_R_NON_FIPS_METHOD 111
+# define DH_R_NO_PARAMETERS_SET 107
+# define DH_R_NO_PRIVATE_VALUE 100
+# define DH_R_PARAMETER_ENCODING_ERROR 105
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/e_os2.h b/openssl/e_os2.h
new file mode 100644
index 0000000..d22c036
--- /dev/null
+++ b/openssl/e_os2.h
@@ -0,0 +1,315 @@
+/* e_os2.h */
+/* ====================================================================
+ * Copyright (c) 1998-2000 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/opensslconf.h>
+
+#ifndef HEADER_E_OS2_H
+#define HEADER_E_OS2_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************
+ * Detect operating systems. This probably needs completing.
+ * The result is that at least one OPENSSL_SYS_os macro should be defined.
+ * However, if none is defined, Unix is assumed.
+ **/
+
+#define OPENSSL_SYS_UNIX
+
+/* ----------------------- Macintosh, before MacOS X ----------------------- */
+#if defined(__MWERKS__) && defined(macintosh) || defined(OPENSSL_SYSNAME_MAC)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_MACINTOSH_CLASSIC
+#endif
+
+/* ----------------------- NetWare ----------------------------------------- */
+#if defined(NETWARE) || defined(OPENSSL_SYSNAME_NETWARE)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_NETWARE
+#endif
+
+/* ---------------------- Microsoft operating systems ---------------------- */
+
+/* Note that MSDOS actually denotes 32-bit environments running on top of
+ MS-DOS, such as DJGPP one. */
+#if defined(OPENSSL_SYSNAME_MSDOS)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_MSDOS
+#endif
+
+/* For 32 bit environment, there seems to be the CygWin environment and then
+ all the others that try to do the same thing Microsoft does... */
+#if defined(OPENSSL_SYSNAME_UWIN)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_WIN32_UWIN
+#else
+# if defined(__CYGWIN32__) || defined(OPENSSL_SYSNAME_CYGWIN32)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_WIN32_CYGWIN
+# else
+# if defined(_WIN32) || defined(OPENSSL_SYSNAME_WIN32)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_WIN32
+# endif
+# if defined(OPENSSL_SYSNAME_WINNT)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_WINNT
+# endif
+# if defined(OPENSSL_SYSNAME_WINCE)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_WINCE
+# endif
+# endif
+#endif
+
+/* Anything that tries to look like Microsoft is "Windows" */
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_WINDOWS
+# ifndef OPENSSL_SYS_MSDOS
+# define OPENSSL_SYS_MSDOS
+# endif
+#endif
+
+/* DLL settings. This part is a bit tough, because it's up to the application
+ implementor how he or she will link the application, so it requires some
+ macro to be used. */
+#ifdef OPENSSL_SYS_WINDOWS
+# ifndef OPENSSL_OPT_WINDLL
+# if defined(_WINDLL) /* This is used when building OpenSSL to indicate that
+ DLL linkage should be used */
+# define OPENSSL_OPT_WINDLL
+# endif
+# endif
+#endif
+
+/* -------------------------------- OpenVMS -------------------------------- */
+#if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYSNAME_VMS)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_VMS
+# if defined(__DECC)
+# define OPENSSL_SYS_VMS_DECC
+# elif defined(__DECCXX)
+# define OPENSSL_SYS_VMS_DECC
+# define OPENSSL_SYS_VMS_DECCXX
+# else
+# define OPENSSL_SYS_VMS_NODECC
+# endif
+#endif
+
+/* --------------------------------- OS/2 ---------------------------------- */
+#if defined(__EMX__) || defined(__OS2__)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_OS2
+#endif
+
+/* --------------------------------- Unix ---------------------------------- */
+#ifdef OPENSSL_SYS_UNIX
+# if defined(linux) || defined(__linux__) || defined(OPENSSL_SYSNAME_LINUX)
+# define OPENSSL_SYS_LINUX
+# endif
+# ifdef OPENSSL_SYSNAME_MPE
+# define OPENSSL_SYS_MPE
+# endif
+# ifdef OPENSSL_SYSNAME_SNI
+# define OPENSSL_SYS_SNI
+# endif
+# ifdef OPENSSL_SYSNAME_ULTRASPARC
+# define OPENSSL_SYS_ULTRASPARC
+# endif
+# ifdef OPENSSL_SYSNAME_NEWS4
+# define OPENSSL_SYS_NEWS4
+# endif
+# ifdef OPENSSL_SYSNAME_MACOSX
+# define OPENSSL_SYS_MACOSX
+# endif
+# ifdef OPENSSL_SYSNAME_MACOSX_RHAPSODY
+# define OPENSSL_SYS_MACOSX_RHAPSODY
+# define OPENSSL_SYS_MACOSX
+# endif
+# ifdef OPENSSL_SYSNAME_SUNOS
+# define OPENSSL_SYS_SUNOS
+#endif
+# if defined(_CRAY) || defined(OPENSSL_SYSNAME_CRAY)
+# define OPENSSL_SYS_CRAY
+# endif
+# if defined(_AIX) || defined(OPENSSL_SYSNAME_AIX)
+# define OPENSSL_SYS_AIX
+# endif
+#endif
+
+/* --------------------------------- VOS ----------------------------------- */
+#if defined(__VOS__) || defined(OPENSSL_SYSNAME_VOS)
+# define OPENSSL_SYS_VOS
+#ifdef __HPPA__
+# define OPENSSL_SYS_VOS_HPPA
+#endif
+#ifdef __IA32__
+# define OPENSSL_SYS_VOS_IA32
+#endif
+#endif
+
+/* ------------------------------- VxWorks --------------------------------- */
+#ifdef OPENSSL_SYSNAME_VXWORKS
+# define OPENSSL_SYS_VXWORKS
+#endif
+
+/* --------------------------------- BeOS ---------------------------------- */
+#if defined(__BEOS__)
+# define OPENSSL_SYS_BEOS
+# include <sys/socket.h>
+# if defined(BONE_VERSION)
+# define OPENSSL_SYS_BEOS_BONE
+# else
+# define OPENSSL_SYS_BEOS_R5
+# endif
+#endif
+
+/**
+ * That's it for OS-specific stuff
+ *****************************************************************************/
+
+
+/* Specials for I/O an exit */
+#ifdef OPENSSL_SYS_MSDOS
+# define OPENSSL_UNISTD_IO <io.h>
+# define OPENSSL_DECLARE_EXIT extern void exit(int);
+#else
+# define OPENSSL_UNISTD_IO OPENSSL_UNISTD
+# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */
+#endif
+
+/* Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN, to define and declare
+ certain global symbols that, with some compilers under VMS, have to be
+ defined and declared explicitely with globaldef and globalref.
+ Definitions of OPENSSL_EXPORT and OPENSSL_IMPORT, to define and declare
+ DLL exports and imports for compilers under Win32. These are a little
+ more complicated to use. Basically, for any library that exports some
+ global variables, the following code must be present in the header file
+ that declares them, before OPENSSL_EXTERN is used:
+
+ #ifdef SOME_BUILD_FLAG_MACRO
+ # undef OPENSSL_EXTERN
+ # define OPENSSL_EXTERN OPENSSL_EXPORT
+ #endif
+
+ The default is to have OPENSSL_EXPORT, OPENSSL_IMPORT and OPENSSL_GLOBAL
+ have some generally sensible values, and for OPENSSL_EXTERN to have the
+ value OPENSSL_IMPORT.
+*/
+
+#if defined(OPENSSL_SYS_VMS_NODECC)
+# define OPENSSL_EXPORT globalref
+# define OPENSSL_IMPORT globalref
+# define OPENSSL_GLOBAL globaldef
+#elif defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL)
+# define OPENSSL_EXPORT extern __declspec(dllexport)
+# define OPENSSL_IMPORT extern __declspec(dllimport)
+# define OPENSSL_GLOBAL
+#else
+# define OPENSSL_EXPORT extern
+# define OPENSSL_IMPORT extern
+# define OPENSSL_GLOBAL
+#endif
+#define OPENSSL_EXTERN OPENSSL_IMPORT
+
+/* Macros to allow global variables to be reached through function calls when
+ required (if a shared library version requires it, for example.
+ The way it's done allows definitions like this:
+
+ // in foobar.c
+ OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0)
+ // in foobar.h
+ OPENSSL_DECLARE_GLOBAL(int,foobar);
+ #define foobar OPENSSL_GLOBAL_REF(foobar)
+*/
+#ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) \
+ type *_shadow_##name(void) \
+ { static type _hide_##name=value; return &_hide_##name; }
+# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void)
+# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name()))
+#else
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value;
+# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name
+# define OPENSSL_GLOBAL_REF(name) _shadow_##name
+#endif
+
+#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && macintosh==1 && !defined(MAC_OS_GUSI_SOURCE)
+# define ossl_ssize_t long
+#endif
+
+#ifdef OPENSSL_SYS_MSDOS
+# define ossl_ssize_t long
+#endif
+
+#if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) || defined(OPENSSL_SYS_SUNOS)
+# define ssize_t int
+#endif
+
+#if defined(__ultrix) && !defined(ssize_t)
+# define ossl_ssize_t int
+#endif
+
+#ifndef ossl_ssize_t
+# define ossl_ssize_t ssize_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/ec.h b/openssl/ec.h
new file mode 120000
index 0000000..740f151
--- /dev/null
+++ b/openssl/ec.h
@@ -0,0 +1 @@
+ec/ec.h
\ No newline at end of file
diff --git a/openssl/ec/Makefile b/openssl/ec/Makefile
new file mode 100644
index 0000000..564abb2
--- /dev/null
+++ b/openssl/ec/Makefile
@@ -0,0 +1,66 @@
+# Copyright 2010 by Nest Labs, Inc. All rights reserved.
+#
+# This program is confidential and proprietary to Nest Labs, Inc.,
+# and may not be reproduced, published or disclosed to others without
+# company authorization.
+#
+
+DEPTH = ../../
+
+include $(DEPTH)Makefile.config
+
+CFLAGS += -Os
+
+OUTDIR = $(OBJ_DIR)
+SRCDIR = ./
+INCDIR = ./
+
+OBJECT_FILES = \
+ ec_lib \
+ ecp_smpl \
+ ecp_mont \
+ ecp_nist \
+ ec_cvt \
+ ec_mult \
+ ec_err \
+ ec_curve \
+ ec_check \
+ ec_print \
+ ec_asn1 \
+ ec_key \
+ ec2_smpl \
+ ec2_mult \
+ ec_pmeth \
+ eck_prn \
+ ecp_oct \
+ ec2_oct \
+ ec_oct
+
+HEADER_FILES = \
+ ec_lcl
+
+OBJECTS = $(OBJECT_FILES:%=$(OUTDIR)/%.o)
+HEADERS = $(HEADER_FILES:%=$(INCDIR)/%.h)
+
+all: $(OUTDIR) $(LIB_DIR)/libec.a
+
+$(OUTDIR):
+ $(MKDIR) $(OUTDIR)
+
+clean:
+ $(RM) $(OUTDIR)
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.c $(HEADERS)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.cpp $(HEADERS)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(OUTDIR)/libec.a: $(OBJECTS)
+ $(ARCHIVE) $@ $(OBJECTS)
+ $(RANLIB) $@
+
+$(LIB_DIR)/libec.a: $(OUTDIR)/libec.a
+ $(MKDIR) $(dir $@)
+ $(CP) $< $@
+
diff --git a/openssl/ec/ec.h b/openssl/ec/ec.h
new file mode 100644
index 0000000..c4e7aea
--- /dev/null
+++ b/openssl/ec/ec.h
@@ -0,0 +1,1193 @@
+/* crypto/ec/ec.h */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/**
+ * \file crypto/ec/ec.h Include file for the OpenSSL EC functions
+ * \author Originally written by Bodo Moeller for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 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 HEADER_EC_H
+# define HEADER_EC_H
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_EC
+# error EC is disabled.
+# endif
+
+# include <openssl/asn1.h>
+# include <openssl/symhacks.h>
+# ifndef OPENSSL_NO_DEPRECATED
+# include <openssl/bn.h>
+# endif
+
+# ifdef __cplusplus
+extern "C" {
+# elif defined(__SUNPRO_C)
+# if __SUNPRO_C >= 0x520
+# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+# endif
+# endif
+
+# ifndef OPENSSL_ECC_MAX_FIELD_BITS
+# define OPENSSL_ECC_MAX_FIELD_BITS 661
+# endif
+
+/** Enum for the point conversion form as defined in X9.62 (ECDSA)
+ * for the encoding of a elliptic curve point (x,y) */
+typedef enum {
+ /** the point is encoded as z||x, where the octet z specifies
+ * which solution of the quadratic equation y is */
+ POINT_CONVERSION_COMPRESSED = 2,
+ /** the point is encoded as z||x||y, where z is the octet 0x02 */
+ POINT_CONVERSION_UNCOMPRESSED = 4,
+ /** the point is encoded as z||x||y, where the octet z specifies
+ * which solution of the quadratic equation y is */
+ POINT_CONVERSION_HYBRID = 6
+} point_conversion_form_t;
+
+typedef struct ec_method_st EC_METHOD;
+
+typedef struct ec_group_st
+ /*-
+ EC_METHOD *meth;
+ -- field definition
+ -- curve coefficients
+ -- optional generator with associated information (order, cofactor)
+ -- optional extra data (precomputed table for fast computation of multiples of generator)
+ -- ASN1 stuff
+ */
+ EC_GROUP;
+
+typedef struct ec_point_st EC_POINT;
+
+/********************************************************************/
+/* EC_METHODs for curves over GF(p) */
+/********************************************************************/
+
+/** Returns the basic GFp ec methods which provides the basis for the
+ * optimized methods.
+ * \return EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_simple_method(void);
+
+/** Returns GFp methods using montgomery multiplication.
+ * \return EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_mont_method(void);
+
+/** Returns GFp methods using optimized methods for NIST recommended curves
+ * \return EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nist_method(void);
+
+# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+/** Returns 64-bit optimized methods for nistp224
+ * \return EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nistp224_method(void);
+
+/** Returns 64-bit optimized methods for nistp256
+ * \return EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nistp256_method(void);
+
+/** Returns 64-bit optimized methods for nistp521
+ * \return EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nistp521_method(void);
+# endif
+
+# ifndef OPENSSL_NO_EC2M
+/********************************************************************/
+/* EC_METHOD for curves over GF(2^m) */
+/********************************************************************/
+
+/** Returns the basic GF2m ec method
+ * \return EC_METHOD object
+ */
+const EC_METHOD *EC_GF2m_simple_method(void);
+
+# endif
+
+/********************************************************************/
+/* EC_GROUP functions */
+/********************************************************************/
+
+/** Creates a new EC_GROUP object
+ * \param meth EC_METHOD to use
+ * \return newly created EC_GROUP object or NULL in case of an error.
+ */
+EC_GROUP *EC_GROUP_new(const EC_METHOD *meth);
+
+/** Frees a EC_GROUP object
+ * \param group EC_GROUP object to be freed.
+ */
+void EC_GROUP_free(EC_GROUP *group);
+
+/** Clears and frees a EC_GROUP object
+ * \param group EC_GROUP object to be cleared and freed.
+ */
+void EC_GROUP_clear_free(EC_GROUP *group);
+
+/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD.
+ * \param dst destination EC_GROUP object
+ * \param src source EC_GROUP object
+ * \return 1 on success and 0 if an error occurred.
+ */
+int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);
+
+/** Creates a new EC_GROUP object and copies the copies the content
+ * form src to the newly created EC_KEY object
+ * \param src source EC_GROUP object
+ * \return newly created EC_GROUP object or NULL in case of an error.
+ */
+EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);
+
+/** Returns the EC_METHOD of the EC_GROUP object.
+ * \param group EC_GROUP object
+ * \return EC_METHOD used in this EC_GROUP object.
+ */
+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
+
+/** Returns the field type of the EC_METHOD.
+ * \param meth EC_METHOD object
+ * \return NID of the underlying field type OID.
+ */
+int EC_METHOD_get_field_type(const EC_METHOD *meth);
+
+/** Sets the generator and it's order/cofactor of a EC_GROUP object.
+ * \param group EC_GROUP object
+ * \param generator EC_POINT object with the generator.
+ * \param order the order of the group generated by the generator.
+ * \param cofactor the index of the sub-group generated by the generator
+ * in the group of all points on the elliptic curve.
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
+ const BIGNUM *order, const BIGNUM *cofactor);
+
+/** Returns the generator of a EC_GROUP object.
+ * \param group EC_GROUP object
+ * \return the currently used generator (possibly NULL).
+ */
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
+
+/** Gets the order of a EC_GROUP
+ * \param group EC_GROUP object
+ * \param order BIGNUM to which the order is copied
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
+
+/** Gets the cofactor of a EC_GROUP
+ * \param group EC_GROUP object
+ * \param cofactor BIGNUM to which the cofactor is copied
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
+ BN_CTX *ctx);
+
+/** Sets the name of a EC_GROUP object
+ * \param group EC_GROUP object
+ * \param nid NID of the curve name OID
+ */
+void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);
+
+/** Returns the curve name of a EC_GROUP object
+ * \param group EC_GROUP object
+ * \return NID of the curve name OID or 0 if not set.
+ */
+int EC_GROUP_get_curve_name(const EC_GROUP *group);
+
+void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
+int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
+
+void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
+ point_conversion_form_t form);
+point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
+
+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x);
+size_t EC_GROUP_get_seed_len(const EC_GROUP *);
+size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
+
+/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b
+ * \param group EC_GROUP object
+ * \param p BIGNUM with the prime number
+ * \param a BIGNUM with parameter a of the equation
+ * \param b BIGNUM with parameter b of the equation
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx);
+
+/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b
+ * \param group EC_GROUP object
+ * \param p BIGNUM for the prime number
+ * \param a BIGNUM for parameter a of the equation
+ * \param b BIGNUM for parameter b of the equation
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+ BIGNUM *b, BN_CTX *ctx);
+
+# ifndef OPENSSL_NO_EC2M
+/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
+ * \param group EC_GROUP object
+ * \param p BIGNUM with the polynomial defining the underlying field
+ * \param a BIGNUM with parameter a of the equation
+ * \param b BIGNUM with parameter b of the equation
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx);
+
+/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
+ * \param group EC_GROUP object
+ * \param p BIGNUM for the polynomial defining the underlying field
+ * \param a BIGNUM for parameter a of the equation
+ * \param b BIGNUM for parameter b of the equation
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+ BIGNUM *b, BN_CTX *ctx);
+# endif
+/** Returns the number of bits needed to represent a field element
+ * \param group EC_GROUP object
+ * \return number of bits needed to represent a field element
+ */
+int EC_GROUP_get_degree(const EC_GROUP *group);
+
+/** Checks whether the parameter in the EC_GROUP define a valid ec group
+ * \param group EC_GROUP object
+ * \param ctx BN_CTX object (optional)
+ * \return 1 if group is a valid ec group and 0 otherwise
+ */
+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
+
+/** Checks whether the discriminant of the elliptic curve is zero or not
+ * \param group EC_GROUP object
+ * \param ctx BN_CTX object (optional)
+ * \return 1 if the discriminant is not zero and 0 otherwise
+ */
+int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);
+
+/** Compares two EC_GROUP objects
+ * \param a first EC_GROUP object
+ * \param b second EC_GROUP object
+ * \param ctx BN_CTX object (optional)
+ * \return 0 if both groups are equal and 1 otherwise
+ */
+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
+
+/*
+ * EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() after
+ * choosing an appropriate EC_METHOD
+ */
+
+/** Creates a new EC_GROUP object with the specified parameters defined
+ * over GFp (defined by the equation y^2 = x^3 + a*x + b)
+ * \param p BIGNUM with the prime number
+ * \param a BIGNUM with the parameter a of the equation
+ * \param b BIGNUM with the parameter b of the equation
+ * \param ctx BN_CTX object (optional)
+ * \return newly created EC_GROUP object with the specified parameters
+ */
+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx);
+# ifndef OPENSSL_NO_EC2M
+/** Creates a new EC_GROUP object with the specified parameters defined
+ * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
+ * \param p BIGNUM with the polynomial defining the underlying field
+ * \param a BIGNUM with the parameter a of the equation
+ * \param b BIGNUM with the parameter b of the equation
+ * \param ctx BN_CTX object (optional)
+ * \return newly created EC_GROUP object with the specified parameters
+ */
+EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx);
+# endif
+/** Creates a EC_GROUP object with a curve specified by a NID
+ * \param nid NID of the OID of the curve name
+ * \return newly created EC_GROUP object with specified curve or NULL
+ * if an error occurred
+ */
+EC_GROUP *EC_GROUP_new_by_curve_name(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 */
+/********************************************************************/
+
+/** Creates a new EC_POINT object for the specified EC_GROUP
+ * \param group EC_GROUP the underlying EC_GROUP object
+ * \return newly created EC_POINT object or NULL if an error occurred
+ */
+EC_POINT *EC_POINT_new(const EC_GROUP *group);
+
+/** Frees a EC_POINT object
+ * \param point EC_POINT object to be freed
+ */
+void EC_POINT_free(EC_POINT *point);
+
+/** Clears and frees a EC_POINT object
+ * \param point EC_POINT object to be cleared and freed
+ */
+void EC_POINT_clear_free(EC_POINT *point);
+
+/** Copies EC_POINT object
+ * \param dst destination EC_POINT object
+ * \param src source EC_POINT object
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
+
+/** Creates a new EC_POINT object and copies the content of the supplied
+ * EC_POINT
+ * \param src source EC_POINT object
+ * \param group underlying the EC_GROUP object
+ * \return newly created EC_POINT object or NULL if an error occurred
+ */
+EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
+
+/** Returns the EC_METHOD used in EC_POINT object
+ * \param point EC_POINT object
+ * \return the EC_METHOD used
+ */
+const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);
+
+/** Sets a point to infinity (neutral element)
+ * \param group underlying EC_GROUP object
+ * \param point EC_POINT to set to infinity
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
+
+/** Sets the jacobian projective coordinates of a EC_POINT over GFp
+ * \param group underlying EC_GROUP object
+ * \param p EC_POINT object
+ * \param x BIGNUM with the x-coordinate
+ * \param y BIGNUM with the y-coordinate
+ * \param z BIGNUM with the z-coordinate
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
+ EC_POINT *p, const BIGNUM *x,
+ const BIGNUM *y, const BIGNUM *z,
+ BN_CTX *ctx);
+
+/** Gets the jacobian projective coordinates of a EC_POINT over GFp
+ * \param group underlying EC_GROUP object
+ * \param p EC_POINT object
+ * \param x BIGNUM for the x-coordinate
+ * \param y BIGNUM for the y-coordinate
+ * \param z BIGNUM for the z-coordinate
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
+ const EC_POINT *p, BIGNUM *x,
+ BIGNUM *y, BIGNUM *z,
+ BN_CTX *ctx);
+
+/** Sets the affine coordinates of a EC_POINT over GFp
+ * \param group underlying EC_GROUP object
+ * \param p EC_POINT object
+ * \param x BIGNUM with the x-coordinate
+ * \param y BIGNUM with the y-coordinate
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
+ const BIGNUM *x, const BIGNUM *y,
+ BN_CTX *ctx);
+
+/** Gets the affine coordinates of a EC_POINT over GFp
+ * \param group underlying EC_GROUP object
+ * \param p EC_POINT object
+ * \param x BIGNUM for the x-coordinate
+ * \param y BIGNUM for the y-coordinate
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
+ const EC_POINT *p, BIGNUM *x,
+ BIGNUM *y, BN_CTX *ctx);
+
+/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp
+ * \param group underlying EC_GROUP object
+ * \param p EC_POINT object
+ * \param x BIGNUM with x-coordinate
+ * \param y_bit integer with the y-Bit (either 0 or 1)
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
+ EC_POINT *p, const BIGNUM *x,
+ int y_bit, BN_CTX *ctx);
+# ifndef OPENSSL_NO_EC2M
+/** Sets the affine coordinates of a EC_POINT over GF2m
+ * \param group underlying EC_GROUP object
+ * \param p EC_POINT object
+ * \param x BIGNUM with the x-coordinate
+ * \param y BIGNUM with the y-coordinate
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
+ const BIGNUM *x, const BIGNUM *y,
+ BN_CTX *ctx);
+
+/** Gets the affine coordinates of a EC_POINT over GF2m
+ * \param group underlying EC_GROUP object
+ * \param p EC_POINT object
+ * \param x BIGNUM for the x-coordinate
+ * \param y BIGNUM for the y-coordinate
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
+ const EC_POINT *p, BIGNUM *x,
+ BIGNUM *y, BN_CTX *ctx);
+
+/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m
+ * \param group underlying EC_GROUP object
+ * \param p EC_POINT object
+ * \param x BIGNUM with x-coordinate
+ * \param y_bit integer with the y-Bit (either 0 or 1)
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group,
+ EC_POINT *p, const BIGNUM *x,
+ int y_bit, BN_CTX *ctx);
+# endif
+/** Encodes a EC_POINT object to a octet string
+ * \param group underlying EC_GROUP object
+ * \param p EC_POINT object
+ * \param form point conversion form
+ * \param buf memory buffer for the result. If NULL the function returns
+ * required buffer size.
+ * \param len length of the memory buffer
+ * \param ctx BN_CTX object (optional)
+ * \return the length of the encoded octet string or 0 if an error occurred
+ */
+size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
+ point_conversion_form_t form,
+ unsigned char *buf, size_t len, BN_CTX *ctx);
+
+/** Decodes a EC_POINT from a octet string
+ * \param group underlying EC_GROUP object
+ * \param p EC_POINT object
+ * \param buf memory buffer with the encoded ec point
+ * \param len length of the encoded ec point
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
+ const unsigned char *buf, size_t len, BN_CTX *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 *);
+
+/********************************************************************/
+/* functions for doing EC_POINT arithmetic */
+/********************************************************************/
+
+/** Computes the sum of two EC_POINT
+ * \param group underlying EC_GROUP object
+ * \param r EC_POINT object for the result (r = a + b)
+ * \param a EC_POINT object with the first summand
+ * \param b EC_POINT object with the second summand
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *ctx);
+
+/** Computes the double of a EC_POINT
+ * \param group underlying EC_GROUP object
+ * \param r EC_POINT object for the result (r = 2 * a)
+ * \param a EC_POINT object
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+ BN_CTX *ctx);
+
+/** Computes the inverse of a EC_POINT
+ * \param group underlying EC_GROUP object
+ * \param a EC_POINT object to be inverted (it's used for the result as well)
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
+
+/** Checks whether the point is the neutral element of the group
+ * \param group the underlying EC_GROUP object
+ * \param p EC_POINT object
+ * \return 1 if the point is the neutral element and 0 otherwise
+ */
+int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);
+
+/** Checks whether the point is on the curve
+ * \param group underlying EC_GROUP object
+ * \param point EC_POINT object to check
+ * \param ctx BN_CTX object (optional)
+ * \return 1 if point if on the curve and 0 otherwise
+ */
+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
+ BN_CTX *ctx);
+
+/** Compares two EC_POINTs
+ * \param group underlying EC_GROUP object
+ * \param a first EC_POINT object
+ * \param b second EC_POINT object
+ * \param ctx BN_CTX object (optional)
+ * \return 0 if both points are equal and a value != 0 otherwise
+ */
+int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
+ BN_CTX *ctx);
+
+int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
+int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
+ EC_POINT *points[], BN_CTX *ctx);
+
+/** Computes r = generator * n sum_{i=0}^{num-1} p[i] * m[i]
+ * \param group underlying EC_GROUP object
+ * \param r EC_POINT object for the result
+ * \param n BIGNUM with the multiplier for the group generator (optional)
+ * \param num number futher summands
+ * \param p array of size num of EC_POINT objects
+ * \param m array of size num of BIGNUM objects
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
+ size_t num, const EC_POINT *p[], const BIGNUM *m[],
+ BN_CTX *ctx);
+
+/** Computes r = generator * n + q * m
+ * \param group underlying EC_GROUP object
+ * \param r EC_POINT object for the result
+ * \param n BIGNUM with the multiplier for the group generator (optional)
+ * \param q EC_POINT object with the first factor of the second summand
+ * \param m BIGNUM with the second factor of the second summand
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
+ const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
+
+/** Stores multiples of generator for faster point multiplication
+ * \param group EC_GROUP object
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occured
+ */
+int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+
+/** Reports whether a precomputation has been done
+ * \param group EC_GROUP object
+ * \return 1 if a pre-computation has been done and 0 otherwise
+ */
+int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
+
+/********************************************************************/
+/* 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 *);
+# ifndef OPENSSL_NO_EC2M
+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);
+# endif
+
+# 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) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
+# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,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
+
+/********************************************************************/
+/* EC_KEY functions */
+/********************************************************************/
+
+typedef struct ec_key_st EC_KEY;
+
+/* some values for the encoding_flag */
+# define EC_PKEY_NO_PARAMETERS 0x001
+# define EC_PKEY_NO_PUBKEY 0x002
+
+/* some values for the flags field */
+# define EC_FLAG_NON_FIPS_ALLOW 0x1
+# define EC_FLAG_FIPS_CHECKED 0x2
+
+/** Creates a new EC_KEY object.
+ * \return EC_KEY object or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_new(void);
+
+int EC_KEY_get_flags(const EC_KEY *key);
+
+void EC_KEY_set_flags(EC_KEY *key, int flags);
+
+void EC_KEY_clear_flags(EC_KEY *key, int flags);
+
+/** Creates a new EC_KEY object using a named curve as underlying
+ * EC_GROUP object.
+ * \param nid NID of the named curve.
+ * \return EC_KEY object or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_new_by_curve_name(int nid);
+
+/** Frees a EC_KEY object.
+ * \param key EC_KEY object to be freed.
+ */
+void EC_KEY_free(EC_KEY *key);
+
+/** Copies a EC_KEY object.
+ * \param dst destination EC_KEY object
+ * \param src src EC_KEY object
+ * \return dst or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
+
+/** Creates a new EC_KEY object and copies the content from src to it.
+ * \param src the source EC_KEY object
+ * \return newly created EC_KEY object or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_dup(const EC_KEY *src);
+
+/** Increases the internal reference count of a EC_KEY object.
+ * \param key EC_KEY object
+ * \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_up_ref(EC_KEY *key);
+
+/** Returns the EC_GROUP object of a EC_KEY object
+ * \param key EC_KEY object
+ * \return the EC_GROUP object (possibly NULL).
+ */
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
+
+/** Sets the EC_GROUP of a EC_KEY object.
+ * \param key EC_KEY object
+ * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY
+ * object will use an own copy of the EC_GROUP).
+ * \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
+
+/** Returns the private key of a EC_KEY object.
+ * \param key EC_KEY object
+ * \return a BIGNUM with the private key (possibly NULL).
+ */
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
+
+/** Sets the private key of a EC_KEY object.
+ * \param key EC_KEY object
+ * \param prv BIGNUM with the private key (note: the EC_KEY object
+ * will use an own copy of the BIGNUM).
+ * \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
+
+/** Returns the public key of a EC_KEY object.
+ * \param key the EC_KEY object
+ * \return a EC_POINT object with the public key (possibly NULL)
+ */
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
+
+/** Sets the public key of a EC_KEY object.
+ * \param key EC_KEY object
+ * \param pub EC_POINT object with the public key (note: the EC_KEY object
+ * will use an own copy of the EC_POINT object).
+ * \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
+
+unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
+void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags);
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
+void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
+/* functions to set/get method specific data */
+void *EC_KEY_get_key_method_data(EC_KEY *key,
+ void *(*dup_func) (void *),
+ void (*free_func) (void *),
+ void (*clear_free_func) (void *));
+/** Sets the key method data of an EC_KEY object, if none has yet been set.
+ * \param key EC_KEY object
+ * \param data opaque data to install.
+ * \param dup_func a function that duplicates |data|.
+ * \param free_func a function that frees |data|.
+ * \param clear_free_func a function that wipes and frees |data|.
+ * \return the previously set data pointer, or NULL if |data| was inserted.
+ */
+void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
+ void *(*dup_func) (void *),
+ void (*free_func) (void *),
+ void (*clear_free_func) (void *));
+/* wrapper functions for the underlying EC_GROUP object */
+void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);
+
+/** Creates a table of pre-computed multiples of the generator to
+ * accelerate further EC_KEY operations.
+ * \param key EC_KEY object
+ * \param ctx BN_CTX object (optional)
+ * \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
+
+/** Creates a new ec private (and optional a new public) key.
+ * \param key EC_KEY object
+ * \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_generate_key(EC_KEY *key);
+
+/** Verifies that a private and/or public key is valid.
+ * \param key the EC_KEY object
+ * \return 1 on success and 0 otherwise.
+ */
+int EC_KEY_check_key(const EC_KEY *key);
+
+/** Sets a public key from affine coordindates performing
+ * neccessary NIST PKV tests.
+ * \param key the EC_KEY object
+ * \param x public key x coordinate
+ * \param y public key y coordinate
+ * \return 1 on success and 0 otherwise.
+ */
+int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
+ BIGNUM *y);
+
+/********************************************************************/
+/* de- and encoding functions for SEC1 ECPrivateKey */
+/********************************************************************/
+
+/** Decodes a private key from a memory buffer.
+ * \param key a pointer to a EC_KEY object which should be used (or NULL)
+ * \param in pointer to memory with the DER encoded private key
+ * \param len length of the DER encoded private key
+ * \return the decoded private key or NULL if an error occurred.
+ */
+EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes a private key object and stores the result in a buffer.
+ * \param key the EC_KEY object to encode
+ * \param out the buffer for the result (if NULL the function returns number
+ * of bytes needed).
+ * \return 1 on success and 0 if an error occurred.
+ */
+int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
+
+/********************************************************************/
+/* de- and encoding functions for EC parameters */
+/********************************************************************/
+
+/** Decodes ec parameter from a memory buffer.
+ * \param key a pointer to a EC_KEY object which should be used (or NULL)
+ * \param in pointer to memory with the DER encoded ec parameters
+ * \param len length of the DER encoded ec parameters
+ * \return a EC_KEY object with the decoded parameters or NULL if an error
+ * occurred.
+ */
+EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes ec parameter and stores the result in a buffer.
+ * \param key the EC_KEY object with ec paramters to encode
+ * \param out the buffer for the result (if NULL the function returns number
+ * of bytes needed).
+ * \return 1 on success and 0 if an error occurred.
+ */
+int i2d_ECParameters(EC_KEY *key, unsigned char **out);
+
+/********************************************************************/
+/* de- and encoding functions for EC public key */
+/* (octet string, not DER -- hence 'o2i' and 'i2o') */
+/********************************************************************/
+
+/** Decodes a ec public key from a octet string.
+ * \param key a pointer to a EC_KEY object which should be used
+ * \param in memory buffer with the encoded public key
+ * \param len length of the encoded public key
+ * \return EC_KEY object with decoded public key or NULL if an error
+ * occurred.
+ */
+EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes a ec public key in an octet string.
+ * \param key the EC_KEY object with the public key
+ * \param out the buffer for the result (if NULL the function returns number
+ * of bytes needed).
+ * \return 1 on success and 0 if an error occurred
+ */
+int i2o_ECPublicKey(EC_KEY *key, unsigned char **out);
+
+# ifndef OPENSSL_NO_BIO
+/** Prints out the ec parameters on human readable form.
+ * \param bp BIO object to which the information is printed
+ * \param key EC_KEY object
+ * \return 1 on success and 0 if an error occurred
+ */
+int ECParameters_print(BIO *bp, const EC_KEY *key);
+
+/** Prints out the contents of a EC_KEY object
+ * \param bp BIO object to which the information is printed
+ * \param key EC_KEY object
+ * \param off line offset
+ * \return 1 on success and 0 if an error occurred
+ */
+int EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
+
+# endif
+# ifndef OPENSSL_NO_FP_API
+/** Prints out the ec parameters on human readable form.
+ * \param fp file descriptor to which the information is printed
+ * \param key EC_KEY object
+ * \return 1 on success and 0 if an error occurred
+ */
+int ECParameters_print_fp(FILE *fp, const EC_KEY *key);
+
+/** Prints out the contents of a EC_KEY object
+ * \param fp file descriptor to which the information is printed
+ * \param key EC_KEY object
+ * \param off line offset
+ * \return 1 on success and 0 if an error occurred
+ */
+int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
+
+# endif
+
+# define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
+
+# ifndef __cplusplus
+# if defined(__SUNPRO_C)
+# if __SUNPRO_C >= 0x520
+# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+# endif
+# endif
+# endif
+
+# define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
+ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \
+ EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
+
+# define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1)
+
+/* 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.
+ */
+void ERR_load_EC_strings(void);
+
+/* Error codes for the EC functions. */
+
+/* Function codes. */
+# define EC_F_BN_TO_FELEM 224
+# 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_DO_EC_KEY_PRINT 221
+# define EC_F_ECKEY_PARAM2TYPE 223
+# define EC_F_ECKEY_PARAM_DECODE 212
+# define EC_F_ECKEY_PRIV_DECODE 213
+# define EC_F_ECKEY_PRIV_ENCODE 214
+# define EC_F_ECKEY_PUB_DECODE 215
+# define EC_F_ECKEY_PUB_ENCODE 216
+# define EC_F_ECKEY_TYPE2PARAM 220
+# 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_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_EX_DATA_SET_DATA 211
+# define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208
+# 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_SET_TO_ONE 209
+# define EC_F_EC_GFP_MONT_FIELD_SQR 132
+# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189
+# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135
+# define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225
+# define EC_F_EC_GFP_NISTP224_POINTS_MUL 228
+# define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226
+# define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230
+# define EC_F_EC_GFP_NISTP256_POINTS_MUL 231
+# define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232
+# define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233
+# define EC_F_EC_GFP_NISTP521_POINTS_MUL 234
+# define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235
+# 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 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_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_NEW 108
+# define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 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_NEW 182
+# define EC_F_EC_KEY_PRINT 180
+# define EC_F_EC_KEY_PRINT_FP 181
+# define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229
+# define EC_F_EC_POINTS_MAKE_AFFINE 136
+# 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_INVERT 210
+# 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_PRE_COMP_DUP 207
+# define EC_F_EC_PRE_COMP_NEW 196
+# define EC_F_EC_WNAF_MUL 187
+# define EC_F_EC_WNAF_PRECOMPUTE_MULT 188
+# define EC_F_I2D_ECPARAMETERS 190
+# define EC_F_I2D_ECPKPARAMETERS 191
+# define EC_F_I2D_ECPRIVATEKEY 192
+# define EC_F_I2O_ECPUBLICKEY 151
+# define EC_F_NISTP224_PRE_COMP_NEW 227
+# define EC_F_NISTP256_PRE_COMP_NEW 236
+# define EC_F_NISTP521_PRE_COMP_NEW 237
+# define EC_F_O2I_ECPUBLICKEY 152
+# define EC_F_OLD_EC_PRIV_DECODE 222
+# define EC_F_PKEY_EC_CTRL 197
+# define EC_F_PKEY_EC_CTRL_STR 198
+# define EC_F_PKEY_EC_DERIVE 217
+# define EC_F_PKEY_EC_KEYGEN 199
+# define EC_F_PKEY_EC_PARAMGEN 219
+# define EC_F_PKEY_EC_SIGN 218
+
+/* Reason codes. */
+# define EC_R_ASN1_ERROR 115
+# define EC_R_ASN1_UNKNOWN_FIELD 116
+# define EC_R_BIGNUM_OUT_OF_RANGE 144
+# define EC_R_BUFFER_TOO_SMALL 100
+# define EC_R_COORDINATES_OUT_OF_RANGE 146
+# define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
+# define EC_R_DECODE_ERROR 142
+# define EC_R_DISCRIMINANT_IS_ZERO 118
+# define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
+# define EC_R_FIELD_TOO_LARGE 143
+# define EC_R_GF2M_NOT_SUPPORTED 147
+# define EC_R_GROUP2PKPARAMETERS_FAILURE 120
+# define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
+# define EC_R_INCOMPATIBLE_OBJECTS 101
+# define EC_R_INVALID_ARGUMENT 112
+# define EC_R_INVALID_COMPRESSED_POINT 110
+# define EC_R_INVALID_COMPRESSION_BIT 109
+# define EC_R_INVALID_CURVE 141
+# define EC_R_INVALID_DIGEST_TYPE 138
+# 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_PENTANOMIAL_BASIS 132
+# define EC_R_INVALID_PRIVATE_KEY 123
+# define EC_R_INVALID_TRINOMIAL_BASIS 137
+# define EC_R_KEYS_NOT_SET 140
+# 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_PARAMETERS_SET 139
+# 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_CURVE_PARAMETERS 145
+# define EC_R_WRONG_ORDER 130
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/ec/ec2_mult.c b/openssl/ec/ec2_mult.c
new file mode 100644
index 0000000..68cc877
--- /dev/null
+++ b/openssl/ec/ec2_mult.c
@@ -0,0 +1,463 @@
+/* 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-2003 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"
+
+#ifndef OPENSSL_NO_EC2M
+
+/*-
+ * 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" (CHES '99, LNCS 1717).
+ * 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
+ * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
+ * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ */
+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
+ * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
+ * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ * 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)) {
+ BN_zero(x2);
+ BN_zero(z2);
+ 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 a modified algorithm 2P of
+ * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
+ * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ *
+ * To protect against side-channel attack the function uses constant time swap,
+ * avoiding conditional branches.
+ */
+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;
+ BN_ULONG mask, word;
+
+ if (r == point) {
+ ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, 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;
+
+ bn_wexpand(x1, group->field.top);
+ bn_wexpand(z1, group->field.top);
+ bn_wexpand(x2, group->field.top);
+ bn_wexpand(z2, group->field.top);
+
+ 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;
+ mask = BN_TBIT;
+ word = scalar->d[i];
+ while (!(word & mask))
+ mask >>= 1;
+ mask >>= 1;
+ /* if top most bit was at word break, go to next word */
+ if (!mask) {
+ i--;
+ mask = BN_TBIT;
+ }
+
+ for (; i >= 0; i--) {
+ word = scalar->d[i];
+ while (mask) {
+ BN_consttime_swap(word & mask, x1, x2, group->field.top);
+ BN_consttime_swap(word & mask, z1, z2, group->field.top);
+ if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx))
+ goto err;
+ if (!gf2m_Mdouble(group, x1, z1, ctx))
+ goto err;
+ BN_consttime_swap(word & mask, x1, x2, group->field.top);
+ BN_consttime_swap(word & mask, z1, z2, group->field.top);
+ mask >>= 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_negative(&r->X, 0);
+ BN_set_negative(&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;
+ size_t i;
+ EC_POINT *p = NULL;
+ EC_POINT *acc = 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, or if we can perform a fast multiplication based on
+ * precomputation.
+ */
+ if ((scalar && (num > 1)) || (num > 2)
+ || (num == 0 && EC_GROUP_have_precompute_mult(group))) {
+ ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+ goto err;
+ }
+
+ if ((p = EC_POINT_new(group)) == NULL)
+ goto err;
+ if ((acc = EC_POINT_new(group)) == NULL)
+ goto err;
+
+ if (!EC_POINT_set_to_infinity(group, acc))
+ goto err;
+
+ if (scalar) {
+ if (!ec_GF2m_montgomery_point_multiply
+ (group, p, scalar, group->generator, ctx))
+ goto err;
+ if (BN_is_negative(scalar))
+ if (!group->meth->invert(group, p, ctx))
+ goto err;
+ if (!group->meth->add(group, acc, acc, 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_is_negative(scalars[i]))
+ if (!group->meth->invert(group, p, ctx))
+ goto err;
+ if (!group->meth->add(group, acc, acc, p, ctx))
+ goto err;
+ }
+
+ if (!EC_POINT_copy(r, acc))
+ goto err;
+
+ ret = 1;
+
+ err:
+ if (p)
+ EC_POINT_free(p);
+ if (acc)
+ EC_POINT_free(acc);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+/*
+ * Precomputation for point multiplication: fall back to wNAF methods because
+ * ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate
+ */
+
+int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+{
+ return ec_wNAF_precompute_mult(group, ctx);
+}
+
+int ec_GF2m_have_precompute_mult(const EC_GROUP *group)
+{
+ return ec_wNAF_have_precompute_mult(group);
+}
+
+#endif
diff --git a/openssl/ec/ec2_oct.c b/openssl/ec/ec2_oct.c
new file mode 100644
index 0000000..c245d88
--- /dev/null
+++ b/openssl/ec/ec2_oct.c
@@ -0,0 +1,403 @@
+/* crypto/ec/ec2_oct.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-2005 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"
+
+#ifndef OPENSSL_NO_EC2M
+
+/*-
+ * Calculates 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.
+ *
+ * The method is from the following publication:
+ *
+ * Harper, Menezes, Vanstone:
+ * "Public-Key Cryptosystems with Very Small Key Lengths",
+ * EUROCRYPT '92, Springer-Verlag LNCS 658,
+ * published February 1993
+ *
+ * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
+ * the same method, but claim no priority date earlier than July 29, 1994
+ * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
+ */
+int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group,
+ EC_POINT *point,
+ const BIGNUM *x_, int y_bit,
+ BN_CTX *ctx)
+{
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp, *x, *y, *z;
+ int ret = 0, z0;
+
+ /* clear error queue */
+ ERR_clear_error();
+
+ 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)) {
+ unsigned long err = ERR_peek_last_error();
+
+ if (ERR_GET_LIB(err) == ERR_LIB_BN
+ && ERR_GET_REASON(err) == BN_R_NO_SOLUTION) {
+ ERR_clear_error();
+ ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES,
+ EC_R_INVALID_COMPRESSED_POINT);
+ } else
+ ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES,
+ ERR_R_BN_LIB);
+ 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;
+}
+
+/*
+ * 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.
+ */
+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;
+
+ 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;
+ 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]++;
+ }
+
+ 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 & ~1U;
+ 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;
+ }
+
+ /* test required by X9.62 */
+ if (!EC_POINT_is_on_curve(group, point, ctx)) {
+ 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;
+}
+#endif
diff --git a/openssl/ec/ec2_smpl.c b/openssl/ec/ec2_smpl.c
new file mode 100644
index 0000000..077c7fc
--- /dev/null
+++ b/openssl/ec/ec2_smpl.c
@@ -0,0 +1,797 @@
+/* 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-2005 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"
+
+#ifndef OPENSSL_NO_EC2M
+
+# ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+# endif
+
+const EC_METHOD *EC_GF2m_simple_method(void)
+{
+ static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
+ 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,
+ 0, 0, 0,
+ ec_GF2m_simple_add,
+ ec_GF2m_simple_dbl,
+ ec_GF2m_simple_invert,
+ 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,
+
+ /*
+ * the following three method functions are defined in ec2_mult.c
+ */
+ ec_GF2m_simple_mul,
+ ec_GF2m_precompute_mult,
+ ec_GF2m_have_precompute_mult,
+
+ 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 */
+ };
+
+# ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return fips_ec_gf2m_simple_method();
+# endif
+
+ 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;
+ group->poly[5] = -1;
+}
+
+/*
+ * 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];
+ dest->poly[5] = src->poly[5];
+ if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2)
+ == NULL)
+ return 0;
+ if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2)
+ == NULL)
+ return 0;
+ 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, 6) - 1;
+ 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;
+ if (bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2)
+ == NULL)
+ goto err;
+ 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;
+ if (bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2)
+ == NULL)
+ goto err;
+ 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:
+ if (ctx != NULL)
+ 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;
+ BN_zero(&point->Z);
+ return 1;
+}
+
+/*
+ * 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_negative(&point->X, 0);
+ if (!BN_copy(&point->Y, y))
+ goto err;
+ BN_set_negative(&point->Y, 0);
+ if (!BN_copy(&point->Z, BN_value_one()))
+ goto err;
+ BN_set_negative(&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_negative(x, 0);
+ }
+ if (y != NULL) {
+ if (!BN_copy(y, &point->Y))
+ goto err;
+ BN_set_negative(y, 0);
+ }
+ ret = 1;
+
+ err:
+ 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)
+{
+ int ret = -1;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *lh, *y2;
+ int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
+ const BIGNUM *, BN_CTX *);
+ int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+
+ if (EC_POINT_is_at_infinity(group, point))
+ return 1;
+
+ field_mul = group->meth->field_mul;
+ field_sqr = group->meth->field_sqr;
+
+ /* only support affine coordinates */
+ if (!point->Z_is_one)
+ return -1;
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return -1;
+ }
+
+ BN_CTX_start(ctx);
+ y2 = BN_CTX_get(ctx);
+ lh = BN_CTX_get(ctx);
+ if (lh == NULL)
+ goto err;
+
+ /*-
+ * We have a curve defined by a Weierstrass equation
+ * y^2 + x*y = x^3 + a*x^2 + b.
+ * <=> x^3 + a*x^2 + x*y + b + y^2 = 0
+ * <=> ((x + a) * x + y ) * x + b + y^2 = 0
+ */
+ if (!BN_GF2m_add(lh, &point->X, &group->a))
+ goto err;
+ if (!field_mul(group, lh, lh, &point->X, ctx))
+ goto err;
+ if (!BN_GF2m_add(lh, lh, &point->Y))
+ goto err;
+ if (!field_mul(group, lh, lh, &point->X, ctx))
+ goto err;
+ if (!BN_GF2m_add(lh, lh, &group->b))
+ goto err;
+ if (!field_sqr(group, y2, &point->Y, ctx))
+ goto err;
+ if (!BN_GF2m_add(lh, lh, y2))
+ goto err;
+ ret = BN_is_zero(lh);
+ 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 (EC_POINT_is_at_infinity(group, b))
+ return 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);
+}
+
+#endif
diff --git a/openssl/ec/ec_ameth.c b/openssl/ec/ec_ameth.c
new file mode 100644
index 0000000..5cefb5a
--- /dev/null
+++ b/openssl/ec/ec_ameth.c
@@ -0,0 +1,627 @@
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/ec.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_CMS
+# include <openssl/cms.h>
+#endif
+#include "asn1_locl.h"
+
+static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
+{
+ const EC_GROUP *group;
+ int nid;
+ if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
+ ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
+ return 0;
+ }
+ if (EC_GROUP_get_asn1_flag(group)
+ && (nid = EC_GROUP_get_curve_name(group)))
+ /* we have a 'named curve' => just set the OID */
+ {
+ *ppval = OBJ_nid2obj(nid);
+ *pptype = V_ASN1_OBJECT;
+ } else { /* explicit parameters */
+
+ ASN1_STRING *pstr = NULL;
+ pstr = ASN1_STRING_new();
+ if (!pstr)
+ return 0;
+ pstr->length = i2d_ECParameters(ec_key, &pstr->data);
+ if (pstr->length <= 0) {
+ ASN1_STRING_free(pstr);
+ ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
+ return 0;
+ }
+ *ppval = pstr;
+ *pptype = V_ASN1_SEQUENCE;
+ }
+ return 1;
+}
+
+static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+{
+ EC_KEY *ec_key = pkey->pkey.ec;
+ void *pval = NULL;
+ int ptype;
+ unsigned char *penc = NULL, *p;
+ int penclen;
+
+ if (!eckey_param2type(&ptype, &pval, ec_key)) {
+ ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
+ return 0;
+ }
+ penclen = i2o_ECPublicKey(ec_key, NULL);
+ if (penclen <= 0)
+ goto err;
+ penc = OPENSSL_malloc(penclen);
+ if (!penc)
+ goto err;
+ p = penc;
+ penclen = i2o_ECPublicKey(ec_key, &p);
+ if (penclen <= 0)
+ goto err;
+ if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
+ ptype, pval, penc, penclen))
+ return 1;
+ err:
+ if (ptype == V_ASN1_OBJECT)
+ ASN1_OBJECT_free(pval);
+ else
+ ASN1_STRING_free(pval);
+ if (penc)
+ OPENSSL_free(penc);
+ return 0;
+}
+
+static EC_KEY *eckey_type2param(int ptype, void *pval)
+{
+ EC_KEY *eckey = NULL;
+ if (ptype == V_ASN1_SEQUENCE) {
+ ASN1_STRING *pstr = pval;
+ const unsigned char *pm = NULL;
+ int pmlen;
+ pm = pstr->data;
+ pmlen = pstr->length;
+ if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) {
+ ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
+ goto ecerr;
+ }
+ } else if (ptype == V_ASN1_OBJECT) {
+ ASN1_OBJECT *poid = pval;
+ EC_GROUP *group;
+
+ /*
+ * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID
+ */
+ if ((eckey = EC_KEY_new()) == NULL) {
+ ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
+ goto ecerr;
+ }
+ group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
+ if (group == NULL)
+ goto ecerr;
+ EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+ if (EC_KEY_set_group(eckey, group) == 0)
+ goto ecerr;
+ EC_GROUP_free(group);
+ } else {
+ ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
+ goto ecerr;
+ }
+
+ return eckey;
+
+ ecerr:
+ if (eckey)
+ EC_KEY_free(eckey);
+ return NULL;
+}
+
+static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+{
+ const unsigned char *p = NULL;
+ void *pval;
+ int ptype, pklen;
+ EC_KEY *eckey = NULL;
+ X509_ALGOR *palg;
+
+ if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+ return 0;
+ X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+ eckey = eckey_type2param(ptype, pval);
+
+ if (!eckey) {
+ ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
+ return 0;
+ }
+
+ /* We have parameters now set public key */
+ if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
+ ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
+ goto ecerr;
+ }
+
+ EVP_PKEY_assign_EC_KEY(pkey, eckey);
+ return 1;
+
+ ecerr:
+ if (eckey)
+ EC_KEY_free(eckey);
+ return 0;
+}
+
+static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+ int r;
+ const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
+ const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
+ *pb = EC_KEY_get0_public_key(b->pkey.ec);
+ r = EC_POINT_cmp(group, pa, pb, NULL);
+ if (r == 0)
+ return 1;
+ if (r == 1)
+ return 0;
+ return -2;
+}
+
+static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
+{
+ const unsigned char *p = NULL;
+ void *pval;
+ int ptype, pklen;
+ EC_KEY *eckey = NULL;
+ X509_ALGOR *palg;
+
+ if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+ return 0;
+ X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+ eckey = eckey_type2param(ptype, pval);
+
+ if (!eckey)
+ goto ecliberr;
+
+ /* We have parameters now set private key */
+ if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
+ ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
+ goto ecerr;
+ }
+
+ /* calculate public key (if necessary) */
+ if (EC_KEY_get0_public_key(eckey) == NULL) {
+ const BIGNUM *priv_key;
+ const EC_GROUP *group;
+ EC_POINT *pub_key;
+ /*
+ * the public key was not included in the SEC1 private key =>
+ * calculate the public key
+ */
+ group = EC_KEY_get0_group(eckey);
+ pub_key = EC_POINT_new(group);
+ if (pub_key == NULL) {
+ ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+ goto ecliberr;
+ }
+ if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
+ EC_POINT_free(pub_key);
+ ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+ goto ecliberr;
+ }
+ priv_key = EC_KEY_get0_private_key(eckey);
+ if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
+ EC_POINT_free(pub_key);
+ ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+ goto ecliberr;
+ }
+ if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
+ EC_POINT_free(pub_key);
+ ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+ goto ecliberr;
+ }
+ EC_POINT_free(pub_key);
+ }
+
+ EVP_PKEY_assign_EC_KEY(pkey, eckey);
+ return 1;
+
+ ecliberr:
+ ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+ ecerr:
+ if (eckey)
+ EC_KEY_free(eckey);
+ return 0;
+}
+
+static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+ EC_KEY *ec_key;
+ unsigned char *ep, *p;
+ int eplen, ptype;
+ void *pval;
+ unsigned int tmp_flags, old_flags;
+
+ ec_key = pkey->pkey.ec;
+
+ if (!eckey_param2type(&ptype, &pval, ec_key)) {
+ ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
+ return 0;
+ }
+
+ /* set the private key */
+
+ /*
+ * do not include the parameters in the SEC1 private key see PKCS#11
+ * 12.11
+ */
+ old_flags = EC_KEY_get_enc_flags(ec_key);
+ tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
+ EC_KEY_set_enc_flags(ec_key, tmp_flags);
+ eplen = i2d_ECPrivateKey(ec_key, NULL);
+ if (!eplen) {
+ EC_KEY_set_enc_flags(ec_key, old_flags);
+ ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
+ return 0;
+ }
+ ep = (unsigned char *)OPENSSL_malloc(eplen);
+ if (!ep) {
+ EC_KEY_set_enc_flags(ec_key, old_flags);
+ ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ p = ep;
+ if (!i2d_ECPrivateKey(ec_key, &p)) {
+ EC_KEY_set_enc_flags(ec_key, old_flags);
+ OPENSSL_free(ep);
+ ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
+ return 0;
+ }
+ /* restore old encoding flags */
+ EC_KEY_set_enc_flags(ec_key, old_flags);
+
+ if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
+ ptype, pval, ep, eplen))
+ return 0;
+
+ return 1;
+}
+
+static int int_ec_size(const EVP_PKEY *pkey)
+{
+ return ECDSA_size(pkey->pkey.ec);
+}
+
+static int ec_bits(const EVP_PKEY *pkey)
+{
+ BIGNUM *order = BN_new();
+ const EC_GROUP *group;
+ int ret;
+
+ if (!order) {
+ ERR_clear_error();
+ return 0;
+ }
+ group = EC_KEY_get0_group(pkey->pkey.ec);
+ if (!EC_GROUP_get_order(group, order, NULL)) {
+ ERR_clear_error();
+ return 0;
+ }
+
+ ret = BN_num_bits(order);
+ BN_free(order);
+ return ret;
+}
+
+static int ec_missing_parameters(const EVP_PKEY *pkey)
+{
+ if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
+ return 1;
+ return 0;
+}
+
+static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+{
+ EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
+ if (group == NULL)
+ return 0;
+ if (EC_KEY_set_group(to->pkey.ec, group) == 0)
+ return 0;
+ EC_GROUP_free(group);
+ return 1;
+}
+
+static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+ const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
+ *group_b = EC_KEY_get0_group(b->pkey.ec);
+ if (EC_GROUP_cmp(group_a, group_b, NULL))
+ return 0;
+ else
+ return 1;
+}
+
+static void int_ec_free(EVP_PKEY *pkey)
+{
+ EC_KEY_free(pkey->pkey.ec);
+}
+
+static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype)
+{
+ unsigned char *buffer = NULL;
+ const char *ecstr;
+ size_t buf_len = 0, i;
+ int ret = 0, reason = ERR_R_BIO_LIB;
+ BIGNUM *pub_key = NULL, *order = NULL;
+ BN_CTX *ctx = NULL;
+ const EC_GROUP *group;
+ const EC_POINT *public_key;
+ const BIGNUM *priv_key;
+
+ if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
+ reason = ERR_R_PASSED_NULL_PARAMETER;
+ goto err;
+ }
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+
+ if (ktype > 0) {
+ public_key = EC_KEY_get0_public_key(x);
+ if (public_key != NULL) {
+ if ((pub_key = EC_POINT_point2bn(group, public_key,
+ EC_KEY_get_conv_form(x), NULL,
+ ctx)) == NULL) {
+ reason = ERR_R_EC_LIB;
+ goto err;
+ }
+ buf_len = (size_t)BN_num_bytes(pub_key);
+ }
+ }
+
+ if (ktype == 2) {
+ priv_key = EC_KEY_get0_private_key(x);
+ if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
+ buf_len = i;
+ } else
+ priv_key = NULL;
+
+ if (ktype > 0) {
+ buf_len += 10;
+ if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
+ reason = ERR_R_MALLOC_FAILURE;
+ goto err;
+ }
+ }
+ if (ktype == 2)
+ ecstr = "Private-Key";
+ else if (ktype == 1)
+ ecstr = "Public-Key";
+ else
+ ecstr = "ECDSA-Parameters";
+
+ if (!BIO_indent(bp, off, 128))
+ goto err;
+ if ((order = BN_new()) == NULL)
+ goto err;
+ if (!EC_GROUP_get_order(group, order, NULL))
+ goto err;
+ if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0)
+ goto err;
+
+ if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key,
+ buffer, off))
+ goto err;
+ if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key,
+ buffer, off))
+ goto err;
+ if (!ECPKParameters_print(bp, group, off))
+ goto err;
+ ret = 1;
+ err:
+ if (!ret)
+ ECerr(EC_F_DO_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);
+}
+
+static int eckey_param_decode(EVP_PKEY *pkey,
+ const unsigned char **pder, int derlen)
+{
+ EC_KEY *eckey;
+ if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
+ ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
+ return 0;
+ }
+ EVP_PKEY_assign_EC_KEY(pkey, eckey);
+ return 1;
+}
+
+static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+ return i2d_ECParameters(pkey->pkey.ec, pder);
+}
+
+static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx)
+{
+ return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
+}
+
+static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx)
+{
+ return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
+}
+
+static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx)
+{
+ return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
+}
+
+static int old_ec_priv_decode(EVP_PKEY *pkey,
+ const unsigned char **pder, int derlen)
+{
+ EC_KEY *ec;
+ if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
+ ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
+ return 0;
+ }
+ EVP_PKEY_assign_EC_KEY(pkey, ec);
+ return 1;
+}
+
+static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+ return i2d_ECPrivateKey(pkey->pkey.ec, pder);
+}
+
+static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+ switch (op) {
+ case ASN1_PKEY_CTRL_PKCS7_SIGN:
+ if (arg1 == 0) {
+ int snid, hnid;
+ X509_ALGOR *alg1, *alg2;
+ PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
+ if (alg1 == NULL || alg1->algorithm == NULL)
+ return -1;
+ hnid = OBJ_obj2nid(alg1->algorithm);
+ if (hnid == NID_undef)
+ return -1;
+ if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+ return -1;
+ X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+ }
+ return 1;
+#ifndef OPENSSL_NO_CMS
+ case ASN1_PKEY_CTRL_CMS_SIGN:
+ if (arg1 == 0) {
+ int snid, hnid;
+ X509_ALGOR *alg1, *alg2;
+ CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
+ if (alg1 == NULL || alg1->algorithm == NULL)
+ return -1;
+ hnid = OBJ_obj2nid(alg1->algorithm);
+ if (hnid == NID_undef)
+ return -1;
+ if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+ return -1;
+ X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+ }
+ return 1;
+#endif
+
+ case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+ *(int *)arg2 = NID_sha1;
+ return 2;
+
+ default:
+ return -2;
+
+ }
+
+}
+
+const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
+ EVP_PKEY_EC,
+ EVP_PKEY_EC,
+ 0,
+ "EC",
+ "OpenSSL EC algorithm",
+
+ eckey_pub_decode,
+ eckey_pub_encode,
+ eckey_pub_cmp,
+ eckey_pub_print,
+
+ eckey_priv_decode,
+ eckey_priv_encode,
+ eckey_priv_print,
+
+ int_ec_size,
+ ec_bits,
+
+ eckey_param_decode,
+ eckey_param_encode,
+ ec_missing_parameters,
+ ec_copy_parameters,
+ ec_cmp_parameters,
+ eckey_param_print,
+ 0,
+
+ int_ec_free,
+ ec_pkey_ctrl,
+ old_ec_priv_decode,
+ old_ec_priv_encode
+};
diff --git a/openssl/ec/ec_asn1.c b/openssl/ec/ec_asn1.c
new file mode 100644
index 0000000..b4b0e9f
--- /dev/null
+++ b/openssl/ec/ec_asn1.c
@@ -0,0 +1,1308 @@
+/* crypto/ec/ec_asn1.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2003 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 <string.h>
+#include "ec_lcl.h"
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+
+int EC_GROUP_get_basis_type(const EC_GROUP *group)
+{
+ int i = 0;
+
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
+ NID_X9_62_characteristic_two_field)
+ /* everything else is currently not supported */
+ return 0;
+
+ while (group->poly[i] != 0)
+ i++;
+
+ if (i == 4)
+ return NID_X9_62_ppBasis;
+ else if (i == 2)
+ return NID_X9_62_tpBasis;
+ else
+ /* everything else is currently not supported */
+ return 0;
+}
+
+#ifndef OPENSSL_NO_EC2M
+int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
+{
+ if (group == NULL)
+ return 0;
+
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
+ NID_X9_62_characteristic_two_field
+ || !((group->poly[0] != 0) && (group->poly[1] != 0)
+ && (group->poly[2] == 0))) {
+ ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
+ if (k)
+ *k = group->poly[1];
+
+ return 1;
+}
+
+int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
+ unsigned int *k2, unsigned int *k3)
+{
+ if (group == NULL)
+ return 0;
+
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
+ NID_X9_62_characteristic_two_field
+ || !((group->poly[0] != 0) && (group->poly[1] != 0)
+ && (group->poly[2] != 0) && (group->poly[3] != 0)
+ && (group->poly[4] == 0))) {
+ ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+
+ if (k1)
+ *k1 = group->poly[3];
+ if (k2)
+ *k2 = group->poly[2];
+ if (k3)
+ *k3 = group->poly[1];
+
+ return 1;
+}
+#endif
+
+/* some structures needed for the asn1 encoding */
+typedef struct x9_62_pentanomial_st {
+ long k1;
+ long k2;
+ long k3;
+} X9_62_PENTANOMIAL;
+
+typedef struct x9_62_characteristic_two_st {
+ long m;
+ ASN1_OBJECT *type;
+ union {
+ char *ptr;
+ /* NID_X9_62_onBasis */
+ ASN1_NULL *onBasis;
+ /* NID_X9_62_tpBasis */
+ ASN1_INTEGER *tpBasis;
+ /* NID_X9_62_ppBasis */
+ X9_62_PENTANOMIAL *ppBasis;
+ /* anything else */
+ ASN1_TYPE *other;
+ } p;
+} X9_62_CHARACTERISTIC_TWO;
+
+typedef struct x9_62_fieldid_st {
+ ASN1_OBJECT *fieldType;
+ union {
+ char *ptr;
+ /* NID_X9_62_prime_field */
+ ASN1_INTEGER *prime;
+ /* NID_X9_62_characteristic_two_field */
+ X9_62_CHARACTERISTIC_TWO *char_two;
+ /* anything else */
+ ASN1_TYPE *other;
+ } p;
+} X9_62_FIELDID;
+
+typedef struct x9_62_curve_st {
+ ASN1_OCTET_STRING *a;
+ ASN1_OCTET_STRING *b;
+ ASN1_BIT_STRING *seed;
+} X9_62_CURVE;
+
+typedef struct ec_parameters_st {
+ long version;
+ X9_62_FIELDID *fieldID;
+ X9_62_CURVE *curve;
+ ASN1_OCTET_STRING *base;
+ ASN1_INTEGER *order;
+ ASN1_INTEGER *cofactor;
+} ECPARAMETERS;
+
+struct ecpk_parameters_st {
+ int type;
+ union {
+ ASN1_OBJECT *named_curve;
+ ECPARAMETERS *parameters;
+ ASN1_NULL *implicitlyCA;
+ } value;
+} /* ECPKPARAMETERS */ ;
+
+/* SEC1 ECPrivateKey */
+typedef struct ec_privatekey_st {
+ long version;
+ ASN1_OCTET_STRING *privateKey;
+ ECPKPARAMETERS *parameters;
+ ASN1_BIT_STRING *publicKey;
+} EC_PRIVATEKEY;
+
+/* the OpenSSL ASN.1 definitions */
+ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
+ ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
+ ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
+ ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
+} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
+
+ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);
+
+ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
+ ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)),
+ ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)),
+ ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL))
+} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);
+
+ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
+ ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
+ ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
+ ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
+} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
+
+ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
+
+ASN1_ADB(X9_62_FIELDID) = {
+ ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
+ ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO))
+} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
+
+ASN1_SEQUENCE(X9_62_FIELDID) = {
+ ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
+ ASN1_ADB_OBJECT(X9_62_FIELDID)
+} ASN1_SEQUENCE_END(X9_62_FIELDID)
+
+ASN1_SEQUENCE(X9_62_CURVE) = {
+ ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
+ ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
+ ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(X9_62_CURVE)
+
+ASN1_SEQUENCE(ECPARAMETERS) = {
+ ASN1_SIMPLE(ECPARAMETERS, version, LONG),
+ ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
+ ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
+ ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
+ ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
+ ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(ECPARAMETERS)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
+
+ASN1_CHOICE(ECPKPARAMETERS) = {
+ ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
+ ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
+ ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
+} ASN1_CHOICE_END(ECPKPARAMETERS)
+
+DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
+IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
+
+ASN1_SEQUENCE(EC_PRIVATEKEY) = {
+ ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
+ ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
+ ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
+ ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
+} ASN1_SEQUENCE_END(EC_PRIVATEKEY)
+
+DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
+IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
+
+/* some declarations of internal function */
+
+/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */
+static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
+/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
+static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
+/*
+ * ec_asn1_parameters2group() creates a EC_GROUP object from a ECPARAMETERS
+ * object
+ */
+static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *);
+/*
+ * ec_asn1_group2parameters() creates a ECPARAMETERS object from a EC_GROUP
+ * object
+ */
+static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,
+ ECPARAMETERS *);
+/*
+ * ec_asn1_pkparameters2group() creates a EC_GROUP object from a
+ * ECPKPARAMETERS object
+ */
+static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *);
+/*
+ * ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a
+ * EC_GROUP object
+ */
+static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *,
+ ECPKPARAMETERS *);
+
+/* the function definitions */
+
+static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
+{
+ int ok = 0, nid;
+ BIGNUM *tmp = NULL;
+
+ if (group == NULL || field == NULL)
+ return 0;
+
+ /* clear the old values (if necessary) */
+ if (field->fieldType != NULL)
+ ASN1_OBJECT_free(field->fieldType);
+ if (field->p.other != NULL)
+ ASN1_TYPE_free(field->p.other);
+
+ nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
+ /* set OID for the field */
+ if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
+ goto err;
+ }
+
+ if (nid == NID_X9_62_prime_field) {
+ if ((tmp = BN_new()) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ /* the parameters are specified by the prime number p */
+ if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
+ goto err;
+ }
+ /* set the prime number */
+ field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL);
+ if (field->p.prime == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ } else /* nid == NID_X9_62_characteristic_two_field */
+#ifdef OPENSSL_NO_EC2M
+ {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
+ goto err;
+ }
+#else
+ {
+ int field_type;
+ X9_62_CHARACTERISTIC_TWO *char_two;
+
+ field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
+ char_two = field->p.char_two;
+
+ if (char_two == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ char_two->m = (long)EC_GROUP_get_degree(group);
+
+ field_type = EC_GROUP_get_basis_type(group);
+
+ if (field_type == 0) {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
+ goto err;
+ }
+ /* set base type OID */
+ if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
+ goto err;
+ }
+
+ if (field_type == NID_X9_62_tpBasis) {
+ unsigned int k;
+
+ if (!EC_GROUP_get_trinomial_basis(group, &k))
+ goto err;
+
+ char_two->p.tpBasis = ASN1_INTEGER_new();
+ if (!char_two->p.tpBasis) {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ } else if (field_type == NID_X9_62_ppBasis) {
+ unsigned int k1, k2, k3;
+
+ if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
+ goto err;
+
+ char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
+ if (!char_two->p.ppBasis) {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* set k? values */
+ char_two->p.ppBasis->k1 = (long)k1;
+ char_two->p.ppBasis->k2 = (long)k2;
+ char_two->p.ppBasis->k3 = (long)k3;
+ } else { /* field_type == NID_X9_62_onBasis */
+
+ /* for ONB the parameters are (asn1) NULL */
+ char_two->p.onBasis = ASN1_NULL_new();
+ if (!char_two->p.onBasis) {
+ ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ }
+#endif
+
+ ok = 1;
+
+ err:if (tmp)
+ BN_free(tmp);
+ return (ok);
+}
+
+static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
+{
+ int ok = 0, nid;
+ BIGNUM *tmp_1 = NULL, *tmp_2 = NULL;
+ unsigned char *buffer_1 = NULL, *buffer_2 = NULL,
+ *a_buf = NULL, *b_buf = NULL;
+ size_t len_1, len_2;
+ unsigned char char_zero = 0;
+
+ if (!group || !curve || !curve->a || !curve->b)
+ return 0;
+
+ if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
+
+ /* get a and b */
+ if (nid == NID_X9_62_prime_field) {
+ if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) {
+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+#ifndef OPENSSL_NO_EC2M
+ else { /* nid == NID_X9_62_characteristic_two_field */
+
+ if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) {
+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+#endif
+ len_1 = (size_t)BN_num_bytes(tmp_1);
+ len_2 = (size_t)BN_num_bytes(tmp_2);
+
+ if (len_1 == 0) {
+ /* len_1 == 0 => a == 0 */
+ a_buf = &char_zero;
+ len_1 = 1;
+ } else {
+ if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) {
+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
+ goto err;
+ }
+ a_buf = buffer_1;
+ }
+
+ if (len_2 == 0) {
+ /* len_2 == 0 => b == 0 */
+ b_buf = &char_zero;
+ len_2 = 1;
+ } else {
+ if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) {
+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
+ goto err;
+ }
+ b_buf = buffer_2;
+ }
+
+ /* set a and b */
+ if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
+ !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) {
+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
+ goto err;
+ }
+
+ /* set the seed (optional) */
+ if (group->seed) {
+ if (!curve->seed)
+ if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
+ (int)group->seed_len)) {
+ ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ } else {
+ if (curve->seed) {
+ ASN1_BIT_STRING_free(curve->seed);
+ curve->seed = NULL;
+ }
+ }
+
+ ok = 1;
+
+ err:if (buffer_1)
+ OPENSSL_free(buffer_1);
+ if (buffer_2)
+ OPENSSL_free(buffer_2);
+ if (tmp_1)
+ BN_free(tmp_1);
+ if (tmp_2)
+ BN_free(tmp_2);
+ return (ok);
+}
+
+static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group,
+ ECPARAMETERS *param)
+{
+ int ok = 0;
+ size_t len = 0;
+ ECPARAMETERS *ret = NULL;
+ BIGNUM *tmp = NULL;
+ unsigned char *buffer = NULL;
+ const EC_POINT *point = NULL;
+ point_conversion_form_t form;
+
+ if ((tmp = BN_new()) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (param == NULL) {
+ if ((ret = ECPARAMETERS_new()) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ } else
+ ret = param;
+
+ /* set the version (always one) */
+ ret->version = (long)0x1;
+
+ /* set the fieldID */
+ if (!ec_asn1_group2fieldid(group, ret->fieldID)) {
+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ /* set the curve */
+ if (!ec_asn1_group2curve(group, ret->curve)) {
+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ /* set the base point */
+ if ((point = EC_GROUP_get0_generator(group)) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR);
+ goto err;
+ }
+
+ form = EC_GROUP_get_point_conversion_form(group);
+
+ len = EC_POINT_point2oct(group, point, form, NULL, len, NULL);
+ if (len == 0) {
+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+ goto err;
+ }
+ if ((buffer = OPENSSL_malloc(len)) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) {
+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+ goto err;
+ }
+ if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) {
+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
+ goto err;
+ }
+
+ /* set the order */
+ if (!EC_GROUP_get_order(group, tmp, NULL)) {
+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB);
+ goto err;
+ }
+ ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
+ if (ret->order == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
+ goto err;
+ }
+
+ /* set the cofactor (optional) */
+ if (EC_GROUP_get_cofactor(group, tmp, NULL)) {
+ ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
+ if (ret->cofactor == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ }
+
+ ok = 1;
+
+ err:if (!ok) {
+ if (ret && !param)
+ ECPARAMETERS_free(ret);
+ ret = NULL;
+ }
+ if (tmp)
+ BN_free(tmp);
+ if (buffer)
+ OPENSSL_free(buffer);
+ return (ret);
+}
+
+ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
+ ECPKPARAMETERS *params)
+{
+ int ok = 1, tmp;
+ ECPKPARAMETERS *ret = params;
+
+ if (ret == NULL) {
+ if ((ret = ECPKPARAMETERS_new()) == NULL) {
+ ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ } else {
+ if (ret->type == 0 && ret->value.named_curve)
+ ASN1_OBJECT_free(ret->value.named_curve);
+ else if (ret->type == 1 && ret->value.parameters)
+ ECPARAMETERS_free(ret->value.parameters);
+ }
+
+ if (EC_GROUP_get_asn1_flag(group)) {
+ /*
+ * use the asn1 OID to describe the the elliptic curve parameters
+ */
+ tmp = EC_GROUP_get_curve_name(group);
+ if (tmp) {
+ ret->type = 0;
+ if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
+ ok = 0;
+ } else
+ /* we don't kmow the nid => ERROR */
+ ok = 0;
+ } else {
+ /* use the ECPARAMETERS structure */
+ ret->type = 1;
+ if ((ret->value.parameters =
+ ec_asn1_group2parameters(group, NULL)) == NULL)
+ ok = 0;
+ }
+
+ if (!ok) {
+ ECPKPARAMETERS_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params)
+{
+ int ok = 0, tmp;
+ EC_GROUP *ret = NULL;
+ BIGNUM *p = NULL, *a = NULL, *b = NULL;
+ EC_POINT *point = NULL;
+ long field_bits;
+
+ if (!params->fieldID || !params->fieldID->fieldType ||
+ !params->fieldID->p.ptr) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+ goto err;
+ }
+
+ /* now extract the curve parameters a and b */
+ if (!params->curve || !params->curve->a ||
+ !params->curve->a->data || !params->curve->b ||
+ !params->curve->b->data) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+ goto err;
+ }
+ a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
+ if (a == NULL) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
+ goto err;
+ }
+ b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
+ if (b == NULL) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ /* get the field parameters */
+ tmp = OBJ_obj2nid(params->fieldID->fieldType);
+ if (tmp == NID_X9_62_characteristic_two_field)
+#ifdef OPENSSL_NO_EC2M
+ {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED);
+ goto err;
+ }
+#else
+ {
+ X9_62_CHARACTERISTIC_TWO *char_two;
+
+ char_two = params->fieldID->p.char_two;
+
+ field_bits = char_two->m;
+ if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
+ goto err;
+ }
+
+ if ((p = BN_new()) == NULL) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* get the base type */
+ tmp = OBJ_obj2nid(char_two->type);
+
+ if (tmp == NID_X9_62_tpBasis) {
+ long tmp_long;
+
+ if (!char_two->p.tpBasis) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+ goto err;
+ }
+
+ tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
+
+ if (!(char_two->m > tmp_long && tmp_long > 0)) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
+ EC_R_INVALID_TRINOMIAL_BASIS);
+ goto err;
+ }
+
+ /* create the polynomial */
+ if (!BN_set_bit(p, (int)char_two->m))
+ goto err;
+ if (!BN_set_bit(p, (int)tmp_long))
+ goto err;
+ if (!BN_set_bit(p, 0))
+ goto err;
+ } else if (tmp == NID_X9_62_ppBasis) {
+ X9_62_PENTANOMIAL *penta;
+
+ penta = char_two->p.ppBasis;
+ if (!penta) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+ goto err;
+ }
+
+ if (!
+ (char_two->m > penta->k3 && penta->k3 > penta->k2
+ && penta->k2 > penta->k1 && penta->k1 > 0)) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP,
+ EC_R_INVALID_PENTANOMIAL_BASIS);
+ goto err;
+ }
+
+ /* create the polynomial */
+ if (!BN_set_bit(p, (int)char_two->m))
+ goto err;
+ if (!BN_set_bit(p, (int)penta->k1))
+ goto err;
+ if (!BN_set_bit(p, (int)penta->k2))
+ goto err;
+ if (!BN_set_bit(p, (int)penta->k3))
+ goto err;
+ if (!BN_set_bit(p, 0))
+ goto err;
+ } else if (tmp == NID_X9_62_onBasis) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED);
+ goto err;
+ } else { /* error */
+
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+ goto err;
+ }
+
+ /* create the EC_GROUP structure */
+ ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
+ }
+#endif
+ else if (tmp == NID_X9_62_prime_field) {
+ /* we have a curve over a prime field */
+ /* extract the prime number */
+ if (!params->fieldID->p.prime) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+ goto err;
+ }
+ p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
+ if (p == NULL) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
+ goto err;
+ }
+
+ if (BN_is_negative(p) || BN_is_zero(p)) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
+ goto err;
+ }
+
+ field_bits = BN_num_bits(p);
+ if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE);
+ goto err;
+ }
+
+ /* create the EC_GROUP structure */
+ ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
+ } else {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD);
+ goto err;
+ }
+
+ if (ret == NULL) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ /* extract seed (optional) */
+ if (params->curve->seed != NULL) {
+ if (ret->seed != NULL)
+ OPENSSL_free(ret->seed);
+ if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length))) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ memcpy(ret->seed, params->curve->seed->data,
+ params->curve->seed->length);
+ ret->seed_len = params->curve->seed->length;
+ }
+
+ if (!params->order || !params->base || !params->base->data) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR);
+ goto err;
+ }
+
+ if ((point = EC_POINT_new(ret)) == NULL)
+ goto err;
+
+ /* set the point conversion form */
+ EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
+ (params->base->data[0] & ~0x01));
+
+ /* extract the ec point */
+ if (!EC_POINT_oct2point(ret, point, params->base->data,
+ params->base->length, NULL)) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ /* extract the order */
+ if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ if (BN_is_negative(a) || BN_is_zero(a)) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
+ goto err;
+ }
+ if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER);
+ goto err;
+ }
+
+ /* extract the cofactor (optional) */
+ if (params->cofactor == NULL) {
+ if (b) {
+ BN_free(b);
+ b = NULL;
+ }
+ } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ /* set the generator, order and cofactor (if present) */
+ if (!EC_GROUP_set_generator(ret, point, a, b)) {
+ ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ ok = 1;
+
+ err:if (!ok) {
+ if (ret)
+ EC_GROUP_clear_free(ret);
+ ret = NULL;
+ }
+
+ if (p)
+ BN_free(p);
+ if (a)
+ BN_free(a);
+ if (b)
+ BN_free(b);
+ if (point)
+ EC_POINT_free(point);
+ return (ret);
+}
+
+EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params)
+{
+ EC_GROUP *ret = NULL;
+ int tmp = 0;
+
+ if (params == NULL) {
+ ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_MISSING_PARAMETERS);
+ return NULL;
+ }
+
+ if (params->type == 0) { /* the curve is given by an OID */
+ tmp = OBJ_obj2nid(params->value.named_curve);
+ if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) {
+ ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP,
+ EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
+ return NULL;
+ }
+ EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
+ } else if (params->type == 1) { /* the parameters are given by a
+ * ECPARAMETERS structure */
+ ret = ec_asn1_parameters2group(params->value.parameters);
+ if (!ret) {
+ ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB);
+ return NULL;
+ }
+ EC_GROUP_set_asn1_flag(ret, 0x0);
+ } else if (params->type == 2) { /* implicitlyCA */
+ return NULL;
+ } else {
+ ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR);
+ return NULL;
+ }
+
+ return ret;
+}
+
+/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
+
+EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
+{
+ EC_GROUP *group = NULL;
+ ECPKPARAMETERS *params = NULL;
+
+ if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) {
+ ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
+ ECPKPARAMETERS_free(params);
+ return NULL;
+ }
+
+ if ((group = ec_asn1_pkparameters2group(params)) == NULL) {
+ ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
+ ECPKPARAMETERS_free(params);
+ return NULL;
+ }
+
+ if (a && *a)
+ EC_GROUP_clear_free(*a);
+ if (a)
+ *a = group;
+
+ ECPKPARAMETERS_free(params);
+ return (group);
+}
+
+int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
+{
+ int ret = 0;
+ ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL);
+ if (tmp == NULL) {
+ ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
+ return 0;
+ }
+ if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) {
+ ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
+ ECPKPARAMETERS_free(tmp);
+ return 0;
+ }
+ ECPKPARAMETERS_free(tmp);
+ return (ret);
+}
+
+/* some EC_KEY functions */
+
+EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
+{
+ int ok = 0;
+ EC_KEY *ret = NULL;
+ EC_PRIVATEKEY *priv_key = NULL;
+
+ if ((priv_key = d2i_EC_PRIVATEKEY(NULL, in, len)) == NULL) {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ return NULL;
+ }
+
+ if (a == NULL || *a == NULL) {
+ if ((ret = EC_KEY_new()) == NULL) {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ } else
+ ret = *a;
+
+ if (priv_key->parameters) {
+ if (ret->group)
+ EC_GROUP_clear_free(ret->group);
+ ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
+ }
+
+ if (ret->group == NULL) {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ ret->version = priv_key->version;
+
+ if (priv_key->privateKey) {
+ ret->priv_key = BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey),
+ M_ASN1_STRING_length(priv_key->privateKey),
+ ret->priv_key);
+ if (ret->priv_key == NULL) {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_BN_LIB);
+ goto err;
+ }
+ } else {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY);
+ goto err;
+ }
+
+ if (ret->pub_key)
+ EC_POINT_clear_free(ret->pub_key);
+ ret->pub_key = EC_POINT_new(ret->group);
+ if (ret->pub_key == NULL) {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ if (priv_key->publicKey) {
+ const unsigned char *pub_oct;
+ int pub_oct_len;
+
+ pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
+ pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
+ /*
+ * The first byte - point conversion form - must be present.
+ */
+ if (pub_oct_len <= 0) {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL);
+ goto err;
+ }
+ /* Save the point conversion form. */
+ ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01);
+ if (!EC_POINT_oct2point(ret->group, ret->pub_key,
+ pub_oct, (size_t)(pub_oct_len), NULL)) {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+ } else {
+ if (!EC_POINT_mul
+ (ret->group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+ /* Remember the original private-key-only encoding. */
+ ret->enc_flag |= EC_PKEY_NO_PUBKEY;
+ }
+
+ if (a)
+ *a = ret;
+ ok = 1;
+ err:
+ if (!ok) {
+ if (ret && (a == NULL || *a != ret))
+ EC_KEY_free(ret);
+ ret = NULL;
+ }
+
+ if (priv_key)
+ EC_PRIVATEKEY_free(priv_key);
+
+ return (ret);
+}
+
+int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
+{
+ int ret = 0, ok = 0;
+ unsigned char *buffer = NULL;
+ size_t buf_len = 0, tmp_len;
+ EC_PRIVATEKEY *priv_key = NULL;
+
+ if (a == NULL || a->group == NULL || a->priv_key == NULL ||
+ (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
+ goto err;
+ }
+
+ if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ priv_key->version = a->version;
+
+ buf_len = (size_t)BN_num_bytes(a->priv_key);
+ buffer = OPENSSL_malloc(buf_len);
+ if (buffer == NULL) {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!BN_bn2bin(a->priv_key, buffer)) {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
+ goto err;
+ }
+
+ if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) {
+ if ((priv_key->parameters =
+ ec_asn1_group2pkparameters(a->group,
+ priv_key->parameters)) == NULL) {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+
+ if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) {
+ priv_key->publicKey = M_ASN1_BIT_STRING_new();
+ if (priv_key->publicKey == NULL) {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
+ a->conv_form, NULL, 0, NULL);
+
+ if (tmp_len > buf_len) {
+ unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
+ if (!tmp_buffer) {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ buffer = tmp_buffer;
+ buf_len = tmp_len;
+ }
+
+ if (!EC_POINT_point2oct(a->group, a->pub_key,
+ a->conv_form, buffer, buf_len, NULL)) {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+ priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ }
+
+ if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+ ok = 1;
+ err:
+ if (buffer)
+ OPENSSL_free(buffer);
+ if (priv_key)
+ EC_PRIVATEKEY_free(priv_key);
+ return (ok ? ret : 0);
+}
+
+int i2d_ECParameters(EC_KEY *a, unsigned char **out)
+{
+ if (a == NULL) {
+ ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ return i2d_ECPKParameters(a->group, out);
+}
+
+EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
+{
+ EC_KEY *ret;
+
+ if (in == NULL || *in == NULL) {
+ ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+
+ if (a == NULL || *a == NULL) {
+ if ((ret = EC_KEY_new()) == NULL) {
+ ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ } else
+ ret = *a;
+
+ if (!d2i_ECPKParameters(&ret->group, in, len)) {
+ ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
+ if (a == NULL || *a != ret)
+ EC_KEY_free(ret);
+ return NULL;
+ }
+
+ if (a)
+ *a = ret;
+
+ return ret;
+}
+
+EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
+{
+ EC_KEY *ret = NULL;
+
+ if (a == NULL || (*a) == NULL || (*a)->group == NULL) {
+ /*
+ * sorry, but a EC_GROUP-structur is necessary to set the public key
+ */
+ ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ ret = *a;
+ if (ret->pub_key == NULL &&
+ (ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
+ ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) {
+ ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
+ return 0;
+ }
+ /* save the point conversion form */
+ ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01);
+ *in += len;
+ return ret;
+}
+
+int i2o_ECPublicKey(EC_KEY *a, unsigned char **out)
+{
+ size_t buf_len = 0;
+ int new_buffer = 0;
+
+ if (a == NULL) {
+ ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ buf_len = EC_POINT_point2oct(a->group, a->pub_key,
+ a->conv_form, NULL, 0, NULL);
+
+ if (out == NULL || buf_len == 0)
+ /* out == NULL => just return the length of the octet string */
+ return buf_len;
+
+ if (*out == NULL) {
+ if ((*out = OPENSSL_malloc(buf_len)) == NULL) {
+ ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ new_buffer = 1;
+ }
+ if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
+ *out, buf_len, NULL)) {
+ ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
+ if (new_buffer) {
+ OPENSSL_free(*out);
+ *out = NULL;
+ }
+ return 0;
+ }
+ if (!new_buffer)
+ *out += buf_len;
+ return buf_len;
+}
diff --git a/openssl/ec/ec_check.c b/openssl/ec/ec_check.c
new file mode 100644
index 0000000..d3f5349
--- /dev/null
+++ b/openssl/ec/ec_check.c
@@ -0,0 +1,120 @@
+/* crypto/ec/ec_check.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).
+ *
+ */
+
+#include "ec_lcl.h"
+#include <openssl/err.h>
+
+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
+{
+ int ret = 0;
+ BIGNUM *order;
+ BN_CTX *new_ctx = NULL;
+ EC_POINT *point = NULL;
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ BN_CTX_start(ctx);
+ if ((order = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ /* check the discriminant */
+ if (!EC_GROUP_check_discriminant(group, ctx)) {
+ ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
+ goto err;
+ }
+
+ /* check the generator */
+ if (group->generator == NULL) {
+ ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
+ goto err;
+ }
+ if (!EC_POINT_is_on_curve(group, group->generator, ctx)) {
+ ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
+ goto err;
+ }
+
+ /* check the order of the generator */
+ if ((point = EC_POINT_new(group)) == NULL)
+ goto err;
+ if (!EC_GROUP_get_order(group, order, ctx))
+ goto err;
+ if (BN_is_zero(order)) {
+ ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
+ goto err;
+ }
+
+ if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx))
+ goto err;
+ if (!EC_POINT_is_at_infinity(group, point)) {
+ ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
+ goto err;
+ }
+
+ ret = 1;
+
+ err:
+ if (ctx != NULL)
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (point)
+ EC_POINT_free(point);
+ return ret;
+}
diff --git a/openssl/ec/ec_curve.c b/openssl/ec/ec_curve.c
new file mode 100644
index 0000000..e4bcb5d
--- /dev/null
+++ b/openssl/ec/ec_curve.c
@@ -0,0 +1,2615 @@
+/* crypto/ec/ec_curve.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2010 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.
+ *
+ */
+
+#include "ec_lcl.h"
+#include <openssl/err.h>
+#include <openssl/obj_mac.h>
+#include <openssl/opensslconf.h>
+
+typedef struct {
+ int field_type, /* either NID_X9_62_prime_field or
+ * NID_X9_62_characteristic_two_field */
+ seed_len, param_len;
+ unsigned int cofactor; /* promoted to BN_ULONG */
+} EC_CURVE_DATA;
+
+/* the nist prime curves */
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 24 * 6];
+} _EC_NIST_PRIME_192 = {
+ {
+ NID_X9_62_prime_field, 20, 24, 1
+ },
+ {
+ /* seed */
+ 0x30, 0x45, 0xAE, 0x6F, 0xC8, 0x42, 0x2F, 0x64, 0xED, 0x57, 0x95, 0x28,
+ 0xD3, 0x81, 0x20, 0xEA, 0xE1, 0x21, 0x96, 0xD5,
+ /* p */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ /* a */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+ /* b */
+ 0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7, 0xE9, 0xAB,
+ 0x72, 0x24, 0x30, 0x49, 0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1,
+ /* x */
+ 0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF, 0x20, 0xEB,
+ 0x43, 0xA1, 0x88, 0x00, 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12,
+ /* y */
+ 0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, 0x11, 0xed,
+ 0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1, 0x1e, 0x79, 0x48, 0x11,
+ /* order */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x99, 0xDE, 0xF8, 0x36, 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 28 * 6];
+} _EC_NIST_PRIME_224 = {
+ {
+ NID_X9_62_prime_field, 20, 28, 1
+ },
+ {
+ /* seed */
+ 0xBD, 0x71, 0x34, 0x47, 0x99, 0xD5, 0xC7, 0xFC, 0xDC, 0x45, 0xB5, 0x9F,
+ 0xA3, 0xB9, 0xAB, 0x8F, 0x6A, 0x94, 0x8B, 0xC5,
+ /* p */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE,
+ /* b */
+ 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
+ 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
+ 0x23, 0x55, 0xFF, 0xB4,
+ /* x */
+ 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
+ 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
+ 0x11, 0x5C, 0x1D, 0x21,
+ /* y */
+ 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
+ 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
+ 0x85, 0x00, 0x7e, 0x34,
+ /* order */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
+ 0x5C, 0x5C, 0x2A, 0x3D
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 48 * 6];
+} _EC_NIST_PRIME_384 = {
+ {
+ NID_X9_62_prime_field, 20, 48, 1
+ },
+ {
+ /* seed */
+ 0xA3, 0x35, 0x92, 0x6A, 0xA3, 0x19, 0xA2, 0x7A, 0x1D, 0x00, 0x89, 0x6A,
+ 0x67, 0x73, 0xA4, 0x82, 0x7A, 0xCD, 0xAC, 0x73,
+ /* p */
+ 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, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ /* a */
+ 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, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
+ /* b */
+ 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
+ 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
+ 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
+ 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
+ /* x */
+ 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
+ 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
+ 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
+ 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
+ /* y */
+ 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
+ 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
+ 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
+ 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
+ /* order */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
+ 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 66 * 6];
+} _EC_NIST_PRIME_521 = {
+ {
+ NID_X9_62_prime_field, 20, 66, 1
+ },
+ {
+ /* seed */
+ 0xD0, 0x9E, 0x88, 0x00, 0x29, 0x1C, 0xB8, 0x53, 0x96, 0xCC, 0x67, 0x17,
+ 0x39, 0x32, 0x84, 0xAA, 0xA0, 0xDA, 0x64, 0xBA,
+ /* p */
+ 0x01, 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,
+ /* a */
+ 0x01, 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, 0xFC,
+ /* b */
+ 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
+ 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
+ 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
+ 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
+ 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
+ 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
+ /* x */
+ 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
+ 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
+ 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
+ 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
+ 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
+ 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
+ /* y */
+ 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
+ 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
+ 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
+ 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
+ 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
+ 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
+ /* order */
+ 0x01, 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, 0xFA, 0x51, 0x86,
+ 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
+ 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
+ 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09
+ }
+};
+
+/* the x9.62 prime curves (minus the nist prime curves) */
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 24 * 6];
+} _EC_X9_62_PRIME_192V2 = {
+ {
+ NID_X9_62_prime_field, 20, 24, 1
+ },
+ {
+ /* seed */
+ 0x31, 0xA9, 0x2E, 0xE2, 0x02, 0x9F, 0xD1, 0x0D, 0x90, 0x1B, 0x11, 0x3E,
+ 0x99, 0x07, 0x10, 0xF0, 0xD2, 0x1A, 0xC6, 0xB6,
+ /* p */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ /* a */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+ /* b */
+ 0xCC, 0x22, 0xD6, 0xDF, 0xB9, 0x5C, 0x6B, 0x25, 0xE4, 0x9C, 0x0D, 0x63,
+ 0x64, 0xA4, 0xE5, 0x98, 0x0C, 0x39, 0x3A, 0xA2, 0x16, 0x68, 0xD9, 0x53,
+ /* x */
+ 0xEE, 0xA2, 0xBA, 0xE7, 0xE1, 0x49, 0x78, 0x42, 0xF2, 0xDE, 0x77, 0x69,
+ 0xCF, 0xE9, 0xC9, 0x89, 0xC0, 0x72, 0xAD, 0x69, 0x6F, 0x48, 0x03, 0x4A,
+ /* y */
+ 0x65, 0x74, 0xd1, 0x1d, 0x69, 0xb6, 0xec, 0x7a, 0x67, 0x2b, 0xb8, 0x2a,
+ 0x08, 0x3d, 0xf2, 0xf2, 0xb0, 0x84, 0x7d, 0xe9, 0x70, 0xb2, 0xde, 0x15,
+ /* order */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+ 0x5F, 0xB1, 0xA7, 0x24, 0xDC, 0x80, 0x41, 0x86, 0x48, 0xD8, 0xDD, 0x31
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 24 * 6];
+} _EC_X9_62_PRIME_192V3 = {
+ {
+ NID_X9_62_prime_field, 20, 24, 1
+ },
+ {
+ /* seed */
+ 0xC4, 0x69, 0x68, 0x44, 0x35, 0xDE, 0xB3, 0x78, 0xC4, 0xB6, 0x5C, 0xA9,
+ 0x59, 0x1E, 0x2A, 0x57, 0x63, 0x05, 0x9A, 0x2E,
+ /* p */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ /* a */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+ /* b */
+ 0x22, 0x12, 0x3D, 0xC2, 0x39, 0x5A, 0x05, 0xCA, 0xA7, 0x42, 0x3D, 0xAE,
+ 0xCC, 0xC9, 0x47, 0x60, 0xA7, 0xD4, 0x62, 0x25, 0x6B, 0xD5, 0x69, 0x16,
+ /* x */
+ 0x7D, 0x29, 0x77, 0x81, 0x00, 0xC6, 0x5A, 0x1D, 0xA1, 0x78, 0x37, 0x16,
+ 0x58, 0x8D, 0xCE, 0x2B, 0x8B, 0x4A, 0xEE, 0x8E, 0x22, 0x8F, 0x18, 0x96,
+ /* y */
+ 0x38, 0xa9, 0x0f, 0x22, 0x63, 0x73, 0x37, 0x33, 0x4b, 0x49, 0xdc, 0xb6,
+ 0x6a, 0x6d, 0xc8, 0xf9, 0x97, 0x8a, 0xca, 0x76, 0x48, 0xa9, 0x43, 0xb0,
+ /* order */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x7A, 0x62, 0xD0, 0x31, 0xC8, 0x3F, 0x42, 0x94, 0xF6, 0x40, 0xEC, 0x13
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 30 * 6];
+} _EC_X9_62_PRIME_239V1 = {
+ {
+ NID_X9_62_prime_field, 20, 30, 1
+ },
+ {
+ /* seed */
+ 0xE4, 0x3B, 0xB4, 0x60, 0xF0, 0xB8, 0x0C, 0xC0, 0xC0, 0xB0, 0x75, 0x79,
+ 0x8E, 0x94, 0x80, 0x60, 0xF8, 0x32, 0x1B, 0x7D,
+ /* p */
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ /* a */
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+ /* b */
+ 0x6B, 0x01, 0x6C, 0x3B, 0xDC, 0xF1, 0x89, 0x41, 0xD0, 0xD6, 0x54, 0x92,
+ 0x14, 0x75, 0xCA, 0x71, 0xA9, 0xDB, 0x2F, 0xB2, 0x7D, 0x1D, 0x37, 0x79,
+ 0x61, 0x85, 0xC2, 0x94, 0x2C, 0x0A,
+ /* x */
+ 0x0F, 0xFA, 0x96, 0x3C, 0xDC, 0xA8, 0x81, 0x6C, 0xCC, 0x33, 0xB8, 0x64,
+ 0x2B, 0xED, 0xF9, 0x05, 0xC3, 0xD3, 0x58, 0x57, 0x3D, 0x3F, 0x27, 0xFB,
+ 0xBD, 0x3B, 0x3C, 0xB9, 0xAA, 0xAF,
+ /* y */
+ 0x7d, 0xeb, 0xe8, 0xe4, 0xe9, 0x0a, 0x5d, 0xae, 0x6e, 0x40, 0x54, 0xca,
+ 0x53, 0x0b, 0xa0, 0x46, 0x54, 0xb3, 0x68, 0x18, 0xce, 0x22, 0x6b, 0x39,
+ 0xfc, 0xcb, 0x7b, 0x02, 0xf1, 0xae,
+ /* order */
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF, 0x9E, 0x5E, 0x9A, 0x9F, 0x5D, 0x90, 0x71, 0xFB, 0xD1,
+ 0x52, 0x26, 0x88, 0x90, 0x9D, 0x0B
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 30 * 6];
+} _EC_X9_62_PRIME_239V2 = {
+ {
+ NID_X9_62_prime_field, 20, 30, 1
+ },
+ {
+ /* seed */
+ 0xE8, 0xB4, 0x01, 0x16, 0x04, 0x09, 0x53, 0x03, 0xCA, 0x3B, 0x80, 0x99,
+ 0x98, 0x2B, 0xE0, 0x9F, 0xCB, 0x9A, 0xE6, 0x16,
+ /* p */
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ /* a */
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+ /* b */
+ 0x61, 0x7F, 0xAB, 0x68, 0x32, 0x57, 0x6C, 0xBB, 0xFE, 0xD5, 0x0D, 0x99,
+ 0xF0, 0x24, 0x9C, 0x3F, 0xEE, 0x58, 0xB9, 0x4B, 0xA0, 0x03, 0x8C, 0x7A,
+ 0xE8, 0x4C, 0x8C, 0x83, 0x2F, 0x2C,
+ /* x */
+ 0x38, 0xAF, 0x09, 0xD9, 0x87, 0x27, 0x70, 0x51, 0x20, 0xC9, 0x21, 0xBB,
+ 0x5E, 0x9E, 0x26, 0x29, 0x6A, 0x3C, 0xDC, 0xF2, 0xF3, 0x57, 0x57, 0xA0,
+ 0xEA, 0xFD, 0x87, 0xB8, 0x30, 0xE7,
+ /* y */
+ 0x5b, 0x01, 0x25, 0xe4, 0xdb, 0xea, 0x0e, 0xc7, 0x20, 0x6d, 0xa0, 0xfc,
+ 0x01, 0xd9, 0xb0, 0x81, 0x32, 0x9f, 0xb5, 0x55, 0xde, 0x6e, 0xf4, 0x60,
+ 0x23, 0x7d, 0xff, 0x8b, 0xe4, 0xba,
+ /* order */
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x80, 0x00, 0x00, 0xCF, 0xA7, 0xE8, 0x59, 0x43, 0x77, 0xD4, 0x14, 0xC0,
+ 0x38, 0x21, 0xBC, 0x58, 0x20, 0x63
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 30 * 6];
+} _EC_X9_62_PRIME_239V3 = {
+ {
+ NID_X9_62_prime_field, 20, 30, 1
+ },
+ {
+ /* seed */
+ 0x7D, 0x73, 0x74, 0x16, 0x8F, 0xFE, 0x34, 0x71, 0xB6, 0x0A, 0x85, 0x76,
+ 0x86, 0xA1, 0x94, 0x75, 0xD3, 0xBF, 0xA2, 0xFF,
+ /* p */
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ /* a */
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+ /* b */
+ 0x25, 0x57, 0x05, 0xFA, 0x2A, 0x30, 0x66, 0x54, 0xB1, 0xF4, 0xCB, 0x03,
+ 0xD6, 0xA7, 0x50, 0xA3, 0x0C, 0x25, 0x01, 0x02, 0xD4, 0x98, 0x87, 0x17,
+ 0xD9, 0xBA, 0x15, 0xAB, 0x6D, 0x3E,
+ /* x */
+ 0x67, 0x68, 0xAE, 0x8E, 0x18, 0xBB, 0x92, 0xCF, 0xCF, 0x00, 0x5C, 0x94,
+ 0x9A, 0xA2, 0xC6, 0xD9, 0x48, 0x53, 0xD0, 0xE6, 0x60, 0xBB, 0xF8, 0x54,
+ 0xB1, 0xC9, 0x50, 0x5F, 0xE9, 0x5A,
+ /* y */
+ 0x16, 0x07, 0xe6, 0x89, 0x8f, 0x39, 0x0c, 0x06, 0xbc, 0x1d, 0x55, 0x2b,
+ 0xad, 0x22, 0x6f, 0x3b, 0x6f, 0xcf, 0xe4, 0x8b, 0x6e, 0x81, 0x84, 0x99,
+ 0xaf, 0x18, 0xe3, 0xed, 0x6c, 0xf3,
+ /* order */
+ 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x7F, 0xFF, 0xFF, 0x97, 0x5D, 0xEB, 0x41, 0xB3, 0xA6, 0x05, 0x7C, 0x3C,
+ 0x43, 0x21, 0x46, 0x52, 0x65, 0x51
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 32 * 6];
+} _EC_X9_62_PRIME_256V1 = {
+ {
+ NID_X9_62_prime_field, 20, 32, 1
+ },
+ {
+ /* seed */
+ 0xC4, 0x9D, 0x36, 0x08, 0x86, 0xE7, 0x04, 0x93, 0x6A, 0x66, 0x78, 0xE1,
+ 0x13, 0x9D, 0x26, 0xB7, 0x81, 0x9F, 0x7E, 0x90,
+ /* p */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ /* a */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+ /* b */
+ 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
+ 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
+ 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
+ /* x */
+ 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
+ 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
+ 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
+ /* y */
+ 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
+ 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
+ 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
+ /* order */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
+ 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
+ }
+};
+
+/* the secg prime curves (minus the nist and x9.62 prime curves) */
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 14 * 6];
+} _EC_SECG_PRIME_112R1 = {
+ {
+ NID_X9_62_prime_field, 20, 14, 1
+ },
+ {
+ /* seed */
+ 0x00, 0xF5, 0x0B, 0x02, 0x8E, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61,
+ 0x51, 0x75, 0x29, 0x04, 0x72, 0x78, 0x3F, 0xB1,
+ /* p */
+ 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD,
+ 0x20, 0x8B,
+ /* a */
+ 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD,
+ 0x20, 0x88,
+ /* b */
+ 0x65, 0x9E, 0xF8, 0xBA, 0x04, 0x39, 0x16, 0xEE, 0xDE, 0x89, 0x11, 0x70,
+ 0x2B, 0x22,
+ /* x */
+ 0x09, 0x48, 0x72, 0x39, 0x99, 0x5A, 0x5E, 0xE7, 0x6B, 0x55, 0xF9, 0xC2,
+ 0xF0, 0x98,
+ /* y */
+ 0xa8, 0x9c, 0xe5, 0xaf, 0x87, 0x24, 0xc0, 0xa2, 0x3e, 0x0e, 0x0f, 0xf7,
+ 0x75, 0x00,
+ /* order */
+ 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x76, 0x28, 0xDF, 0xAC, 0x65,
+ 0x61, 0xC5
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 14 * 6];
+} _EC_SECG_PRIME_112R2 = {
+ {
+ NID_X9_62_prime_field, 20, 14, 4
+ },
+ {
+ /* seed */
+ 0x00, 0x27, 0x57, 0xA1, 0x11, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61,
+ 0x51, 0x75, 0x53, 0x16, 0xC0, 0x5E, 0x0B, 0xD4,
+ /* p */
+ 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD,
+ 0x20, 0x8B,
+ /* a */
+ 0x61, 0x27, 0xC2, 0x4C, 0x05, 0xF3, 0x8A, 0x0A, 0xAA, 0xF6, 0x5C, 0x0E,
+ 0xF0, 0x2C,
+ /* b */
+ 0x51, 0xDE, 0xF1, 0x81, 0x5D, 0xB5, 0xED, 0x74, 0xFC, 0xC3, 0x4C, 0x85,
+ 0xD7, 0x09,
+ /* x */
+ 0x4B, 0xA3, 0x0A, 0xB5, 0xE8, 0x92, 0xB4, 0xE1, 0x64, 0x9D, 0xD0, 0x92,
+ 0x86, 0x43,
+ /* y */
+ 0xad, 0xcd, 0x46, 0xf5, 0x88, 0x2e, 0x37, 0x47, 0xde, 0xf3, 0x6e, 0x95,
+ 0x6e, 0x97,
+ /* order */
+ 0x36, 0xDF, 0x0A, 0xAF, 0xD8, 0xB8, 0xD7, 0x59, 0x7C, 0xA1, 0x05, 0x20,
+ 0xD0, 0x4B
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 16 * 6];
+} _EC_SECG_PRIME_128R1 = {
+ {
+ NID_X9_62_prime_field, 20, 16, 1
+ },
+ {
+ /* seed */
+ 0x00, 0x0E, 0x0D, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75,
+ 0x0C, 0xC0, 0x3A, 0x44, 0x73, 0xD0, 0x36, 0x79,
+ /* p */
+ 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ /* a */
+ 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFC,
+ /* b */
+ 0xE8, 0x75, 0x79, 0xC1, 0x10, 0x79, 0xF4, 0x3D, 0xD8, 0x24, 0x99, 0x3C,
+ 0x2C, 0xEE, 0x5E, 0xD3,
+ /* x */
+ 0x16, 0x1F, 0xF7, 0x52, 0x8B, 0x89, 0x9B, 0x2D, 0x0C, 0x28, 0x60, 0x7C,
+ 0xA5, 0x2C, 0x5B, 0x86,
+ /* y */
+ 0xcf, 0x5a, 0xc8, 0x39, 0x5b, 0xaf, 0xeb, 0x13, 0xc0, 0x2d, 0xa2, 0x92,
+ 0xdd, 0xed, 0x7a, 0x83,
+ /* order */
+ 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x75, 0xA3, 0x0D, 0x1B,
+ 0x90, 0x38, 0xA1, 0x15
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 16 * 6];
+} _EC_SECG_PRIME_128R2 = {
+ {
+ NID_X9_62_prime_field, 20, 16, 4
+ },
+ {
+ /* seed */
+ 0x00, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, 0x12, 0xD8,
+ 0xF0, 0x34, 0x31, 0xFC, 0xE6, 0x3B, 0x88, 0xF4,
+ /* p */
+ 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ /* a */
+ 0xD6, 0x03, 0x19, 0x98, 0xD1, 0xB3, 0xBB, 0xFE, 0xBF, 0x59, 0xCC, 0x9B,
+ 0xBF, 0xF9, 0xAE, 0xE1,
+ /* b */
+ 0x5E, 0xEE, 0xFC, 0xA3, 0x80, 0xD0, 0x29, 0x19, 0xDC, 0x2C, 0x65, 0x58,
+ 0xBB, 0x6D, 0x8A, 0x5D,
+ /* x */
+ 0x7B, 0x6A, 0xA5, 0xD8, 0x5E, 0x57, 0x29, 0x83, 0xE6, 0xFB, 0x32, 0xA7,
+ 0xCD, 0xEB, 0xC1, 0x40,
+ /* y */
+ 0x27, 0xb6, 0x91, 0x6a, 0x89, 0x4d, 0x3a, 0xee, 0x71, 0x06, 0xfe, 0x80,
+ 0x5f, 0xc3, 0x4b, 0x44,
+ /* order */
+ 0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xBE, 0x00, 0x24, 0x72,
+ 0x06, 0x13, 0xB5, 0xA3
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 21 * 6];
+} _EC_SECG_PRIME_160K1 = {
+ {
+ NID_X9_62_prime_field, 0, 21, 1
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x73,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+ /* x */
+ 0x00, 0x3B, 0x4C, 0x38, 0x2C, 0xE3, 0x7A, 0xA1, 0x92, 0xA4, 0x01, 0x9E,
+ 0x76, 0x30, 0x36, 0xF4, 0xF5, 0xDD, 0x4D, 0x7E, 0xBB,
+ /* y */
+ 0x00, 0x93, 0x8c, 0xf9, 0x35, 0x31, 0x8f, 0xdc, 0xed, 0x6b, 0xc2, 0x82,
+ 0x86, 0x53, 0x17, 0x33, 0xc3, 0xf0, 0x3c, 0x4f, 0xee,
+ /* order */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB8,
+ 0xFA, 0x16, 0xDF, 0xAB, 0x9A, 0xCA, 0x16, 0xB6, 0xB3
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 21 * 6];
+} _EC_SECG_PRIME_160R1 = {
+ {
+ NID_X9_62_prime_field, 20, 21, 1
+ },
+ {
+ /* seed */
+ 0x10, 0x53, 0xCD, 0xE4, 0x2C, 0x14, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+ 0x15, 0x17, 0x53, 0x3B, 0xF3, 0xF8, 0x33, 0x45,
+ /* p */
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF,
+ /* a */
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFC,
+ /* b */
+ 0x00, 0x1C, 0x97, 0xBE, 0xFC, 0x54, 0xBD, 0x7A, 0x8B, 0x65, 0xAC, 0xF8,
+ 0x9F, 0x81, 0xD4, 0xD4, 0xAD, 0xC5, 0x65, 0xFA, 0x45,
+ /* x */
+ 0x00, 0x4A, 0x96, 0xB5, 0x68, 0x8E, 0xF5, 0x73, 0x28, 0x46, 0x64, 0x69,
+ 0x89, 0x68, 0xC3, 0x8B, 0xB9, 0x13, 0xCB, 0xFC, 0x82,
+ /* y */
+ 0x00, 0x23, 0xa6, 0x28, 0x55, 0x31, 0x68, 0x94, 0x7d, 0x59, 0xdc, 0xc9,
+ 0x12, 0x04, 0x23, 0x51, 0x37, 0x7a, 0xc5, 0xfb, 0x32,
+ /* order */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF4,
+ 0xC8, 0xF9, 0x27, 0xAE, 0xD3, 0xCA, 0x75, 0x22, 0x57
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 21 * 6];
+} _EC_SECG_PRIME_160R2 = {
+ {
+ NID_X9_62_prime_field, 20, 21, 1
+ },
+ {
+ /* seed */
+ 0xB9, 0x9B, 0x99, 0xB0, 0x99, 0xB3, 0x23, 0xE0, 0x27, 0x09, 0xA4, 0xD6,
+ 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51,
+ /* p */
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x73,
+ /* a */
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x70,
+ /* b */
+ 0x00, 0xB4, 0xE1, 0x34, 0xD3, 0xFB, 0x59, 0xEB, 0x8B, 0xAB, 0x57, 0x27,
+ 0x49, 0x04, 0x66, 0x4D, 0x5A, 0xF5, 0x03, 0x88, 0xBA,
+ /* x */
+ 0x00, 0x52, 0xDC, 0xB0, 0x34, 0x29, 0x3A, 0x11, 0x7E, 0x1F, 0x4F, 0xF1,
+ 0x1B, 0x30, 0xF7, 0x19, 0x9D, 0x31, 0x44, 0xCE, 0x6D,
+ /* y */
+ 0x00, 0xfe, 0xaf, 0xfe, 0xf2, 0xe3, 0x31, 0xf2, 0x96, 0xe0, 0x71, 0xfa,
+ 0x0d, 0xf9, 0x98, 0x2c, 0xfe, 0xa7, 0xd4, 0x3f, 0x2e,
+ /* order */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35,
+ 0x1E, 0xE7, 0x86, 0xA8, 0x18, 0xF3, 0xA1, 0xA1, 0x6B
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 24 * 6];
+} _EC_SECG_PRIME_192K1 = {
+ {
+ NID_X9_62_prime_field, 0, 24, 1
+ },
+ {
+ /* no seed */
+ /* p */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEE, 0x37,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ /* x */
+ 0xDB, 0x4F, 0xF1, 0x0E, 0xC0, 0x57, 0xE9, 0xAE, 0x26, 0xB0, 0x7D, 0x02,
+ 0x80, 0xB7, 0xF4, 0x34, 0x1D, 0xA5, 0xD1, 0xB1, 0xEA, 0xE0, 0x6C, 0x7D,
+ /* y */
+ 0x9b, 0x2f, 0x2f, 0x6d, 0x9c, 0x56, 0x28, 0xa7, 0x84, 0x41, 0x63, 0xd0,
+ 0x15, 0xbe, 0x86, 0x34, 0x40, 0x82, 0xaa, 0x88, 0xd9, 0x5e, 0x2f, 0x9d,
+ /* order */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+ 0x26, 0xF2, 0xFC, 0x17, 0x0F, 0x69, 0x46, 0x6A, 0x74, 0xDE, 0xFD, 0x8D
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 29 * 6];
+} _EC_SECG_PRIME_224K1 = {
+ {
+ NID_X9_62_prime_field, 0, 29, 1
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFE, 0xFF, 0xFF, 0xE5, 0x6D,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x05,
+ /* x */
+ 0x00, 0xA1, 0x45, 0x5B, 0x33, 0x4D, 0xF0, 0x99, 0xDF, 0x30, 0xFC, 0x28,
+ 0xA1, 0x69, 0xA4, 0x67, 0xE9, 0xE4, 0x70, 0x75, 0xA9, 0x0F, 0x7E, 0x65,
+ 0x0E, 0xB6, 0xB7, 0xA4, 0x5C,
+ /* y */
+ 0x00, 0x7e, 0x08, 0x9f, 0xed, 0x7f, 0xba, 0x34, 0x42, 0x82, 0xca, 0xfb,
+ 0xd6, 0xf7, 0xe3, 0x19, 0xf7, 0xc0, 0xb0, 0xbd, 0x59, 0xe2, 0xca, 0x4b,
+ 0xdb, 0x55, 0x6d, 0x61, 0xa5,
+ /* order */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0xDC, 0xE8, 0xD2, 0xEC, 0x61, 0x84, 0xCA, 0xF0, 0xA9,
+ 0x71, 0x76, 0x9F, 0xB1, 0xF7
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 32 * 6];
+} _EC_SECG_PRIME_256K1 = {
+ {
+ NID_X9_62_prime_field, 0, 32, 1
+ },
+ {
+ /* no seed */
+ /* p */
+ 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, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+ /* x */
+ 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95,
+ 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9,
+ 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98,
+ /* y */
+ 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc,
+ 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19,
+ 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, 0xd4, 0xb8,
+ /* order */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
+ 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41
+ }
+};
+
+/* some wap/wtls curves */
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 15 * 6];
+} _EC_WTLS_8 = {
+ {
+ NID_X9_62_prime_field, 0, 15, 1
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFD, 0xE7,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x03,
+ /* x */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01,
+ /* y */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02,
+ /* order */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xEC, 0xEA, 0x55, 0x1A,
+ 0xD8, 0x37, 0xE9
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 21 * 6];
+} _EC_WTLS_9 = {
+ {
+ NID_X9_62_prime_field, 0, 21, 1
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80, 0x8F,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ /* x */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* y */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ /* order */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xCD,
+ 0xC9, 0x8A, 0xE0, 0xE2, 0xDE, 0x57, 0x4A, 0xBF, 0x33
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 28 * 6];
+} _EC_WTLS_12 = {
+ {
+ NID_X9_62_prime_field, 0, 28, 1
+ },
+ {
+ /* no seed */
+ /* p */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFE,
+ /* b */
+ 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
+ 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
+ 0x23, 0x55, 0xFF, 0xB4,
+ /* x */
+ 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
+ 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
+ 0x11, 0x5C, 0x1D, 0x21,
+ /* y */
+ 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
+ 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
+ 0x85, 0x00, 0x7e, 0x34,
+ /* order */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
+ 0x5C, 0x5C, 0x2A, 0x3D
+ }
+};
+
+#ifndef OPENSSL_NO_EC2M
+
+/* characteristic two curves */
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 15 * 6];
+} _EC_SECG_CHAR2_113R1 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 15, 2
+ },
+ {
+ /* seed */
+ 0x10, 0xE7, 0x23, 0xAB, 0x14, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15,
+ 0x17, 0x56, 0xFE, 0xBF, 0x8F, 0xCB, 0x49, 0xA9,
+ /* p */
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x01,
+ /* a */
+ 0x00, 0x30, 0x88, 0x25, 0x0C, 0xA6, 0xE7, 0xC7, 0xFE, 0x64, 0x9C, 0xE8,
+ 0x58, 0x20, 0xF7,
+ /* b */
+ 0x00, 0xE8, 0xBE, 0xE4, 0xD3, 0xE2, 0x26, 0x07, 0x44, 0x18, 0x8B, 0xE0,
+ 0xE9, 0xC7, 0x23,
+ /* x */
+ 0x00, 0x9D, 0x73, 0x61, 0x6F, 0x35, 0xF4, 0xAB, 0x14, 0x07, 0xD7, 0x35,
+ 0x62, 0xC1, 0x0F,
+ /* y */
+ 0x00, 0xA5, 0x28, 0x30, 0x27, 0x79, 0x58, 0xEE, 0x84, 0xD1, 0x31, 0x5E,
+ 0xD3, 0x18, 0x86,
+ /* order */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xCC, 0xEC, 0x8A,
+ 0x39, 0xE5, 0x6F
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 15 * 6];
+} _EC_SECG_CHAR2_113R2 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 15, 2
+ },
+ {
+ /* seed */
+ 0x10, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE, 0xF4, 0xD6,
+ 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x5D,
+ /* p */
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x01,
+ /* a */
+ 0x00, 0x68, 0x99, 0x18, 0xDB, 0xEC, 0x7E, 0x5A, 0x0D, 0xD6, 0xDF, 0xC0,
+ 0xAA, 0x55, 0xC7,
+ /* b */
+ 0x00, 0x95, 0xE9, 0xA9, 0xEC, 0x9B, 0x29, 0x7B, 0xD4, 0xBF, 0x36, 0xE0,
+ 0x59, 0x18, 0x4F,
+ /* x */
+ 0x01, 0xA5, 0x7A, 0x6A, 0x7B, 0x26, 0xCA, 0x5E, 0xF5, 0x2F, 0xCD, 0xB8,
+ 0x16, 0x47, 0x97,
+ /* y */
+ 0x00, 0xB3, 0xAD, 0xC9, 0x4E, 0xD1, 0xFE, 0x67, 0x4C, 0x06, 0xE6, 0x95,
+ 0xBA, 0xBA, 0x1D,
+ /* order */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x78, 0x9B, 0x24,
+ 0x96, 0xAF, 0x93
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 17 * 6];
+} _EC_SECG_CHAR2_131R1 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 17, 2
+ },
+ {
+ /* seed */
+ 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, 0x98, 0x5B, 0xD3,
+ 0xAD, 0xBA, 0xDA, 0x21, 0xB4, 0x3A, 0x97, 0xE2,
+ /* p */
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x0D,
+ /* a */
+ 0x07, 0xA1, 0x1B, 0x09, 0xA7, 0x6B, 0x56, 0x21, 0x44, 0x41, 0x8F, 0xF3,
+ 0xFF, 0x8C, 0x25, 0x70, 0xB8,
+ /* b */
+ 0x02, 0x17, 0xC0, 0x56, 0x10, 0x88, 0x4B, 0x63, 0xB9, 0xC6, 0xC7, 0x29,
+ 0x16, 0x78, 0xF9, 0xD3, 0x41,
+ /* x */
+ 0x00, 0x81, 0xBA, 0xF9, 0x1F, 0xDF, 0x98, 0x33, 0xC4, 0x0F, 0x9C, 0x18,
+ 0x13, 0x43, 0x63, 0x83, 0x99,
+ /* y */
+ 0x07, 0x8C, 0x6E, 0x7E, 0xA3, 0x8C, 0x00, 0x1F, 0x73, 0xC8, 0x13, 0x4B,
+ 0x1B, 0x4E, 0xF9, 0xE1, 0x50,
+ /* order */
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x23, 0x95,
+ 0x3A, 0x94, 0x64, 0xB5, 0x4D
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 17 * 6];
+} _EC_SECG_CHAR2_131R2 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 17, 2
+ },
+ {
+ /* seed */
+ 0x98, 0x5B, 0xD3, 0xAD, 0xBA, 0xD4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+ 0x15, 0x17, 0x5A, 0x21, 0xB4, 0x3A, 0x97, 0xE3,
+ /* p */
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x0D,
+ /* a */
+ 0x03, 0xE5, 0xA8, 0x89, 0x19, 0xD7, 0xCA, 0xFC, 0xBF, 0x41, 0x5F, 0x07,
+ 0xC2, 0x17, 0x65, 0x73, 0xB2,
+ /* b */
+ 0x04, 0xB8, 0x26, 0x6A, 0x46, 0xC5, 0x56, 0x57, 0xAC, 0x73, 0x4C, 0xE3,
+ 0x8F, 0x01, 0x8F, 0x21, 0x92,
+ /* x */
+ 0x03, 0x56, 0xDC, 0xD8, 0xF2, 0xF9, 0x50, 0x31, 0xAD, 0x65, 0x2D, 0x23,
+ 0x95, 0x1B, 0xB3, 0x66, 0xA8,
+ /* y */
+ 0x06, 0x48, 0xF0, 0x6D, 0x86, 0x79, 0x40, 0xA5, 0x36, 0x6D, 0x9E, 0x26,
+ 0x5D, 0xE9, 0xEB, 0x24, 0x0F,
+ /* order */
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x69, 0x54, 0xA2,
+ 0x33, 0x04, 0x9B, 0xA9, 0x8F
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 21 * 6];
+} _EC_NIST_CHAR2_163K = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 21, 2
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* x */
+ 0x02, 0xFE, 0x13, 0xC0, 0x53, 0x7B, 0xBC, 0x11, 0xAC, 0xAA, 0x07, 0xD7,
+ 0x93, 0xDE, 0x4E, 0x6D, 0x5E, 0x5C, 0x94, 0xEE, 0xE8,
+ /* y */
+ 0x02, 0x89, 0x07, 0x0F, 0xB0, 0x5D, 0x38, 0xFF, 0x58, 0x32, 0x1F, 0x2E,
+ 0x80, 0x05, 0x36, 0xD5, 0x38, 0xCC, 0xDA, 0xA3, 0xD9,
+ /* order */
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01,
+ 0x08, 0xA2, 0xE0, 0xCC, 0x0D, 0x99, 0xF8, 0xA5, 0xEF
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 21 * 6];
+} _EC_SECG_CHAR2_163R1 = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 21, 2
+ },
+ {
+ /* no seed */
+# if 0
+ /*
+ * The algorithm used to derive the curve parameters from the seed
+ * used here is slightly different than the algorithm described in
+ * X9.62 .
+ */
+ 0x24, 0xB7, 0xB1, 0x37, 0xC8, 0xA1, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75,
+ 0x61, 0x51, 0x75, 0x6F, 0xD0, 0xDA, 0x2E, 0x5C,
+# endif
+ /* p */
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9,
+ /* a */
+ 0x07, 0xB6, 0x88, 0x2C, 0xAA, 0xEF, 0xA8, 0x4F, 0x95, 0x54, 0xFF, 0x84,
+ 0x28, 0xBD, 0x88, 0xE2, 0x46, 0xD2, 0x78, 0x2A, 0xE2,
+ /* b */
+ 0x07, 0x13, 0x61, 0x2D, 0xCD, 0xDC, 0xB4, 0x0A, 0xAB, 0x94, 0x6B, 0xDA,
+ 0x29, 0xCA, 0x91, 0xF7, 0x3A, 0xF9, 0x58, 0xAF, 0xD9,
+ /* x */
+ 0x03, 0x69, 0x97, 0x96, 0x97, 0xAB, 0x43, 0x89, 0x77, 0x89, 0x56, 0x67,
+ 0x89, 0x56, 0x7F, 0x78, 0x7A, 0x78, 0x76, 0xA6, 0x54,
+ /* y */
+ 0x00, 0x43, 0x5E, 0xDB, 0x42, 0xEF, 0xAF, 0xB2, 0x98, 0x9D, 0x51, 0xFE,
+ 0xFC, 0xE3, 0xC8, 0x09, 0x88, 0xF4, 0x1F, 0xF8, 0x83,
+ /* order */
+ 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x48,
+ 0xAA, 0xB6, 0x89, 0xC2, 0x9C, 0xA7, 0x10, 0x27, 0x9B
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 21 * 6];
+} _EC_NIST_CHAR2_163B = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 21, 2
+ },
+ {
+ /* no seed */
+# if 0
+ /*
+ * The seed here was used to created the curve parameters in normal
+ * basis representation (and not the polynomial representation used
+ * here)
+ */
+ 0x85, 0xE2, 0x5B, 0xFE, 0x5C, 0x86, 0x22, 0x6C, 0xDB, 0x12, 0x01, 0x6F,
+ 0x75, 0x53, 0xF9, 0xD0, 0xE6, 0x93, 0xA2, 0x68,
+# endif
+ /* p */
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* b */
+ 0x02, 0x0A, 0x60, 0x19, 0x07, 0xB8, 0xC9, 0x53, 0xCA, 0x14, 0x81, 0xEB,
+ 0x10, 0x51, 0x2F, 0x78, 0x74, 0x4A, 0x32, 0x05, 0xFD,
+ /* x */
+ 0x03, 0xF0, 0xEB, 0xA1, 0x62, 0x86, 0xA2, 0xD5, 0x7E, 0xA0, 0x99, 0x11,
+ 0x68, 0xD4, 0x99, 0x46, 0x37, 0xE8, 0x34, 0x3E, 0x36,
+ /* y */
+ 0x00, 0xD5, 0x1F, 0xBC, 0x6C, 0x71, 0xA0, 0x09, 0x4F, 0xA2, 0xCD, 0xD5,
+ 0x45, 0xB1, 0x1C, 0x5C, 0x0C, 0x79, 0x73, 0x24, 0xF1,
+ /* order */
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x92,
+ 0xFE, 0x77, 0xE7, 0x0C, 0x12, 0xA4, 0x23, 0x4C, 0x33
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 25 * 6];
+} _EC_SECG_CHAR2_193R1 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 25, 2
+ },
+ {
+ /* seed */
+ 0x10, 0x3F, 0xAE, 0xC7, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51,
+ 0x75, 0x77, 0x7F, 0xC5, 0xB1, 0x91, 0xEF, 0x30,
+ /* p */
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x01,
+ /* a */
+ 0x00, 0x17, 0x85, 0x8F, 0xEB, 0x7A, 0x98, 0x97, 0x51, 0x69, 0xE1, 0x71,
+ 0xF7, 0x7B, 0x40, 0x87, 0xDE, 0x09, 0x8A, 0xC8, 0xA9, 0x11, 0xDF, 0x7B,
+ 0x01,
+ /* b */
+ 0x00, 0xFD, 0xFB, 0x49, 0xBF, 0xE6, 0xC3, 0xA8, 0x9F, 0xAC, 0xAD, 0xAA,
+ 0x7A, 0x1E, 0x5B, 0xBC, 0x7C, 0xC1, 0xC2, 0xE5, 0xD8, 0x31, 0x47, 0x88,
+ 0x14,
+ /* x */
+ 0x01, 0xF4, 0x81, 0xBC, 0x5F, 0x0F, 0xF8, 0x4A, 0x74, 0xAD, 0x6C, 0xDF,
+ 0x6F, 0xDE, 0xF4, 0xBF, 0x61, 0x79, 0x62, 0x53, 0x72, 0xD8, 0xC0, 0xC5,
+ 0xE1,
+ /* y */
+ 0x00, 0x25, 0xE3, 0x99, 0xF2, 0x90, 0x37, 0x12, 0xCC, 0xF3, 0xEA, 0x9E,
+ 0x3A, 0x1A, 0xD1, 0x7F, 0xB0, 0xB3, 0x20, 0x1B, 0x6A, 0xF7, 0xCE, 0x1B,
+ 0x05,
+ /* order */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xC7, 0xF3, 0x4A, 0x77, 0x8F, 0x44, 0x3A, 0xCC, 0x92, 0x0E, 0xBA,
+ 0x49
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 25 * 6];
+} _EC_SECG_CHAR2_193R2 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 25, 2
+ },
+ {
+ /* seed */
+ 0x10, 0xB7, 0xB4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51,
+ 0x37, 0xC8, 0xA1, 0x6F, 0xD0, 0xDA, 0x22, 0x11,
+ /* p */
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x01,
+ /* a */
+ 0x01, 0x63, 0xF3, 0x5A, 0x51, 0x37, 0xC2, 0xCE, 0x3E, 0xA6, 0xED, 0x86,
+ 0x67, 0x19, 0x0B, 0x0B, 0xC4, 0x3E, 0xCD, 0x69, 0x97, 0x77, 0x02, 0x70,
+ 0x9B,
+ /* b */
+ 0x00, 0xC9, 0xBB, 0x9E, 0x89, 0x27, 0xD4, 0xD6, 0x4C, 0x37, 0x7E, 0x2A,
+ 0xB2, 0x85, 0x6A, 0x5B, 0x16, 0xE3, 0xEF, 0xB7, 0xF6, 0x1D, 0x43, 0x16,
+ 0xAE,
+ /* x */
+ 0x00, 0xD9, 0xB6, 0x7D, 0x19, 0x2E, 0x03, 0x67, 0xC8, 0x03, 0xF3, 0x9E,
+ 0x1A, 0x7E, 0x82, 0xCA, 0x14, 0xA6, 0x51, 0x35, 0x0A, 0xAE, 0x61, 0x7E,
+ 0x8F,
+ /* y */
+ 0x01, 0xCE, 0x94, 0x33, 0x56, 0x07, 0xC3, 0x04, 0xAC, 0x29, 0xE7, 0xDE,
+ 0xFB, 0xD9, 0xCA, 0x01, 0xF5, 0x96, 0xF9, 0x27, 0x22, 0x4C, 0xDE, 0xCF,
+ 0x6C,
+ /* order */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x5A, 0xAB, 0x56, 0x1B, 0x00, 0x54, 0x13, 0xCC, 0xD4, 0xEE, 0x99,
+ 0xD5
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 30 * 6];
+} _EC_NIST_CHAR2_233K = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 30, 4
+ },
+ {
+ /* no seed */
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* x */
+ 0x01, 0x72, 0x32, 0xBA, 0x85, 0x3A, 0x7E, 0x73, 0x1A, 0xF1, 0x29, 0xF2,
+ 0x2F, 0xF4, 0x14, 0x95, 0x63, 0xA4, 0x19, 0xC2, 0x6B, 0xF5, 0x0A, 0x4C,
+ 0x9D, 0x6E, 0xEF, 0xAD, 0x61, 0x26,
+ /* y */
+ 0x01, 0xDB, 0x53, 0x7D, 0xEC, 0xE8, 0x19, 0xB7, 0xF7, 0x0F, 0x55, 0x5A,
+ 0x67, 0xC4, 0x27, 0xA8, 0xCD, 0x9B, 0xF1, 0x8A, 0xEB, 0x9B, 0x56, 0xE0,
+ 0xC1, 0x10, 0x56, 0xFA, 0xE6, 0xA3,
+ /* order */
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x9D, 0x5B, 0xB9, 0x15, 0xBC, 0xD4, 0x6E, 0xFB,
+ 0x1A, 0xD5, 0xF1, 0x73, 0xAB, 0xDF
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 30 * 6];
+} _EC_NIST_CHAR2_233B = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 30, 2
+ },
+ {
+ /* seed */
+ 0x74, 0xD5, 0x9F, 0xF0, 0x7F, 0x6B, 0x41, 0x3D, 0x0E, 0xA1, 0x4B, 0x34,
+ 0x4B, 0x20, 0xA2, 0xDB, 0x04, 0x9B, 0x50, 0xC3,
+ /* p */
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* b */
+ 0x00, 0x66, 0x64, 0x7E, 0xDE, 0x6C, 0x33, 0x2C, 0x7F, 0x8C, 0x09, 0x23,
+ 0xBB, 0x58, 0x21, 0x3B, 0x33, 0x3B, 0x20, 0xE9, 0xCE, 0x42, 0x81, 0xFE,
+ 0x11, 0x5F, 0x7D, 0x8F, 0x90, 0xAD,
+ /* x */
+ 0x00, 0xFA, 0xC9, 0xDF, 0xCB, 0xAC, 0x83, 0x13, 0xBB, 0x21, 0x39, 0xF1,
+ 0xBB, 0x75, 0x5F, 0xEF, 0x65, 0xBC, 0x39, 0x1F, 0x8B, 0x36, 0xF8, 0xF8,
+ 0xEB, 0x73, 0x71, 0xFD, 0x55, 0x8B,
+ /* y */
+ 0x01, 0x00, 0x6A, 0x08, 0xA4, 0x19, 0x03, 0x35, 0x06, 0x78, 0xE5, 0x85,
+ 0x28, 0xBE, 0xBF, 0x8A, 0x0B, 0xEF, 0xF8, 0x67, 0xA7, 0xCA, 0x36, 0x71,
+ 0x6F, 0x7E, 0x01, 0xF8, 0x10, 0x52,
+ /* order */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x13, 0xE9, 0x74, 0xE7, 0x2F, 0x8A, 0x69, 0x22, 0x03,
+ 0x1D, 0x26, 0x03, 0xCF, 0xE0, 0xD7
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 30 * 6];
+} _EC_SECG_CHAR2_239K1 = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 30, 4
+ },
+ {
+ /* no seed */
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* x */
+ 0x29, 0xA0, 0xB6, 0xA8, 0x87, 0xA9, 0x83, 0xE9, 0x73, 0x09, 0x88, 0xA6,
+ 0x87, 0x27, 0xA8, 0xB2, 0xD1, 0x26, 0xC4, 0x4C, 0xC2, 0xCC, 0x7B, 0x2A,
+ 0x65, 0x55, 0x19, 0x30, 0x35, 0xDC,
+ /* y */
+ 0x76, 0x31, 0x08, 0x04, 0xF1, 0x2E, 0x54, 0x9B, 0xDB, 0x01, 0x1C, 0x10,
+ 0x30, 0x89, 0xE7, 0x35, 0x10, 0xAC, 0xB2, 0x75, 0xFC, 0x31, 0x2A, 0x5D,
+ 0xC6, 0xB7, 0x65, 0x53, 0xF0, 0xCA,
+ /* order */
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5A, 0x79, 0xFE, 0xC6, 0x7C, 0xB6, 0xE9, 0x1F, 0x1C,
+ 0x1D, 0xA8, 0x00, 0xE4, 0x78, 0xA5
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 36 * 6];
+} _EC_NIST_CHAR2_283K = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 36, 4
+ },
+ {
+ /* no seed */
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* x */
+ 0x05, 0x03, 0x21, 0x3F, 0x78, 0xCA, 0x44, 0x88, 0x3F, 0x1A, 0x3B, 0x81,
+ 0x62, 0xF1, 0x88, 0xE5, 0x53, 0xCD, 0x26, 0x5F, 0x23, 0xC1, 0x56, 0x7A,
+ 0x16, 0x87, 0x69, 0x13, 0xB0, 0xC2, 0xAC, 0x24, 0x58, 0x49, 0x28, 0x36,
+ /* y */
+ 0x01, 0xCC, 0xDA, 0x38, 0x0F, 0x1C, 0x9E, 0x31, 0x8D, 0x90, 0xF9, 0x5D,
+ 0x07, 0xE5, 0x42, 0x6F, 0xE8, 0x7E, 0x45, 0xC0, 0xE8, 0x18, 0x46, 0x98,
+ 0xE4, 0x59, 0x62, 0x36, 0x4E, 0x34, 0x11, 0x61, 0x77, 0xDD, 0x22, 0x59,
+ /* order */
+ 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xAE, 0x2E, 0xD0, 0x75, 0x77,
+ 0x26, 0x5D, 0xFF, 0x7F, 0x94, 0x45, 0x1E, 0x06, 0x1E, 0x16, 0x3C, 0x61
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 36 * 6];
+} _EC_NIST_CHAR2_283B = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 36, 2
+ },
+ {
+ /* no seed */
+ 0x77, 0xE2, 0xB0, 0x73, 0x70, 0xEB, 0x0F, 0x83, 0x2A, 0x6D, 0xD5, 0xB6,
+ 0x2D, 0xFC, 0x88, 0xCD, 0x06, 0xBB, 0x84, 0xBE,
+ /* p */
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* b */
+ 0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, 0xAF, 0x8A,
+ 0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76, 0x45, 0x30, 0x9F, 0xA2,
+ 0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26, 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5,
+ /* x */
+ 0x05, 0xF9, 0x39, 0x25, 0x8D, 0xB7, 0xDD, 0x90, 0xE1, 0x93, 0x4F, 0x8C,
+ 0x70, 0xB0, 0xDF, 0xEC, 0x2E, 0xED, 0x25, 0xB8, 0x55, 0x7E, 0xAC, 0x9C,
+ 0x80, 0xE2, 0xE1, 0x98, 0xF8, 0xCD, 0xBE, 0xCD, 0x86, 0xB1, 0x20, 0x53,
+ /* y */
+ 0x03, 0x67, 0x68, 0x54, 0xFE, 0x24, 0x14, 0x1C, 0xB9, 0x8F, 0xE6, 0xD4,
+ 0xB2, 0x0D, 0x02, 0xB4, 0x51, 0x6F, 0xF7, 0x02, 0x35, 0x0E, 0xDD, 0xB0,
+ 0x82, 0x67, 0x79, 0xC8, 0x13, 0xF0, 0xDF, 0x45, 0xBE, 0x81, 0x12, 0xF4,
+ /* order */
+ 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x90, 0x39, 0x96, 0x60, 0xFC,
+ 0x93, 0x8A, 0x90, 0x16, 0x5B, 0x04, 0x2A, 0x7C, 0xEF, 0xAD, 0xB3, 0x07
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 52 * 6];
+} _EC_NIST_CHAR2_409K = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 52, 4
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ /* x */
+ 0x00, 0x60, 0xF0, 0x5F, 0x65, 0x8F, 0x49, 0xC1, 0xAD, 0x3A, 0xB1, 0x89,
+ 0x0F, 0x71, 0x84, 0x21, 0x0E, 0xFD, 0x09, 0x87, 0xE3, 0x07, 0xC8, 0x4C,
+ 0x27, 0xAC, 0xCF, 0xB8, 0xF9, 0xF6, 0x7C, 0xC2, 0xC4, 0x60, 0x18, 0x9E,
+ 0xB5, 0xAA, 0xAA, 0x62, 0xEE, 0x22, 0x2E, 0xB1, 0xB3, 0x55, 0x40, 0xCF,
+ 0xE9, 0x02, 0x37, 0x46,
+ /* y */
+ 0x01, 0xE3, 0x69, 0x05, 0x0B, 0x7C, 0x4E, 0x42, 0xAC, 0xBA, 0x1D, 0xAC,
+ 0xBF, 0x04, 0x29, 0x9C, 0x34, 0x60, 0x78, 0x2F, 0x91, 0x8E, 0xA4, 0x27,
+ 0xE6, 0x32, 0x51, 0x65, 0xE9, 0xEA, 0x10, 0xE3, 0xDA, 0x5F, 0x6C, 0x42,
+ 0xE9, 0xC5, 0x52, 0x15, 0xAA, 0x9C, 0xA2, 0x7A, 0x58, 0x63, 0xEC, 0x48,
+ 0xD8, 0xE0, 0x28, 0x6B,
+ /* order */
+ 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFE, 0x5F, 0x83, 0xB2, 0xD4, 0xEA, 0x20, 0x40, 0x0E, 0xC4,
+ 0x55, 0x7D, 0x5E, 0xD3, 0xE3, 0xE7, 0xCA, 0x5B, 0x4B, 0x5C, 0x83, 0xB8,
+ 0xE0, 0x1E, 0x5F, 0xCF
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 52 * 6];
+} _EC_NIST_CHAR2_409B = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 52, 2
+ },
+ {
+ /* seed */
+ 0x40, 0x99, 0xB5, 0xA4, 0x57, 0xF9, 0xD6, 0x9F, 0x79, 0x21, 0x3D, 0x09,
+ 0x4C, 0x4B, 0xCD, 0x4D, 0x42, 0x62, 0x21, 0x0B,
+ /* p */
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ /* b */
+ 0x00, 0x21, 0xA5, 0xC2, 0xC8, 0xEE, 0x9F, 0xEB, 0x5C, 0x4B, 0x9A, 0x75,
+ 0x3B, 0x7B, 0x47, 0x6B, 0x7F, 0xD6, 0x42, 0x2E, 0xF1, 0xF3, 0xDD, 0x67,
+ 0x47, 0x61, 0xFA, 0x99, 0xD6, 0xAC, 0x27, 0xC8, 0xA9, 0xA1, 0x97, 0xB2,
+ 0x72, 0x82, 0x2F, 0x6C, 0xD5, 0x7A, 0x55, 0xAA, 0x4F, 0x50, 0xAE, 0x31,
+ 0x7B, 0x13, 0x54, 0x5F,
+ /* x */
+ 0x01, 0x5D, 0x48, 0x60, 0xD0, 0x88, 0xDD, 0xB3, 0x49, 0x6B, 0x0C, 0x60,
+ 0x64, 0x75, 0x62, 0x60, 0x44, 0x1C, 0xDE, 0x4A, 0xF1, 0x77, 0x1D, 0x4D,
+ 0xB0, 0x1F, 0xFE, 0x5B, 0x34, 0xE5, 0x97, 0x03, 0xDC, 0x25, 0x5A, 0x86,
+ 0x8A, 0x11, 0x80, 0x51, 0x56, 0x03, 0xAE, 0xAB, 0x60, 0x79, 0x4E, 0x54,
+ 0xBB, 0x79, 0x96, 0xA7,
+ /* y */
+ 0x00, 0x61, 0xB1, 0xCF, 0xAB, 0x6B, 0xE5, 0xF3, 0x2B, 0xBF, 0xA7, 0x83,
+ 0x24, 0xED, 0x10, 0x6A, 0x76, 0x36, 0xB9, 0xC5, 0xA7, 0xBD, 0x19, 0x8D,
+ 0x01, 0x58, 0xAA, 0x4F, 0x54, 0x88, 0xD0, 0x8F, 0x38, 0x51, 0x4F, 0x1F,
+ 0xDF, 0x4B, 0x4F, 0x40, 0xD2, 0x18, 0x1B, 0x36, 0x81, 0xC3, 0x64, 0xBA,
+ 0x02, 0x73, 0xC7, 0x06,
+ /* order */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0xE2, 0xAA, 0xD6, 0xA6, 0x12, 0xF3, 0x33, 0x07, 0xBE,
+ 0x5F, 0xA4, 0x7C, 0x3C, 0x9E, 0x05, 0x2F, 0x83, 0x81, 0x64, 0xCD, 0x37,
+ 0xD9, 0xA2, 0x11, 0x73
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 72 * 6];
+} _EC_NIST_CHAR2_571K = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 72, 4
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x25,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* x */
+ 0x02, 0x6E, 0xB7, 0xA8, 0x59, 0x92, 0x3F, 0xBC, 0x82, 0x18, 0x96, 0x31,
+ 0xF8, 0x10, 0x3F, 0xE4, 0xAC, 0x9C, 0xA2, 0x97, 0x00, 0x12, 0xD5, 0xD4,
+ 0x60, 0x24, 0x80, 0x48, 0x01, 0x84, 0x1C, 0xA4, 0x43, 0x70, 0x95, 0x84,
+ 0x93, 0xB2, 0x05, 0xE6, 0x47, 0xDA, 0x30, 0x4D, 0xB4, 0xCE, 0xB0, 0x8C,
+ 0xBB, 0xD1, 0xBA, 0x39, 0x49, 0x47, 0x76, 0xFB, 0x98, 0x8B, 0x47, 0x17,
+ 0x4D, 0xCA, 0x88, 0xC7, 0xE2, 0x94, 0x52, 0x83, 0xA0, 0x1C, 0x89, 0x72,
+ /* y */
+ 0x03, 0x49, 0xDC, 0x80, 0x7F, 0x4F, 0xBF, 0x37, 0x4F, 0x4A, 0xEA, 0xDE,
+ 0x3B, 0xCA, 0x95, 0x31, 0x4D, 0xD5, 0x8C, 0xEC, 0x9F, 0x30, 0x7A, 0x54,
+ 0xFF, 0xC6, 0x1E, 0xFC, 0x00, 0x6D, 0x8A, 0x2C, 0x9D, 0x49, 0x79, 0xC0,
+ 0xAC, 0x44, 0xAE, 0xA7, 0x4F, 0xBE, 0xBB, 0xB9, 0xF7, 0x72, 0xAE, 0xDC,
+ 0xB6, 0x20, 0xB0, 0x1A, 0x7B, 0xA7, 0xAF, 0x1B, 0x32, 0x04, 0x30, 0xC8,
+ 0x59, 0x19, 0x84, 0xF6, 0x01, 0xCD, 0x4C, 0x14, 0x3E, 0xF1, 0xC7, 0xA3,
+ /* order */
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x13, 0x18, 0x50, 0xE1, 0xF1, 0x9A, 0x63, 0xE4, 0xB3, 0x91, 0xA8, 0xDB,
+ 0x91, 0x7F, 0x41, 0x38, 0xB6, 0x30, 0xD8, 0x4B, 0xE5, 0xD6, 0x39, 0x38,
+ 0x1E, 0x91, 0xDE, 0xB4, 0x5C, 0xFE, 0x77, 0x8F, 0x63, 0x7C, 0x10, 0x01
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 72 * 6];
+} _EC_NIST_CHAR2_571B = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 72, 2
+ },
+ {
+ /* seed */
+ 0x2A, 0xA0, 0x58, 0xF7, 0x3A, 0x0E, 0x33, 0xAB, 0x48, 0x6B, 0x0F, 0x61,
+ 0x04, 0x10, 0xC5, 0x3A, 0x7F, 0x13, 0x23, 0x10,
+ /* p */
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x25,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* b */
+ 0x02, 0xF4, 0x0E, 0x7E, 0x22, 0x21, 0xF2, 0x95, 0xDE, 0x29, 0x71, 0x17,
+ 0xB7, 0xF3, 0xD6, 0x2F, 0x5C, 0x6A, 0x97, 0xFF, 0xCB, 0x8C, 0xEF, 0xF1,
+ 0xCD, 0x6B, 0xA8, 0xCE, 0x4A, 0x9A, 0x18, 0xAD, 0x84, 0xFF, 0xAB, 0xBD,
+ 0x8E, 0xFA, 0x59, 0x33, 0x2B, 0xE7, 0xAD, 0x67, 0x56, 0xA6, 0x6E, 0x29,
+ 0x4A, 0xFD, 0x18, 0x5A, 0x78, 0xFF, 0x12, 0xAA, 0x52, 0x0E, 0x4D, 0xE7,
+ 0x39, 0xBA, 0xCA, 0x0C, 0x7F, 0xFE, 0xFF, 0x7F, 0x29, 0x55, 0x72, 0x7A,
+ /* x */
+ 0x03, 0x03, 0x00, 0x1D, 0x34, 0xB8, 0x56, 0x29, 0x6C, 0x16, 0xC0, 0xD4,
+ 0x0D, 0x3C, 0xD7, 0x75, 0x0A, 0x93, 0xD1, 0xD2, 0x95, 0x5F, 0xA8, 0x0A,
+ 0xA5, 0xF4, 0x0F, 0xC8, 0xDB, 0x7B, 0x2A, 0xBD, 0xBD, 0xE5, 0x39, 0x50,
+ 0xF4, 0xC0, 0xD2, 0x93, 0xCD, 0xD7, 0x11, 0xA3, 0x5B, 0x67, 0xFB, 0x14,
+ 0x99, 0xAE, 0x60, 0x03, 0x86, 0x14, 0xF1, 0x39, 0x4A, 0xBF, 0xA3, 0xB4,
+ 0xC8, 0x50, 0xD9, 0x27, 0xE1, 0xE7, 0x76, 0x9C, 0x8E, 0xEC, 0x2D, 0x19,
+ /* y */
+ 0x03, 0x7B, 0xF2, 0x73, 0x42, 0xDA, 0x63, 0x9B, 0x6D, 0xCC, 0xFF, 0xFE,
+ 0xB7, 0x3D, 0x69, 0xD7, 0x8C, 0x6C, 0x27, 0xA6, 0x00, 0x9C, 0xBB, 0xCA,
+ 0x19, 0x80, 0xF8, 0x53, 0x39, 0x21, 0xE8, 0xA6, 0x84, 0x42, 0x3E, 0x43,
+ 0xBA, 0xB0, 0x8A, 0x57, 0x62, 0x91, 0xAF, 0x8F, 0x46, 0x1B, 0xB2, 0xA8,
+ 0xB3, 0x53, 0x1D, 0x2F, 0x04, 0x85, 0xC1, 0x9B, 0x16, 0xE2, 0xF1, 0x51,
+ 0x6E, 0x23, 0xDD, 0x3C, 0x1A, 0x48, 0x27, 0xAF, 0x1B, 0x8A, 0xC1, 0x5B,
+ /* order */
+ 0x03, 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,
+ 0xE6, 0x61, 0xCE, 0x18, 0xFF, 0x55, 0x98, 0x73, 0x08, 0x05, 0x9B, 0x18,
+ 0x68, 0x23, 0x85, 0x1E, 0xC7, 0xDD, 0x9C, 0xA1, 0x16, 0x1D, 0xE9, 0x3D,
+ 0x51, 0x74, 0xD6, 0x6E, 0x83, 0x82, 0xE9, 0xBB, 0x2F, 0xE8, 0x4E, 0x47
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 21 * 6];
+} _EC_X9_62_CHAR2_163V1 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 21, 2
+ },
+ {
+ /* seed */
+ 0xD2, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE, 0xF4, 0xD6,
+ 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x54,
+ /* p */
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
+ /* a */
+ 0x07, 0x25, 0x46, 0xB5, 0x43, 0x52, 0x34, 0xA4, 0x22, 0xE0, 0x78, 0x96,
+ 0x75, 0xF4, 0x32, 0xC8, 0x94, 0x35, 0xDE, 0x52, 0x42,
+ /* b */
+ 0x00, 0xC9, 0x51, 0x7D, 0x06, 0xD5, 0x24, 0x0D, 0x3C, 0xFF, 0x38, 0xC7,
+ 0x4B, 0x20, 0xB6, 0xCD, 0x4D, 0x6F, 0x9D, 0xD4, 0xD9,
+ /* x */
+ 0x07, 0xAF, 0x69, 0x98, 0x95, 0x46, 0x10, 0x3D, 0x79, 0x32, 0x9F, 0xCC,
+ 0x3D, 0x74, 0x88, 0x0F, 0x33, 0xBB, 0xE8, 0x03, 0xCB,
+ /* y */
+ 0x01, 0xEC, 0x23, 0x21, 0x1B, 0x59, 0x66, 0xAD, 0xEA, 0x1D, 0x3F, 0x87,
+ 0xF7, 0xEA, 0x58, 0x48, 0xAE, 0xF0, 0xB7, 0xCA, 0x9F,
+ /* order */
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE6,
+ 0x0F, 0xC8, 0x82, 0x1C, 0xC7, 0x4D, 0xAE, 0xAF, 0xC1
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 21 * 6];
+} _EC_X9_62_CHAR2_163V2 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 21, 2
+ },
+ {
+ /* seed */
+ 0x53, 0x81, 0x4C, 0x05, 0x0D, 0x44, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+ 0x15, 0x17, 0x58, 0x0C, 0xA4, 0xE2, 0x9F, 0xFD,
+ /* p */
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
+ /* a */
+ 0x01, 0x08, 0xB3, 0x9E, 0x77, 0xC4, 0xB1, 0x08, 0xBE, 0xD9, 0x81, 0xED,
+ 0x0E, 0x89, 0x0E, 0x11, 0x7C, 0x51, 0x1C, 0xF0, 0x72,
+ /* b */
+ 0x06, 0x67, 0xAC, 0xEB, 0x38, 0xAF, 0x4E, 0x48, 0x8C, 0x40, 0x74, 0x33,
+ 0xFF, 0xAE, 0x4F, 0x1C, 0x81, 0x16, 0x38, 0xDF, 0x20,
+ /* x */
+ 0x00, 0x24, 0x26, 0x6E, 0x4E, 0xB5, 0x10, 0x6D, 0x0A, 0x96, 0x4D, 0x92,
+ 0xC4, 0x86, 0x0E, 0x26, 0x71, 0xDB, 0x9B, 0x6C, 0xC5,
+ /* y */
+ 0x07, 0x9F, 0x68, 0x4D, 0xDF, 0x66, 0x84, 0xC5, 0xCD, 0x25, 0x8B, 0x38,
+ 0x90, 0x02, 0x1B, 0x23, 0x86, 0xDF, 0xD1, 0x9F, 0xC5,
+ /* order */
+ 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xF6,
+ 0x4D, 0xE1, 0x15, 0x1A, 0xDB, 0xB7, 0x8F, 0x10, 0xA7
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 21 * 6];
+} _EC_X9_62_CHAR2_163V3 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 21, 2
+ },
+ {
+ /* seed */
+ 0x50, 0xCB, 0xF1, 0xD9, 0x5C, 0xA9, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75,
+ 0x61, 0x51, 0x75, 0xF1, 0x6A, 0x36, 0xA3, 0xB8,
+ /* p */
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
+ /* a */
+ 0x07, 0xA5, 0x26, 0xC6, 0x3D, 0x3E, 0x25, 0xA2, 0x56, 0xA0, 0x07, 0x69,
+ 0x9F, 0x54, 0x47, 0xE3, 0x2A, 0xE4, 0x56, 0xB5, 0x0E,
+ /* b */
+ 0x03, 0xF7, 0x06, 0x17, 0x98, 0xEB, 0x99, 0xE2, 0x38, 0xFD, 0x6F, 0x1B,
+ 0xF9, 0x5B, 0x48, 0xFE, 0xEB, 0x48, 0x54, 0x25, 0x2B,
+ /* x */
+ 0x02, 0xF9, 0xF8, 0x7B, 0x7C, 0x57, 0x4D, 0x0B, 0xDE, 0xCF, 0x8A, 0x22,
+ 0xE6, 0x52, 0x47, 0x75, 0xF9, 0x8C, 0xDE, 0xBD, 0xCB,
+ /* y */
+ 0x05, 0xB9, 0x35, 0x59, 0x0C, 0x15, 0x5E, 0x17, 0xEA, 0x48, 0xEB, 0x3F,
+ 0xF3, 0x71, 0x8B, 0x89, 0x3D, 0xF5, 0x9A, 0x05, 0xD0,
+ /* order */
+ 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x1A,
+ 0xEE, 0x14, 0x0F, 0x11, 0x0A, 0xFF, 0x96, 0x13, 0x09
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 23 * 6];
+} _EC_X9_62_CHAR2_176V1 = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 23, 0xFF6E
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x07,
+ /* a */
+ 0x00, 0xE4, 0xE6, 0xDB, 0x29, 0x95, 0x06, 0x5C, 0x40, 0x7D, 0x9D, 0x39,
+ 0xB8, 0xD0, 0x96, 0x7B, 0x96, 0x70, 0x4B, 0xA8, 0xE9, 0xC9, 0x0B,
+ /* b */
+ 0x00, 0x5D, 0xDA, 0x47, 0x0A, 0xBE, 0x64, 0x14, 0xDE, 0x8E, 0xC1, 0x33,
+ 0xAE, 0x28, 0xE9, 0xBB, 0xD7, 0xFC, 0xEC, 0x0A, 0xE0, 0xFF, 0xF2,
+ /* x */
+ 0x00, 0x8D, 0x16, 0xC2, 0x86, 0x67, 0x98, 0xB6, 0x00, 0xF9, 0xF0, 0x8B,
+ 0xB4, 0xA8, 0xE8, 0x60, 0xF3, 0x29, 0x8C, 0xE0, 0x4A, 0x57, 0x98,
+ /* y */
+ 0x00, 0x6F, 0xA4, 0x53, 0x9C, 0x2D, 0xAD, 0xDD, 0xD6, 0xBA, 0xB5, 0x16,
+ 0x7D, 0x61, 0xB4, 0x36, 0xE1, 0xD9, 0x2B, 0xB1, 0x6A, 0x56, 0x2C,
+ /* order */
+ 0x00, 0x00, 0x01, 0x00, 0x92, 0x53, 0x73, 0x97, 0xEC, 0xA4, 0xF6, 0x14,
+ 0x57, 0x99, 0xD6, 0x2B, 0x0A, 0x19, 0xCE, 0x06, 0xFE, 0x26, 0xAD
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 24 * 6];
+} _EC_X9_62_CHAR2_191V1 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 24, 2
+ },
+ {
+ /* seed */
+ 0x4E, 0x13, 0xCA, 0x54, 0x27, 0x44, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+ 0x15, 0x17, 0x55, 0x2F, 0x27, 0x9A, 0x8C, 0x84,
+ /* p */
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01,
+ /* a */
+ 0x28, 0x66, 0x53, 0x7B, 0x67, 0x67, 0x52, 0x63, 0x6A, 0x68, 0xF5, 0x65,
+ 0x54, 0xE1, 0x26, 0x40, 0x27, 0x6B, 0x64, 0x9E, 0xF7, 0x52, 0x62, 0x67,
+ /* b */
+ 0x2E, 0x45, 0xEF, 0x57, 0x1F, 0x00, 0x78, 0x6F, 0x67, 0xB0, 0x08, 0x1B,
+ 0x94, 0x95, 0xA3, 0xD9, 0x54, 0x62, 0xF5, 0xDE, 0x0A, 0xA1, 0x85, 0xEC,
+ /* x */
+ 0x36, 0xB3, 0xDA, 0xF8, 0xA2, 0x32, 0x06, 0xF9, 0xC4, 0xF2, 0x99, 0xD7,
+ 0xB2, 0x1A, 0x9C, 0x36, 0x91, 0x37, 0xF2, 0xC8, 0x4A, 0xE1, 0xAA, 0x0D,
+ /* y */
+ 0x76, 0x5B, 0xE7, 0x34, 0x33, 0xB3, 0xF9, 0x5E, 0x33, 0x29, 0x32, 0xE7,
+ 0x0E, 0xA2, 0x45, 0xCA, 0x24, 0x18, 0xEA, 0x0E, 0xF9, 0x80, 0x18, 0xFB,
+ /* order */
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0xA2, 0x0E, 0x90, 0xC3, 0x90, 0x67, 0xC8, 0x93, 0xBB, 0xB9, 0xA5
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 24 * 6];
+} _EC_X9_62_CHAR2_191V2 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 24, 4
+ },
+ {
+ /* seed */
+ 0x08, 0x71, 0xEF, 0x2F, 0xEF, 0x24, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+ 0x15, 0x17, 0x58, 0xBE, 0xE0, 0xD9, 0x5C, 0x15,
+ /* p */
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01,
+ /* a */
+ 0x40, 0x10, 0x28, 0x77, 0x4D, 0x77, 0x77, 0xC7, 0xB7, 0x66, 0x6D, 0x13,
+ 0x66, 0xEA, 0x43, 0x20, 0x71, 0x27, 0x4F, 0x89, 0xFF, 0x01, 0xE7, 0x18,
+ /* b */
+ 0x06, 0x20, 0x04, 0x8D, 0x28, 0xBC, 0xBD, 0x03, 0xB6, 0x24, 0x9C, 0x99,
+ 0x18, 0x2B, 0x7C, 0x8C, 0xD1, 0x97, 0x00, 0xC3, 0x62, 0xC4, 0x6A, 0x01,
+ /* x */
+ 0x38, 0x09, 0xB2, 0xB7, 0xCC, 0x1B, 0x28, 0xCC, 0x5A, 0x87, 0x92, 0x6A,
+ 0xAD, 0x83, 0xFD, 0x28, 0x78, 0x9E, 0x81, 0xE2, 0xC9, 0xE3, 0xBF, 0x10,
+ /* y */
+ 0x17, 0x43, 0x43, 0x86, 0x62, 0x6D, 0x14, 0xF3, 0xDB, 0xF0, 0x17, 0x60,
+ 0xD9, 0x21, 0x3A, 0x3E, 0x1C, 0xF3, 0x7A, 0xEC, 0x43, 0x7D, 0x66, 0x8A,
+ /* order */
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x50, 0x50, 0x8C, 0xB8, 0x9F, 0x65, 0x28, 0x24, 0xE0, 0x6B, 0x81, 0x73
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 24 * 6];
+} _EC_X9_62_CHAR2_191V3 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 24, 6
+ },
+ {
+ /* seed */
+ 0xE0, 0x53, 0x51, 0x2D, 0xC6, 0x84, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+ 0x15, 0x17, 0x50, 0x67, 0xAE, 0x78, 0x6D, 0x1F,
+ /* p */
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01,
+ /* a */
+ 0x6C, 0x01, 0x07, 0x47, 0x56, 0x09, 0x91, 0x22, 0x22, 0x10, 0x56, 0x91,
+ 0x1C, 0x77, 0xD7, 0x7E, 0x77, 0xA7, 0x77, 0xE7, 0xE7, 0xE7, 0x7F, 0xCB,
+ /* b */
+ 0x71, 0xFE, 0x1A, 0xF9, 0x26, 0xCF, 0x84, 0x79, 0x89, 0xEF, 0xEF, 0x8D,
+ 0xB4, 0x59, 0xF6, 0x63, 0x94, 0xD9, 0x0F, 0x32, 0xAD, 0x3F, 0x15, 0xE8,
+ /* x */
+ 0x37, 0x5D, 0x4C, 0xE2, 0x4F, 0xDE, 0x43, 0x44, 0x89, 0xDE, 0x87, 0x46,
+ 0xE7, 0x17, 0x86, 0x01, 0x50, 0x09, 0xE6, 0x6E, 0x38, 0xA9, 0x26, 0xDD,
+ /* y */
+ 0x54, 0x5A, 0x39, 0x17, 0x61, 0x96, 0x57, 0x5D, 0x98, 0x59, 0x99, 0x36,
+ 0x6E, 0x6A, 0xD3, 0x4C, 0xE0, 0xA7, 0x7C, 0xD7, 0x12, 0x7B, 0x06, 0xBE,
+ /* order */
+ 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0x61, 0x0C, 0x0B, 0x19, 0x68, 0x12, 0xBF, 0xB6, 0x28, 0x8A, 0x3E, 0xA3
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 27 * 6];
+} _EC_X9_62_CHAR2_208W1 = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 27, 0xFE48
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x07,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0xC8, 0x61, 0x9E, 0xD4, 0x5A, 0x62, 0xE6, 0x21, 0x2E, 0x11, 0x60,
+ 0x34, 0x9E, 0x2B, 0xFA, 0x84, 0x44, 0x39, 0xFA, 0xFC, 0x2A, 0x3F, 0xD1,
+ 0x63, 0x8F, 0x9E,
+ /* x */
+ 0x00, 0x89, 0xFD, 0xFB, 0xE4, 0xAB, 0xE1, 0x93, 0xDF, 0x95, 0x59, 0xEC,
+ 0xF0, 0x7A, 0xC0, 0xCE, 0x78, 0x55, 0x4E, 0x27, 0x84, 0xEB, 0x8C, 0x1E,
+ 0xD1, 0xA5, 0x7A,
+ /* y */
+ 0x00, 0x0F, 0x55, 0xB5, 0x1A, 0x06, 0xE7, 0x8E, 0x9A, 0xC3, 0x8A, 0x03,
+ 0x5F, 0xF5, 0x20, 0xD8, 0xB0, 0x17, 0x81, 0xBE, 0xB1, 0xA6, 0xBB, 0x08,
+ 0x61, 0x7D, 0xE3,
+ /* order */
+ 0x00, 0x00, 0x01, 0x01, 0xBA, 0xF9, 0x5C, 0x97, 0x23, 0xC5, 0x7B, 0x6C,
+ 0x21, 0xDA, 0x2E, 0xFF, 0x2D, 0x5E, 0xD5, 0x88, 0xBD, 0xD5, 0x71, 0x7E,
+ 0x21, 0x2F, 0x9D
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 30 * 6];
+} _EC_X9_62_CHAR2_239V1 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 30, 4
+ },
+ {
+ /* seed */
+ 0xD3, 0x4B, 0x9A, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75,
+ 0xCA, 0x71, 0xB9, 0x20, 0xBF, 0xEF, 0xB0, 0x5D,
+ /* p */
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0x32, 0x01, 0x08, 0x57, 0x07, 0x7C, 0x54, 0x31, 0x12, 0x3A, 0x46, 0xB8,
+ 0x08, 0x90, 0x67, 0x56, 0xF5, 0x43, 0x42, 0x3E, 0x8D, 0x27, 0x87, 0x75,
+ 0x78, 0x12, 0x57, 0x78, 0xAC, 0x76,
+ /* b */
+ 0x79, 0x04, 0x08, 0xF2, 0xEE, 0xDA, 0xF3, 0x92, 0xB0, 0x12, 0xED, 0xEF,
+ 0xB3, 0x39, 0x2F, 0x30, 0xF4, 0x32, 0x7C, 0x0C, 0xA3, 0xF3, 0x1F, 0xC3,
+ 0x83, 0xC4, 0x22, 0xAA, 0x8C, 0x16,
+ /* x */
+ 0x57, 0x92, 0x70, 0x98, 0xFA, 0x93, 0x2E, 0x7C, 0x0A, 0x96, 0xD3, 0xFD,
+ 0x5B, 0x70, 0x6E, 0xF7, 0xE5, 0xF5, 0xC1, 0x56, 0xE1, 0x6B, 0x7E, 0x7C,
+ 0x86, 0x03, 0x85, 0x52, 0xE9, 0x1D,
+ /* y */
+ 0x61, 0xD8, 0xEE, 0x50, 0x77, 0xC3, 0x3F, 0xEC, 0xF6, 0xF1, 0xA1, 0x6B,
+ 0x26, 0x8D, 0xE4, 0x69, 0xC3, 0xC7, 0x74, 0x4E, 0xA9, 0xA9, 0x71, 0x64,
+ 0x9F, 0xC7, 0xA9, 0x61, 0x63, 0x05,
+ /* order */
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0F, 0x4D, 0x42, 0xFF, 0xE1, 0x49, 0x2A, 0x49, 0x93,
+ 0xF1, 0xCA, 0xD6, 0x66, 0xE4, 0x47
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 30 * 6];
+} _EC_X9_62_CHAR2_239V2 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 30, 6
+ },
+ {
+ /* seed */
+ 0x2A, 0xA6, 0x98, 0x2F, 0xDF, 0xA4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+ 0x15, 0x17, 0x5D, 0x26, 0x67, 0x27, 0x27, 0x7D,
+ /* p */
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0x42, 0x30, 0x01, 0x77, 0x57, 0xA7, 0x67, 0xFA, 0xE4, 0x23, 0x98, 0x56,
+ 0x9B, 0x74, 0x63, 0x25, 0xD4, 0x53, 0x13, 0xAF, 0x07, 0x66, 0x26, 0x64,
+ 0x79, 0xB7, 0x56, 0x54, 0xE6, 0x5F,
+ /* b */
+ 0x50, 0x37, 0xEA, 0x65, 0x41, 0x96, 0xCF, 0xF0, 0xCD, 0x82, 0xB2, 0xC1,
+ 0x4A, 0x2F, 0xCF, 0x2E, 0x3F, 0xF8, 0x77, 0x52, 0x85, 0xB5, 0x45, 0x72,
+ 0x2F, 0x03, 0xEA, 0xCD, 0xB7, 0x4B,
+ /* x */
+ 0x28, 0xF9, 0xD0, 0x4E, 0x90, 0x00, 0x69, 0xC8, 0xDC, 0x47, 0xA0, 0x85,
+ 0x34, 0xFE, 0x76, 0xD2, 0xB9, 0x00, 0xB7, 0xD7, 0xEF, 0x31, 0xF5, 0x70,
+ 0x9F, 0x20, 0x0C, 0x4C, 0xA2, 0x05,
+ /* y */
+ 0x56, 0x67, 0x33, 0x4C, 0x45, 0xAF, 0xF3, 0xB5, 0xA0, 0x3B, 0xAD, 0x9D,
+ 0xD7, 0x5E, 0x2C, 0x71, 0xA9, 0x93, 0x62, 0x56, 0x7D, 0x54, 0x53, 0xF7,
+ 0xFA, 0x6E, 0x22, 0x7E, 0xC8, 0x33,
+ /* order */
+ 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+ 0x55, 0x55, 0x55, 0x3C, 0x6F, 0x28, 0x85, 0x25, 0x9C, 0x31, 0xE3, 0xFC,
+ 0xDF, 0x15, 0x46, 0x24, 0x52, 0x2D
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 30 * 6];
+} _EC_X9_62_CHAR2_239V3 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 30, 0xA
+ },
+ {
+ /* seed */
+ 0x9E, 0x07, 0x6F, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75,
+ 0xE1, 0x1E, 0x9F, 0xDD, 0x77, 0xF9, 0x20, 0x41,
+ /* p */
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0x01, 0x23, 0x87, 0x74, 0x66, 0x6A, 0x67, 0x76, 0x6D, 0x66, 0x76, 0xF7,
+ 0x78, 0xE6, 0x76, 0xB6, 0x69, 0x99, 0x17, 0x66, 0x66, 0xE6, 0x87, 0x66,
+ 0x6D, 0x87, 0x66, 0xC6, 0x6A, 0x9F,
+ /* b */
+ 0x6A, 0x94, 0x19, 0x77, 0xBA, 0x9F, 0x6A, 0x43, 0x51, 0x99, 0xAC, 0xFC,
+ 0x51, 0x06, 0x7E, 0xD5, 0x87, 0xF5, 0x19, 0xC5, 0xEC, 0xB5, 0x41, 0xB8,
+ 0xE4, 0x41, 0x11, 0xDE, 0x1D, 0x40,
+ /* x */
+ 0x70, 0xF6, 0xE9, 0xD0, 0x4D, 0x28, 0x9C, 0x4E, 0x89, 0x91, 0x3C, 0xE3,
+ 0x53, 0x0B, 0xFD, 0xE9, 0x03, 0x97, 0x7D, 0x42, 0xB1, 0x46, 0xD5, 0x39,
+ 0xBF, 0x1B, 0xDE, 0x4E, 0x9C, 0x92,
+ /* y */
+ 0x2E, 0x5A, 0x0E, 0xAF, 0x6E, 0x5E, 0x13, 0x05, 0xB9, 0x00, 0x4D, 0xCE,
+ 0x5C, 0x0E, 0xD7, 0xFE, 0x59, 0xA3, 0x56, 0x08, 0xF3, 0x38, 0x37, 0xC8,
+ 0x16, 0xD8, 0x0B, 0x79, 0xF4, 0x61,
+ /* order */
+ 0x0C, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xAC, 0x49, 0x12, 0xD2, 0xD9, 0xDF, 0x90, 0x3E, 0xF9,
+ 0x88, 0x8B, 0x8A, 0x0E, 0x4C, 0xFF
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 35 * 6];
+} _EC_X9_62_CHAR2_272W1 = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 35, 0xFF06
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B,
+ /* a */
+ 0x00, 0x91, 0xA0, 0x91, 0xF0, 0x3B, 0x5F, 0xBA, 0x4A, 0xB2, 0xCC, 0xF4,
+ 0x9C, 0x4E, 0xDD, 0x22, 0x0F, 0xB0, 0x28, 0x71, 0x2D, 0x42, 0xBE, 0x75,
+ 0x2B, 0x2C, 0x40, 0x09, 0x4D, 0xBA, 0xCD, 0xB5, 0x86, 0xFB, 0x20,
+ /* b */
+ 0x00, 0x71, 0x67, 0xEF, 0xC9, 0x2B, 0xB2, 0xE3, 0xCE, 0x7C, 0x8A, 0xAA,
+ 0xFF, 0x34, 0xE1, 0x2A, 0x9C, 0x55, 0x70, 0x03, 0xD7, 0xC7, 0x3A, 0x6F,
+ 0xAF, 0x00, 0x3F, 0x99, 0xF6, 0xCC, 0x84, 0x82, 0xE5, 0x40, 0xF7,
+ /* x */
+ 0x00, 0x61, 0x08, 0xBA, 0xBB, 0x2C, 0xEE, 0xBC, 0xF7, 0x87, 0x05, 0x8A,
+ 0x05, 0x6C, 0xBE, 0x0C, 0xFE, 0x62, 0x2D, 0x77, 0x23, 0xA2, 0x89, 0xE0,
+ 0x8A, 0x07, 0xAE, 0x13, 0xEF, 0x0D, 0x10, 0xD1, 0x71, 0xDD, 0x8D,
+ /* y */
+ 0x00, 0x10, 0xC7, 0x69, 0x57, 0x16, 0x85, 0x1E, 0xEF, 0x6B, 0xA7, 0xF6,
+ 0x87, 0x2E, 0x61, 0x42, 0xFB, 0xD2, 0x41, 0xB8, 0x30, 0xFF, 0x5E, 0xFC,
+ 0xAC, 0xEC, 0xCA, 0xB0, 0x5E, 0x02, 0x00, 0x5D, 0xDE, 0x9D, 0x23,
+ /* order */
+ 0x00, 0x00, 0x01, 0x00, 0xFA, 0xF5, 0x13, 0x54, 0xE0, 0xE3, 0x9E, 0x48,
+ 0x92, 0xDF, 0x6E, 0x31, 0x9C, 0x72, 0xC8, 0x16, 0x16, 0x03, 0xFA, 0x45,
+ 0xAA, 0x7B, 0x99, 0x8A, 0x16, 0x7B, 0x8F, 0x1E, 0x62, 0x95, 0x21
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 39 * 6];
+} _EC_X9_62_CHAR2_304W1 = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 39, 0xFE2E
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x07,
+ /* a */
+ 0x00, 0xFD, 0x0D, 0x69, 0x31, 0x49, 0xA1, 0x18, 0xF6, 0x51, 0xE6, 0xDC,
+ 0xE6, 0x80, 0x20, 0x85, 0x37, 0x7E, 0x5F, 0x88, 0x2D, 0x1B, 0x51, 0x0B,
+ 0x44, 0x16, 0x00, 0x74, 0xC1, 0x28, 0x80, 0x78, 0x36, 0x5A, 0x03, 0x96,
+ 0xC8, 0xE6, 0x81,
+ /* b */
+ 0x00, 0xBD, 0xDB, 0x97, 0xE5, 0x55, 0xA5, 0x0A, 0x90, 0x8E, 0x43, 0xB0,
+ 0x1C, 0x79, 0x8E, 0xA5, 0xDA, 0xA6, 0x78, 0x8F, 0x1E, 0xA2, 0x79, 0x4E,
+ 0xFC, 0xF5, 0x71, 0x66, 0xB8, 0xC1, 0x40, 0x39, 0x60, 0x1E, 0x55, 0x82,
+ 0x73, 0x40, 0xBE,
+ /* x */
+ 0x00, 0x19, 0x7B, 0x07, 0x84, 0x5E, 0x9B, 0xE2, 0xD9, 0x6A, 0xDB, 0x0F,
+ 0x5F, 0x3C, 0x7F, 0x2C, 0xFF, 0xBD, 0x7A, 0x3E, 0xB8, 0xB6, 0xFE, 0xC3,
+ 0x5C, 0x7F, 0xD6, 0x7F, 0x26, 0xDD, 0xF6, 0x28, 0x5A, 0x64, 0x4F, 0x74,
+ 0x0A, 0x26, 0x14,
+ /* y */
+ 0x00, 0xE1, 0x9F, 0xBE, 0xB7, 0x6E, 0x0D, 0xA1, 0x71, 0x51, 0x7E, 0xCF,
+ 0x40, 0x1B, 0x50, 0x28, 0x9B, 0xF0, 0x14, 0x10, 0x32, 0x88, 0x52, 0x7A,
+ 0x9B, 0x41, 0x6A, 0x10, 0x5E, 0x80, 0x26, 0x0B, 0x54, 0x9F, 0xDC, 0x1B,
+ 0x92, 0xC0, 0x3B,
+ /* order */
+ 0x00, 0x00, 0x01, 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, 0x80, 0x01,
+ 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, 0x80, 0x01, 0x02, 0x2D, 0x5C,
+ 0x91, 0xDD, 0x17, 0x3F, 0x8F, 0xB5, 0x61, 0xDA, 0x68, 0x99, 0x16, 0x44,
+ 0x43, 0x05, 0x1D
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[20 + 45 * 6];
+} _EC_X9_62_CHAR2_359V1 = {
+ {
+ NID_X9_62_characteristic_two_field, 20, 45, 0x4C
+ },
+ {
+ /* seed */
+ 0x2B, 0x35, 0x49, 0x20, 0xB7, 0x24, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+ 0x15, 0x17, 0x58, 0x5B, 0xA1, 0x33, 0x2D, 0xC6,
+ /* p */
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0x56, 0x67, 0x67, 0x6A, 0x65, 0x4B, 0x20, 0x75, 0x4F, 0x35, 0x6E, 0xA9,
+ 0x20, 0x17, 0xD9, 0x46, 0x56, 0x7C, 0x46, 0x67, 0x55, 0x56, 0xF1, 0x95,
+ 0x56, 0xA0, 0x46, 0x16, 0xB5, 0x67, 0xD2, 0x23, 0xA5, 0xE0, 0x56, 0x56,
+ 0xFB, 0x54, 0x90, 0x16, 0xA9, 0x66, 0x56, 0xA5, 0x57,
+ /* b */
+ 0x24, 0x72, 0xE2, 0xD0, 0x19, 0x7C, 0x49, 0x36, 0x3F, 0x1F, 0xE7, 0xF5,
+ 0xB6, 0xDB, 0x07, 0x5D, 0x52, 0xB6, 0x94, 0x7D, 0x13, 0x5D, 0x8C, 0xA4,
+ 0x45, 0x80, 0x5D, 0x39, 0xBC, 0x34, 0x56, 0x26, 0x08, 0x96, 0x87, 0x74,
+ 0x2B, 0x63, 0x29, 0xE7, 0x06, 0x80, 0x23, 0x19, 0x88,
+ /* x */
+ 0x3C, 0x25, 0x8E, 0xF3, 0x04, 0x77, 0x67, 0xE7, 0xED, 0xE0, 0xF1, 0xFD,
+ 0xAA, 0x79, 0xDA, 0xEE, 0x38, 0x41, 0x36, 0x6A, 0x13, 0x2E, 0x16, 0x3A,
+ 0xCE, 0xD4, 0xED, 0x24, 0x01, 0xDF, 0x9C, 0x6B, 0xDC, 0xDE, 0x98, 0xE8,
+ 0xE7, 0x07, 0xC0, 0x7A, 0x22, 0x39, 0xB1, 0xB0, 0x97,
+ /* y */
+ 0x53, 0xD7, 0xE0, 0x85, 0x29, 0x54, 0x70, 0x48, 0x12, 0x1E, 0x9C, 0x95,
+ 0xF3, 0x79, 0x1D, 0xD8, 0x04, 0x96, 0x39, 0x48, 0xF3, 0x4F, 0xAE, 0x7B,
+ 0xF4, 0x4E, 0xA8, 0x23, 0x65, 0xDC, 0x78, 0x68, 0xFE, 0x57, 0xE4, 0xAE,
+ 0x2D, 0xE2, 0x11, 0x30, 0x5A, 0x40, 0x71, 0x04, 0xBD,
+ /* order */
+ 0x01, 0xAF, 0x28, 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, 0xAF, 0x28,
+ 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, 0xAF, 0x28, 0x6B, 0xC9, 0xFB,
+ 0x8F, 0x6B, 0x85, 0xC5, 0x56, 0x89, 0x2C, 0x20, 0xA7, 0xEB, 0x96, 0x4F,
+ 0xE7, 0x71, 0x9E, 0x74, 0xF4, 0x90, 0x75, 0x8D, 0x3B
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 47 * 6];
+} _EC_X9_62_CHAR2_368W1 = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 47, 0xFF70
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+ /* a */
+ 0x00, 0xE0, 0xD2, 0xEE, 0x25, 0x09, 0x52, 0x06, 0xF5, 0xE2, 0xA4, 0xF9,
+ 0xED, 0x22, 0x9F, 0x1F, 0x25, 0x6E, 0x79, 0xA0, 0xE2, 0xB4, 0x55, 0x97,
+ 0x0D, 0x8D, 0x0D, 0x86, 0x5B, 0xD9, 0x47, 0x78, 0xC5, 0x76, 0xD6, 0x2F,
+ 0x0A, 0xB7, 0x51, 0x9C, 0xCD, 0x2A, 0x1A, 0x90, 0x6A, 0xE3, 0x0D,
+ /* b */
+ 0x00, 0xFC, 0x12, 0x17, 0xD4, 0x32, 0x0A, 0x90, 0x45, 0x2C, 0x76, 0x0A,
+ 0x58, 0xED, 0xCD, 0x30, 0xC8, 0xDD, 0x06, 0x9B, 0x3C, 0x34, 0x45, 0x38,
+ 0x37, 0xA3, 0x4E, 0xD5, 0x0C, 0xB5, 0x49, 0x17, 0xE1, 0xC2, 0x11, 0x2D,
+ 0x84, 0xD1, 0x64, 0xF4, 0x44, 0xF8, 0xF7, 0x47, 0x86, 0x04, 0x6A,
+ /* x */
+ 0x00, 0x10, 0x85, 0xE2, 0x75, 0x53, 0x81, 0xDC, 0xCC, 0xE3, 0xC1, 0x55,
+ 0x7A, 0xFA, 0x10, 0xC2, 0xF0, 0xC0, 0xC2, 0x82, 0x56, 0x46, 0xC5, 0xB3,
+ 0x4A, 0x39, 0x4C, 0xBC, 0xFA, 0x8B, 0xC1, 0x6B, 0x22, 0xE7, 0xE7, 0x89,
+ 0xE9, 0x27, 0xBE, 0x21, 0x6F, 0x02, 0xE1, 0xFB, 0x13, 0x6A, 0x5F,
+ /* y */
+ 0x00, 0x7B, 0x3E, 0xB1, 0xBD, 0xDC, 0xBA, 0x62, 0xD5, 0xD8, 0xB2, 0x05,
+ 0x9B, 0x52, 0x57, 0x97, 0xFC, 0x73, 0x82, 0x2C, 0x59, 0x05, 0x9C, 0x62,
+ 0x3A, 0x45, 0xFF, 0x38, 0x43, 0xCE, 0xE8, 0xF8, 0x7C, 0xD1, 0x85, 0x5A,
+ 0xDA, 0xA8, 0x1E, 0x2A, 0x07, 0x50, 0xB8, 0x0F, 0xDA, 0x23, 0x10,
+ /* order */
+ 0x00, 0x00, 0x01, 0x00, 0x90, 0x51, 0x2D, 0xA9, 0xAF, 0x72, 0xB0, 0x83,
+ 0x49, 0xD9, 0x8A, 0x5D, 0xD4, 0xC7, 0xB0, 0x53, 0x2E, 0xCA, 0x51, 0xCE,
+ 0x03, 0xE2, 0xD1, 0x0F, 0x3B, 0x7A, 0xC5, 0x79, 0xBD, 0x87, 0xE9, 0x09,
+ 0xAE, 0x40, 0xA6, 0xF1, 0x31, 0xE9, 0xCF, 0xCE, 0x5B, 0xD9, 0x67
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 54 * 6];
+} _EC_X9_62_CHAR2_431R1 = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 54, 0x2760
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0x1A, 0x82, 0x7E, 0xF0, 0x0D, 0xD6, 0xFC, 0x0E, 0x23, 0x4C, 0xAF, 0x04,
+ 0x6C, 0x6A, 0x5D, 0x8A, 0x85, 0x39, 0x5B, 0x23, 0x6C, 0xC4, 0xAD, 0x2C,
+ 0xF3, 0x2A, 0x0C, 0xAD, 0xBD, 0xC9, 0xDD, 0xF6, 0x20, 0xB0, 0xEB, 0x99,
+ 0x06, 0xD0, 0x95, 0x7F, 0x6C, 0x6F, 0xEA, 0xCD, 0x61, 0x54, 0x68, 0xDF,
+ 0x10, 0x4D, 0xE2, 0x96, 0xCD, 0x8F,
+ /* b */
+ 0x10, 0xD9, 0xB4, 0xA3, 0xD9, 0x04, 0x7D, 0x8B, 0x15, 0x43, 0x59, 0xAB,
+ 0xFB, 0x1B, 0x7F, 0x54, 0x85, 0xB0, 0x4C, 0xEB, 0x86, 0x82, 0x37, 0xDD,
+ 0xC9, 0xDE, 0xDA, 0x98, 0x2A, 0x67, 0x9A, 0x5A, 0x91, 0x9B, 0x62, 0x6D,
+ 0x4E, 0x50, 0xA8, 0xDD, 0x73, 0x1B, 0x10, 0x7A, 0x99, 0x62, 0x38, 0x1F,
+ 0xB5, 0xD8, 0x07, 0xBF, 0x26, 0x18,
+ /* x */
+ 0x12, 0x0F, 0xC0, 0x5D, 0x3C, 0x67, 0xA9, 0x9D, 0xE1, 0x61, 0xD2, 0xF4,
+ 0x09, 0x26, 0x22, 0xFE, 0xCA, 0x70, 0x1B, 0xE4, 0xF5, 0x0F, 0x47, 0x58,
+ 0x71, 0x4E, 0x8A, 0x87, 0xBB, 0xF2, 0xA6, 0x58, 0xEF, 0x8C, 0x21, 0xE7,
+ 0xC5, 0xEF, 0xE9, 0x65, 0x36, 0x1F, 0x6C, 0x29, 0x99, 0xC0, 0xC2, 0x47,
+ 0xB0, 0xDB, 0xD7, 0x0C, 0xE6, 0xB7,
+ /* y */
+ 0x20, 0xD0, 0xAF, 0x89, 0x03, 0xA9, 0x6F, 0x8D, 0x5F, 0xA2, 0xC2, 0x55,
+ 0x74, 0x5D, 0x3C, 0x45, 0x1B, 0x30, 0x2C, 0x93, 0x46, 0xD9, 0xB7, 0xE4,
+ 0x85, 0xE7, 0xBC, 0xE4, 0x1F, 0x6B, 0x59, 0x1F, 0x3E, 0x8F, 0x6A, 0xDD,
+ 0xCB, 0xB0, 0xBC, 0x4C, 0x2F, 0x94, 0x7A, 0x7D, 0xE1, 0xA8, 0x9B, 0x62,
+ 0x5D, 0x6A, 0x59, 0x8B, 0x37, 0x60,
+ /* order */
+ 0x00, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40,
+ 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40,
+ 0x34, 0x03, 0x40, 0x34, 0x03, 0x23, 0xC3, 0x13, 0xFA, 0xB5, 0x05, 0x89,
+ 0x70, 0x3B, 0x5E, 0xC6, 0x8D, 0x35, 0x87, 0xFE, 0xC6, 0x0D, 0x16, 0x1C,
+ 0xC1, 0x49, 0xC1, 0xAD, 0x4A, 0x91
+ }
+};
+
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 15 * 6];
+} _EC_WTLS_1 = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 15, 2
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x01,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01,
+ /* x */
+ 0x01, 0x66, 0x79, 0x79, 0xA4, 0x0B, 0xA4, 0x97, 0xE5, 0xD5, 0xC2, 0x70,
+ 0x78, 0x06, 0x17,
+ /* y */
+ 0x00, 0xF4, 0x4B, 0x4A, 0xF1, 0xEC, 0xC2, 0x63, 0x0E, 0x08, 0x78, 0x5C,
+ 0xEB, 0xCC, 0x15,
+ /* order */
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBF, 0x91, 0xAF,
+ 0x6D, 0xEA, 0x73
+ }
+};
+
+/* IPSec curves */
+/*
+ * NOTE: The of curves over a extension field of non prime degree is not
+ * recommended (Weil-descent). As the group order is not a prime this curve
+ * is not suitable for ECDSA.
+ */
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 20 * 6];
+} _EC_IPSEC_155_ID3 = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 20, 3
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x33, 0x8f,
+ /* x */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
+ /* y */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc8,
+ /* order */
+ 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xC7, 0xF3,
+ 0xC7, 0x88, 0x1B, 0xD0, 0x86, 0x8F, 0xA8, 0x6C
+ }
+};
+
+/*
+ * NOTE: The of curves over a extension field of non prime degree is not
+ * recommended (Weil-descent). As the group order is not a prime this curve
+ * is not suitable for ECDSA.
+ */
+static const struct {
+ EC_CURVE_DATA h;
+ unsigned char data[0 + 24 * 6];
+} _EC_IPSEC_185_ID4 = {
+ {
+ NID_X9_62_characteristic_two_field, 0, 24, 2
+ },
+ {
+ /* no seed */
+ /* p */
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* a */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* b */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xe9,
+ /* x */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ /* y */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
+ /* order */
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xED, 0xF9, 0x7C, 0x44, 0xDB, 0x9F, 0x24, 0x20, 0xBA, 0xFC, 0xA7, 0x5E
+ }
+};
+
+#endif
+
+typedef struct _ec_list_element_st {
+ int nid;
+ const EC_CURVE_DATA *data;
+ const EC_METHOD *(*meth) (void);
+ const char *comment;
+} ec_list_element;
+
+static const ec_list_element curve_list[] = {
+ /* prime field curves */
+ /* secg curves */
+ {NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0,
+ "SECG/WTLS curve over a 112 bit prime field"},
+ {NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0,
+ "SECG curve over a 112 bit prime field"},
+ {NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0,
+ "SECG curve over a 128 bit prime field"},
+ {NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0,
+ "SECG curve over a 128 bit prime field"},
+ {NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0,
+ "SECG curve over a 160 bit prime field"},
+ {NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0,
+ "SECG curve over a 160 bit prime field"},
+ {NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0,
+ "SECG/WTLS curve over a 160 bit prime field"},
+ /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
+ {NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0,
+ "SECG curve over a 192 bit prime field"},
+ {NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0,
+ "SECG curve over a 224 bit prime field"},
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+ {NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method,
+ "NIST/SECG curve over a 224 bit prime field"},
+#else
+ {NID_secp224r1, &_EC_NIST_PRIME_224.h, 0,
+ "NIST/SECG curve over a 224 bit prime field"},
+#endif
+ {NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0,
+ "SECG curve over a 256 bit prime field"},
+ /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
+ {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0,
+ "NIST/SECG curve over a 384 bit prime field"},
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+ {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method,
+ "NIST/SECG curve over a 521 bit prime field"},
+#else
+ {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0,
+ "NIST/SECG curve over a 521 bit prime field"},
+#endif
+ /* X9.62 curves */
+ {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0,
+ "NIST/X9.62/SECG curve over a 192 bit prime field"},
+ {NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0,
+ "X9.62 curve over a 192 bit prime field"},
+ {NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0,
+ "X9.62 curve over a 192 bit prime field"},
+ {NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0,
+ "X9.62 curve over a 239 bit prime field"},
+ {NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0,
+ "X9.62 curve over a 239 bit prime field"},
+ {NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0,
+ "X9.62 curve over a 239 bit prime field"},
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+ {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, EC_GFp_nistp256_method,
+ "X9.62/SECG curve over a 256 bit prime field"},
+#else
+ {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, 0,
+ "X9.62/SECG curve over a 256 bit prime field"},
+#endif
+#ifndef OPENSSL_NO_EC2M
+ /* characteristic two field curves */
+ /* NIST/SECG curves */
+ {NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0,
+ "SECG curve over a 113 bit binary field"},
+ {NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0,
+ "SECG curve over a 113 bit binary field"},
+ {NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0,
+ "SECG/WTLS curve over a 131 bit binary field"},
+ {NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0,
+ "SECG curve over a 131 bit binary field"},
+ {NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0,
+ "NIST/SECG/WTLS curve over a 163 bit binary field"},
+ {NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0,
+ "SECG curve over a 163 bit binary field"},
+ {NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0,
+ "NIST/SECG curve over a 163 bit binary field"},
+ {NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0,
+ "SECG curve over a 193 bit binary field"},
+ {NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0,
+ "SECG curve over a 193 bit binary field"},
+ {NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0,
+ "NIST/SECG/WTLS curve over a 233 bit binary field"},
+ {NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0,
+ "NIST/SECG/WTLS curve over a 233 bit binary field"},
+ {NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0,
+ "SECG curve over a 239 bit binary field"},
+ {NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0,
+ "NIST/SECG curve over a 283 bit binary field"},
+ {NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0,
+ "NIST/SECG curve over a 283 bit binary field"},
+ {NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0,
+ "NIST/SECG curve over a 409 bit binary field"},
+ {NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0,
+ "NIST/SECG curve over a 409 bit binary field"},
+ {NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0,
+ "NIST/SECG curve over a 571 bit binary field"},
+ {NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0,
+ "NIST/SECG curve over a 571 bit binary field"},
+ /* X9.62 curves */
+ {NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0,
+ "X9.62 curve over a 163 bit binary field"},
+ {NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0,
+ "X9.62 curve over a 163 bit binary field"},
+ {NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0,
+ "X9.62 curve over a 163 bit binary field"},
+ {NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0,
+ "X9.62 curve over a 176 bit binary field"},
+ {NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0,
+ "X9.62 curve over a 191 bit binary field"},
+ {NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0,
+ "X9.62 curve over a 191 bit binary field"},
+ {NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0,
+ "X9.62 curve over a 191 bit binary field"},
+ {NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0,
+ "X9.62 curve over a 208 bit binary field"},
+ {NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0,
+ "X9.62 curve over a 239 bit binary field"},
+ {NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0,
+ "X9.62 curve over a 239 bit binary field"},
+ {NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0,
+ "X9.62 curve over a 239 bit binary field"},
+ {NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0,
+ "X9.62 curve over a 272 bit binary field"},
+ {NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0,
+ "X9.62 curve over a 304 bit binary field"},
+ {NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0,
+ "X9.62 curve over a 359 bit binary field"},
+ {NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0,
+ "X9.62 curve over a 368 bit binary field"},
+ {NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0,
+ "X9.62 curve over a 431 bit binary field"},
+ /*
+ * the WAP/WTLS curves [unlike SECG, spec has its own OIDs for curves
+ * from X9.62]
+ */
+ {NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0,
+ "WTLS curve over a 113 bit binary field"},
+ {NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0,
+ "NIST/SECG/WTLS curve over a 163 bit binary field"},
+ {NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0,
+ "SECG curve over a 113 bit binary field"},
+ {NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0,
+ "X9.62 curve over a 163 bit binary field"},
+#endif
+ {NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0,
+ "SECG/WTLS curve over a 112 bit prime field"},
+ {NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0,
+ "SECG/WTLS curve over a 160 bit prime field"},
+ {NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0,
+ "WTLS curve over a 112 bit prime field"},
+ {NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0,
+ "WTLS curve over a 160 bit prime field"},
+#ifndef OPENSSL_NO_EC2M
+ {NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0,
+ "NIST/SECG/WTLS curve over a 233 bit binary field"},
+ {NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0,
+ "NIST/SECG/WTLS curve over a 233 bit binary field"},
+#endif
+ {NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0,
+ "WTLS curvs over a 224 bit prime field"},
+#ifndef OPENSSL_NO_EC2M
+ /* IPSec curves */
+ {NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0,
+ "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
+ "\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
+ {NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0,
+ "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
+ "\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
+#endif
+};
+
+#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))
+
+static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
+{
+ EC_GROUP *group = NULL;
+ EC_POINT *P = NULL;
+ BN_CTX *ctx = NULL;
+ BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order =
+ NULL;
+ int ok = 0;
+ int seed_len, param_len;
+ const EC_METHOD *meth;
+ const EC_CURVE_DATA *data;
+ const unsigned char *params;
+
+ if ((ctx = BN_CTX_new()) == NULL) {
+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ data = curve.data;
+ seed_len = data->seed_len;
+ param_len = data->param_len;
+ params = (const unsigned char *)(data + 1); /* skip header */
+ params += seed_len; /* skip seed */
+
+ if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL))
+ || !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL))
+ || !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ if (curve.meth != 0) {
+ meth = curve.meth();
+ if (((group = EC_GROUP_new(meth)) == NULL) ||
+ (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ goto err;
+ }
+ } else if (data->field_type == NID_X9_62_prime_field) {
+ if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+#ifndef OPENSSL_NO_EC2M
+ else { /* field_type ==
+ * NID_X9_62_characteristic_two_field */
+
+ if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) {
+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+#endif
+
+ if ((P = EC_POINT_new(group)) == NULL) {
+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL))
+ || !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+ goto err;
+ }
+ if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ goto err;
+ }
+ if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL))
+ || !BN_set_word(x, (BN_ULONG)data->cofactor)) {
+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+ goto err;
+ }
+ if (!EC_GROUP_set_generator(group, P, order, x)) {
+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ goto err;
+ }
+ if (seed_len) {
+ if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) {
+ ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+ ok = 1;
+ err:
+ if (!ok) {
+ EC_GROUP_free(group);
+ group = NULL;
+ }
+ if (P)
+ EC_POINT_free(P);
+ if (ctx)
+ BN_CTX_free(ctx);
+ if (p)
+ BN_free(p);
+ if (a)
+ BN_free(a);
+ if (b)
+ BN_free(b);
+ if (order)
+ BN_free(order);
+ if (x)
+ BN_free(x);
+ if (y)
+ BN_free(y);
+ return group;
+}
+
+EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
+{
+ size_t i;
+ EC_GROUP *ret = NULL;
+
+ if (nid <= 0)
+ return NULL;
+
+ for (i = 0; i < curve_list_length; i++)
+ if (curve_list[i].nid == nid) {
+ ret = ec_group_new_from_data(curve_list[i]);
+ break;
+ }
+
+ if (ret == NULL) {
+ ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
+ return NULL;
+ }
+
+ EC_GROUP_set_curve_name(ret, nid);
+
+ return ret;
+}
+
+size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)
+{
+ size_t i, min;
+
+ if (r == NULL || nitems == 0)
+ return curve_list_length;
+
+ min = nitems < curve_list_length ? nitems : curve_list_length;
+
+ for (i = 0; i < min; i++) {
+ r[i].nid = curve_list[i].nid;
+ r[i].comment = curve_list[i].comment;
+ }
+
+ return curve_list_length;
+}
diff --git a/openssl/ec/ec_cvt.c b/openssl/ec/ec_cvt.c
new file mode 100644
index 0000000..1a8f70a
--- /dev/null
+++ b/openssl/ec/ec_cvt.c
@@ -0,0 +1,188 @@
+/* crypto/ec/ec_cvt.c */
+/*
+ * Originally written by Bodo Moeller 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.
+ *
+ */
+
+#include <openssl/err.h>
+#include "ec_lcl.h"
+
+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx)
+{
+ const EC_METHOD *meth;
+ EC_GROUP *ret;
+
+#ifdef FORCE_SIMPLE_EC_METHOD
+
+ meth = EC_GFp_simple_method();
+
+ ret = EC_GROUP_new(meth);
+ if (ret == NULL)
+ return NULL;
+
+ if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
+ {
+ EC_GROUP_free(ret);
+ return NULL;
+ }
+
+ return ret;
+
+#else /* FORCE_SIMPLE_EC_METHOD */
+
+#if defined(OPENSSL_BN_ASM_MONT)
+ /*
+ * This might appear controversial, but the fact is that generic
+ * prime method was observed to deliver better performance even
+ * for NIST primes on a range of platforms, e.g.: 60%-15%
+ * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25%
+ * in 32-bit build and 35%--12% in 64-bit build on Core2...
+ * Coefficients are relative to optimized bn_nist.c for most
+ * intensive ECDSA verify and ECDH operations for 192- and 521-
+ * bit keys respectively. Choice of these boundary values is
+ * arguable, because the dependency of improvement coefficient
+ * from key length is not a "monotone" curve. For example while
+ * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's
+ * generally faster, sometimes "respectfully" faster, sometimes
+ * "tolerably" slower... What effectively happens is that loop
+ * with bn_mul_add_words is put against bn_mul_mont, and the
+ * latter "wins" on short vectors. Correct solution should be
+ * implementing dedicated NxN multiplication subroutines for
+ * small N. But till it materializes, let's stick to generic
+ * prime method...
+ * <appro>
+ */
+ meth = EC_GFp_mont_method();
+#else
+ meth = EC_GFp_nist_method();
+#endif
+
+ ret = EC_GROUP_new(meth);
+ if (ret == NULL)
+ return NULL;
+
+ if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) {
+ unsigned long err;
+
+ err = ERR_peek_last_error();
+
+ if (!(ERR_GET_LIB(err) == ERR_LIB_EC &&
+ ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) ||
+ (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME)))) {
+ /* real error */
+
+ EC_GROUP_clear_free(ret);
+ return NULL;
+ }
+
+ /*
+ * not an actual error, we just cannot use EC_GFp_nist_method
+ */
+
+ ERR_clear_error();
+
+ EC_GROUP_clear_free(ret);
+ meth = EC_GFp_mont_method();
+
+ ret = EC_GROUP_new(meth);
+ if (ret == NULL)
+ return NULL;
+
+ if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) {
+ EC_GROUP_clear_free(ret);
+ return NULL;
+ }
+ }
+
+#endif /* FORCE_SIMPLE_EC_METHOD */
+
+ return ret;
+}
+
+#ifndef OPENSSL_NO_EC2M
+EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx)
+{
+ const EC_METHOD *meth;
+ EC_GROUP *ret;
+
+ meth = EC_GF2m_simple_method();
+
+ ret = EC_GROUP_new(meth);
+ if (ret == NULL)
+ return NULL;
+
+ if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) {
+ EC_GROUP_clear_free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+#endif
diff --git a/openssl/ec/ec_err.c b/openssl/ec/ec_err.c
new file mode 100644
index 0000000..58eae7c
--- /dev/null
+++ b/openssl/ec/ec_err.c
@@ -0,0 +1,319 @@
+/* crypto/ec/ec_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2011 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).
+ *
+ */
+
+/*
+ * NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ec.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason)
+
+static ERR_STRING_DATA EC_str_functs[] = {
+ {ERR_FUNC(EC_F_BN_TO_FELEM), "BN_TO_FELEM"},
+ {ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"},
+ {ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
+ {ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
+ {ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"},
+ {ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "DO_EC_KEY_PRINT"},
+ {ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "ECKEY_PARAM2TYPE"},
+ {ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "ECKEY_PARAM_DECODE"},
+ {ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "ECKEY_PRIV_DECODE"},
+ {ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "ECKEY_PRIV_ENCODE"},
+ {ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "ECKEY_PUB_DECODE"},
+ {ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "ECKEY_PUB_ENCODE"},
+ {ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "ECKEY_TYPE2PARAM"},
+ {ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"},
+ {ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
+ {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"},
+ {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"},
+ {ERR_FUNC(EC_F_ECP_NIST_MOD_192), "ECP_NIST_MOD_192"},
+ {ERR_FUNC(EC_F_ECP_NIST_MOD_224), "ECP_NIST_MOD_224"},
+ {ERR_FUNC(EC_F_ECP_NIST_MOD_256), "ECP_NIST_MOD_256"},
+ {ERR_FUNC(EC_F_ECP_NIST_MOD_521), "ECP_NIST_MOD_521"},
+ {ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "EC_ASN1_GROUP2CURVE"},
+ {ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "EC_ASN1_GROUP2FIELDID"},
+ {ERR_FUNC(EC_F_EC_ASN1_GROUP2PARAMETERS), "EC_ASN1_GROUP2PARAMETERS"},
+ {ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS), "EC_ASN1_GROUP2PKPARAMETERS"},
+ {ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP), "EC_ASN1_PARAMETERS2GROUP"},
+ {ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP), "EC_ASN1_PKPARAMETERS2GROUP"},
+ {ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA), "EC_EX_DATA_set_data"},
+ {ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY),
+ "EC_GF2M_MONTGOMERY_POINT_MULTIPLY"},
+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT),
+ "ec_GF2m_simple_group_check_discriminant"},
+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE),
+ "ec_GF2m_simple_group_set_curve"},
+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"},
+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"},
+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES),
+ "ec_GF2m_simple_point_get_affine_coordinates"},
+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES),
+ "ec_GF2m_simple_point_set_affine_coordinates"},
+ {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES),
+ "ec_GF2m_simple_set_compressed_coordinates"},
+ {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"},
+ {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"},
+ {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"},
+ {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE),
+ "ec_GFp_mont_field_set_to_one"},
+ {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"},
+ {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE),
+ "ec_GFp_mont_group_set_curve"},
+ {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP),
+ "EC_GFP_MONT_GROUP_SET_CURVE_GFP"},
+ {ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE),
+ "ec_GFp_nistp224_group_set_curve"},
+ {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL), "ec_GFp_nistp224_points_mul"},
+ {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES),
+ "ec_GFp_nistp224_point_get_affine_coordinates"},
+ {ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE),
+ "ec_GFp_nistp256_group_set_curve"},
+ {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL), "ec_GFp_nistp256_points_mul"},
+ {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES),
+ "ec_GFp_nistp256_point_get_affine_coordinates"},
+ {ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE),
+ "ec_GFp_nistp521_group_set_curve"},
+ {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL), "ec_GFp_nistp521_points_mul"},
+ {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES),
+ "ec_GFp_nistp521_point_get_affine_coordinates"},
+ {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"},
+ {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"},
+ {ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE),
+ "ec_GFp_nist_group_set_curve"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT),
+ "ec_GFp_simple_group_check_discriminant"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE),
+ "ec_GFp_simple_group_set_curve"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP),
+ "EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR),
+ "EC_GFP_SIMPLE_GROUP_SET_GENERATOR"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE),
+ "ec_GFp_simple_points_make_affine"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES),
+ "ec_GFp_simple_point_get_affine_coordinates"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP),
+ "EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES),
+ "ec_GFp_simple_point_set_affine_coordinates"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP),
+ "EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES),
+ "ec_GFp_simple_set_compressed_coordinates"},
+ {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP),
+ "EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP"},
+ {ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"},
+ {ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT),
+ "EC_GROUP_check_discriminant"},
+ {ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"},
+ {ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR), "EC_GROUP_get0_generator"},
+ {ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR), "EC_GROUP_get_cofactor"},
+ {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"},
+ {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"},
+ {ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"},
+ {ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"},
+ {ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS),
+ "EC_GROUP_get_pentanomial_basis"},
+ {ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS),
+ "EC_GROUP_get_trinomial_basis"},
+ {ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"},
+ {ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"},
+ {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "EC_GROUP_NEW_FROM_DATA"},
+ {ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT), "EC_GROUP_precompute_mult"},
+ {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"},
+ {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"},
+ {ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA), "EC_GROUP_SET_EXTRA_DATA"},
+ {ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"},
+ {ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"},
+ {ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"},
+ {ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"},
+ {ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
+ {ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
+ {ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
+ {ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES),
+ "EC_KEY_set_public_key_affine_coordinates"},
+ {ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
+ {ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"},
+ {ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"},
+ {ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"},
+ {ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"},
+ {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M),
+ "EC_POINT_get_affine_coordinates_GF2m"},
+ {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP),
+ "EC_POINT_get_affine_coordinates_GFp"},
+ {ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP),
+ "EC_POINT_get_Jprojective_coordinates_GFp"},
+ {ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"},
+ {ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"},
+ {ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"},
+ {ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"},
+ {ERR_FUNC(EC_F_EC_POINT_MUL), "EC_POINT_mul"},
+ {ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"},
+ {ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"},
+ {ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"},
+ {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M),
+ "EC_POINT_set_affine_coordinates_GF2m"},
+ {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP),
+ "EC_POINT_set_affine_coordinates_GFp"},
+ {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M),
+ "EC_POINT_set_compressed_coordinates_GF2m"},
+ {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP),
+ "EC_POINT_set_compressed_coordinates_GFp"},
+ {ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP),
+ "EC_POINT_set_Jprojective_coordinates_GFp"},
+ {ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"},
+ {ERR_FUNC(EC_F_EC_PRE_COMP_DUP), "EC_PRE_COMP_DUP"},
+ {ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "EC_PRE_COMP_NEW"},
+ {ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"},
+ {ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"},
+ {ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"},
+ {ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"},
+ {ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
+ {ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"},
+ {ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "NISTP224_PRE_COMP_NEW"},
+ {ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "NISTP256_PRE_COMP_NEW"},
+ {ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "NISTP521_PRE_COMP_NEW"},
+ {ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
+ {ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"},
+ {ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"},
+ {ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "PKEY_EC_CTRL_STR"},
+ {ERR_FUNC(EC_F_PKEY_EC_DERIVE), "PKEY_EC_DERIVE"},
+ {ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "PKEY_EC_KEYGEN"},
+ {ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "PKEY_EC_PARAMGEN"},
+ {ERR_FUNC(EC_F_PKEY_EC_SIGN), "PKEY_EC_SIGN"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA EC_str_reasons[] = {
+ {ERR_REASON(EC_R_ASN1_ERROR), "asn1 error"},
+ {ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD), "asn1 unknown field"},
+ {ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"},
+ {ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"},
+ {ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"},
+ {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),
+ "d2i ecpkparameters failure"},
+ {ERR_REASON(EC_R_DECODE_ERROR), "decode error"},
+ {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"},
+ {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),
+ "ec group new by name failure"},
+ {ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"},
+ {ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"},
+ {ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),
+ "group2pkparameters failure"},
+ {ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),
+ "i2d ecpkparameters failure"},
+ {ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"},
+ {ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"},
+ {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"},
+ {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"},
+ {ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"},
+ {ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"},
+ {ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"},
+ {ERR_REASON(EC_R_INVALID_FIELD), "invalid field"},
+ {ERR_REASON(EC_R_INVALID_FORM), "invalid form"},
+ {ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"},
+ {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"},
+ {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"},
+ {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"},
+ {ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"},
+ {ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"},
+ {ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"},
+ {ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"},
+ {ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME),
+ "not a supported NIST prime"},
+ {ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"},
+ {ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"},
+ {ERR_REASON(EC_R_NO_FIELD_MOD), "no field mod"},
+ {ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"},
+ {ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"},
+ {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),
+ "pkparameters2group failure"},
+ {ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"},
+ {ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"},
+ {ERR_REASON(EC_R_SLOT_FULL), "slot full"},
+ {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"},
+ {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"},
+ {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"},
+ {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"},
+ {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"},
+ {ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"},
+ {ERR_REASON(EC_R_WRONG_ORDER), "wrong order"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_EC_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(EC_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, EC_str_functs);
+ ERR_load_strings(0, EC_str_reasons);
+ }
+#endif
+}
diff --git a/openssl/ec/ec_key.c b/openssl/ec/ec_key.c
new file mode 100644
index 0000000..ebdffc8
--- /dev/null
+++ b/openssl/ec/ec_key.c
@@ -0,0 +1,559 @@
+/* crypto/ec/ec_key.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 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 originally developed by SUN MICROSYSTEMS, INC., and
+ * contributed to the OpenSSL project.
+ */
+
+#include <string.h>
+#include "ec_lcl.h"
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+EC_KEY *EC_KEY_new(void)
+{
+ EC_KEY *ret;
+
+ ret = (EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
+ if (ret == NULL) {
+ ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+
+ ret->version = 1;
+ ret->flags = 0;
+ ret->group = NULL;
+ ret->pub_key = NULL;
+ ret->priv_key = NULL;
+ ret->enc_flag = 0;
+ ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
+ ret->references = 1;
+ ret->method_data = NULL;
+ return (ret);
+}
+
+EC_KEY *EC_KEY_new_by_curve_name(int nid)
+{
+ EC_KEY *ret = EC_KEY_new();
+ if (ret == NULL)
+ return NULL;
+ ret->group = EC_GROUP_new_by_curve_name(nid);
+ if (ret->group == NULL) {
+ EC_KEY_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+void EC_KEY_free(EC_KEY *r)
+{
+ int i;
+
+ if (r == NULL)
+ return;
+
+ i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC);
+#ifdef REF_PRINT
+ REF_PRINT("EC_KEY", r);
+#endif
+ if (i > 0)
+ return;
+#ifdef REF_CHECK
+ if (i < 0) {
+ fprintf(stderr, "EC_KEY_free, bad reference count\n");
+ abort();
+ }
+#endif
+
+ if (r->group != NULL)
+ EC_GROUP_free(r->group);
+ if (r->pub_key != NULL)
+ EC_POINT_free(r->pub_key);
+ if (r->priv_key != NULL)
+ BN_clear_free(r->priv_key);
+
+ EC_EX_DATA_free_all_data(&r->method_data);
+
+ OPENSSL_cleanse((void *)r, sizeof(EC_KEY));
+
+ OPENSSL_free(r);
+}
+
+EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
+{
+ EC_EXTRA_DATA *d;
+
+ if (dest == NULL || src == NULL) {
+ ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ /* copy the parameters */
+ if (src->group) {
+ const EC_METHOD *meth = EC_GROUP_method_of(src->group);
+ /* clear the old group */
+ if (dest->group)
+ EC_GROUP_free(dest->group);
+ dest->group = EC_GROUP_new(meth);
+ if (dest->group == NULL)
+ return NULL;
+ if (!EC_GROUP_copy(dest->group, src->group))
+ return NULL;
+ }
+ /* copy the public key */
+ if (src->pub_key && src->group) {
+ if (dest->pub_key)
+ EC_POINT_free(dest->pub_key);
+ dest->pub_key = EC_POINT_new(src->group);
+ if (dest->pub_key == NULL)
+ return NULL;
+ if (!EC_POINT_copy(dest->pub_key, src->pub_key))
+ return NULL;
+ }
+ /* copy the private key */
+ if (src->priv_key) {
+ if (dest->priv_key == NULL) {
+ dest->priv_key = BN_new();
+ if (dest->priv_key == NULL)
+ return NULL;
+ }
+ if (!BN_copy(dest->priv_key, src->priv_key))
+ return NULL;
+ }
+ /* copy method/extra data */
+ EC_EX_DATA_free_all_data(&dest->method_data);
+
+ for (d = src->method_data; d != NULL; d = d->next) {
+ void *t = d->dup_func(d->data);
+
+ if (t == NULL)
+ return 0;
+ if (!EC_EX_DATA_set_data
+ (&dest->method_data, t, d->dup_func, d->free_func,
+ d->clear_free_func))
+ return 0;
+ }
+
+ /* copy the rest */
+ dest->enc_flag = src->enc_flag;
+ dest->conv_form = src->conv_form;
+ dest->version = src->version;
+ dest->flags = src->flags;
+
+ return dest;
+}
+
+EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
+{
+ EC_KEY *ret = EC_KEY_new();
+ if (ret == NULL)
+ return NULL;
+ if (EC_KEY_copy(ret, ec_key) == NULL) {
+ EC_KEY_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+int EC_KEY_up_ref(EC_KEY *r)
+{
+ int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC);
+#ifdef REF_PRINT
+ REF_PRINT("EC_KEY", r);
+#endif
+#ifdef REF_CHECK
+ if (i < 2) {
+ fprintf(stderr, "EC_KEY_up, bad reference count\n");
+ abort();
+ }
+#endif
+ return ((i > 1) ? 1 : 0);
+}
+
+int EC_KEY_generate_key(EC_KEY *eckey)
+{
+ int ok = 0;
+ BN_CTX *ctx = NULL;
+ BIGNUM *priv_key = NULL, *order = NULL;
+ EC_POINT *pub_key = NULL;
+
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_ec_key_generate_key(eckey);
+#endif
+
+ if (!eckey || !eckey->group) {
+ ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if ((order = BN_new()) == NULL)
+ goto err;
+ if ((ctx = BN_CTX_new()) == NULL)
+ goto err;
+
+ if (eckey->priv_key == NULL) {
+ priv_key = BN_new();
+ if (priv_key == NULL)
+ goto err;
+ } else
+ priv_key = eckey->priv_key;
+
+ if (!EC_GROUP_get_order(eckey->group, order, ctx))
+ goto err;
+
+ do
+ if (!BN_rand_range(priv_key, order))
+ goto err;
+ while (BN_is_zero(priv_key)) ;
+
+ if (eckey->pub_key == NULL) {
+ pub_key = EC_POINT_new(eckey->group);
+ if (pub_key == NULL)
+ goto err;
+ } else
+ pub_key = eckey->pub_key;
+
+ if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
+ goto err;
+
+ eckey->priv_key = priv_key;
+ eckey->pub_key = pub_key;
+
+ ok = 1;
+
+ err:
+ if (order)
+ BN_free(order);
+ if (pub_key != NULL && eckey->pub_key == NULL)
+ EC_POINT_free(pub_key);
+ if (priv_key != NULL && eckey->priv_key == NULL)
+ BN_free(priv_key);
+ if (ctx != NULL)
+ BN_CTX_free(ctx);
+ return (ok);
+}
+
+int EC_KEY_check_key(const EC_KEY *eckey)
+{
+ int ok = 0;
+ BN_CTX *ctx = NULL;
+ const BIGNUM *order = NULL;
+ EC_POINT *point = NULL;
+
+ if (!eckey || !eckey->group || !eckey->pub_key) {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY);
+ goto err;
+ }
+
+ if ((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ if ((point = EC_POINT_new(eckey->group)) == NULL)
+ goto err;
+
+ /* testing whether the pub_key is on the elliptic curve */
+ if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
+ goto err;
+ }
+ /* testing whether pub_key * order is the point at infinity */
+ order = &eckey->group->order;
+ if (BN_is_zero(order)) {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
+ goto err;
+ }
+ if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
+ goto err;
+ }
+ if (!EC_POINT_is_at_infinity(eckey->group, point)) {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
+ goto err;
+ }
+ /*
+ * in case the priv_key is present : check if generator * priv_key ==
+ * pub_key
+ */
+ if (eckey->priv_key) {
+ if (BN_cmp(eckey->priv_key, order) >= 0) {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER);
+ goto err;
+ }
+ if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
+ NULL, NULL, ctx)) {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
+ goto err;
+ }
+ if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
+ ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
+ goto err;
+ }
+ }
+ ok = 1;
+ err:
+ if (ctx != NULL)
+ BN_CTX_free(ctx);
+ if (point != NULL)
+ EC_POINT_free(point);
+ return (ok);
+}
+
+int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
+ BIGNUM *y)
+{
+ BN_CTX *ctx = NULL;
+ BIGNUM *tx, *ty;
+ EC_POINT *point = NULL;
+ int ok = 0, tmp_nid, is_char_two = 0;
+
+ if (!key || !key->group || !x || !y) {
+ ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ ctx = BN_CTX_new();
+ if (!ctx)
+ goto err;
+
+ point = EC_POINT_new(key->group);
+
+ if (!point)
+ goto err;
+
+ tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group));
+
+ if (tmp_nid == NID_X9_62_characteristic_two_field)
+ is_char_two = 1;
+
+ tx = BN_CTX_get(ctx);
+ ty = BN_CTX_get(ctx);
+#ifndef OPENSSL_NO_EC2M
+ if (is_char_two) {
+ if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
+ x, y, ctx))
+ goto err;
+ if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point,
+ tx, ty, ctx))
+ goto err;
+ } else
+#endif
+ {
+ if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
+ x, y, ctx))
+ goto err;
+ if (!EC_POINT_get_affine_coordinates_GFp(key->group, point,
+ tx, ty, ctx))
+ goto err;
+ }
+ /*
+ * Check if retrieved coordinates match originals: if not values are out
+ * of range.
+ */
+ if (BN_cmp(x, tx) || BN_cmp(y, ty)) {
+ ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
+ EC_R_COORDINATES_OUT_OF_RANGE);
+ goto err;
+ }
+
+ if (!EC_KEY_set_public_key(key, point))
+ goto err;
+
+ if (EC_KEY_check_key(key) == 0)
+ goto err;
+
+ ok = 1;
+
+ err:
+ if (ctx)
+ BN_CTX_free(ctx);
+ if (point)
+ EC_POINT_free(point);
+ return ok;
+
+}
+
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
+{
+ return key->group;
+}
+
+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
+{
+ if (key->group != NULL)
+ EC_GROUP_free(key->group);
+ key->group = EC_GROUP_dup(group);
+ return (key->group == NULL) ? 0 : 1;
+}
+
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
+{
+ return key->priv_key;
+}
+
+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
+{
+ if (key->priv_key)
+ BN_clear_free(key->priv_key);
+ key->priv_key = BN_dup(priv_key);
+ return (key->priv_key == NULL) ? 0 : 1;
+}
+
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
+{
+ return key->pub_key;
+}
+
+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
+{
+ if (key->pub_key != NULL)
+ EC_POINT_free(key->pub_key);
+ key->pub_key = EC_POINT_dup(pub_key, key->group);
+ return (key->pub_key == NULL) ? 0 : 1;
+}
+
+unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
+{
+ return key->enc_flag;
+}
+
+void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
+{
+ key->enc_flag = flags;
+}
+
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
+{
+ return key->conv_form;
+}
+
+void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
+{
+ key->conv_form = cform;
+ if (key->group != NULL)
+ EC_GROUP_set_point_conversion_form(key->group, cform);
+}
+
+void *EC_KEY_get_key_method_data(EC_KEY *key,
+ void *(*dup_func) (void *),
+ void (*free_func) (void *),
+ void (*clear_free_func) (void *))
+{
+ void *ret;
+
+ CRYPTO_r_lock(CRYPTO_LOCK_EC);
+ ret =
+ EC_EX_DATA_get_data(key->method_data, dup_func, free_func,
+ clear_free_func);
+ CRYPTO_r_unlock(CRYPTO_LOCK_EC);
+
+ return ret;
+}
+
+void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
+ void *(*dup_func) (void *),
+ void (*free_func) (void *),
+ void (*clear_free_func) (void *))
+{
+ EC_EXTRA_DATA *ex_data;
+
+ CRYPTO_w_lock(CRYPTO_LOCK_EC);
+ ex_data =
+ EC_EX_DATA_get_data(key->method_data, dup_func, free_func,
+ clear_free_func);
+ if (ex_data == NULL)
+ EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func,
+ clear_free_func);
+ CRYPTO_w_unlock(CRYPTO_LOCK_EC);
+
+ return ex_data;
+}
+
+void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
+{
+ if (key->group != NULL)
+ EC_GROUP_set_asn1_flag(key->group, flag);
+}
+
+int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
+{
+ if (key->group == NULL)
+ return 0;
+ return EC_GROUP_precompute_mult(key->group, ctx);
+}
+
+int EC_KEY_get_flags(const EC_KEY *key)
+{
+ return key->flags;
+}
+
+void EC_KEY_set_flags(EC_KEY *key, int flags)
+{
+ key->flags |= flags;
+}
+
+void EC_KEY_clear_flags(EC_KEY *key, int flags)
+{
+ key->flags &= ~flags;
+}
diff --git a/openssl/ec/ec_lcl.h b/openssl/ec/ec_lcl.h
new file mode 100644
index 0000000..319e651
--- /dev/null
+++ b/openssl/ec/ec_lcl.h
@@ -0,0 +1,551 @@
+/* crypto/ec/ec_lcl.h */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2010 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.
+ *
+ */
+
+#include <stdlib.h>
+
+#include <openssl/obj_mac.h>
+#include <openssl/ec.h>
+#include <openssl/bn.h>
+
+#if defined(__SUNPRO_C)
+# if __SUNPRO_C >= 0x520
+# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+# endif
+#endif
+
+/* Use default functions for poin2oct, oct2point and compressed coordinates */
+#define EC_FLAGS_DEFAULT_OCT 0x1
+
+/*
+ * Structure details are not part of the exported interface, so all this may
+ * change in future versions.
+ */
+
+struct ec_method_st {
+ /* Various method flags */
+ int flags;
+ /* used by EC_METHOD_get_field_type: */
+ int field_type; /* a NID */
+ /*
+ * used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free,
+ * EC_GROUP_copy:
+ */
+ int (*group_init) (EC_GROUP *);
+ void (*group_finish) (EC_GROUP *);
+ void (*group_clear_finish) (EC_GROUP *);
+ int (*group_copy) (EC_GROUP *, const EC_GROUP *);
+ /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
+ /* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
+ int (*group_set_curve) (EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+ int (*group_get_curve) (const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b,
+ BN_CTX *);
+ /* used by EC_GROUP_get_degree: */
+ int (*group_get_degree) (const EC_GROUP *);
+ /* used by EC_GROUP_check: */
+ int (*group_check_discriminant) (const EC_GROUP *, BN_CTX *);
+ /*
+ * used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free,
+ * EC_POINT_copy:
+ */
+ int (*point_init) (EC_POINT *);
+ void (*point_finish) (EC_POINT *);
+ void (*point_clear_finish) (EC_POINT *);
+ int (*point_copy) (EC_POINT *, const EC_POINT *);
+ /*-
+ * used by EC_POINT_set_to_infinity,
+ * EC_POINT_set_Jprojective_coordinates_GFp,
+ * EC_POINT_get_Jprojective_coordinates_GFp,
+ * EC_POINT_set_affine_coordinates_GFp, ..._GF2m,
+ * EC_POINT_get_affine_coordinates_GFp, ..._GF2m,
+ * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
+ */
+ int (*point_set_to_infinity) (const EC_GROUP *, EC_POINT *);
+ int (*point_set_Jprojective_coordinates_GFp) (const EC_GROUP *,
+ EC_POINT *, const BIGNUM *x,
+ const BIGNUM *y,
+ const BIGNUM *z, BN_CTX *);
+ int (*point_get_Jprojective_coordinates_GFp) (const EC_GROUP *,
+ const EC_POINT *, BIGNUM *x,
+ BIGNUM *y, BIGNUM *z,
+ BN_CTX *);
+ int (*point_set_affine_coordinates) (const EC_GROUP *, EC_POINT *,
+ const BIGNUM *x, const BIGNUM *y,
+ BN_CTX *);
+ int (*point_get_affine_coordinates) (const EC_GROUP *, const EC_POINT *,
+ BIGNUM *x, BIGNUM *y, BN_CTX *);
+ int (*point_set_compressed_coordinates) (const EC_GROUP *, EC_POINT *,
+ const BIGNUM *x, int y_bit,
+ BN_CTX *);
+ /* used by EC_POINT_point2oct, EC_POINT_oct2point: */
+ size_t (*point2oct) (const EC_GROUP *, const EC_POINT *,
+ point_conversion_form_t form, unsigned char *buf,
+ size_t len, BN_CTX *);
+ int (*oct2point) (const EC_GROUP *, EC_POINT *, const unsigned char *buf,
+ size_t len, BN_CTX *);
+ /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
+ int (*add) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *);
+ int (*dbl) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
+ int (*invert) (const EC_GROUP *, EC_POINT *, BN_CTX *);
+ /*
+ * used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp:
+ */
+ int (*is_at_infinity) (const EC_GROUP *, const EC_POINT *);
+ int (*is_on_curve) (const EC_GROUP *, const EC_POINT *, BN_CTX *);
+ int (*point_cmp) (const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
+ BN_CTX *);
+ /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
+ int (*make_affine) (const EC_GROUP *, EC_POINT *, BN_CTX *);
+ int (*points_make_affine) (const EC_GROUP *, size_t num, EC_POINT *[],
+ BN_CTX *);
+ /*
+ * used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult,
+ * EC_POINT_have_precompute_mult (default implementations are used if the
+ * 'mul' pointer is 0):
+ */
+ int (*mul) (const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+ size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
+ BN_CTX *);
+ int (*precompute_mult) (EC_GROUP *group, BN_CTX *);
+ int (*have_precompute_mult) (const EC_GROUP *group);
+ /* internal functions */
+ /*
+ * 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and
+ * 'dbl' so that the same implementations of point operations can be used
+ * with different optimized implementations of expensive field
+ * operations:
+ */
+ int (*field_mul) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+ int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+ int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+ /* e.g. to Montgomery */
+ int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+ /* e.g. from Montgomery */
+ int (*field_decode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+ int (*field_set_to_one) (const EC_GROUP *, BIGNUM *r, BN_CTX *);
+} /* EC_METHOD */ ;
+
+typedef struct ec_extra_data_st {
+ struct ec_extra_data_st *next;
+ void *data;
+ void *(*dup_func) (void *);
+ void (*free_func) (void *);
+ void (*clear_free_func) (void *);
+} EC_EXTRA_DATA; /* used in EC_GROUP */
+
+struct ec_group_st {
+ const EC_METHOD *meth;
+ EC_POINT *generator; /* optional */
+ BIGNUM order, cofactor;
+ int curve_name; /* optional NID for named curve */
+ int asn1_flag; /* flag to control the asn1 encoding */
+ point_conversion_form_t asn1_form;
+ unsigned char *seed; /* optional seed for parameters (appears in
+ * ASN1) */
+ size_t seed_len;
+ EC_EXTRA_DATA *extra_data; /* linked list */
+ /*
+ * The following members are handled by the method functions, even if
+ * they appear generic
+ */
+ /*
+ * Field specification. For curves over GF(p), this is the modulus; for
+ * curves over GF(2^m), this is the irreducible polynomial defining the
+ * field.
+ */
+ BIGNUM field;
+ /*
+ * Field specification for curves over GF(2^m). The irreducible f(t) is
+ * then of the form: t^poly[0] + t^poly[1] + ... + t^poly[k] where m =
+ * poly[0] > poly[1] > ... > poly[k] = 0. The array is terminated with
+ * poly[k+1]=-1. All elliptic curve irreducibles have at most 5 non-zero
+ * terms.
+ */
+ int poly[6];
+ /*
+ * Curve coefficients. (Here the assumption is that BIGNUMs can be used
+ * or abused for all kinds of fields, not just GF(p).) For characteristic
+ * > 3, the curve is defined by a Weierstrass equation of the form y^2 =
+ * x^3 + a*x + b. For characteristic 2, the curve is defined by an
+ * equation of the form y^2 + x*y = x^3 + a*x^2 + b.
+ */
+ BIGNUM a, b;
+ /* enable optimized point arithmetics for special case */
+ int a_is_minus3;
+ /* method-specific (e.g., Montgomery structure) */
+ void *field_data1;
+ /* method-specific */
+ void *field_data2;
+ /* method-specific */
+ int (*field_mod_func) (BIGNUM *, const BIGNUM *, const BIGNUM *,
+ BN_CTX *);
+} /* EC_GROUP */ ;
+
+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;
+ int flags;
+ EC_EXTRA_DATA *method_data;
+} /* EC_KEY */ ;
+
+/*
+ * Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs
+ * only (with visibility limited to 'package' level for now). We use the
+ * function pointers as index for retrieval; this obviates global
+ * ex_data-style index tables.
+ */
+int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data,
+ void *(*dup_func) (void *),
+ void (*free_func) (void *),
+ void (*clear_free_func) (void *));
+void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *, void *(*dup_func) (void *),
+ void (*free_func) (void *),
+ void (*clear_free_func) (void *));
+void EC_EX_DATA_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *),
+ void (*free_func) (void *),
+ void (*clear_free_func) (void *));
+void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *),
+ void (*free_func) (void *),
+ void (*clear_free_func) (void *));
+void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **);
+void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **);
+
+struct ec_point_st {
+ const EC_METHOD *meth;
+ /*
+ * All members except 'meth' are handled by the method functions, even if
+ * they appear generic
+ */
+ BIGNUM X;
+ BIGNUM Y;
+ BIGNUM Z; /* Jacobian projective coordinates: (X, Y, Z)
+ * represents (X/Z^2, Y/Z^3) if Z != 0 */
+ int Z_is_one; /* enable optimized point arithmetics for
+ * special case */
+} /* EC_POINT */ ;
+
+/*
+ * method functions in ec_mult.c (ec_lib.c uses these as defaults if
+ * group->method->mul is 0)
+ */
+int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+ size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
+ BN_CTX *);
+int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
+int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
+
+/* method functions in ecp_smpl.c */
+int ec_GFp_simple_group_init(EC_GROUP *);
+void ec_GFp_simple_group_finish(EC_GROUP *);
+void ec_GFp_simple_group_clear_finish(EC_GROUP *);
+int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
+int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
+ BIGNUM *b, BN_CTX *);
+int ec_GFp_simple_group_get_degree(const EC_GROUP *);
+int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
+int ec_GFp_simple_point_init(EC_POINT *);
+void ec_GFp_simple_point_finish(EC_POINT *);
+void ec_GFp_simple_point_clear_finish(EC_POINT *);
+int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
+int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
+int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *,
+ EC_POINT *, const BIGNUM *x,
+ const BIGNUM *y,
+ const BIGNUM *z, BN_CTX *);
+int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *,
+ const EC_POINT *, BIGNUM *x,
+ BIGNUM *y, BIGNUM *z,
+ BN_CTX *);
+int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
+ const BIGNUM *x,
+ const BIGNUM *y, BN_CTX *);
+int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *,
+ const EC_POINT *, BIGNUM *x,
+ BIGNUM *y, BN_CTX *);
+int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
+ const BIGNUM *x, int y_bit,
+ BN_CTX *);
+size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *,
+ point_conversion_form_t form,
+ unsigned char *buf, size_t len, BN_CTX *);
+int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
+ const unsigned char *buf, size_t len, BN_CTX *);
+int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *);
+int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+ BN_CTX *);
+int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
+int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
+ BN_CTX *);
+int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num,
+ EC_POINT *[], BN_CTX *);
+int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+
+/* method functions in ecp_mont.c */
+int ec_GFp_mont_group_init(EC_GROUP *);
+int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+void ec_GFp_mont_group_finish(EC_GROUP *);
+void ec_GFp_mont_group_clear_finish(EC_GROUP *);
+int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
+int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
+
+/* method functions in ecp_nist.c */
+int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
+int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+
+/* method functions in ec2_smpl.c */
+int ec_GF2m_simple_group_init(EC_GROUP *);
+void ec_GF2m_simple_group_finish(EC_GROUP *);
+void ec_GF2m_simple_group_clear_finish(EC_GROUP *);
+int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
+int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *);
+int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
+ BIGNUM *b, BN_CTX *);
+int ec_GF2m_simple_group_get_degree(const EC_GROUP *);
+int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
+int ec_GF2m_simple_point_init(EC_POINT *);
+void ec_GF2m_simple_point_finish(EC_POINT *);
+void ec_GF2m_simple_point_clear_finish(EC_POINT *);
+int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
+int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
+int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
+ const BIGNUM *x,
+ const BIGNUM *y, BN_CTX *);
+int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *,
+ const EC_POINT *, BIGNUM *x,
+ BIGNUM *y, BN_CTX *);
+int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
+ const BIGNUM *x, int y_bit,
+ BN_CTX *);
+size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *,
+ point_conversion_form_t form,
+ unsigned char *buf, size_t len, BN_CTX *);
+int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
+ const unsigned char *buf, size_t len, BN_CTX *);
+int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *);
+int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+ BN_CTX *);
+int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
+int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
+ BN_CTX *);
+int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num,
+ EC_POINT *[], BN_CTX *);
+int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *);
+int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *);
+
+/* method functions in ec2_mult.c */
+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 *);
+int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
+
+/* method functions in ec2_mult.c */
+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 *);
+int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
+
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+/* method functions in ecp_nistp224.c */
+int ec_GFp_nistp224_group_init(EC_GROUP *group);
+int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *);
+int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx);
+int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[], const BIGNUM *scalars[],
+ BN_CTX *);
+int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx);
+int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group);
+
+/* method functions in ecp_nistp256.c */
+int ec_GFp_nistp256_group_init(EC_GROUP *group);
+int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *);
+int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx);
+int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[], const BIGNUM *scalars[],
+ BN_CTX *);
+int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx);
+int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
+
+/* method functions in ecp_nistp521.c */
+int ec_GFp_nistp521_group_init(EC_GROUP *group);
+int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *);
+int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx);
+int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[], const BIGNUM *scalars[],
+ BN_CTX *);
+int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx);
+int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
+
+/* utility functions in ecp_nistputil.c */
+void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
+ size_t felem_size,
+ void *tmp_felems,
+ void (*felem_one) (void *out),
+ int (*felem_is_zero) (const void
+ *in),
+ void (*felem_assign) (void *out,
+ const void
+ *in),
+ void (*felem_square) (void *out,
+ const void
+ *in),
+ void (*felem_mul) (void *out,
+ const void
+ *in1,
+ const void
+ *in2),
+ void (*felem_inv) (void *out,
+ const void
+ *in),
+ void (*felem_contract) (void
+ *out,
+ const
+ void
+ *in));
+void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
+ unsigned char *digit, unsigned char in);
+#endif
diff --git a/openssl/ec/ec_lib.c b/openssl/ec/ec_lib.c
new file mode 100644
index 0000000..9a54f41
--- /dev/null
+++ b/openssl/ec/ec_lib.c
@@ -0,0 +1,1052 @@
+/* crypto/ec/ec_lib.c */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 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.
+ * Binary polynomial ECC support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/opensslv.h>
+
+#include "ec_lcl.h"
+
+const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT;
+
+/* functions for EC_GROUP objects */
+
+EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
+{
+ EC_GROUP *ret;
+
+ if (meth == NULL) {
+ ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
+ return NULL;
+ }
+ if (meth->group_init == 0) {
+ ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return NULL;
+ }
+
+ ret = OPENSSL_malloc(sizeof *ret);
+ if (ret == NULL) {
+ ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ ret->meth = meth;
+
+ ret->extra_data = NULL;
+
+ ret->generator = NULL;
+ BN_init(&ret->order);
+ BN_init(&ret->cofactor);
+
+ ret->curve_name = 0;
+ ret->asn1_flag = 0;
+ ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
+
+ ret->seed = NULL;
+ ret->seed_len = 0;
+
+ if (!meth->group_init(ret)) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+void EC_GROUP_free(EC_GROUP *group)
+{
+ if (!group)
+ return;
+
+ if (group->meth->group_finish != 0)
+ group->meth->group_finish(group);
+
+ EC_EX_DATA_free_all_data(&group->extra_data);
+
+ if (group->generator != NULL)
+ EC_POINT_free(group->generator);
+ BN_free(&group->order);
+ BN_free(&group->cofactor);
+
+ if (group->seed)
+ OPENSSL_free(group->seed);
+
+ OPENSSL_free(group);
+}
+
+void EC_GROUP_clear_free(EC_GROUP *group)
+{
+ if (!group)
+ return;
+
+ if (group->meth->group_clear_finish != 0)
+ group->meth->group_clear_finish(group);
+ else if (group->meth->group_finish != 0)
+ group->meth->group_finish(group);
+
+ EC_EX_DATA_clear_free_all_data(&group->extra_data);
+
+ if (group->generator != NULL)
+ EC_POINT_clear_free(group->generator);
+ BN_clear_free(&group->order);
+ BN_clear_free(&group->cofactor);
+
+ if (group->seed) {
+ OPENSSL_cleanse(group->seed, group->seed_len);
+ OPENSSL_free(group->seed);
+ }
+
+ OPENSSL_cleanse(group, sizeof *group);
+ OPENSSL_free(group);
+}
+
+int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
+{
+ EC_EXTRA_DATA *d;
+
+ if (dest->meth->group_copy == 0) {
+ ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (dest->meth != src->meth) {
+ ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ if (dest == src)
+ return 1;
+
+ EC_EX_DATA_free_all_data(&dest->extra_data);
+
+ for (d = src->extra_data; d != NULL; d = d->next) {
+ void *t = d->dup_func(d->data);
+
+ if (t == NULL)
+ return 0;
+ if (!EC_EX_DATA_set_data
+ (&dest->extra_data, t, d->dup_func, d->free_func,
+ d->clear_free_func))
+ return 0;
+ }
+
+ if (src->generator != NULL) {
+ if (dest->generator == NULL) {
+ dest->generator = EC_POINT_new(dest);
+ if (dest->generator == NULL)
+ return 0;
+ }
+ if (!EC_POINT_copy(dest->generator, src->generator))
+ return 0;
+ } else {
+ /* src->generator == NULL */
+ if (dest->generator != NULL) {
+ EC_POINT_clear_free(dest->generator);
+ dest->generator = NULL;
+ }
+ }
+
+ if (!BN_copy(&dest->order, &src->order))
+ return 0;
+ if (!BN_copy(&dest->cofactor, &src->cofactor))
+ return 0;
+
+ dest->curve_name = src->curve_name;
+ dest->asn1_flag = src->asn1_flag;
+ dest->asn1_form = src->asn1_form;
+
+ if (src->seed) {
+ if (dest->seed)
+ OPENSSL_free(dest->seed);
+ dest->seed = OPENSSL_malloc(src->seed_len);
+ if (dest->seed == NULL)
+ return 0;
+ if (!memcpy(dest->seed, src->seed, src->seed_len))
+ return 0;
+ dest->seed_len = src->seed_len;
+ } else {
+ if (dest->seed)
+ OPENSSL_free(dest->seed);
+ dest->seed = NULL;
+ dest->seed_len = 0;
+ }
+
+ return dest->meth->group_copy(dest, src);
+}
+
+EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
+{
+ EC_GROUP *t = NULL;
+ int ok = 0;
+
+ if (a == NULL)
+ return NULL;
+
+ if ((t = EC_GROUP_new(a->meth)) == NULL)
+ return (NULL);
+ if (!EC_GROUP_copy(t, a))
+ goto err;
+
+ ok = 1;
+
+ err:
+ if (!ok) {
+ if (t)
+ EC_GROUP_free(t);
+ return NULL;
+ } else
+ return t;
+}
+
+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
+{
+ return group->meth;
+}
+
+int EC_METHOD_get_field_type(const EC_METHOD *meth)
+{
+ return meth->field_type;
+}
+
+int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
+ const BIGNUM *order, const BIGNUM *cofactor)
+{
+ if (generator == NULL) {
+ ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if (group->generator == NULL) {
+ group->generator = EC_POINT_new(group);
+ if (group->generator == NULL)
+ return 0;
+ }
+ if (!EC_POINT_copy(group->generator, generator))
+ return 0;
+
+ if (order != NULL) {
+ if (!BN_copy(&group->order, order))
+ return 0;
+ } else
+ BN_zero(&group->order);
+
+ if (cofactor != NULL) {
+ if (!BN_copy(&group->cofactor, cofactor))
+ return 0;
+ } else
+ BN_zero(&group->cofactor);
+
+ return 1;
+}
+
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
+{
+ return group->generator;
+}
+
+int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
+{
+ if (!BN_copy(order, &group->order))
+ return 0;
+
+ return !BN_is_zero(order);
+}
+
+int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
+ BN_CTX *ctx)
+{
+ if (!BN_copy(cofactor, &group->cofactor))
+ return 0;
+
+ return !BN_is_zero(&group->cofactor);
+}
+
+void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
+{
+ group->curve_name = nid;
+}
+
+int EC_GROUP_get_curve_name(const EC_GROUP *group)
+{
+ return group->curve_name;
+}
+
+void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
+{
+ group->asn1_flag = flag;
+}
+
+int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
+{
+ return group->asn1_flag;
+}
+
+void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
+ point_conversion_form_t form)
+{
+ group->asn1_form = form;
+}
+
+point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP
+ *group)
+{
+ return group->asn1_form;
+}
+
+size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
+{
+ if (group->seed) {
+ OPENSSL_free(group->seed);
+ group->seed = NULL;
+ group->seed_len = 0;
+ }
+
+ if (!len || !p)
+ return 1;
+
+ if ((group->seed = OPENSSL_malloc(len)) == NULL)
+ return 0;
+ memcpy(group->seed, p, len);
+ group->seed_len = len;
+
+ return len;
+}
+
+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
+{
+ return group->seed;
+}
+
+size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
+{
+ return group->seed_len;
+}
+
+int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx)
+{
+ if (group->meth->group_set_curve == 0) {
+ ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ return group->meth->group_set_curve(group, p, a, b, ctx);
+}
+
+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+ BIGNUM *b, BN_CTX *ctx)
+{
+ if (group->meth->group_get_curve == 0) {
+ ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ return group->meth->group_get_curve(group, p, a, b, ctx);
+}
+
+#ifndef OPENSSL_NO_EC2M
+int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx)
+{
+ if (group->meth->group_set_curve == 0) {
+ ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ return group->meth->group_set_curve(group, p, a, b, ctx);
+}
+
+int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+ BIGNUM *b, BN_CTX *ctx)
+{
+ if (group->meth->group_get_curve == 0) {
+ ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ return group->meth->group_get_curve(group, p, a, b, ctx);
+}
+#endif
+
+int EC_GROUP_get_degree(const EC_GROUP *group)
+{
+ if (group->meth->group_get_degree == 0) {
+ ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ return group->meth->group_get_degree(group);
+}
+
+int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
+{
+ if (group->meth->group_check_discriminant == 0) {
+ ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ return group->meth->group_check_discriminant(group, ctx);
+}
+
+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
+{
+ int r = 0;
+ BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
+ BN_CTX *ctx_new = NULL;
+
+ /* compare the field types */
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
+ EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
+ return 1;
+ /* compare the curve name (if present in both) */
+ if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
+ EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
+ return 1;
+
+ if (!ctx)
+ ctx_new = ctx = BN_CTX_new();
+ if (!ctx)
+ return -1;
+
+ BN_CTX_start(ctx);
+ a1 = BN_CTX_get(ctx);
+ a2 = BN_CTX_get(ctx);
+ a3 = BN_CTX_get(ctx);
+ b1 = BN_CTX_get(ctx);
+ b2 = BN_CTX_get(ctx);
+ b3 = BN_CTX_get(ctx);
+ if (!b3) {
+ BN_CTX_end(ctx);
+ if (ctx_new)
+ BN_CTX_free(ctx);
+ return -1;
+ }
+
+ /*
+ * XXX This approach assumes that the external representation of curves
+ * over the same field type is the same.
+ */
+ if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
+ !b->meth->group_get_curve(b, b1, b2, b3, ctx))
+ r = 1;
+
+ if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
+ r = 1;
+
+ /* XXX EC_POINT_cmp() assumes that the methods are equal */
+ if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
+ EC_GROUP_get0_generator(b), ctx))
+ r = 1;
+
+ if (!r) {
+ /* compare the order and cofactor */
+ if (!EC_GROUP_get_order(a, a1, ctx) ||
+ !EC_GROUP_get_order(b, b1, ctx) ||
+ !EC_GROUP_get_cofactor(a, a2, ctx) ||
+ !EC_GROUP_get_cofactor(b, b2, ctx)) {
+ BN_CTX_end(ctx);
+ if (ctx_new)
+ BN_CTX_free(ctx);
+ return -1;
+ }
+ if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
+ r = 1;
+ }
+
+ BN_CTX_end(ctx);
+ if (ctx_new)
+ BN_CTX_free(ctx);
+
+ return r;
+}
+
+/* this has 'package' visibility */
+int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data,
+ void *(*dup_func) (void *),
+ void (*free_func) (void *),
+ void (*clear_free_func) (void *))
+{
+ EC_EXTRA_DATA *d;
+
+ if (ex_data == NULL)
+ return 0;
+
+ for (d = *ex_data; d != NULL; d = d->next) {
+ if (d->dup_func == dup_func && d->free_func == free_func
+ && d->clear_free_func == clear_free_func) {
+ ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL);
+ return 0;
+ }
+ }
+
+ if (data == NULL)
+ /* no explicit entry needed */
+ return 1;
+
+ d = OPENSSL_malloc(sizeof *d);
+ if (d == NULL)
+ return 0;
+
+ d->data = data;
+ d->dup_func = dup_func;
+ d->free_func = free_func;
+ d->clear_free_func = clear_free_func;
+
+ d->next = *ex_data;
+ *ex_data = d;
+
+ return 1;
+}
+
+/* this has 'package' visibility */
+void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data,
+ void *(*dup_func) (void *),
+ void (*free_func) (void *),
+ void (*clear_free_func) (void *))
+{
+ const EC_EXTRA_DATA *d;
+
+ for (d = ex_data; d != NULL; d = d->next) {
+ if (d->dup_func == dup_func && d->free_func == free_func
+ && d->clear_free_func == clear_free_func)
+ return d->data;
+ }
+
+ return NULL;
+}
+
+/* this has 'package' visibility */
+void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data,
+ void *(*dup_func) (void *),
+ void (*free_func) (void *),
+ void (*clear_free_func) (void *))
+{
+ EC_EXTRA_DATA **p;
+
+ if (ex_data == NULL)
+ return;
+
+ for (p = ex_data; *p != NULL; p = &((*p)->next)) {
+ if ((*p)->dup_func == dup_func && (*p)->free_func == free_func
+ && (*p)->clear_free_func == clear_free_func) {
+ EC_EXTRA_DATA *next = (*p)->next;
+
+ (*p)->free_func((*p)->data);
+ OPENSSL_free(*p);
+
+ *p = next;
+ return;
+ }
+ }
+}
+
+/* this has 'package' visibility */
+void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data,
+ void *(*dup_func) (void *),
+ void (*free_func) (void *),
+ void (*clear_free_func) (void *))
+{
+ EC_EXTRA_DATA **p;
+
+ if (ex_data == NULL)
+ return;
+
+ for (p = ex_data; *p != NULL; p = &((*p)->next)) {
+ if ((*p)->dup_func == dup_func && (*p)->free_func == free_func
+ && (*p)->clear_free_func == clear_free_func) {
+ EC_EXTRA_DATA *next = (*p)->next;
+
+ (*p)->clear_free_func((*p)->data);
+ OPENSSL_free(*p);
+
+ *p = next;
+ return;
+ }
+ }
+}
+
+/* this has 'package' visibility */
+void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data)
+{
+ EC_EXTRA_DATA *d;
+
+ if (ex_data == NULL)
+ return;
+
+ d = *ex_data;
+ while (d) {
+ EC_EXTRA_DATA *next = d->next;
+
+ d->free_func(d->data);
+ OPENSSL_free(d);
+
+ d = next;
+ }
+ *ex_data = NULL;
+}
+
+/* this has 'package' visibility */
+void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data)
+{
+ EC_EXTRA_DATA *d;
+
+ if (ex_data == NULL)
+ return;
+
+ d = *ex_data;
+ while (d) {
+ EC_EXTRA_DATA *next = d->next;
+
+ d->clear_free_func(d->data);
+ OPENSSL_free(d);
+
+ d = next;
+ }
+ *ex_data = NULL;
+}
+
+/* functions for EC_POINT objects */
+
+EC_POINT *EC_POINT_new(const EC_GROUP *group)
+{
+ EC_POINT *ret;
+
+ if (group == NULL) {
+ ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ if (group->meth->point_init == 0) {
+ ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return NULL;
+ }
+
+ ret = OPENSSL_malloc(sizeof *ret);
+ if (ret == NULL) {
+ ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ ret->meth = group->meth;
+
+ if (!ret->meth->point_init(ret)) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+void EC_POINT_free(EC_POINT *point)
+{
+ if (!point)
+ return;
+
+ if (point->meth->point_finish != 0)
+ point->meth->point_finish(point);
+ OPENSSL_free(point);
+}
+
+void EC_POINT_clear_free(EC_POINT *point)
+{
+ if (!point)
+ return;
+
+ if (point->meth->point_clear_finish != 0)
+ point->meth->point_clear_finish(point);
+ else if (point->meth->point_finish != 0)
+ point->meth->point_finish(point);
+ OPENSSL_cleanse(point, sizeof *point);
+ OPENSSL_free(point);
+}
+
+int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
+{
+ if (dest->meth->point_copy == 0) {
+ ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (dest->meth != src->meth) {
+ ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ if (dest == src)
+ return 1;
+ return dest->meth->point_copy(dest, src);
+}
+
+EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
+{
+ EC_POINT *t;
+ int r;
+
+ if (a == NULL)
+ return NULL;
+
+ t = EC_POINT_new(group);
+ if (t == NULL)
+ return (NULL);
+ r = EC_POINT_copy(t, a);
+ if (!r) {
+ EC_POINT_free(t);
+ return NULL;
+ } else
+ return t;
+}
+
+const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
+{
+ return point->meth;
+}
+
+int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
+{
+ if (group->meth->point_set_to_infinity == 0) {
+ ECerr(EC_F_EC_POINT_SET_TO_INFINITY,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return group->meth->point_set_to_infinity(group, point);
+}
+
+int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
+ EC_POINT *point, const BIGNUM *x,
+ const BIGNUM *y, const BIGNUM *z,
+ BN_CTX *ctx)
+{
+ if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
+ ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
+ EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x,
+ y, z, ctx);
+}
+
+int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
+ const EC_POINT *point, BIGNUM *x,
+ BIGNUM *y, BIGNUM *z,
+ BN_CTX *ctx)
+{
+ if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
+ ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
+ EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x,
+ y, z, ctx);
+}
+
+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
+ EC_POINT *point, const BIGNUM *x,
+ const BIGNUM *y, BN_CTX *ctx)
+{
+ if (group->meth->point_set_affine_coordinates == 0) {
+ ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
+ EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
+}
+
+#ifndef OPENSSL_NO_EC2M
+int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group,
+ EC_POINT *point, const BIGNUM *x,
+ const BIGNUM *y, BN_CTX *ctx)
+{
+ if (group->meth->point_set_affine_coordinates == 0) {
+ ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
+ EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
+}
+#endif
+
+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
+ const EC_POINT *point, BIGNUM *x,
+ BIGNUM *y, BN_CTX *ctx)
+{
+ if (group->meth->point_get_affine_coordinates == 0) {
+ ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
+ EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
+}
+
+#ifndef OPENSSL_NO_EC2M
+int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
+ const EC_POINT *point, BIGNUM *x,
+ BIGNUM *y, BN_CTX *ctx)
+{
+ if (group->meth->point_get_affine_coordinates == 0) {
+ ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
+ EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
+}
+#endif
+
+int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *ctx)
+{
+ if (group->meth->add == 0) {
+ ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if ((group->meth != r->meth) || (r->meth != a->meth)
+ || (a->meth != b->meth)) {
+ ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return group->meth->add(group, r, a, b, ctx);
+}
+
+int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+ BN_CTX *ctx)
+{
+ if (group->meth->dbl == 0) {
+ ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if ((group->meth != r->meth) || (r->meth != a->meth)) {
+ ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return group->meth->dbl(group, r, a, ctx);
+}
+
+int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
+{
+ if (group->meth->invert == 0) {
+ ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != a->meth) {
+ ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return group->meth->invert(group, a, ctx);
+}
+
+int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
+{
+ if (group->meth->is_at_infinity == 0) {
+ ECerr(EC_F_EC_POINT_IS_AT_INFINITY,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return group->meth->is_at_infinity(group, point);
+}
+
+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
+ BN_CTX *ctx)
+{
+ if (group->meth->is_on_curve == 0) {
+ ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return group->meth->is_on_curve(group, point, ctx);
+}
+
+int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
+ BN_CTX *ctx)
+{
+ if (group->meth->point_cmp == 0) {
+ ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return -1;
+ }
+ if ((group->meth != a->meth) || (a->meth != b->meth)) {
+ ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
+ return -1;
+ }
+ return group->meth->point_cmp(group, a, b, ctx);
+}
+
+int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+{
+ if (group->meth->make_affine == 0) {
+ ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ return group->meth->make_affine(group, point, ctx);
+}
+
+int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
+ EC_POINT *points[], BN_CTX *ctx)
+{
+ size_t i;
+
+ if (group->meth->points_make_affine == 0) {
+ ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ for (i = 0; i < num; i++) {
+ if (group->meth != points[i]->meth) {
+ ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ }
+ return group->meth->points_make_affine(group, num, points, ctx);
+}
+
+/*
+ * Functions for point multiplication. If group->meth->mul is 0, we use the
+ * wNAF-based implementations in ec_mult.c; otherwise we dispatch through
+ * methods.
+ */
+
+int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+ size_t num, const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx)
+{
+ if (group->meth->mul == 0)
+ /* use default */
+ return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+
+ return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
+}
+
+int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
+ const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
+{
+ /* just a convenient interface to EC_POINTs_mul() */
+
+ const EC_POINT *points[1];
+ const BIGNUM *scalars[1];
+
+ points[0] = point;
+ scalars[0] = p_scalar;
+
+ return EC_POINTs_mul(group, r, g_scalar,
+ (point != NULL
+ && p_scalar != NULL), points, scalars, ctx);
+}
+
+int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+{
+ if (group->meth->mul == 0)
+ /* use default */
+ return ec_wNAF_precompute_mult(group, ctx);
+
+ if (group->meth->precompute_mult != 0)
+ return group->meth->precompute_mult(group, ctx);
+ else
+ return 1; /* nothing to do, so report success */
+}
+
+int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
+{
+ if (group->meth->mul == 0)
+ /* use default */
+ return ec_wNAF_have_precompute_mult(group);
+
+ if (group->meth->have_precompute_mult != 0)
+ return group->meth->have_precompute_mult(group);
+ else
+ return 0; /* cannot tell whether precomputation has
+ * been performed */
+}
diff --git a/openssl/ec/ec_mult.c b/openssl/ec/ec_mult.c
new file mode 100644
index 0000000..0c2d335
--- /dev/null
+++ b/openssl/ec/ec_mult.c
@@ -0,0 +1,921 @@
+/* crypto/ec/ec_mult.c */
+/*
+ * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 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 this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <string.h>
+
+#include <openssl/err.h>
+
+#include "ec_lcl.h"
+
+/*
+ * This file implements the wNAF-based interleaving multi-exponentation method
+ * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
+ * for multiplication with precomputation, we use wNAF splitting
+ * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
+ */
+
+/* structure for precomputed multiples of the generator */
+typedef struct ec_pre_comp_st {
+ const EC_GROUP *group; /* parent EC_GROUP object */
+ size_t blocksize; /* block size for wNAF splitting */
+ size_t numblocks; /* max. number of blocks for which we have
+ * precomputation */
+ size_t w; /* window size */
+ EC_POINT **points; /* array with pre-calculated multiples of
+ * generator: 'num' pointers to EC_POINT
+ * objects followed by a NULL */
+ size_t num; /* numblocks * 2^(w-1) */
+ int references;
+} EC_PRE_COMP;
+
+/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */
+static void *ec_pre_comp_dup(void *);
+static void ec_pre_comp_free(void *);
+static void ec_pre_comp_clear_free(void *);
+
+static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
+{
+ EC_PRE_COMP *ret = NULL;
+
+ if (!group)
+ return NULL;
+
+ ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP));
+ if (!ret) {
+ ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ return ret;
+ }
+ ret->group = group;
+ ret->blocksize = 8; /* default */
+ ret->numblocks = 0;
+ ret->w = 4; /* default */
+ ret->points = NULL;
+ ret->num = 0;
+ ret->references = 1;
+ return ret;
+}
+
+static void *ec_pre_comp_dup(void *src_)
+{
+ EC_PRE_COMP *src = src_;
+
+ /* no need to actually copy, these objects never change! */
+
+ CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+
+ return src_;
+}
+
+static void ec_pre_comp_free(void *pre_)
+{
+ int i;
+ EC_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ if (pre->points) {
+ EC_POINT **p;
+
+ for (p = pre->points; *p != NULL; p++)
+ EC_POINT_free(*p);
+ OPENSSL_free(pre->points);
+ }
+ OPENSSL_free(pre);
+}
+
+static void ec_pre_comp_clear_free(void *pre_)
+{
+ int i;
+ EC_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ if (pre->points) {
+ EC_POINT **p;
+
+ for (p = pre->points; *p != NULL; p++) {
+ EC_POINT_clear_free(*p);
+ OPENSSL_cleanse(p, sizeof *p);
+ }
+ OPENSSL_free(pre->points);
+ }
+ OPENSSL_cleanse(pre, sizeof *pre);
+ OPENSSL_free(pre);
+}
+
+/*-
+ * Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
+ * This is an array r[] of values that are either zero or odd with an
+ * absolute value less than 2^w satisfying
+ * scalar = \sum_j r[j]*2^j
+ * where at most one of any w+1 consecutive digits is non-zero
+ * with the exception that the most significant digit may be only
+ * w-1 zeros away from that next non-zero digit.
+ */
+static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
+{
+ int window_val;
+ int ok = 0;
+ signed char *r = NULL;
+ int sign = 1;
+ int bit, next_bit, mask;
+ size_t len = 0, j;
+
+ if (BN_is_zero(scalar)) {
+ r = OPENSSL_malloc(1);
+ if (!r) {
+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ r[0] = 0;
+ *ret_len = 1;
+ return r;
+ }
+
+ if (w <= 0 || w > 7) { /* 'signed char' can represent integers with
+ * absolute values less than 2^7 */
+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ bit = 1 << w; /* at most 128 */
+ next_bit = bit << 1; /* at most 256 */
+ mask = next_bit - 1; /* at most 255 */
+
+ if (BN_is_negative(scalar)) {
+ sign = -1;
+ }
+
+ if (scalar->d == NULL || scalar->top == 0) {
+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ len = BN_num_bits(scalar);
+ r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer
+ * than binary representation (*ret_len will
+ * be set to the actual length, i.e. at most
+ * BN_num_bits(scalar) + 1) */
+ if (r == NULL) {
+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ window_val = scalar->d[0] & mask;
+ j = 0;
+ while ((window_val != 0) || (j + w + 1 < len)) { /* if j+w+1 >= len,
+ * window_val will not
+ * increase */
+ int digit = 0;
+
+ /* 0 <= window_val <= 2^(w+1) */
+
+ if (window_val & 1) {
+ /* 0 < window_val < 2^(w+1) */
+
+ if (window_val & bit) {
+ digit = window_val - next_bit; /* -2^w < digit < 0 */
+
+#if 1 /* modified wNAF */
+ if (j + w + 1 >= len) {
+ /*
+ * special case for generating modified wNAFs: no new
+ * bits will be added into window_val, so using a
+ * positive digit here will decrease the total length of
+ * the representation
+ */
+
+ digit = window_val & (mask >> 1); /* 0 < digit < 2^w */
+ }
+#endif
+ } else {
+ digit = window_val; /* 0 < digit < 2^w */
+ }
+
+ if (digit <= -bit || digit >= bit || !(digit & 1)) {
+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ window_val -= digit;
+
+ /*
+ * now window_val is 0 or 2^(w+1) in standard wNAF generation;
+ * for modified window NAFs, it may also be 2^w
+ */
+ if (window_val != 0 && window_val != next_bit
+ && window_val != bit) {
+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+
+ r[j++] = sign * digit;
+
+ window_val >>= 1;
+ window_val += bit * BN_is_bit_set(scalar, j + w);
+
+ if (window_val > next_bit) {
+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+
+ if (j > len + 1) {
+ ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ len = j;
+ ok = 1;
+
+ err:
+ if (!ok) {
+ OPENSSL_free(r);
+ r = NULL;
+ }
+ if (ok)
+ *ret_len = len;
+ return r;
+}
+
+/*
+ * TODO: table should be optimised for the wNAF-based implementation,
+ * sometimes smaller windows will give better performance (thus the
+ * boundaries should be increased)
+ */
+#define EC_window_bits_for_scalar_size(b) \
+ ((size_t) \
+ ((b) >= 2000 ? 6 : \
+ (b) >= 800 ? 5 : \
+ (b) >= 300 ? 4 : \
+ (b) >= 70 ? 3 : \
+ (b) >= 20 ? 2 : \
+ 1))
+
+/*-
+ * Compute
+ * \sum scalars[i]*points[i],
+ * also including
+ * scalar*generator
+ * in the addition if scalar != NULL
+ */
+int ec_wNAF_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;
+ const EC_POINT *generator = NULL;
+ EC_POINT *tmp = NULL;
+ size_t totalnum;
+ size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
+ size_t pre_points_per_block = 0;
+ size_t i, j;
+ int k;
+ int r_is_inverted = 0;
+ int r_is_at_infinity = 1;
+ size_t *wsize = NULL; /* individual window sizes */
+ signed char **wNAF = NULL; /* individual wNAFs */
+ size_t *wNAF_len = NULL;
+ size_t max_len = 0;
+ size_t num_val;
+ EC_POINT **val = NULL; /* precomputation */
+ EC_POINT **v;
+ EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or
+ * 'pre_comp->points' */
+ const EC_PRE_COMP *pre_comp = NULL;
+ int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be
+ * treated like other scalars, i.e.
+ * precomputation is not available */
+ int ret = 0;
+
+ if (group->meth != r->meth) {
+ ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+
+ if ((scalar == NULL) && (num == 0)) {
+ return EC_POINT_set_to_infinity(group, r);
+ }
+
+ for (i = 0; i < num; i++) {
+ if (group->meth != points[i]->meth) {
+ ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ }
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+ }
+
+ if (scalar != NULL) {
+ generator = EC_GROUP_get0_generator(group);
+ if (generator == NULL) {
+ ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR);
+ goto err;
+ }
+
+#ifndef NO_ECPOINT_MULTIPLY_PRECOMP
+
+ /* look if we can use precomputed multiples of generator */
+
+ pre_comp =
+ EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup,
+ ec_pre_comp_free, ec_pre_comp_clear_free);
+
+ if (pre_comp && pre_comp->numblocks
+ && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) ==
+ 0)) {
+ blocksize = pre_comp->blocksize;
+
+ /*
+ * determine maximum number of blocks that wNAF splitting may
+ * yield (NB: maximum wNAF length is bit length plus one)
+ */
+ numblocks = (BN_num_bits(scalar) / blocksize) + 1;
+
+ /*
+ * we cannot use more blocks than we have precomputation for
+ */
+ if (numblocks > pre_comp->numblocks)
+ numblocks = pre_comp->numblocks;
+
+ pre_points_per_block = (size_t)1 << (pre_comp->w - 1);
+
+ /* check that pre_comp looks sane */
+ if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ } else
+#endif /* NO_ECPOINT_MULTIPLY_PRECOMP */
+ {
+ /* can't use precomputation */
+ pre_comp = NULL;
+ numblocks = 1;
+ num_scalar = 1; /* treat 'scalar' like 'num'-th element of
+ * 'scalars' */
+ }
+ }
+
+ totalnum = num + numblocks;
+
+ wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]);
+ wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
+ wNAF = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space
+ * for pivot */
+ val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
+
+ /* Ensure wNAF is initialised in case we end up going to err */
+ if (wNAF)
+ wNAF[0] = NULL; /* preliminary pivot */
+
+ if (!wsize || !wNAF_len || !wNAF || !val_sub) {
+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /*
+ * num_val will be the total number of temporarily precomputed points
+ */
+ num_val = 0;
+
+ for (i = 0; i < num + num_scalar; i++) {
+ size_t bits;
+
+ bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
+ wsize[i] = EC_window_bits_for_scalar_size(bits);
+ num_val += (size_t)1 << (wsize[i] - 1);
+ wNAF[i + 1] = NULL; /* make sure we always have a pivot */
+ wNAF[i] =
+ compute_wNAF((i < num ? scalars[i] : scalar), wsize[i],
+ &wNAF_len[i]);
+ if (wNAF[i] == NULL)
+ goto err;
+ if (wNAF_len[i] > max_len)
+ max_len = wNAF_len[i];
+ }
+
+ if (numblocks) {
+ /* we go here iff scalar != NULL */
+
+#ifndef NO_ECPOINT_MULTIPLY_PRECOMP
+ if (pre_comp == NULL) {
+#endif /* NO_ECPOINT_MULTIPLY_PRECOMP */
+ if (num_scalar != 1) {
+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ /* we have already generated a wNAF for 'scalar' */
+#ifndef NO_ECPOINT_MULTIPLY_PRECOMP
+ } else {
+ signed char *tmp_wNAF = NULL;
+ size_t tmp_len = 0;
+
+ if (num_scalar != 0) {
+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ /*
+ * use the window size for which we have precomputation
+ */
+ wsize[num] = pre_comp->w;
+ tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
+ if (!tmp_wNAF)
+ goto err;
+
+ if (tmp_len <= max_len) {
+ /*
+ * One of the other wNAFs is at least as long as the wNAF
+ * belonging to the generator, so wNAF splitting will not buy
+ * us anything.
+ */
+
+ numblocks = 1;
+ totalnum = num + 1; /* don't use wNAF splitting */
+ wNAF[num] = tmp_wNAF;
+ wNAF[num + 1] = NULL;
+ wNAF_len[num] = tmp_len;
+ if (tmp_len > max_len)
+ max_len = tmp_len;
+ /*
+ * pre_comp->points starts with the points that we need here:
+ */
+ val_sub[num] = pre_comp->points;
+ } else {
+ /*
+ * don't include tmp_wNAF directly into wNAF array - use wNAF
+ * splitting and include the blocks
+ */
+
+ signed char *pp;
+ EC_POINT **tmp_points;
+
+ if (tmp_len < numblocks * blocksize) {
+ /*
+ * possibly we can do with fewer blocks than estimated
+ */
+ numblocks = (tmp_len + blocksize - 1) / blocksize;
+ if (numblocks > pre_comp->numblocks) {
+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ totalnum = num + numblocks;
+ }
+
+ /* split wNAF in 'numblocks' parts */
+ pp = tmp_wNAF;
+ tmp_points = pre_comp->points;
+
+ for (i = num; i < totalnum; i++) {
+ if (i < totalnum - 1) {
+ wNAF_len[i] = blocksize;
+ if (tmp_len < blocksize) {
+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ tmp_len -= blocksize;
+ } else
+ /*
+ * last block gets whatever is left (this could be
+ * more or less than 'blocksize'!)
+ */
+ wNAF_len[i] = tmp_len;
+
+ wNAF[i + 1] = NULL;
+ wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
+ if (wNAF[i] == NULL) {
+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(tmp_wNAF);
+ goto err;
+ }
+ memcpy(wNAF[i], pp, wNAF_len[i]);
+ if (wNAF_len[i] > max_len)
+ max_len = wNAF_len[i];
+
+ if (*tmp_points == NULL) {
+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ OPENSSL_free(tmp_wNAF);
+ goto err;
+ }
+ val_sub[i] = tmp_points;
+ tmp_points += pre_points_per_block;
+ pp += blocksize;
+ }
+ OPENSSL_free(tmp_wNAF);
+ }
+ }
+#endif /* NO_ECPOINT_MULTIPLY_PRECOMP */
+ }
+
+ /*
+ * All points we precompute now go into a single array 'val'.
+ * 'val_sub[i]' is a pointer to the subarray for the i-th point, or to a
+ * subarray of 'pre_comp->points' if we already have precomputation.
+ */
+ val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);
+ if (val == NULL) {
+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ val[num_val] = NULL; /* pivot element */
+
+ /* allocate points for precomputation */
+ v = val;
+ for (i = 0; i < num + num_scalar; i++) {
+ val_sub[i] = v;
+ for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) {
+ *v = EC_POINT_new(group);
+ if (*v == NULL)
+ goto err;
+ v++;
+ }
+ }
+ if (!(v == val + num_val)) {
+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ if (!(tmp = EC_POINT_new(group)))
+ goto err;
+
+ /*-
+ * prepare precomputed values:
+ * val_sub[i][0] := points[i]
+ * val_sub[i][1] := 3 * points[i]
+ * val_sub[i][2] := 5 * points[i]
+ * ...
+ */
+ for (i = 0; i < num + num_scalar; i++) {
+ if (i < num) {
+ if (!EC_POINT_copy(val_sub[i][0], points[i]))
+ goto err;
+ } else {
+ if (!EC_POINT_copy(val_sub[i][0], generator))
+ goto err;
+ }
+
+ if (wsize[i] > 1) {
+ if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx))
+ goto err;
+ for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) {
+ if (!EC_POINT_add
+ (group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx))
+ goto err;
+ }
+ }
+ }
+
+#if 1 /* optional; EC_window_bits_for_scalar_size
+ * assumes we do this step */
+ if (!EC_POINTs_make_affine(group, num_val, val, ctx))
+ goto err;
+#endif
+
+ r_is_at_infinity = 1;
+
+ for (k = max_len - 1; k >= 0; k--) {
+ if (!r_is_at_infinity) {
+ if (!EC_POINT_dbl(group, r, r, ctx))
+ goto err;
+ }
+
+ for (i = 0; i < totalnum; i++) {
+ if (wNAF_len[i] > (size_t)k) {
+ int digit = wNAF[i][k];
+ int is_neg;
+
+ if (digit) {
+ is_neg = digit < 0;
+
+ if (is_neg)
+ digit = -digit;
+
+ if (is_neg != r_is_inverted) {
+ if (!r_is_at_infinity) {
+ if (!EC_POINT_invert(group, r, ctx))
+ goto err;
+ }
+ r_is_inverted = !r_is_inverted;
+ }
+
+ /* digit > 0 */
+
+ if (r_is_at_infinity) {
+ if (!EC_POINT_copy(r, val_sub[i][digit >> 1]))
+ goto err;
+ r_is_at_infinity = 0;
+ } else {
+ if (!EC_POINT_add
+ (group, r, r, val_sub[i][digit >> 1], ctx))
+ goto err;
+ }
+ }
+ }
+ }
+ }
+
+ if (r_is_at_infinity) {
+ if (!EC_POINT_set_to_infinity(group, r))
+ goto err;
+ } else {
+ if (r_is_inverted)
+ if (!EC_POINT_invert(group, r, ctx))
+ goto err;
+ }
+
+ ret = 1;
+
+ err:
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (tmp != NULL)
+ EC_POINT_free(tmp);
+ if (wsize != NULL)
+ OPENSSL_free(wsize);
+ if (wNAF_len != NULL)
+ OPENSSL_free(wNAF_len);
+ if (wNAF != NULL) {
+ signed char **w;
+
+ for (w = wNAF; *w != NULL; w++)
+ OPENSSL_free(*w);
+
+ OPENSSL_free(wNAF);
+ }
+ if (val != NULL) {
+ for (v = val; *v != NULL; v++)
+ EC_POINT_clear_free(*v);
+
+ OPENSSL_free(val);
+ }
+ if (val_sub != NULL) {
+ OPENSSL_free(val_sub);
+ }
+ return ret;
+}
+
+/*-
+ * ec_wNAF_precompute_mult()
+ * creates an EC_PRE_COMP object with preprecomputed multiples of the generator
+ * for use with wNAF splitting as implemented in ec_wNAF_mul().
+ *
+ * 'pre_comp->points' is an array of multiples of the generator
+ * of the following form:
+ * points[0] = generator;
+ * points[1] = 3 * generator;
+ * ...
+ * points[2^(w-1)-1] = (2^(w-1)-1) * generator;
+ * points[2^(w-1)] = 2^blocksize * generator;
+ * points[2^(w-1)+1] = 3 * 2^blocksize * generator;
+ * ...
+ * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) * generator
+ * points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) * generator
+ * ...
+ * points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator
+ * points[2^(w-1)*numblocks] = NULL
+ */
+int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+{
+ const EC_POINT *generator;
+ EC_POINT *tmp_point = NULL, *base = NULL, **var;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *order;
+ size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
+ EC_POINT **points = NULL;
+ EC_PRE_COMP *pre_comp;
+ int ret = 0;
+
+ /* if there is an old EC_PRE_COMP object, throw it away */
+ EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup,
+ ec_pre_comp_free, ec_pre_comp_clear_free);
+
+ if ((pre_comp = ec_pre_comp_new(group)) == NULL)
+ return 0;
+
+ generator = EC_GROUP_get0_generator(group);
+ if (generator == NULL) {
+ ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR);
+ goto err;
+ }
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ goto err;
+ }
+
+ BN_CTX_start(ctx);
+ order = BN_CTX_get(ctx);
+ if (order == NULL)
+ goto err;
+
+ if (!EC_GROUP_get_order(group, order, ctx))
+ goto err;
+ if (BN_is_zero(order)) {
+ ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);
+ goto err;
+ }
+
+ bits = BN_num_bits(order);
+ /*
+ * The following parameters mean we precompute (approximately) one point
+ * per bit. TBD: The combination 8, 4 is perfect for 160 bits; for other
+ * bit lengths, other parameter combinations might provide better
+ * efficiency.
+ */
+ blocksize = 8;
+ w = 4;
+ if (EC_window_bits_for_scalar_size(bits) > w) {
+ /* let's not make the window too small ... */
+ w = EC_window_bits_for_scalar_size(bits);
+ }
+
+ numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks
+ * to use for wNAF
+ * splitting */
+
+ pre_points_per_block = (size_t)1 << (w - 1);
+ num = pre_points_per_block * numblocks; /* number of points to compute
+ * and store */
+
+ points = OPENSSL_malloc(sizeof(EC_POINT *) * (num + 1));
+ if (!points) {
+ ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ var = points;
+ var[num] = NULL; /* pivot */
+ for (i = 0; i < num; i++) {
+ if ((var[i] = EC_POINT_new(group)) == NULL) {
+ ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) {
+ ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!EC_POINT_copy(base, generator))
+ goto err;
+
+ /* do the precomputation */
+ for (i = 0; i < numblocks; i++) {
+ size_t j;
+
+ if (!EC_POINT_dbl(group, tmp_point, base, ctx))
+ goto err;
+
+ if (!EC_POINT_copy(*var++, base))
+ goto err;
+
+ for (j = 1; j < pre_points_per_block; j++, var++) {
+ /*
+ * calculate odd multiples of the current base point
+ */
+ if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))
+ goto err;
+ }
+
+ if (i < numblocks - 1) {
+ /*
+ * get the next base (multiply current one by 2^blocksize)
+ */
+ size_t k;
+
+ if (blocksize <= 2) {
+ ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ if (!EC_POINT_dbl(group, base, tmp_point, ctx))
+ goto err;
+ for (k = 2; k < blocksize; k++) {
+ if (!EC_POINT_dbl(group, base, base, ctx))
+ goto err;
+ }
+ }
+ }
+
+ if (!EC_POINTs_make_affine(group, num, points, ctx))
+ goto err;
+
+ pre_comp->group = group;
+ pre_comp->blocksize = blocksize;
+ pre_comp->numblocks = numblocks;
+ pre_comp->w = w;
+ pre_comp->points = points;
+ points = NULL;
+ pre_comp->num = num;
+
+ if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp,
+ ec_pre_comp_dup, ec_pre_comp_free,
+ ec_pre_comp_clear_free))
+ goto err;
+ pre_comp = NULL;
+
+ ret = 1;
+ err:
+ if (ctx != NULL)
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (pre_comp)
+ ec_pre_comp_free(pre_comp);
+ if (points) {
+ EC_POINT **p;
+
+ for (p = points; *p != NULL; p++)
+ EC_POINT_free(*p);
+ OPENSSL_free(points);
+ }
+ if (tmp_point)
+ EC_POINT_free(tmp_point);
+ if (base)
+ EC_POINT_free(base);
+ return ret;
+}
+
+int ec_wNAF_have_precompute_mult(const EC_GROUP *group)
+{
+ if (EC_EX_DATA_get_data
+ (group->extra_data, ec_pre_comp_dup, ec_pre_comp_free,
+ ec_pre_comp_clear_free) != NULL)
+ return 1;
+ else
+ return 0;
+}
diff --git a/openssl/ec/ec_oct.c b/openssl/ec/ec_oct.c
new file mode 100644
index 0000000..040c414
--- /dev/null
+++ b/openssl/ec/ec_oct.c
@@ -0,0 +1,192 @@
+/* crypto/ec/ec_lib.c */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 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.
+ * Binary polynomial ECC support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/opensslv.h>
+
+#include "ec_lcl.h"
+
+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
+ EC_POINT *point, const BIGNUM *x,
+ int y_bit, BN_CTX *ctx)
+{
+ if (group->meth->point_set_compressed_coordinates == 0
+ && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
+ ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,
+ EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
+ if (group->meth->field_type == NID_X9_62_prime_field)
+ return ec_GFp_simple_set_compressed_coordinates(group, point, x,
+ y_bit, ctx);
+ else
+#ifdef OPENSSL_NO_EC2M
+ {
+ ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,
+ EC_R_GF2M_NOT_SUPPORTED);
+ return 0;
+ }
+#else
+ return ec_GF2m_simple_set_compressed_coordinates(group, point, x,
+ y_bit, ctx);
+#endif
+ }
+ return group->meth->point_set_compressed_coordinates(group, point, x,
+ y_bit, ctx);
+}
+
+#ifndef OPENSSL_NO_EC2M
+int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group,
+ EC_POINT *point, const BIGNUM *x,
+ int y_bit, BN_CTX *ctx)
+{
+ if (group->meth->point_set_compressed_coordinates == 0
+ && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
+ ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M,
+ EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
+ if (group->meth->field_type == NID_X9_62_prime_field)
+ return ec_GFp_simple_set_compressed_coordinates(group, point, x,
+ y_bit, ctx);
+ else
+ return ec_GF2m_simple_set_compressed_coordinates(group, point, x,
+ y_bit, ctx);
+ }
+ return group->meth->point_set_compressed_coordinates(group, point, x,
+ y_bit, ctx);
+}
+#endif
+
+size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
+ point_conversion_form_t form, unsigned char *buf,
+ size_t len, BN_CTX *ctx)
+{
+ if (group->meth->point2oct == 0
+ && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
+ ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
+ if (group->meth->field_type == NID_X9_62_prime_field)
+ return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
+ else
+#ifdef OPENSSL_NO_EC2M
+ {
+ ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED);
+ return 0;
+ }
+#else
+ return ec_GF2m_simple_point2oct(group, point,
+ form, buf, len, ctx);
+#endif
+ }
+
+ return group->meth->point2oct(group, point, form, buf, len, ctx);
+}
+
+int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
+ const unsigned char *buf, size_t len, BN_CTX *ctx)
+{
+ if (group->meth->oct2point == 0
+ && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
+ ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ if (group->meth != point->meth) {
+ ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
+ return 0;
+ }
+ if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
+ if (group->meth->field_type == NID_X9_62_prime_field)
+ return ec_GFp_simple_oct2point(group, point, buf, len, ctx);
+ else
+#ifdef OPENSSL_NO_EC2M
+ {
+ ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED);
+ return 0;
+ }
+#else
+ return ec_GF2m_simple_oct2point(group, point, buf, len, ctx);
+#endif
+ }
+ return group->meth->oct2point(group, point, buf, len, ctx);
+}
diff --git a/openssl/ec/ec_pmeth.c b/openssl/ec/ec_pmeth.c
new file mode 100644
index 0000000..c189d3f
--- /dev/null
+++ b/openssl/ec/ec_pmeth.c
@@ -0,0 +1,332 @@
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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 <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
+#include <openssl/evp.h>
+#include "evp_locl.h"
+
+/* EC pkey context structure */
+
+typedef struct {
+ /* Key and paramgen group */
+ EC_GROUP *gen_group;
+ /* message digest */
+ const EVP_MD *md;
+} EC_PKEY_CTX;
+
+static int pkey_ec_init(EVP_PKEY_CTX *ctx)
+{
+ EC_PKEY_CTX *dctx;
+ dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX));
+ if (!dctx)
+ return 0;
+ dctx->gen_group = NULL;
+ dctx->md = NULL;
+
+ ctx->data = dctx;
+
+ return 1;
+}
+
+static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+ EC_PKEY_CTX *dctx, *sctx;
+ if (!pkey_ec_init(dst))
+ return 0;
+ sctx = src->data;
+ dctx = dst->data;
+ if (sctx->gen_group) {
+ dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
+ if (!dctx->gen_group)
+ return 0;
+ }
+ dctx->md = sctx->md;
+ return 1;
+}
+
+static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
+{
+ EC_PKEY_CTX *dctx = ctx->data;
+ if (dctx) {
+ if (dctx->gen_group)
+ EC_GROUP_free(dctx->gen_group);
+ OPENSSL_free(dctx);
+ }
+}
+
+static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs, size_t tbslen)
+{
+ int ret, type;
+ unsigned int sltmp;
+ EC_PKEY_CTX *dctx = ctx->data;
+ EC_KEY *ec = ctx->pkey->pkey.ec;
+
+ if (!sig) {
+ *siglen = ECDSA_size(ec);
+ return 1;
+ } else if (*siglen < (size_t)ECDSA_size(ec)) {
+ ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ if (dctx->md)
+ type = EVP_MD_type(dctx->md);
+ else
+ type = NID_sha1;
+
+ ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
+
+ if (ret <= 0)
+ return ret;
+ *siglen = (size_t)sltmp;
+ return 1;
+}
+
+static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
+ const unsigned char *sig, size_t siglen,
+ const unsigned char *tbs, size_t tbslen)
+{
+ int ret, type;
+ EC_PKEY_CTX *dctx = ctx->data;
+ EC_KEY *ec = ctx->pkey->pkey.ec;
+
+ if (dctx->md)
+ type = EVP_MD_type(dctx->md);
+ else
+ type = NID_sha1;
+
+ ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
+
+ return ret;
+}
+
+#ifndef OPENSSL_NO_ECDH
+static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
+ size_t *keylen)
+{
+ int ret;
+ size_t outlen;
+ const EC_POINT *pubkey = NULL;
+ if (!ctx->pkey || !ctx->peerkey) {
+ ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
+ return 0;
+ }
+
+ if (!key) {
+ const EC_GROUP *group;
+ group = EC_KEY_get0_group(ctx->pkey->pkey.ec);
+ *keylen = (EC_GROUP_get_degree(group) + 7) / 8;
+ return 1;
+ }
+
+ pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
+
+ /*
+ * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is not
+ * an error, the result is truncated.
+ */
+
+ outlen = *keylen;
+
+ ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0);
+ if (ret < 0)
+ return ret;
+ *keylen = ret;
+ return 1;
+}
+#endif
+
+static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+ EC_PKEY_CTX *dctx = ctx->data;
+ EC_GROUP *group;
+ switch (type) {
+ case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
+ group = EC_GROUP_new_by_curve_name(p1);
+ if (group == NULL) {
+ ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
+ return 0;
+ }
+ if (dctx->gen_group)
+ EC_GROUP_free(dctx->gen_group);
+ dctx->gen_group = group;
+ return 1;
+
+ case EVP_PKEY_CTRL_MD:
+ if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
+ EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
+ ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
+ return 0;
+ }
+ dctx->md = p2;
+ return 1;
+
+ case EVP_PKEY_CTRL_PEER_KEY:
+ /* Default behaviour is OK */
+ case EVP_PKEY_CTRL_DIGESTINIT:
+ case EVP_PKEY_CTRL_PKCS7_SIGN:
+ case EVP_PKEY_CTRL_CMS_SIGN:
+ return 1;
+
+ default:
+ return -2;
+
+ }
+}
+
+static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
+ const char *type, const char *value)
+{
+ if (!strcmp(type, "ec_paramgen_curve")) {
+ int nid;
+ nid = OBJ_sn2nid(value);
+ if (nid == NID_undef)
+ nid = OBJ_ln2nid(value);
+ if (nid == NID_undef) {
+ ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
+ return 0;
+ }
+ return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
+ }
+ return -2;
+}
+
+static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+ EC_KEY *ec = NULL;
+ EC_PKEY_CTX *dctx = ctx->data;
+ int ret = 0;
+ if (dctx->gen_group == NULL) {
+ ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
+ return 0;
+ }
+ ec = EC_KEY_new();
+ if (!ec)
+ return 0;
+ ret = EC_KEY_set_group(ec, dctx->gen_group);
+ if (ret)
+ EVP_PKEY_assign_EC_KEY(pkey, ec);
+ else
+ EC_KEY_free(ec);
+ return ret;
+}
+
+static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+ EC_KEY *ec = NULL;
+ if (ctx->pkey == NULL) {
+ ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
+ return 0;
+ }
+ ec = EC_KEY_new();
+ if (!ec)
+ return 0;
+ EVP_PKEY_assign_EC_KEY(pkey, ec);
+ /* Note: if error return, pkey is freed by parent routine */
+ if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+ return 0;
+ return EC_KEY_generate_key(pkey->pkey.ec);
+}
+
+const EVP_PKEY_METHOD ec_pkey_meth = {
+ EVP_PKEY_EC,
+ 0,
+ pkey_ec_init,
+ pkey_ec_copy,
+ pkey_ec_cleanup,
+
+ 0,
+ pkey_ec_paramgen,
+
+ 0,
+ pkey_ec_keygen,
+
+ 0,
+ pkey_ec_sign,
+
+ 0,
+ pkey_ec_verify,
+
+ 0, 0,
+
+ 0, 0, 0, 0,
+
+ 0, 0,
+
+ 0, 0,
+
+ 0,
+#ifndef OPENSSL_NO_ECDH
+ pkey_ec_derive,
+#else
+ 0,
+#endif
+
+ pkey_ec_ctrl,
+ pkey_ec_ctrl_str
+};
diff --git a/openssl/ec/ec_print.c b/openssl/ec/ec_print.c
new file mode 100644
index 0000000..96b294d
--- /dev/null
+++ b/openssl/ec/ec_print.c
@@ -0,0 +1,179 @@
+/* crypto/ec/ec_print.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).
+ *
+ */
+
+#include <openssl/crypto.h>
+#include "ec_lcl.h"
+
+BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,
+ const EC_POINT *point,
+ point_conversion_form_t form,
+ BIGNUM *ret, BN_CTX *ctx)
+{
+ size_t buf_len = 0;
+ unsigned char *buf;
+
+ buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx);
+ if (buf_len == 0)
+ return NULL;
+
+ if ((buf = OPENSSL_malloc(buf_len)) == NULL)
+ return NULL;
+
+ if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) {
+ OPENSSL_free(buf);
+ return NULL;
+ }
+
+ ret = BN_bin2bn(buf, buf_len, ret);
+
+ OPENSSL_free(buf);
+
+ return ret;
+}
+
+EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
+ const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx)
+{
+ size_t buf_len = 0;
+ unsigned char *buf;
+ EC_POINT *ret;
+
+ if ((buf_len = BN_num_bytes(bn)) == 0)
+ return NULL;
+ buf = OPENSSL_malloc(buf_len);
+ if (buf == NULL)
+ return NULL;
+
+ if (!BN_bn2bin(bn, buf)) {
+ OPENSSL_free(buf);
+ return NULL;
+ }
+
+ if (point == NULL) {
+ if ((ret = EC_POINT_new(group)) == NULL) {
+ OPENSSL_free(buf);
+ return NULL;
+ }
+ } else
+ ret = point;
+
+ if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) {
+ if (point == NULL)
+ EC_POINT_clear_free(ret);
+ OPENSSL_free(buf);
+ return NULL;
+ }
+
+ OPENSSL_free(buf);
+ return ret;
+}
+
+static const char *HEX_DIGITS = "0123456789ABCDEF";
+
+/* the return value must be freed (using OPENSSL_free()) */
+char *EC_POINT_point2hex(const EC_GROUP *group,
+ const EC_POINT *point,
+ point_conversion_form_t form, BN_CTX *ctx)
+{
+ char *ret, *p;
+ size_t buf_len = 0, i;
+ unsigned char *buf, *pbuf;
+
+ buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx);
+ if (buf_len == 0)
+ return NULL;
+
+ if ((buf = OPENSSL_malloc(buf_len)) == NULL)
+ return NULL;
+
+ if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) {
+ OPENSSL_free(buf);
+ return NULL;
+ }
+
+ ret = (char *)OPENSSL_malloc(buf_len * 2 + 2);
+ if (ret == NULL) {
+ OPENSSL_free(buf);
+ return NULL;
+ }
+ p = ret;
+ pbuf = buf;
+ for (i = buf_len; i > 0; i--) {
+ int v = (int)*(pbuf++);
+ *(p++) = HEX_DIGITS[v >> 4];
+ *(p++) = HEX_DIGITS[v & 0x0F];
+ }
+ *p = '\0';
+
+ OPENSSL_free(buf);
+
+ return ret;
+}
+
+EC_POINT *EC_POINT_hex2point(const EC_GROUP *group,
+ const char *buf, EC_POINT *point, BN_CTX *ctx)
+{
+ EC_POINT *ret = NULL;
+ BIGNUM *tmp_bn = NULL;
+
+ if (!BN_hex2bn(&tmp_bn, buf))
+ return NULL;
+
+ ret = EC_POINT_bn2point(group, tmp_bn, point, ctx);
+
+ BN_clear_free(tmp_bn);
+
+ return ret;
+}
diff --git a/openssl/ec/eck_prn.c b/openssl/ec/eck_prn.c
new file mode 100644
index 0000000..a911a0a
--- /dev/null
+++ b/openssl/ec/eck_prn.c
@@ -0,0 +1,367 @@
+/* crypto/ec/eck_prn.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2005 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 originally developed by SUN MICROSYSTEMS, INC., and
+ * contributed to the OpenSSL project.
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/ec.h>
+#include <openssl/bn.h>
+
+#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);
+}
+
+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 EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
+{
+ EVP_PKEY *pk;
+ int ret;
+ pk = EVP_PKEY_new();
+ if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
+ return 0;
+ ret = EVP_PKEY_print_private(bp, pk, off, NULL);
+ EVP_PKEY_free(pk);
+ return ret;
+}
+
+int ECParameters_print(BIO *bp, const EC_KEY *x)
+{
+ EVP_PKEY *pk;
+ int ret;
+ pk = EVP_PKEY_new();
+ if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
+ return 0;
+ ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
+ EVP_PKEY_free(pk);
+ return ret;
+}
+
+static int print_bin(BIO *fp, const char *str, const unsigned char *num,
+ size_t len, int off);
+
+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;
+ const 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;
+ }
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ reason = ERR_R_MALLOC_FAILURE;
+ 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_curve_name(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;
+ }
+#ifndef OPENSSL_NO_EC2M
+ 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 */
+#endif
+ {
+ 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) && !ASN1_bn_print(bp, "Polynomial:", p, buffer,
+ off))
+ goto err;
+ } else {
+ if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off))
+ goto err;
+ }
+ if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off))
+ goto err;
+ if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off))
+ goto err;
+ if (form == POINT_CONVERSION_COMPRESSED) {
+ if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
+ buffer, off))
+ goto err;
+ } else if (form == POINT_CONVERSION_UNCOMPRESSED) {
+ if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
+ buffer, off))
+ goto err;
+ } else { /* form == POINT_CONVERSION_HYBRID */
+
+ if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
+ buffer, off))
+ goto err;
+ }
+ if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
+ buffer, off))
+ goto err;
+ if ((cofactor != NULL) && !ASN1_bn_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);
+}
+
+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;
+}
diff --git a/openssl/ec/ecp_mont.c b/openssl/ec/ecp_mont.c
new file mode 100644
index 0000000..83a240b
--- /dev/null
+++ b/openssl/ec/ecp_mont.c
@@ -0,0 +1,318 @@
+/* crypto/ec/ecp_mont.c */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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 this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <openssl/err.h>
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+#include "ec_lcl.h"
+
+const EC_METHOD *EC_GFp_mont_method(void)
+{
+ static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
+ NID_X9_62_prime_field,
+ ec_GFp_mont_group_init,
+ ec_GFp_mont_group_finish,
+ ec_GFp_mont_group_clear_finish,
+ ec_GFp_mont_group_copy,
+ ec_GFp_mont_group_set_curve,
+#ifdef DISABLE_UNUSED_EC_FUNCTS
+ 0,
+ 0,
+ 0,
+#else
+ ec_GFp_simple_group_get_curve,
+ ec_GFp_simple_group_get_degree,
+ ec_GFp_simple_group_check_discriminant,
+#endif
+ ec_GFp_simple_point_init,
+ ec_GFp_simple_point_finish,
+ ec_GFp_simple_point_clear_finish,
+ ec_GFp_simple_point_copy,
+ ec_GFp_simple_point_set_to_infinity,
+ ec_GFp_simple_set_Jprojective_coordinates_GFp,
+ ec_GFp_simple_get_Jprojective_coordinates_GFp,
+ ec_GFp_simple_point_set_affine_coordinates,
+ ec_GFp_simple_point_get_affine_coordinates,
+ 0, 0, 0,
+ ec_GFp_simple_add,
+ ec_GFp_simple_dbl,
+ ec_GFp_simple_invert,
+ ec_GFp_simple_is_at_infinity,
+ ec_GFp_simple_is_on_curve,
+#ifdef DISABLE_UNUSED_EC_FUNCTS
+ 0,
+#else
+ ec_GFp_simple_cmp,
+#endif
+ ec_GFp_simple_make_affine,
+ ec_GFp_simple_points_make_affine,
+ 0 /* mul */ ,
+ 0 /* precompute_mult */ ,
+ 0 /* have_precompute_mult */ ,
+ ec_GFp_mont_field_mul,
+ ec_GFp_mont_field_sqr,
+ 0 /* field_div */ ,
+ ec_GFp_mont_field_encode,
+ ec_GFp_mont_field_decode,
+ ec_GFp_mont_field_set_to_one
+ };
+
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return fips_ec_gfp_mont_method();
+#endif
+
+ return &ret;
+}
+
+int ec_GFp_mont_group_init(EC_GROUP *group)
+{
+ int ok;
+
+ ok = ec_GFp_simple_group_init(group);
+ group->field_data1 = NULL;
+ group->field_data2 = NULL;
+ return ok;
+}
+
+void ec_GFp_mont_group_finish(EC_GROUP *group)
+{
+ if (group->field_data1 != NULL) {
+ BN_MONT_CTX_free(group->field_data1);
+ group->field_data1 = NULL;
+ }
+ if (group->field_data2 != NULL) {
+ BN_free(group->field_data2);
+ group->field_data2 = NULL;
+ }
+ ec_GFp_simple_group_finish(group);
+}
+
+void ec_GFp_mont_group_clear_finish(EC_GROUP *group)
+{
+ if (group->field_data1 != NULL) {
+ BN_MONT_CTX_free(group->field_data1);
+ group->field_data1 = NULL;
+ }
+ if (group->field_data2 != NULL) {
+ BN_clear_free(group->field_data2);
+ group->field_data2 = NULL;
+ }
+ ec_GFp_simple_group_clear_finish(group);
+}
+
+int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+{
+ if (dest->field_data1 != NULL) {
+ BN_MONT_CTX_free(dest->field_data1);
+ dest->field_data1 = NULL;
+ }
+ if (dest->field_data2 != NULL) {
+ BN_clear_free(dest->field_data2);
+ dest->field_data2 = NULL;
+ }
+
+ if (!ec_GFp_simple_group_copy(dest, src))
+ return 0;
+
+ if (src->field_data1 != NULL) {
+ dest->field_data1 = BN_MONT_CTX_new();
+ if (dest->field_data1 == NULL)
+ return 0;
+ if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1))
+ goto err;
+ }
+ if (src->field_data2 != NULL) {
+ dest->field_data2 = BN_dup(src->field_data2);
+ if (dest->field_data2 == NULL)
+ goto err;
+ }
+
+ return 1;
+
+ err:
+ if (dest->field_data1 != NULL) {
+ BN_MONT_CTX_free(dest->field_data1);
+ dest->field_data1 = NULL;
+ }
+ return 0;
+}
+
+int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+ BN_CTX *new_ctx = NULL;
+ BN_MONT_CTX *mont = NULL;
+ BIGNUM *one = NULL;
+ int ret = 0;
+
+ if (group->field_data1 != NULL) {
+ BN_MONT_CTX_free(group->field_data1);
+ group->field_data1 = NULL;
+ }
+ if (group->field_data2 != NULL) {
+ BN_free(group->field_data2);
+ group->field_data2 = NULL;
+ }
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ mont = BN_MONT_CTX_new();
+ if (mont == NULL)
+ goto err;
+ if (!BN_MONT_CTX_set(mont, p, ctx)) {
+ ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
+ goto err;
+ }
+ one = BN_new();
+ if (one == NULL)
+ goto err;
+ if (!BN_to_montgomery(one, BN_value_one(), mont, ctx))
+ goto err;
+
+ group->field_data1 = mont;
+ mont = NULL;
+ group->field_data2 = one;
+ one = NULL;
+
+ ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+
+ if (!ret) {
+ BN_MONT_CTX_free(group->field_data1);
+ group->field_data1 = NULL;
+ BN_free(group->field_data2);
+ group->field_data2 = NULL;
+ }
+
+ err:
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (mont != NULL)
+ BN_MONT_CTX_free(mont);
+ return ret;
+}
+
+int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx)
+{
+ if (group->field_data1 == NULL) {
+ ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
+ return 0;
+ }
+
+ return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
+}
+
+int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *ctx)
+{
+ if (group->field_data1 == NULL) {
+ ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
+ return 0;
+ }
+
+ return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
+}
+
+int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r,
+ const BIGNUM *a, BN_CTX *ctx)
+{
+ if (group->field_data1 == NULL) {
+ ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
+ return 0;
+ }
+
+ return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
+}
+
+int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r,
+ const BIGNUM *a, BN_CTX *ctx)
+{
+ if (group->field_data1 == NULL) {
+ ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
+ return 0;
+ }
+
+ return BN_from_montgomery(r, a, group->field_data1, ctx);
+}
+
+int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r,
+ BN_CTX *ctx)
+{
+ if (group->field_data2 == NULL) {
+ ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
+ return 0;
+ }
+
+ if (!BN_copy(r, group->field_data2))
+ return 0;
+ return 1;
+}
diff --git a/openssl/ec/ecp_nist.c b/openssl/ec/ecp_nist.c
new file mode 100644
index 0000000..3944e24
--- /dev/null
+++ b/openssl/ec/ecp_nist.c
@@ -0,0 +1,220 @@
+/* crypto/ec/ecp_nist.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 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 this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <limits.h>
+
+#include <openssl/err.h>
+#include <openssl/obj_mac.h>
+#include "ec_lcl.h"
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+const EC_METHOD *EC_GFp_nist_method(void)
+{
+ static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
+ NID_X9_62_prime_field,
+ ec_GFp_simple_group_init,
+ ec_GFp_simple_group_finish,
+ ec_GFp_simple_group_clear_finish,
+ ec_GFp_nist_group_copy,
+ ec_GFp_nist_group_set_curve,
+ ec_GFp_simple_group_get_curve,
+ ec_GFp_simple_group_get_degree,
+ ec_GFp_simple_group_check_discriminant,
+ ec_GFp_simple_point_init,
+ ec_GFp_simple_point_finish,
+ ec_GFp_simple_point_clear_finish,
+ ec_GFp_simple_point_copy,
+ ec_GFp_simple_point_set_to_infinity,
+ ec_GFp_simple_set_Jprojective_coordinates_GFp,
+ ec_GFp_simple_get_Jprojective_coordinates_GFp,
+ ec_GFp_simple_point_set_affine_coordinates,
+ ec_GFp_simple_point_get_affine_coordinates,
+ 0, 0, 0,
+ ec_GFp_simple_add,
+ ec_GFp_simple_dbl,
+ ec_GFp_simple_invert,
+ ec_GFp_simple_is_at_infinity,
+ ec_GFp_simple_is_on_curve,
+ ec_GFp_simple_cmp,
+ ec_GFp_simple_make_affine,
+ ec_GFp_simple_points_make_affine,
+ 0 /* mul */ ,
+ 0 /* precompute_mult */ ,
+ 0 /* have_precompute_mult */ ,
+ ec_GFp_nist_field_mul,
+ ec_GFp_nist_field_sqr,
+ 0 /* field_div */ ,
+ 0 /* field_encode */ ,
+ 0 /* field_decode */ ,
+ 0 /* field_set_to_one */
+ };
+
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return fips_ec_gfp_nist_method();
+#endif
+
+ return &ret;
+}
+
+int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+{
+ dest->field_mod_func = src->field_mod_func;
+
+ return ec_GFp_simple_group_copy(dest, src);
+}
+
+int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp_bn;
+
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+ return 0;
+
+ BN_CTX_start(ctx);
+ if ((tmp_bn = BN_CTX_get(ctx)) == NULL)
+ goto err;
+
+ if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
+ group->field_mod_func = BN_nist_mod_192;
+ else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
+ group->field_mod_func = BN_nist_mod_224;
+ else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
+ group->field_mod_func = BN_nist_mod_256;
+ else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
+ group->field_mod_func = BN_nist_mod_384;
+ else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
+ group->field_mod_func = BN_nist_mod_521;
+ else {
+ ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
+ goto err;
+ }
+
+ ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx)
+{
+ int ret = 0;
+ BN_CTX *ctx_new = NULL;
+
+ if (!group || !r || !a || !b) {
+ ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
+ goto err;
+ }
+ if (!ctx)
+ if ((ctx_new = ctx = BN_CTX_new()) == NULL)
+ goto err;
+
+ if (!BN_mul(r, a, b, ctx))
+ goto err;
+ if (!group->field_mod_func(r, r, &group->field, ctx))
+ goto err;
+
+ ret = 1;
+ err:
+ if (ctx_new)
+ BN_CTX_free(ctx_new);
+ return ret;
+}
+
+int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *ctx)
+{
+ int ret = 0;
+ BN_CTX *ctx_new = NULL;
+
+ if (!group || !r || !a) {
+ ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
+ goto err;
+ }
+ if (!ctx)
+ if ((ctx_new = ctx = BN_CTX_new()) == NULL)
+ goto err;
+
+ if (!BN_sqr(r, a, ctx))
+ goto err;
+ if (!group->field_mod_func(r, r, &group->field, ctx))
+ goto err;
+
+ ret = 1;
+ err:
+ if (ctx_new)
+ BN_CTX_free(ctx_new);
+ return ret;
+}
diff --git a/openssl/ec/ecp_nistp224.c b/openssl/ec/ecp_nistp224.c
new file mode 100644
index 0000000..ed09f97
--- /dev/null
+++ b/openssl/ec/ecp_nistp224.c
@@ -0,0 +1,1769 @@
+/* crypto/ec/ecp_nistp224.c */
+/*
+ * Written by Emilia Kasper (Google) for the OpenSSL project.
+ */
+/* Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ *
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
+ *
+ * Inspired by Daniel J. Bernstein's public domain nistp224 implementation
+ * and Adam Langley's public domain 64-bit C implementation of curve25519
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+
+# ifndef OPENSSL_SYS_VMS
+# include <stdint.h>
+# else
+# include <inttypes.h>
+# endif
+
+# include <string.h>
+# include <openssl/err.h>
+# include "ec_lcl.h"
+
+# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+ /* even with gcc, the typedef won't work for 32-bit platforms */
+typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit
+ * platforms */
+# else
+# error "Need GCC 3.1 or later to define type uint128_t"
+# endif
+
+typedef uint8_t u8;
+typedef uint64_t u64;
+typedef int64_t s64;
+
+/******************************************************************************/
+/*-
+ * INTERNAL REPRESENTATION OF FIELD ELEMENTS
+ *
+ * Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3
+ * using 64-bit coefficients called 'limbs',
+ * and sometimes (for multiplication results) as
+ * b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 + 2^336*b_6
+ * using 128-bit coefficients called 'widelimbs'.
+ * A 4-limb representation is an 'felem';
+ * a 7-widelimb representation is a 'widefelem'.
+ * Even within felems, bits of adjacent limbs overlap, and we don't always
+ * reduce the representations: we ensure that inputs to each felem
+ * multiplication satisfy a_i < 2^60, so outputs satisfy b_i < 4*2^60*2^60,
+ * and fit into a 128-bit word without overflow. The coefficients are then
+ * again partially reduced to obtain an felem satisfying a_i < 2^57.
+ * We only reduce to the unique minimal representation at the end of the
+ * computation.
+ */
+
+typedef uint64_t limb;
+typedef uint128_t widelimb;
+
+typedef limb felem[4];
+typedef widelimb widefelem[7];
+
+/*
+ * Field element represented as a byte arrary. 28*8 = 224 bits is also the
+ * group order size for the elliptic curve, and we also use this type for
+ * scalars for point multiplication.
+ */
+typedef u8 felem_bytearray[28];
+
+static const felem_bytearray nistp224_curve_params[5] = {
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE},
+ {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, /* b */
+ 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA,
+ 0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4},
+ {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, /* x */
+ 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22,
+ 0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21},
+ {0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, /* y */
+ 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
+ 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34}
+};
+
+/*-
+ * Precomputed multiples of the standard generator
+ * Points are given in coordinates (X, Y, Z) where Z normally is 1
+ * (0 for the point at infinity).
+ * For each field element, slice a_0 is word 0, etc.
+ *
+ * The table has 2 * 16 elements, starting with the following:
+ * index | bits | point
+ * ------+---------+------------------------------
+ * 0 | 0 0 0 0 | 0G
+ * 1 | 0 0 0 1 | 1G
+ * 2 | 0 0 1 0 | 2^56G
+ * 3 | 0 0 1 1 | (2^56 + 1)G
+ * 4 | 0 1 0 0 | 2^112G
+ * 5 | 0 1 0 1 | (2^112 + 1)G
+ * 6 | 0 1 1 0 | (2^112 + 2^56)G
+ * 7 | 0 1 1 1 | (2^112 + 2^56 + 1)G
+ * 8 | 1 0 0 0 | 2^168G
+ * 9 | 1 0 0 1 | (2^168 + 1)G
+ * 10 | 1 0 1 0 | (2^168 + 2^56)G
+ * 11 | 1 0 1 1 | (2^168 + 2^56 + 1)G
+ * 12 | 1 1 0 0 | (2^168 + 2^112)G
+ * 13 | 1 1 0 1 | (2^168 + 2^112 + 1)G
+ * 14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G
+ * 15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G
+ * followed by a copy of this with each element multiplied by 2^28.
+ *
+ * The reason for this is so that we can clock bits into four different
+ * locations when doing simple scalar multiplies against the base point,
+ * and then another four locations using the second 16 elements.
+ */
+static const felem gmul[2][16][3] = { {{{0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+ {{0x3280d6115c1d21, 0xc1d356c2112234,
+ 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
+ {0xd5819985007e34, 0x75a05a07476444,
+ 0xfb4c22dfe6cd43, 0xbd376388b5f723},
+ {1, 0, 0, 0}},
+ {{0xfd9675666ebbe9, 0xbca7664d40ce5e,
+ 0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
+ {0x29e0b892dc9c43, 0xece8608436e662,
+ 0xdc858f185310d0, 0x9812dd4eb8d321},
+ {1, 0, 0, 0}},
+ {{0x6d3e678d5d8eb8, 0x559eed1cb362f1,
+ 0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
+ {0xf19f90ed50266d, 0xabf2b4bf65f9df,
+ 0x313865468fafec, 0x5cb379ba910a17},
+ {1, 0, 0, 0}},
+ {{0x0641966cab26e3, 0x91fb2991fab0a0,
+ 0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
+ {0x7510407766af5d, 0x84d929610d5450,
+ 0x81d77aae82f706, 0x6916f6d4338c5b},
+ {1, 0, 0, 0}},
+ {{0xea95ac3b1f15c6, 0x086000905e82d4,
+ 0xdd323ae4d1c8b1, 0x932b56be7685a3},
+ {0x9ef93dea25dbbf, 0x41665960f390f0,
+ 0xfdec76dbe2a8a7, 0x523e80f019062a},
+ {1, 0, 0, 0}},
+ {{0x822fdd26732c73, 0xa01c83531b5d0f,
+ 0x363f37347c1ba4, 0xc391b45c84725c},
+ {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec,
+ 0xc393da7e222a7f, 0x1efb7890ede244},
+ {1, 0, 0, 0}},
+ {{0x4c9e90ca217da1, 0xd11beca79159bb,
+ 0xff8d33c2c98b7c, 0x2610b39409f849},
+ {0x44d1352ac64da0, 0xcdbb7b2c46b4fb,
+ 0x966c079b753c89, 0xfe67e4e820b112},
+ {1, 0, 0, 0}},
+ {{0xe28cae2df5312d, 0xc71b61d16f5c6e,
+ 0x79b7619a3e7c4c, 0x05c73240899b47},
+ {0x9f7f6382c73e3a, 0x18615165c56bda,
+ 0x641fab2116fd56, 0x72855882b08394},
+ {1, 0, 0, 0}},
+ {{0x0469182f161c09, 0x74a98ca8d00fb5,
+ 0xb89da93489a3e0, 0x41c98768fb0c1d},
+ {0xe5ea05fb32da81, 0x3dce9ffbca6855,
+ 0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
+ {1, 0, 0, 0}},
+ {{0xdab22b2333e87f, 0x4430137a5dd2f6,
+ 0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
+ {0x764a7df0c8fda5, 0x185ba5c3fa2044,
+ 0x9281d688bcbe50, 0xc40331df893881},
+ {1, 0, 0, 0}},
+ {{0xb89530796f0f60, 0xade92bd26909a3,
+ 0x1a0c83fb4884da, 0x1765bf22a5a984},
+ {0x772a9ee75db09e, 0x23bc6c67cec16f,
+ 0x4c1edba8b14e2f, 0xe2a215d9611369},
+ {1, 0, 0, 0}},
+ {{0x571e509fb5efb3, 0xade88696410552,
+ 0xc8ae85fada74fe, 0x6c7e4be83bbde3},
+ {0xff9f51160f4652, 0xb47ce2495a6539,
+ 0xa2946c53b582f4, 0x286d2db3ee9a60},
+ {1, 0, 0, 0}},
+ {{0x40bbd5081a44af, 0x0995183b13926c,
+ 0xbcefba6f47f6d0, 0x215619e9cc0057},
+ {0x8bc94d3b0df45e, 0xf11c54a3694f6f,
+ 0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
+ {1, 0, 0, 0}},
+ {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8,
+ 0x1c29819435d2c6, 0xc813132f4c07e9},
+ {0x2891425503b11f, 0x08781030579fea,
+ 0xf5426ba5cc9674, 0x1e28ebf18562bc},
+ {1, 0, 0, 0}},
+ {{0x9f31997cc864eb, 0x06cd91d28b5e4c,
+ 0xff17036691a973, 0xf1aef351497c58},
+ {0xdd1f2d600564ff, 0xdead073b1402db,
+ 0x74a684435bd693, 0xeea7471f962558},
+ {1, 0, 0, 0}}},
+{{{0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+ {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31},
+ {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d},
+ {1, 0, 0, 0}},
+ {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3},
+ {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a},
+ {1, 0, 0, 0}},
+ {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33},
+ {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100},
+ {1, 0, 0, 0}},
+ {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5},
+ {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea},
+ {1, 0, 0, 0}},
+ {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be},
+ {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51},
+ {1, 0, 0, 0}},
+ {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1},
+ {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb},
+ {1, 0, 0, 0}},
+ {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233},
+ {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def},
+ {1, 0, 0, 0}},
+ {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae},
+ {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45},
+ {1, 0, 0, 0}},
+ {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e},
+ {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb},
+ {1, 0, 0, 0}},
+ {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de},
+ {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3},
+ {1, 0, 0, 0}},
+ {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05},
+ {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58},
+ {1, 0, 0, 0}},
+ {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb},
+ {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0},
+ {1, 0, 0, 0}},
+ {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9},
+ {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea},
+ {1, 0, 0, 0}},
+ {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba},
+ {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405},
+ {1, 0, 0, 0}},
+ {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e},
+ {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
+ {1, 0, 0, 0}}}
+};
+
+/* Precomputation for the group generator. */
+typedef struct {
+ felem g_pre_comp[2][16][3];
+ int references;
+} NISTP224_PRE_COMP;
+
+const EC_METHOD *EC_GFp_nistp224_method(void)
+{
+ static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
+ NID_X9_62_prime_field,
+ ec_GFp_nistp224_group_init,
+ ec_GFp_simple_group_finish,
+ ec_GFp_simple_group_clear_finish,
+ ec_GFp_nist_group_copy,
+ ec_GFp_nistp224_group_set_curve,
+ ec_GFp_simple_group_get_curve,
+ ec_GFp_simple_group_get_degree,
+ ec_GFp_simple_group_check_discriminant,
+ ec_GFp_simple_point_init,
+ ec_GFp_simple_point_finish,
+ ec_GFp_simple_point_clear_finish,
+ ec_GFp_simple_point_copy,
+ ec_GFp_simple_point_set_to_infinity,
+ ec_GFp_simple_set_Jprojective_coordinates_GFp,
+ ec_GFp_simple_get_Jprojective_coordinates_GFp,
+ ec_GFp_simple_point_set_affine_coordinates,
+ ec_GFp_nistp224_point_get_affine_coordinates,
+ 0 /* point_set_compressed_coordinates */ ,
+ 0 /* point2oct */ ,
+ 0 /* oct2point */ ,
+ ec_GFp_simple_add,
+ ec_GFp_simple_dbl,
+ ec_GFp_simple_invert,
+ ec_GFp_simple_is_at_infinity,
+ ec_GFp_simple_is_on_curve,
+ ec_GFp_simple_cmp,
+ ec_GFp_simple_make_affine,
+ ec_GFp_simple_points_make_affine,
+ ec_GFp_nistp224_points_mul,
+ ec_GFp_nistp224_precompute_mult,
+ ec_GFp_nistp224_have_precompute_mult,
+ ec_GFp_nist_field_mul,
+ ec_GFp_nist_field_sqr,
+ 0 /* field_div */ ,
+ 0 /* field_encode */ ,
+ 0 /* field_decode */ ,
+ 0 /* field_set_to_one */
+ };
+
+ return &ret;
+}
+
+/*
+ * Helper functions to convert field elements to/from internal representation
+ */
+static void bin28_to_felem(felem out, const u8 in[28])
+{
+ out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
+ out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff;
+ out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff;
+ out[3] = (*((const uint64_t *)(in+20))) >> 8;
+}
+
+static void felem_to_bin28(u8 out[28], const felem in)
+{
+ unsigned i;
+ for (i = 0; i < 7; ++i) {
+ out[i] = in[0] >> (8 * i);
+ out[i + 7] = in[1] >> (8 * i);
+ out[i + 14] = in[2] >> (8 * i);
+ out[i + 21] = in[3] >> (8 * i);
+ }
+}
+
+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
+static void flip_endian(u8 *out, const u8 *in, unsigned len)
+{
+ unsigned i;
+ for (i = 0; i < len; ++i)
+ out[i] = in[len - 1 - i];
+}
+
+/* From OpenSSL BIGNUM to internal representation */
+static int BN_to_felem(felem out, const BIGNUM *bn)
+{
+ felem_bytearray b_in;
+ felem_bytearray b_out;
+ unsigned num_bytes;
+
+ /* BN_bn2bin eats leading zeroes */
+ memset(b_out, 0, sizeof b_out);
+ num_bytes = BN_num_bytes(bn);
+ if (num_bytes > sizeof b_out) {
+ ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+ if (BN_is_negative(bn)) {
+ ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+ num_bytes = BN_bn2bin(bn, b_in);
+ flip_endian(b_out, b_in, num_bytes);
+ bin28_to_felem(out, b_out);
+ return 1;
+}
+
+/* From internal representation to OpenSSL BIGNUM */
+static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
+{
+ felem_bytearray b_in, b_out;
+ felem_to_bin28(b_in, in);
+ flip_endian(b_out, b_in, sizeof b_out);
+ return BN_bin2bn(b_out, sizeof b_out, out);
+}
+
+/******************************************************************************/
+/*-
+ * FIELD OPERATIONS
+ *
+ * Field operations, using the internal representation of field elements.
+ * NB! These operations are specific to our point multiplication and cannot be
+ * expected to be correct in general - e.g., multiplication with a large scalar
+ * will cause an overflow.
+ *
+ */
+
+static void felem_one(felem out)
+{
+ out[0] = 1;
+ out[1] = 0;
+ out[2] = 0;
+ out[3] = 0;
+}
+
+static void felem_assign(felem out, const felem in)
+{
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+}
+
+/* Sum two field elements: out += in */
+static void felem_sum(felem out, const felem in)
+{
+ out[0] += in[0];
+ out[1] += in[1];
+ out[2] += in[2];
+ out[3] += in[3];
+}
+
+/* Get negative value: out = -in */
+/* Assumes in[i] < 2^57 */
+static void felem_neg(felem out, const felem in)
+{
+ static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
+ static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
+ static const limb two58m42m2 = (((limb) 1) << 58) -
+ (((limb) 1) << 42) - (((limb) 1) << 2);
+
+ /* Set to 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] = two58p2 - in[0];
+ out[1] = two58m42m2 - in[1];
+ out[2] = two58m2 - in[2];
+ out[3] = two58m2 - in[3];
+}
+
+/* Subtract field elements: out -= in */
+/* Assumes in[i] < 2^57 */
+static void felem_diff(felem out, const felem in)
+{
+ static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
+ static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
+ static const limb two58m42m2 = (((limb) 1) << 58) -
+ (((limb) 1) << 42) - (((limb) 1) << 2);
+
+ /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] += two58p2;
+ out[1] += two58m42m2;
+ out[2] += two58m2;
+ out[3] += two58m2;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+}
+
+/* Subtract in unreduced 128-bit mode: out -= in */
+/* Assumes in[i] < 2^119 */
+static void widefelem_diff(widefelem out, const widefelem in)
+{
+ static const widelimb two120 = ((widelimb) 1) << 120;
+ static const widelimb two120m64 = (((widelimb) 1) << 120) -
+ (((widelimb) 1) << 64);
+ static const widelimb two120m104m64 = (((widelimb) 1) << 120) -
+ (((widelimb) 1) << 104) - (((widelimb) 1) << 64);
+
+ /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] += two120;
+ out[1] += two120m64;
+ out[2] += two120m64;
+ out[3] += two120;
+ out[4] += two120m104m64;
+ out[5] += two120m64;
+ out[6] += two120m64;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+ out[4] -= in[4];
+ out[5] -= in[5];
+ out[6] -= in[6];
+}
+
+/* Subtract in mixed mode: out128 -= in64 */
+/* in[i] < 2^63 */
+static void felem_diff_128_64(widefelem out, const felem in)
+{
+ static const widelimb two64p8 = (((widelimb) 1) << 64) +
+ (((widelimb) 1) << 8);
+ static const widelimb two64m8 = (((widelimb) 1) << 64) -
+ (((widelimb) 1) << 8);
+ static const widelimb two64m48m8 = (((widelimb) 1) << 64) -
+ (((widelimb) 1) << 48) - (((widelimb) 1) << 8);
+
+ /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+ out[0] += two64p8;
+ out[1] += two64m48m8;
+ out[2] += two64m8;
+ out[3] += two64m8;
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+}
+
+/*
+ * Multiply a field element by a scalar: out = out * scalar The scalars we
+ * actually use are small, so results fit without overflow
+ */
+static void felem_scalar(felem out, const limb scalar)
+{
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+}
+
+/*
+ * Multiply an unreduced field element by a scalar: out = out * scalar The
+ * scalars we actually use are small, so results fit without overflow
+ */
+static void widefelem_scalar(widefelem out, const widelimb scalar)
+{
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+ out[4] *= scalar;
+ out[5] *= scalar;
+ out[6] *= scalar;
+}
+
+/* Square a field element: out = in^2 */
+static void felem_square(widefelem out, const felem in)
+{
+ limb tmp0, tmp1, tmp2;
+ tmp0 = 2 * in[0];
+ tmp1 = 2 * in[1];
+ tmp2 = 2 * in[2];
+ out[0] = ((widelimb) in[0]) * in[0];
+ out[1] = ((widelimb) in[0]) * tmp1;
+ out[2] = ((widelimb) in[0]) * tmp2 + ((widelimb) in[1]) * in[1];
+ out[3] = ((widelimb) in[3]) * tmp0 + ((widelimb) in[1]) * tmp2;
+ out[4] = ((widelimb) in[3]) * tmp1 + ((widelimb) in[2]) * in[2];
+ out[5] = ((widelimb) in[3]) * tmp2;
+ out[6] = ((widelimb) in[3]) * in[3];
+}
+
+/* Multiply two field elements: out = in1 * in2 */
+static void felem_mul(widefelem out, const felem in1, const felem in2)
+{
+ out[0] = ((widelimb) in1[0]) * in2[0];
+ out[1] = ((widelimb) in1[0]) * in2[1] + ((widelimb) in1[1]) * in2[0];
+ out[2] = ((widelimb) in1[0]) * in2[2] + ((widelimb) in1[1]) * in2[1] +
+ ((widelimb) in1[2]) * in2[0];
+ out[3] = ((widelimb) in1[0]) * in2[3] + ((widelimb) in1[1]) * in2[2] +
+ ((widelimb) in1[2]) * in2[1] + ((widelimb) in1[3]) * in2[0];
+ out[4] = ((widelimb) in1[1]) * in2[3] + ((widelimb) in1[2]) * in2[2] +
+ ((widelimb) in1[3]) * in2[1];
+ out[5] = ((widelimb) in1[2]) * in2[3] + ((widelimb) in1[3]) * in2[2];
+ out[6] = ((widelimb) in1[3]) * in2[3];
+}
+
+/*-
+ * Reduce seven 128-bit coefficients to four 64-bit coefficients.
+ * Requires in[i] < 2^126,
+ * ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 */
+static void felem_reduce(felem out, const widefelem in)
+{
+ static const widelimb two127p15 = (((widelimb) 1) << 127) +
+ (((widelimb) 1) << 15);
+ static const widelimb two127m71 = (((widelimb) 1) << 127) -
+ (((widelimb) 1) << 71);
+ static const widelimb two127m71m55 = (((widelimb) 1) << 127) -
+ (((widelimb) 1) << 71) - (((widelimb) 1) << 55);
+ widelimb output[5];
+
+ /* Add 0 mod 2^224-2^96+1 to ensure all differences are positive */
+ output[0] = in[0] + two127p15;
+ output[1] = in[1] + two127m71m55;
+ output[2] = in[2] + two127m71;
+ output[3] = in[3];
+ output[4] = in[4];
+
+ /* Eliminate in[4], in[5], in[6] */
+ output[4] += in[6] >> 16;
+ output[3] += (in[6] & 0xffff) << 40;
+ output[2] -= in[6];
+
+ output[3] += in[5] >> 16;
+ output[2] += (in[5] & 0xffff) << 40;
+ output[1] -= in[5];
+
+ output[2] += output[4] >> 16;
+ output[1] += (output[4] & 0xffff) << 40;
+ output[0] -= output[4];
+
+ /* Carry 2 -> 3 -> 4 */
+ output[3] += output[2] >> 56;
+ output[2] &= 0x00ffffffffffffff;
+
+ output[4] = output[3] >> 56;
+ output[3] &= 0x00ffffffffffffff;
+
+ /* Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72 */
+
+ /* Eliminate output[4] */
+ output[2] += output[4] >> 16;
+ /* output[2] < 2^56 + 2^56 = 2^57 */
+ output[1] += (output[4] & 0xffff) << 40;
+ output[0] -= output[4];
+
+ /* Carry 0 -> 1 -> 2 -> 3 */
+ output[1] += output[0] >> 56;
+ out[0] = output[0] & 0x00ffffffffffffff;
+
+ output[2] += output[1] >> 56;
+ /* output[2] < 2^57 + 2^72 */
+ out[1] = output[1] & 0x00ffffffffffffff;
+ output[3] += output[2] >> 56;
+ /* output[3] <= 2^56 + 2^16 */
+ out[2] = output[2] & 0x00ffffffffffffff;
+
+ /*-
+ * out[0] < 2^56, out[1] < 2^56, out[2] < 2^56,
+ * out[3] <= 2^56 + 2^16 (due to final carry),
+ * so out < 2*p
+ */
+ out[3] = output[3];
+}
+
+static void felem_square_reduce(felem out, const felem in)
+{
+ widefelem tmp;
+ felem_square(tmp, in);
+ felem_reduce(out, tmp);
+}
+
+static void felem_mul_reduce(felem out, const felem in1, const felem in2)
+{
+ widefelem tmp;
+ felem_mul(tmp, in1, in2);
+ felem_reduce(out, tmp);
+}
+
+/*
+ * Reduce to unique minimal representation. Requires 0 <= in < 2*p (always
+ * call felem_reduce first)
+ */
+static void felem_contract(felem out, const felem in)
+{
+ static const int64_t two56 = ((limb) 1) << 56;
+ /* 0 <= in < 2*p, p = 2^224 - 2^96 + 1 */
+ /* if in > p , reduce in = in - 2^224 + 2^96 - 1 */
+ int64_t tmp[4], a;
+ tmp[0] = in[0];
+ tmp[1] = in[1];
+ tmp[2] = in[2];
+ tmp[3] = in[3];
+ /* Case 1: a = 1 iff in >= 2^224 */
+ a = (in[3] >> 56);
+ tmp[0] -= a;
+ tmp[1] += a << 40;
+ tmp[3] &= 0x00ffffffffffffff;
+ /*
+ * Case 2: a = 0 iff p <= in < 2^224, i.e., the high 128 bits are all 1
+ * and the lower part is non-zero
+ */
+ a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) |
+ (((int64_t) (in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63);
+ a &= 0x00ffffffffffffff;
+ /* turn a into an all-one mask (if a = 0) or an all-zero mask */
+ a = (a - 1) >> 63;
+ /* subtract 2^224 - 2^96 + 1 if a is all-one */
+ tmp[3] &= a ^ 0xffffffffffffffff;
+ tmp[2] &= a ^ 0xffffffffffffffff;
+ tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff;
+ tmp[0] -= 1 & a;
+
+ /*
+ * eliminate negative coefficients: if tmp[0] is negative, tmp[1] must be
+ * non-zero, so we only need one step
+ */
+ a = tmp[0] >> 63;
+ tmp[0] += two56 & a;
+ tmp[1] -= 1 & a;
+
+ /* carry 1 -> 2 -> 3 */
+ tmp[2] += tmp[1] >> 56;
+ tmp[1] &= 0x00ffffffffffffff;
+
+ tmp[3] += tmp[2] >> 56;
+ tmp[2] &= 0x00ffffffffffffff;
+
+ /* Now 0 <= out < p */
+ out[0] = tmp[0];
+ out[1] = tmp[1];
+ out[2] = tmp[2];
+ out[3] = tmp[3];
+}
+
+/*
+ * Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field
+ * elements are reduced to in < 2^225, so we only need to check three cases:
+ * 0, 2^224 - 2^96 + 1, and 2^225 - 2^97 + 2
+ */
+static limb felem_is_zero(const felem in)
+{
+ limb zero, two224m96p1, two225m97p2;
+
+ zero = in[0] | in[1] | in[2] | in[3];
+ zero = (((int64_t) (zero) - 1) >> 63) & 1;
+ two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000)
+ | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x00ffffffffffffff);
+ two224m96p1 = (((int64_t) (two224m96p1) - 1) >> 63) & 1;
+ two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000)
+ | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x01ffffffffffffff);
+ two225m97p2 = (((int64_t) (two225m97p2) - 1) >> 63) & 1;
+ return (zero | two224m96p1 | two225m97p2);
+}
+
+static limb felem_is_zero_int(const felem in)
+{
+ return (int)(felem_is_zero(in) & ((limb) 1));
+}
+
+/* Invert a field element */
+/* Computation chain copied from djb's code */
+static void felem_inv(felem out, const felem in)
+{
+ felem ftmp, ftmp2, ftmp3, ftmp4;
+ widefelem tmp;
+ unsigned i;
+
+ felem_square(tmp, in);
+ felem_reduce(ftmp, tmp); /* 2 */
+ felem_mul(tmp, in, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^2 - 1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^3 - 2 */
+ felem_mul(tmp, in, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^3 - 1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp2, tmp); /* 2^4 - 2 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp); /* 2^5 - 4 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp); /* 2^6 - 8 */
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^6 - 1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp2, tmp); /* 2^7 - 2 */
+ for (i = 0; i < 5; ++i) { /* 2^12 - 2^6 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp);
+ }
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(ftmp2, tmp); /* 2^12 - 1 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^13 - 2 */
+ for (i = 0; i < 11; ++i) { /* 2^24 - 2^12 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp);
+ }
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp2, tmp); /* 2^24 - 1 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^25 - 2 */
+ for (i = 0; i < 23; ++i) { /* 2^48 - 2^24 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp);
+ }
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^48 - 1 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp4, tmp); /* 2^49 - 2 */
+ for (i = 0; i < 47; ++i) { /* 2^96 - 2^48 */
+ felem_square(tmp, ftmp4);
+ felem_reduce(ftmp4, tmp);
+ }
+ felem_mul(tmp, ftmp3, ftmp4);
+ felem_reduce(ftmp3, tmp); /* 2^96 - 1 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp4, tmp); /* 2^97 - 2 */
+ for (i = 0; i < 23; ++i) { /* 2^120 - 2^24 */
+ felem_square(tmp, ftmp4);
+ felem_reduce(ftmp4, tmp);
+ }
+ felem_mul(tmp, ftmp2, ftmp4);
+ felem_reduce(ftmp2, tmp); /* 2^120 - 1 */
+ for (i = 0; i < 6; ++i) { /* 2^126 - 2^6 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp);
+ }
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^126 - 1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^127 - 2 */
+ felem_mul(tmp, ftmp, in);
+ felem_reduce(ftmp, tmp); /* 2^127 - 1 */
+ for (i = 0; i < 97; ++i) { /* 2^224 - 2^97 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp);
+ }
+ felem_mul(tmp, ftmp, ftmp3);
+ felem_reduce(out, tmp); /* 2^224 - 2^96 - 1 */
+}
+
+/*
+ * Copy in constant time: if icopy == 1, copy in to out, if icopy == 0, copy
+ * out to itself.
+ */
+static void copy_conditional(felem out, const felem in, limb icopy)
+{
+ unsigned i;
+ /*
+ * icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one
+ */
+ const limb copy = -icopy;
+ for (i = 0; i < 4; ++i) {
+ const limb tmp = copy & (in[i] ^ out[i]);
+ out[i] ^= tmp;
+ }
+}
+
+/******************************************************************************/
+/*-
+ * ELLIPTIC CURVE POINT OPERATIONS
+ *
+ * Points are represented in Jacobian projective coordinates:
+ * (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3),
+ * or to the point at infinity if Z == 0.
+ *
+ */
+
+/*-
+ * Double an elliptic curve point:
+ * (X', Y', Z') = 2 * (X, Y, Z), where
+ * X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
+ * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
+ * Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
+ * while x_out == y_in is not (maybe this works, but it's not tested).
+ */
+static void
+point_double(felem x_out, felem y_out, felem z_out,
+ const felem x_in, const felem y_in, const felem z_in)
+{
+ widefelem tmp, tmp2;
+ felem delta, gamma, beta, alpha, ftmp, ftmp2;
+
+ felem_assign(ftmp, x_in);
+ felem_assign(ftmp2, x_in);
+
+ /* delta = z^2 */
+ felem_square(tmp, z_in);
+ felem_reduce(delta, tmp);
+
+ /* gamma = y^2 */
+ felem_square(tmp, y_in);
+ felem_reduce(gamma, tmp);
+
+ /* beta = x*gamma */
+ felem_mul(tmp, x_in, gamma);
+ felem_reduce(beta, tmp);
+
+ /* alpha = 3*(x-delta)*(x+delta) */
+ felem_diff(ftmp, delta);
+ /* ftmp[i] < 2^57 + 2^58 + 2 < 2^59 */
+ felem_sum(ftmp2, delta);
+ /* ftmp2[i] < 2^57 + 2^57 = 2^58 */
+ felem_scalar(ftmp2, 3);
+ /* ftmp2[i] < 3 * 2^58 < 2^60 */
+ felem_mul(tmp, ftmp, ftmp2);
+ /* tmp[i] < 2^60 * 2^59 * 4 = 2^121 */
+ felem_reduce(alpha, tmp);
+
+ /* x' = alpha^2 - 8*beta */
+ felem_square(tmp, alpha);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+ felem_assign(ftmp, beta);
+ felem_scalar(ftmp, 8);
+ /* ftmp[i] < 8 * 2^57 = 2^60 */
+ felem_diff_128_64(tmp, ftmp);
+ /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+ felem_reduce(x_out, tmp);
+
+ /* z' = (y + z)^2 - gamma - delta */
+ felem_sum(delta, gamma);
+ /* delta[i] < 2^57 + 2^57 = 2^58 */
+ felem_assign(ftmp, y_in);
+ felem_sum(ftmp, z_in);
+ /* ftmp[i] < 2^57 + 2^57 = 2^58 */
+ felem_square(tmp, ftmp);
+ /* tmp[i] < 4 * 2^58 * 2^58 = 2^118 */
+ felem_diff_128_64(tmp, delta);
+ /* tmp[i] < 2^118 + 2^64 + 8 < 2^119 */
+ felem_reduce(z_out, tmp);
+
+ /* y' = alpha*(4*beta - x') - 8*gamma^2 */
+ felem_scalar(beta, 4);
+ /* beta[i] < 4 * 2^57 = 2^59 */
+ felem_diff(beta, x_out);
+ /* beta[i] < 2^59 + 2^58 + 2 < 2^60 */
+ felem_mul(tmp, alpha, beta);
+ /* tmp[i] < 4 * 2^57 * 2^60 = 2^119 */
+ felem_square(tmp2, gamma);
+ /* tmp2[i] < 4 * 2^57 * 2^57 = 2^116 */
+ widefelem_scalar(tmp2, 8);
+ /* tmp2[i] < 8 * 2^116 = 2^119 */
+ widefelem_diff(tmp, tmp2);
+ /* tmp[i] < 2^119 + 2^120 < 2^121 */
+ felem_reduce(y_out, tmp);
+}
+
+/*-
+ * Add two elliptic curve points:
+ * (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where
+ * X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 -
+ * 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2
+ * Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 - X_3) -
+ * Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3
+ * Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2)
+ *
+ * This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0.
+ */
+
+/*
+ * This function is not entirely constant-time: it includes a branch for
+ * checking whether the two input points are equal, (while not equal to the
+ * point at infinity). This case never happens during single point
+ * multiplication, so there is no timing leak for ECDH or ECDSA signing.
+ */
+static void point_add(felem x3, felem y3, felem z3,
+ const felem x1, const felem y1, const felem z1,
+ const int mixed, const felem x2, const felem y2,
+ const felem z2)
+{
+ felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
+ widefelem tmp, tmp2;
+ limb z1_is_zero, z2_is_zero, x_equal, y_equal;
+
+ if (!mixed) {
+ /* ftmp2 = z2^2 */
+ felem_square(tmp, z2);
+ felem_reduce(ftmp2, tmp);
+
+ /* ftmp4 = z2^3 */
+ felem_mul(tmp, ftmp2, z2);
+ felem_reduce(ftmp4, tmp);
+
+ /* ftmp4 = z2^3*y1 */
+ felem_mul(tmp2, ftmp4, y1);
+ felem_reduce(ftmp4, tmp2);
+
+ /* ftmp2 = z2^2*x1 */
+ felem_mul(tmp2, ftmp2, x1);
+ felem_reduce(ftmp2, tmp2);
+ } else {
+ /*
+ * We'll assume z2 = 1 (special case z2 = 0 is handled later)
+ */
+
+ /* ftmp4 = z2^3*y1 */
+ felem_assign(ftmp4, y1);
+
+ /* ftmp2 = z2^2*x1 */
+ felem_assign(ftmp2, x1);
+ }
+
+ /* ftmp = z1^2 */
+ felem_square(tmp, z1);
+ felem_reduce(ftmp, tmp);
+
+ /* ftmp3 = z1^3 */
+ felem_mul(tmp, ftmp, z1);
+ felem_reduce(ftmp3, tmp);
+
+ /* tmp = z1^3*y2 */
+ felem_mul(tmp, ftmp3, y2);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+ /* ftmp3 = z1^3*y2 - z2^3*y1 */
+ felem_diff_128_64(tmp, ftmp4);
+ /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+ felem_reduce(ftmp3, tmp);
+
+ /* tmp = z1^2*x2 */
+ felem_mul(tmp, ftmp, x2);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+ /* ftmp = z1^2*x2 - z2^2*x1 */
+ felem_diff_128_64(tmp, ftmp2);
+ /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+ felem_reduce(ftmp, tmp);
+
+ /*
+ * the formulae are incorrect if the points are equal so we check for
+ * this and do doubling if this happens
+ */
+ x_equal = felem_is_zero(ftmp);
+ y_equal = felem_is_zero(ftmp3);
+ z1_is_zero = felem_is_zero(z1);
+ z2_is_zero = felem_is_zero(z2);
+ /* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */
+ if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
+ point_double(x3, y3, z3, x1, y1, z1);
+ return;
+ }
+
+ /* ftmp5 = z1*z2 */
+ if (!mixed) {
+ felem_mul(tmp, z1, z2);
+ felem_reduce(ftmp5, tmp);
+ } else {
+ /* special case z2 = 0 is handled later */
+ felem_assign(ftmp5, z1);
+ }
+
+ /* z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) */
+ felem_mul(tmp, ftmp, ftmp5);
+ felem_reduce(z_out, tmp);
+
+ /* ftmp = (z1^2*x2 - z2^2*x1)^2 */
+ felem_assign(ftmp5, ftmp);
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp);
+
+ /* ftmp5 = (z1^2*x2 - z2^2*x1)^3 */
+ felem_mul(tmp, ftmp, ftmp5);
+ felem_reduce(ftmp5, tmp);
+
+ /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(ftmp2, tmp);
+
+ /* tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
+ felem_mul(tmp, ftmp4, ftmp5);
+ /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+ /* tmp2 = (z1^3*y2 - z2^3*y1)^2 */
+ felem_square(tmp2, ftmp3);
+ /* tmp2[i] < 4 * 2^57 * 2^57 < 2^116 */
+
+ /* tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 */
+ felem_diff_128_64(tmp2, ftmp5);
+ /* tmp2[i] < 2^116 + 2^64 + 8 < 2^117 */
+
+ /* ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+ felem_assign(ftmp5, ftmp2);
+ felem_scalar(ftmp5, 2);
+ /* ftmp5[i] < 2 * 2^57 = 2^58 */
+
+ /*-
+ * x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 -
+ * 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2
+ */
+ felem_diff_128_64(tmp2, ftmp5);
+ /* tmp2[i] < 2^117 + 2^64 + 8 < 2^118 */
+ felem_reduce(x_out, tmp2);
+
+ /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out */
+ felem_diff(ftmp2, x_out);
+ /* ftmp2[i] < 2^57 + 2^58 + 2 < 2^59 */
+
+ /*
+ * tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out)
+ */
+ felem_mul(tmp2, ftmp3, ftmp2);
+ /* tmp2[i] < 4 * 2^57 * 2^59 = 2^118 */
+
+ /*-
+ * y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) -
+ * z2^3*y1*(z1^2*x2 - z2^2*x1)^3
+ */
+ widefelem_diff(tmp2, tmp);
+ /* tmp2[i] < 2^118 + 2^120 < 2^121 */
+ felem_reduce(y_out, tmp2);
+
+ /*
+ * the result (x_out, y_out, z_out) is incorrect if one of the inputs is
+ * the point at infinity, so we need to check for this separately
+ */
+
+ /*
+ * if point 1 is at infinity, copy point 2 to output, and vice versa
+ */
+ copy_conditional(x_out, x2, z1_is_zero);
+ copy_conditional(x_out, x1, z2_is_zero);
+ copy_conditional(y_out, y2, z1_is_zero);
+ copy_conditional(y_out, y1, z2_is_zero);
+ copy_conditional(z_out, z2, z1_is_zero);
+ copy_conditional(z_out, z1, z2_is_zero);
+ felem_assign(x3, x_out);
+ felem_assign(y3, y_out);
+ felem_assign(z3, z_out);
+}
+
+/*
+ * select_point selects the |idx|th point from a precomputation table and
+ * copies it to out.
+ * The pre_comp array argument should be size of |size| argument
+ */
+static void select_point(const u64 idx, unsigned int size,
+ const felem pre_comp[][3], felem out[3])
+{
+ unsigned i, j;
+ limb *outlimbs = &out[0][0];
+ memset(outlimbs, 0, 3 * sizeof(felem));
+
+ for (i = 0; i < size; i++) {
+ const limb *inlimbs = &pre_comp[i][0][0];
+ u64 mask = i ^ idx;
+ mask |= mask >> 4;
+ mask |= mask >> 2;
+ mask |= mask >> 1;
+ mask &= 1;
+ mask--;
+ for (j = 0; j < 4 * 3; j++)
+ outlimbs[j] |= inlimbs[j] & mask;
+ }
+}
+
+/* get_bit returns the |i|th bit in |in| */
+static char get_bit(const felem_bytearray in, unsigned i)
+{
+ if (i >= 224)
+ return 0;
+ return (in[i >> 3] >> (i & 7)) & 1;
+}
+
+/*
+ * Interleaved point multiplication using precomputed point multiples: The
+ * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars
+ * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the
+ * generator, using certain (large) precomputed multiples in g_pre_comp.
+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out
+ */
+static void batch_mul(felem x_out, felem y_out, felem z_out,
+ const felem_bytearray scalars[],
+ const unsigned num_points, const u8 *g_scalar,
+ const int mixed, const felem pre_comp[][17][3],
+ const felem g_pre_comp[2][16][3])
+{
+ int i, skip;
+ unsigned num;
+ unsigned gen_mul = (g_scalar != NULL);
+ felem nq[3], tmp[4];
+ u64 bits;
+ u8 sign, digit;
+
+ /* set nq to the point at infinity */
+ memset(nq, 0, 3 * sizeof(felem));
+
+ /*
+ * Loop over all scalars msb-to-lsb, interleaving additions of multiples
+ * of the generator (two in each of the last 28 rounds) and additions of
+ * other points multiples (every 5th round).
+ */
+ skip = 1; /* save two point operations in the first
+ * round */
+ for (i = (num_points ? 220 : 27); i >= 0; --i) {
+ /* double */
+ if (!skip)
+ point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+
+ /* add multiples of the generator */
+ if (gen_mul && (i <= 27)) {
+ /* first, look 28 bits upwards */
+ bits = get_bit(g_scalar, i + 196) << 3;
+ bits |= get_bit(g_scalar, i + 140) << 2;
+ bits |= get_bit(g_scalar, i + 84) << 1;
+ bits |= get_bit(g_scalar, i + 28);
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp[1], tmp);
+
+ if (!skip) {
+ /* value 1 below is argument for "mixed" */
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]);
+ } else {
+ memcpy(nq, tmp, 3 * sizeof(felem));
+ skip = 0;
+ }
+
+ /* second, look at the current position */
+ bits = get_bit(g_scalar, i + 168) << 3;
+ bits |= get_bit(g_scalar, i + 112) << 2;
+ bits |= get_bit(g_scalar, i + 56) << 1;
+ bits |= get_bit(g_scalar, i);
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp[0], tmp);
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2],
+ 1 /* mixed */ , tmp[0], tmp[1], tmp[2]);
+ }
+
+ /* do other additions every 5 doublings */
+ if (num_points && (i % 5 == 0)) {
+ /* loop over all scalars */
+ for (num = 0; num < num_points; ++num) {
+ bits = get_bit(scalars[num], i + 4) << 5;
+ bits |= get_bit(scalars[num], i + 3) << 4;
+ bits |= get_bit(scalars[num], i + 2) << 3;
+ bits |= get_bit(scalars[num], i + 1) << 2;
+ bits |= get_bit(scalars[num], i) << 1;
+ bits |= get_bit(scalars[num], i - 1);
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+ /* select the point to add or subtract */
+ select_point(digit, 17, pre_comp[num], tmp);
+ felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative
+ * point */
+ copy_conditional(tmp[1], tmp[3], sign);
+
+ if (!skip) {
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2],
+ mixed, tmp[0], tmp[1], tmp[2]);
+ } else {
+ memcpy(nq, tmp, 3 * sizeof(felem));
+ skip = 0;
+ }
+ }
+ }
+ }
+ felem_assign(x_out, nq[0]);
+ felem_assign(y_out, nq[1]);
+ felem_assign(z_out, nq[2]);
+}
+
+/******************************************************************************/
+/*
+ * FUNCTIONS TO MANAGE PRECOMPUTATION
+ */
+
+static NISTP224_PRE_COMP *nistp224_pre_comp_new()
+{
+ NISTP224_PRE_COMP *ret = NULL;
+ ret = (NISTP224_PRE_COMP *) OPENSSL_malloc(sizeof *ret);
+ if (!ret) {
+ ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ return ret;
+ }
+ memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
+ ret->references = 1;
+ return ret;
+}
+
+static void *nistp224_pre_comp_dup(void *src_)
+{
+ NISTP224_PRE_COMP *src = src_;
+
+ /* no need to actually copy, these objects never change! */
+ CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+
+ return src_;
+}
+
+static void nistp224_pre_comp_free(void *pre_)
+{
+ int i;
+ NISTP224_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ OPENSSL_free(pre);
+}
+
+static void nistp224_pre_comp_clear_free(void *pre_)
+{
+ int i;
+ NISTP224_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ OPENSSL_cleanse(pre, sizeof *pre);
+ OPENSSL_free(pre);
+}
+
+/******************************************************************************/
+/*
+ * OPENSSL EC_METHOD FUNCTIONS
+ */
+
+int ec_GFp_nistp224_group_init(EC_GROUP *group)
+{
+ int ret;
+ ret = ec_GFp_simple_group_init(group);
+ group->a_is_minus3 = 1;
+ return ret;
+}
+
+int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *ctx)
+{
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *curve_p, *curve_a, *curve_b;
+
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+ return 0;
+ BN_CTX_start(ctx);
+ if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_a = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_b = BN_CTX_get(ctx)) == NULL))
+ goto err;
+ BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p);
+ BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a);
+ BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b);
+ if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
+ ECerr(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE,
+ EC_R_WRONG_CURVE_PARAMETERS);
+ goto err;
+ }
+ group->field_mod_func = BN_nist_mod_224;
+ ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+/*
+ * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
+ * (X/Z^2, Y/Z^3)
+ */
+int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx)
+{
+ felem z1, z2, x_in, y_in, x_out, y_out;
+ widefelem tmp;
+
+ if (EC_POINT_is_at_infinity(group, point)) {
+ ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
+ EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+ if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
+ (!BN_to_felem(z1, &point->Z)))
+ return 0;
+ felem_inv(z2, z1);
+ felem_square(tmp, z2);
+ felem_reduce(z1, tmp);
+ felem_mul(tmp, x_in, z1);
+ felem_reduce(x_in, tmp);
+ felem_contract(x_out, x_in);
+ if (x != NULL) {
+ if (!felem_to_BN(x, x_out)) {
+ ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
+ ERR_R_BN_LIB);
+ return 0;
+ }
+ }
+ felem_mul(tmp, z1, z2);
+ felem_reduce(z1, tmp);
+ felem_mul(tmp, y_in, z1);
+ felem_reduce(y_in, tmp);
+ felem_contract(y_out, y_in);
+ if (y != NULL) {
+ if (!felem_to_BN(y, y_out)) {
+ ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
+ ERR_R_BN_LIB);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void make_points_affine(size_t num, felem points[ /* num */ ][3],
+ felem tmp_felems[ /* num+1 */ ])
+{
+ /*
+ * Runs in constant time, unless an input is the point at infinity (which
+ * normally shouldn't happen).
+ */
+ ec_GFp_nistp_points_make_affine_internal(num,
+ points,
+ sizeof(felem),
+ tmp_felems,
+ (void (*)(void *))felem_one,
+ (int (*)(const void *))
+ felem_is_zero_int,
+ (void (*)(void *, const void *))
+ felem_assign,
+ (void (*)(void *, const void *))
+ felem_square_reduce, (void (*)
+ (void *,
+ const void
+ *,
+ const void
+ *))
+ felem_mul_reduce,
+ (void (*)(void *, const void *))
+ felem_inv,
+ (void (*)(void *, const void *))
+ felem_contract);
+}
+
+/*
+ * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
+ * values Result is stored in r (r can equal one of the inputs).
+ */
+int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx)
+{
+ int ret = 0;
+ int j;
+ unsigned i;
+ int mixed = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y, *z, *tmp_scalar;
+ felem_bytearray g_secret;
+ felem_bytearray *secrets = NULL;
+ felem(*pre_comp)[17][3] = NULL;
+ felem *tmp_felems = NULL;
+ felem_bytearray tmp;
+ unsigned num_bytes;
+ int have_pre_comp = 0;
+ size_t num_points = num;
+ felem x_in, y_in, z_in, x_out, y_out, z_out;
+ NISTP224_PRE_COMP *pre = NULL;
+ const felem(*g_pre_comp)[16][3] = NULL;
+ EC_POINT *generator = NULL;
+ const EC_POINT *p = NULL;
+ const BIGNUM *p_scalar = NULL;
+
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+ return 0;
+ BN_CTX_start(ctx);
+ if (((x = BN_CTX_get(ctx)) == NULL) ||
+ ((y = BN_CTX_get(ctx)) == NULL) ||
+ ((z = BN_CTX_get(ctx)) == NULL) ||
+ ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
+ goto err;
+
+ if (scalar != NULL) {
+ pre = EC_EX_DATA_get_data(group->extra_data,
+ nistp224_pre_comp_dup,
+ nistp224_pre_comp_free,
+ nistp224_pre_comp_clear_free);
+ if (pre)
+ /* we have precomputation, try to use it */
+ g_pre_comp = (const felem(*)[16][3])pre->g_pre_comp;
+ else
+ /* try to use the standard precomputation */
+ g_pre_comp = &gmul[0];
+ generator = EC_POINT_new(group);
+ if (generator == NULL)
+ goto err;
+ /* get the generator from precomputation */
+ if (!felem_to_BN(x, g_pre_comp[0][1][0]) ||
+ !felem_to_BN(y, g_pre_comp[0][1][1]) ||
+ !felem_to_BN(z, g_pre_comp[0][1][2])) {
+ ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
+ generator, x, y, z,
+ ctx))
+ goto err;
+ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
+ /* precomputation matches generator */
+ have_pre_comp = 1;
+ else
+ /*
+ * we don't have valid precomputation: treat the generator as a
+ * random point
+ */
+ num_points = num_points + 1;
+ }
+
+ if (num_points > 0) {
+ if (num_points >= 3) {
+ /*
+ * unless we precompute multiples for just one or two points,
+ * converting those into affine form is time well spent
+ */
+ mixed = 1;
+ }
+ secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
+ pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
+ if (mixed)
+ tmp_felems =
+ OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
+ if ((secrets == NULL) || (pre_comp == NULL)
+ || (mixed && (tmp_felems == NULL))) {
+ ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /*
+ * we treat NULL scalars as 0, and NULL points as points at infinity,
+ * i.e., they contribute nothing to the linear combination
+ */
+ memset(secrets, 0, num_points * sizeof(felem_bytearray));
+ memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
+ for (i = 0; i < num_points; ++i) {
+ if (i == num)
+ /* the generator */
+ {
+ p = EC_GROUP_get0_generator(group);
+ p_scalar = scalar;
+ } else
+ /* the i^th point */
+ {
+ p = points[i];
+ p_scalar = scalars[i];
+ }
+ if ((p_scalar != NULL) && (p != NULL)) {
+ /* reduce scalar to 0 <= scalar < 2^224 */
+ if ((BN_num_bits(p_scalar) > 224)
+ || (BN_is_negative(p_scalar))) {
+ /*
+ * this is an unusual input, and we don't guarantee
+ * constant-timeness
+ */
+ if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) {
+ ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ } else
+ num_bytes = BN_bn2bin(p_scalar, tmp);
+ flip_endian(secrets[i], tmp, num_bytes);
+ /* precompute multiples */
+ if ((!BN_to_felem(x_out, &p->X)) ||
+ (!BN_to_felem(y_out, &p->Y)) ||
+ (!BN_to_felem(z_out, &p->Z)))
+ goto err;
+ felem_assign(pre_comp[i][1][0], x_out);
+ felem_assign(pre_comp[i][1][1], y_out);
+ felem_assign(pre_comp[i][1][2], z_out);
+ for (j = 2; j <= 16; ++j) {
+ if (j & 1) {
+ point_add(pre_comp[i][j][0], pre_comp[i][j][1],
+ pre_comp[i][j][2], pre_comp[i][1][0],
+ pre_comp[i][1][1], pre_comp[i][1][2], 0,
+ pre_comp[i][j - 1][0],
+ pre_comp[i][j - 1][1],
+ pre_comp[i][j - 1][2]);
+ } else {
+ point_double(pre_comp[i][j][0], pre_comp[i][j][1],
+ pre_comp[i][j][2], pre_comp[i][j / 2][0],
+ pre_comp[i][j / 2][1],
+ pre_comp[i][j / 2][2]);
+ }
+ }
+ }
+ }
+ if (mixed)
+ make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
+ }
+
+ /* the scalar for the generator */
+ if ((scalar != NULL) && (have_pre_comp)) {
+ memset(g_secret, 0, sizeof g_secret);
+ /* reduce scalar to 0 <= scalar < 2^224 */
+ if ((BN_num_bits(scalar) > 224) || (BN_is_negative(scalar))) {
+ /*
+ * this is an unusual input, and we don't guarantee
+ * constant-timeness
+ */
+ if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
+ ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ } else
+ num_bytes = BN_bn2bin(scalar, tmp);
+ flip_endian(g_secret, tmp, num_bytes);
+ /* do the multiplication with generator precomputation */
+ batch_mul(x_out, y_out, z_out,
+ (const felem_bytearray(*))secrets, num_points,
+ g_secret,
+ mixed, (const felem(*)[17][3])pre_comp, g_pre_comp);
+ } else
+ /* do the multiplication without generator precomputation */
+ batch_mul(x_out, y_out, z_out,
+ (const felem_bytearray(*))secrets, num_points,
+ NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
+ /* reduce the output to its unique minimal representation */
+ felem_contract(x_in, x_out);
+ felem_contract(y_in, y_out);
+ felem_contract(z_in, z_out);
+ if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
+ (!felem_to_BN(z, z_in))) {
+ ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+
+ err:
+ BN_CTX_end(ctx);
+ if (generator != NULL)
+ EC_POINT_free(generator);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (secrets != NULL)
+ OPENSSL_free(secrets);
+ if (pre_comp != NULL)
+ OPENSSL_free(pre_comp);
+ if (tmp_felems != NULL)
+ OPENSSL_free(tmp_felems);
+ return ret;
+}
+
+int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+{
+ int ret = 0;
+ NISTP224_PRE_COMP *pre = NULL;
+ int i, j;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y;
+ EC_POINT *generator = NULL;
+ felem tmp_felems[32];
+
+ /* throw away old precomputation */
+ EC_EX_DATA_free_data(&group->extra_data, nistp224_pre_comp_dup,
+ nistp224_pre_comp_free,
+ nistp224_pre_comp_clear_free);
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+ return 0;
+ BN_CTX_start(ctx);
+ if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL))
+ goto err;
+ /* get the generator */
+ if (group->generator == NULL)
+ goto err;
+ generator = EC_POINT_new(group);
+ if (generator == NULL)
+ goto err;
+ BN_bin2bn(nistp224_curve_params[3], sizeof(felem_bytearray), x);
+ BN_bin2bn(nistp224_curve_params[4], sizeof(felem_bytearray), y);
+ if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
+ goto err;
+ if ((pre = nistp224_pre_comp_new()) == NULL)
+ goto err;
+ /*
+ * if the generator is the standard one, use built-in precomputation
+ */
+ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
+ memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
+ ret = 1;
+ goto err;
+ }
+ if ((!BN_to_felem(pre->g_pre_comp[0][1][0], &group->generator->X)) ||
+ (!BN_to_felem(pre->g_pre_comp[0][1][1], &group->generator->Y)) ||
+ (!BN_to_felem(pre->g_pre_comp[0][1][2], &group->generator->Z)))
+ goto err;
+ /*
+ * compute 2^56*G, 2^112*G, 2^168*G for the first table, 2^28*G, 2^84*G,
+ * 2^140*G, 2^196*G for the second one
+ */
+ for (i = 1; i <= 8; i <<= 1) {
+ point_double(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1],
+ pre->g_pre_comp[1][i][2], pre->g_pre_comp[0][i][0],
+ pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]);
+ for (j = 0; j < 27; ++j) {
+ point_double(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1],
+ pre->g_pre_comp[1][i][2], pre->g_pre_comp[1][i][0],
+ pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
+ }
+ if (i == 8)
+ break;
+ point_double(pre->g_pre_comp[0][2 * i][0],
+ pre->g_pre_comp[0][2 * i][1],
+ pre->g_pre_comp[0][2 * i][2], pre->g_pre_comp[1][i][0],
+ pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
+ for (j = 0; j < 27; ++j) {
+ point_double(pre->g_pre_comp[0][2 * i][0],
+ pre->g_pre_comp[0][2 * i][1],
+ pre->g_pre_comp[0][2 * i][2],
+ pre->g_pre_comp[0][2 * i][0],
+ pre->g_pre_comp[0][2 * i][1],
+ pre->g_pre_comp[0][2 * i][2]);
+ }
+ }
+ for (i = 0; i < 2; i++) {
+ /* g_pre_comp[i][0] is the point at infinity */
+ memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
+ /* the remaining multiples */
+ /* 2^56*G + 2^112*G resp. 2^84*G + 2^140*G */
+ point_add(pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1],
+ pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0],
+ pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
+ 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+ pre->g_pre_comp[i][2][2]);
+ /* 2^56*G + 2^168*G resp. 2^84*G + 2^196*G */
+ point_add(pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1],
+ pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0],
+ pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
+ 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+ pre->g_pre_comp[i][2][2]);
+ /* 2^112*G + 2^168*G resp. 2^140*G + 2^196*G */
+ point_add(pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1],
+ pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0],
+ pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
+ 0, pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1],
+ pre->g_pre_comp[i][4][2]);
+ /*
+ * 2^56*G + 2^112*G + 2^168*G resp. 2^84*G + 2^140*G + 2^196*G
+ */
+ point_add(pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1],
+ pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0],
+ pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
+ 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+ pre->g_pre_comp[i][2][2]);
+ for (j = 1; j < 8; ++j) {
+ /* odd multiples: add G resp. 2^28*G */
+ point_add(pre->g_pre_comp[i][2 * j + 1][0],
+ pre->g_pre_comp[i][2 * j + 1][1],
+ pre->g_pre_comp[i][2 * j + 1][2],
+ pre->g_pre_comp[i][2 * j][0],
+ pre->g_pre_comp[i][2 * j][1],
+ pre->g_pre_comp[i][2 * j][2], 0,
+ pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1],
+ pre->g_pre_comp[i][1][2]);
+ }
+ }
+ make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_felems);
+
+ if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp224_pre_comp_dup,
+ nistp224_pre_comp_free,
+ nistp224_pre_comp_clear_free))
+ goto err;
+ ret = 1;
+ pre = NULL;
+ err:
+ BN_CTX_end(ctx);
+ if (generator != NULL)
+ EC_POINT_free(generator);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (pre)
+ nistp224_pre_comp_free(pre);
+ return ret;
+}
+
+int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group)
+{
+ if (EC_EX_DATA_get_data(group->extra_data, nistp224_pre_comp_dup,
+ nistp224_pre_comp_free,
+ nistp224_pre_comp_clear_free)
+ != NULL)
+ return 1;
+ else
+ return 0;
+}
+
+#else
+static void *dummy = &dummy;
+#endif
diff --git a/openssl/ec/ecp_nistp256.c b/openssl/ec/ecp_nistp256.c
new file mode 100644
index 0000000..a588708
--- /dev/null
+++ b/openssl/ec/ecp_nistp256.c
@@ -0,0 +1,2369 @@
+/* crypto/ec/ecp_nistp256.c */
+/*
+ * Written by Adam Langley (Google) for the OpenSSL project
+ */
+/* Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ *
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * A 64-bit implementation of the NIST P-256 elliptic curve point multiplication
+ *
+ * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
+ * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
+ * work which got its smarts from Daniel J. Bernstein's work on the same.
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+
+# ifndef OPENSSL_SYS_VMS
+# include <stdint.h>
+# else
+# include <inttypes.h>
+# endif
+
+# include <string.h>
+# include <openssl/err.h>
+# include "ec_lcl.h"
+
+# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+ /* even with gcc, the typedef won't work for 32-bit platforms */
+typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit
+ * platforms */
+typedef __int128_t int128_t;
+# else
+# error "Need GCC 3.1 or later to define type uint128_t"
+# endif
+
+typedef uint8_t u8;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int64_t s64;
+
+/*
+ * The underlying field. P256 operates over GF(2^256-2^224+2^192+2^96-1). We
+ * can serialise an element of this field into 32 bytes. We call this an
+ * felem_bytearray.
+ */
+
+typedef u8 felem_bytearray[32];
+
+/*
+ * These are the parameters of P256, taken from FIPS 186-3, page 86. These
+ * values are big-endian.
+ */
+static const felem_bytearray nistp256_curve_params[5] = {
+ {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* p */
+ 0x00, 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, 0x00, 0x00, 0x00, 0x01, /* a = -3 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc}, /* b */
+ {0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
+ 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
+ 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
+ 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b},
+ {0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, /* x */
+ 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
+ 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
+ 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96},
+ {0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, /* y */
+ 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
+ 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
+ 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5}
+};
+
+/*-
+ * The representation of field elements.
+ * ------------------------------------
+ *
+ * We represent field elements with either four 128-bit values, eight 128-bit
+ * values, or four 64-bit values. The field element represented is:
+ * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + v[3]*2^192 (mod p)
+ * or:
+ * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[8]*2^512 (mod p)
+ *
+ * 128-bit values are called 'limbs'. Since the limbs are spaced only 64 bits
+ * apart, but are 128-bits wide, the most significant bits of each limb overlap
+ * with the least significant bits of the next.
+ *
+ * A field element with four limbs is an 'felem'. One with eight limbs is a
+ * 'longfelem'
+ *
+ * A field element with four, 64-bit values is called a 'smallfelem'. Small
+ * values are used as intermediate values before multiplication.
+ */
+
+# define NLIMBS 4
+
+typedef uint128_t limb;
+typedef limb felem[NLIMBS];
+typedef limb longfelem[NLIMBS * 2];
+typedef u64 smallfelem[NLIMBS];
+
+/* This is the value of the prime as four 64-bit words, little-endian. */
+static const u64 kPrime[4] =
+ { 0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul };
+static const u64 bottom63bits = 0x7ffffffffffffffful;
+
+/*
+ * bin32_to_felem takes a little-endian byte array and converts it into felem
+ * form. This assumes that the CPU is little-endian.
+ */
+static void bin32_to_felem(felem out, const u8 in[32])
+{
+ out[0] = *((u64 *)&in[0]);
+ out[1] = *((u64 *)&in[8]);
+ out[2] = *((u64 *)&in[16]);
+ out[3] = *((u64 *)&in[24]);
+}
+
+/*
+ * smallfelem_to_bin32 takes a smallfelem and serialises into a little
+ * endian, 32 byte array. This assumes that the CPU is little-endian.
+ */
+static void smallfelem_to_bin32(u8 out[32], const smallfelem in)
+{
+ *((u64 *)&out[0]) = in[0];
+ *((u64 *)&out[8]) = in[1];
+ *((u64 *)&out[16]) = in[2];
+ *((u64 *)&out[24]) = in[3];
+}
+
+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
+static void flip_endian(u8 *out, const u8 *in, unsigned len)
+{
+ unsigned i;
+ for (i = 0; i < len; ++i)
+ out[i] = in[len - 1 - i];
+}
+
+/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
+static int BN_to_felem(felem out, const BIGNUM *bn)
+{
+ felem_bytearray b_in;
+ felem_bytearray b_out;
+ unsigned num_bytes;
+
+ /* BN_bn2bin eats leading zeroes */
+ memset(b_out, 0, sizeof b_out);
+ num_bytes = BN_num_bytes(bn);
+ if (num_bytes > sizeof b_out) {
+ ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+ if (BN_is_negative(bn)) {
+ ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+ num_bytes = BN_bn2bin(bn, b_in);
+ flip_endian(b_out, b_in, num_bytes);
+ bin32_to_felem(out, b_out);
+ return 1;
+}
+
+/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
+static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in)
+{
+ felem_bytearray b_in, b_out;
+ smallfelem_to_bin32(b_in, in);
+ flip_endian(b_out, b_in, sizeof b_out);
+ return BN_bin2bn(b_out, sizeof b_out, out);
+}
+
+/*-
+ * Field operations
+ * ----------------
+ */
+
+static void smallfelem_one(smallfelem out)
+{
+ out[0] = 1;
+ out[1] = 0;
+ out[2] = 0;
+ out[3] = 0;
+}
+
+static void smallfelem_assign(smallfelem out, const smallfelem in)
+{
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+}
+
+static void felem_assign(felem out, const felem in)
+{
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+}
+
+/* felem_sum sets out = out + in. */
+static void felem_sum(felem out, const felem in)
+{
+ out[0] += in[0];
+ out[1] += in[1];
+ out[2] += in[2];
+ out[3] += in[3];
+}
+
+/* felem_small_sum sets out = out + in. */
+static void felem_small_sum(felem out, const smallfelem in)
+{
+ out[0] += in[0];
+ out[1] += in[1];
+ out[2] += in[2];
+ out[3] += in[3];
+}
+
+/* felem_scalar sets out = out * scalar */
+static void felem_scalar(felem out, const u64 scalar)
+{
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+}
+
+/* longfelem_scalar sets out = out * scalar */
+static void longfelem_scalar(longfelem out, const u64 scalar)
+{
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+ out[4] *= scalar;
+ out[5] *= scalar;
+ out[6] *= scalar;
+ out[7] *= scalar;
+}
+
+# define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9)
+# define two105 (((limb)1) << 105)
+# define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9)
+
+/* zero105 is 0 mod p */
+static const felem zero105 =
+ { two105m41m9, two105, two105m41p9, two105m41p9 };
+
+/*-
+ * smallfelem_neg sets |out| to |-small|
+ * On exit:
+ * out[i] < out[i] + 2^105
+ */
+static void smallfelem_neg(felem out, const smallfelem small)
+{
+ /* In order to prevent underflow, we subtract from 0 mod p. */
+ out[0] = zero105[0] - small[0];
+ out[1] = zero105[1] - small[1];
+ out[2] = zero105[2] - small[2];
+ out[3] = zero105[3] - small[3];
+}
+
+/*-
+ * felem_diff subtracts |in| from |out|
+ * On entry:
+ * in[i] < 2^104
+ * On exit:
+ * out[i] < out[i] + 2^105
+ */
+static void felem_diff(felem out, const felem in)
+{
+ /*
+ * In order to prevent underflow, we add 0 mod p before subtracting.
+ */
+ out[0] += zero105[0];
+ out[1] += zero105[1];
+ out[2] += zero105[2];
+ out[3] += zero105[3];
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+}
+
+# define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11)
+# define two107 (((limb)1) << 107)
+# define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11)
+
+/* zero107 is 0 mod p */
+static const felem zero107 =
+ { two107m43m11, two107, two107m43p11, two107m43p11 };
+
+/*-
+ * An alternative felem_diff for larger inputs |in|
+ * felem_diff_zero107 subtracts |in| from |out|
+ * On entry:
+ * in[i] < 2^106
+ * On exit:
+ * out[i] < out[i] + 2^107
+ */
+static void felem_diff_zero107(felem out, const felem in)
+{
+ /*
+ * In order to prevent underflow, we add 0 mod p before subtracting.
+ */
+ out[0] += zero107[0];
+ out[1] += zero107[1];
+ out[2] += zero107[2];
+ out[3] += zero107[3];
+
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+}
+
+/*-
+ * longfelem_diff subtracts |in| from |out|
+ * On entry:
+ * in[i] < 7*2^67
+ * On exit:
+ * out[i] < out[i] + 2^70 + 2^40
+ */
+static void longfelem_diff(longfelem out, const longfelem in)
+{
+ static const limb two70m8p6 =
+ (((limb) 1) << 70) - (((limb) 1) << 8) + (((limb) 1) << 6);
+ static const limb two70p40 = (((limb) 1) << 70) + (((limb) 1) << 40);
+ static const limb two70 = (((limb) 1) << 70);
+ static const limb two70m40m38p6 =
+ (((limb) 1) << 70) - (((limb) 1) << 40) - (((limb) 1) << 38) +
+ (((limb) 1) << 6);
+ static const limb two70m6 = (((limb) 1) << 70) - (((limb) 1) << 6);
+
+ /* add 0 mod p to avoid underflow */
+ out[0] += two70m8p6;
+ out[1] += two70p40;
+ out[2] += two70;
+ out[3] += two70m40m38p6;
+ out[4] += two70m6;
+ out[5] += two70m6;
+ out[6] += two70m6;
+ out[7] += two70m6;
+
+ /* in[i] < 7*2^67 < 2^70 - 2^40 - 2^38 + 2^6 */
+ out[0] -= in[0];
+ out[1] -= in[1];
+ out[2] -= in[2];
+ out[3] -= in[3];
+ out[4] -= in[4];
+ out[5] -= in[5];
+ out[6] -= in[6];
+ out[7] -= in[7];
+}
+
+# define two64m0 (((limb)1) << 64) - 1
+# define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1
+# define two64m46 (((limb)1) << 64) - (((limb)1) << 46)
+# define two64m32 (((limb)1) << 64) - (((limb)1) << 32)
+
+/* zero110 is 0 mod p */
+static const felem zero110 = { two64m0, two110p32m0, two64m46, two64m32 };
+
+/*-
+ * felem_shrink converts an felem into a smallfelem. The result isn't quite
+ * minimal as the value may be greater than p.
+ *
+ * On entry:
+ * in[i] < 2^109
+ * On exit:
+ * out[i] < 2^64
+ */
+static void felem_shrink(smallfelem out, const felem in)
+{
+ felem tmp;
+ u64 a, b, mask;
+ s64 high, low;
+ static const u64 kPrime3Test = 0x7fffffff00000001ul; /* 2^63 - 2^32 + 1 */
+
+ /* Carry 2->3 */
+ tmp[3] = zero110[3] + in[3] + ((u64)(in[2] >> 64));
+ /* tmp[3] < 2^110 */
+
+ tmp[2] = zero110[2] + (u64)in[2];
+ tmp[0] = zero110[0] + in[0];
+ tmp[1] = zero110[1] + in[1];
+ /* tmp[0] < 2**110, tmp[1] < 2^111, tmp[2] < 2**65 */
+
+ /*
+ * We perform two partial reductions where we eliminate the high-word of
+ * tmp[3]. We don't update the other words till the end.
+ */
+ a = tmp[3] >> 64; /* a < 2^46 */
+ tmp[3] = (u64)tmp[3];
+ tmp[3] -= a;
+ tmp[3] += ((limb) a) << 32;
+ /* tmp[3] < 2^79 */
+
+ b = a;
+ a = tmp[3] >> 64; /* a < 2^15 */
+ b += a; /* b < 2^46 + 2^15 < 2^47 */
+ tmp[3] = (u64)tmp[3];
+ tmp[3] -= a;
+ tmp[3] += ((limb) a) << 32;
+ /* tmp[3] < 2^64 + 2^47 */
+
+ /*
+ * This adjusts the other two words to complete the two partial
+ * reductions.
+ */
+ tmp[0] += b;
+ tmp[1] -= (((limb) b) << 32);
+
+ /*
+ * In order to make space in tmp[3] for the carry from 2 -> 3, we
+ * conditionally subtract kPrime if tmp[3] is large enough.
+ */
+ high = tmp[3] >> 64;
+ /* As tmp[3] < 2^65, high is either 1 or 0 */
+ high <<= 63;
+ high >>= 63;
+ /*-
+ * high is:
+ * all ones if the high word of tmp[3] is 1
+ * all zeros if the high word of tmp[3] if 0 */
+ low = tmp[3];
+ mask = low >> 63;
+ /*-
+ * mask is:
+ * all ones if the MSB of low is 1
+ * all zeros if the MSB of low if 0 */
+ low &= bottom63bits;
+ low -= kPrime3Test;
+ /* if low was greater than kPrime3Test then the MSB is zero */
+ low = ~low;
+ low >>= 63;
+ /*-
+ * low is:
+ * all ones if low was > kPrime3Test
+ * all zeros if low was <= kPrime3Test */
+ mask = (mask & low) | high;
+ tmp[0] -= mask & kPrime[0];
+ tmp[1] -= mask & kPrime[1];
+ /* kPrime[2] is zero, so omitted */
+ tmp[3] -= mask & kPrime[3];
+ /* tmp[3] < 2**64 - 2**32 + 1 */
+
+ tmp[1] += ((u64)(tmp[0] >> 64));
+ tmp[0] = (u64)tmp[0];
+ tmp[2] += ((u64)(tmp[1] >> 64));
+ tmp[1] = (u64)tmp[1];
+ tmp[3] += ((u64)(tmp[2] >> 64));
+ tmp[2] = (u64)tmp[2];
+ /* tmp[i] < 2^64 */
+
+ out[0] = tmp[0];
+ out[1] = tmp[1];
+ out[2] = tmp[2];
+ out[3] = tmp[3];
+}
+
+/* smallfelem_expand converts a smallfelem to an felem */
+static void smallfelem_expand(felem out, const smallfelem in)
+{
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+}
+
+/*-
+ * smallfelem_square sets |out| = |small|^2
+ * On entry:
+ * small[i] < 2^64
+ * On exit:
+ * out[i] < 7 * 2^64 < 2^67
+ */
+static void smallfelem_square(longfelem out, const smallfelem small)
+{
+ limb a;
+ u64 high, low;
+
+ a = ((uint128_t) small[0]) * small[0];
+ low = a;
+ high = a >> 64;
+ out[0] = low;
+ out[1] = high;
+
+ a = ((uint128_t) small[0]) * small[1];
+ low = a;
+ high = a >> 64;
+ out[1] += low;
+ out[1] += low;
+ out[2] = high;
+
+ a = ((uint128_t) small[0]) * small[2];
+ low = a;
+ high = a >> 64;
+ out[2] += low;
+ out[2] *= 2;
+ out[3] = high;
+
+ a = ((uint128_t) small[0]) * small[3];
+ low = a;
+ high = a >> 64;
+ out[3] += low;
+ out[4] = high;
+
+ a = ((uint128_t) small[1]) * small[2];
+ low = a;
+ high = a >> 64;
+ out[3] += low;
+ out[3] *= 2;
+ out[4] += high;
+
+ a = ((uint128_t) small[1]) * small[1];
+ low = a;
+ high = a >> 64;
+ out[2] += low;
+ out[3] += high;
+
+ a = ((uint128_t) small[1]) * small[3];
+ low = a;
+ high = a >> 64;
+ out[4] += low;
+ out[4] *= 2;
+ out[5] = high;
+
+ a = ((uint128_t) small[2]) * small[3];
+ low = a;
+ high = a >> 64;
+ out[5] += low;
+ out[5] *= 2;
+ out[6] = high;
+ out[6] += high;
+
+ a = ((uint128_t) small[2]) * small[2];
+ low = a;
+ high = a >> 64;
+ out[4] += low;
+ out[5] += high;
+
+ a = ((uint128_t) small[3]) * small[3];
+ low = a;
+ high = a >> 64;
+ out[6] += low;
+ out[7] = high;
+}
+
+/*-
+ * felem_square sets |out| = |in|^2
+ * On entry:
+ * in[i] < 2^109
+ * On exit:
+ * out[i] < 7 * 2^64 < 2^67
+ */
+static void felem_square(longfelem out, const felem in)
+{
+ u64 small[4];
+ felem_shrink(small, in);
+ smallfelem_square(out, small);
+}
+
+/*-
+ * smallfelem_mul sets |out| = |small1| * |small2|
+ * On entry:
+ * small1[i] < 2^64
+ * small2[i] < 2^64
+ * On exit:
+ * out[i] < 7 * 2^64 < 2^67
+ */
+static void smallfelem_mul(longfelem out, const smallfelem small1,
+ const smallfelem small2)
+{
+ limb a;
+ u64 high, low;
+
+ a = ((uint128_t) small1[0]) * small2[0];
+ low = a;
+ high = a >> 64;
+ out[0] = low;
+ out[1] = high;
+
+ a = ((uint128_t) small1[0]) * small2[1];
+ low = a;
+ high = a >> 64;
+ out[1] += low;
+ out[2] = high;
+
+ a = ((uint128_t) small1[1]) * small2[0];
+ low = a;
+ high = a >> 64;
+ out[1] += low;
+ out[2] += high;
+
+ a = ((uint128_t) small1[0]) * small2[2];
+ low = a;
+ high = a >> 64;
+ out[2] += low;
+ out[3] = high;
+
+ a = ((uint128_t) small1[1]) * small2[1];
+ low = a;
+ high = a >> 64;
+ out[2] += low;
+ out[3] += high;
+
+ a = ((uint128_t) small1[2]) * small2[0];
+ low = a;
+ high = a >> 64;
+ out[2] += low;
+ out[3] += high;
+
+ a = ((uint128_t) small1[0]) * small2[3];
+ low = a;
+ high = a >> 64;
+ out[3] += low;
+ out[4] = high;
+
+ a = ((uint128_t) small1[1]) * small2[2];
+ low = a;
+ high = a >> 64;
+ out[3] += low;
+ out[4] += high;
+
+ a = ((uint128_t) small1[2]) * small2[1];
+ low = a;
+ high = a >> 64;
+ out[3] += low;
+ out[4] += high;
+
+ a = ((uint128_t) small1[3]) * small2[0];
+ low = a;
+ high = a >> 64;
+ out[3] += low;
+ out[4] += high;
+
+ a = ((uint128_t) small1[1]) * small2[3];
+ low = a;
+ high = a >> 64;
+ out[4] += low;
+ out[5] = high;
+
+ a = ((uint128_t) small1[2]) * small2[2];
+ low = a;
+ high = a >> 64;
+ out[4] += low;
+ out[5] += high;
+
+ a = ((uint128_t) small1[3]) * small2[1];
+ low = a;
+ high = a >> 64;
+ out[4] += low;
+ out[5] += high;
+
+ a = ((uint128_t) small1[2]) * small2[3];
+ low = a;
+ high = a >> 64;
+ out[5] += low;
+ out[6] = high;
+
+ a = ((uint128_t) small1[3]) * small2[2];
+ low = a;
+ high = a >> 64;
+ out[5] += low;
+ out[6] += high;
+
+ a = ((uint128_t) small1[3]) * small2[3];
+ low = a;
+ high = a >> 64;
+ out[6] += low;
+ out[7] = high;
+}
+
+/*-
+ * felem_mul sets |out| = |in1| * |in2|
+ * On entry:
+ * in1[i] < 2^109
+ * in2[i] < 2^109
+ * On exit:
+ * out[i] < 7 * 2^64 < 2^67
+ */
+static void felem_mul(longfelem out, const felem in1, const felem in2)
+{
+ smallfelem small1, small2;
+ felem_shrink(small1, in1);
+ felem_shrink(small2, in2);
+ smallfelem_mul(out, small1, small2);
+}
+
+/*-
+ * felem_small_mul sets |out| = |small1| * |in2|
+ * On entry:
+ * small1[i] < 2^64
+ * in2[i] < 2^109
+ * On exit:
+ * out[i] < 7 * 2^64 < 2^67
+ */
+static void felem_small_mul(longfelem out, const smallfelem small1,
+ const felem in2)
+{
+ smallfelem small2;
+ felem_shrink(small2, in2);
+ smallfelem_mul(out, small1, small2);
+}
+
+# define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4)
+# define two100 (((limb)1) << 100)
+# define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4)
+/* zero100 is 0 mod p */
+static const felem zero100 =
+ { two100m36m4, two100, two100m36p4, two100m36p4 };
+
+/*-
+ * Internal function for the different flavours of felem_reduce.
+ * felem_reduce_ reduces the higher coefficients in[4]-in[7].
+ * On entry:
+ * out[0] >= in[6] + 2^32*in[6] + in[7] + 2^32*in[7]
+ * out[1] >= in[7] + 2^32*in[4]
+ * out[2] >= in[5] + 2^32*in[5]
+ * out[3] >= in[4] + 2^32*in[5] + 2^32*in[6]
+ * On exit:
+ * out[0] <= out[0] + in[4] + 2^32*in[5]
+ * out[1] <= out[1] + in[5] + 2^33*in[6]
+ * out[2] <= out[2] + in[7] + 2*in[6] + 2^33*in[7]
+ * out[3] <= out[3] + 2^32*in[4] + 3*in[7]
+ */
+static void felem_reduce_(felem out, const longfelem in)
+{
+ int128_t c;
+ /* combine common terms from below */
+ c = in[4] + (in[5] << 32);
+ out[0] += c;
+ out[3] -= c;
+
+ c = in[5] - in[7];
+ out[1] += c;
+ out[2] -= c;
+
+ /* the remaining terms */
+ /* 256: [(0,1),(96,-1),(192,-1),(224,1)] */
+ out[1] -= (in[4] << 32);
+ out[3] += (in[4] << 32);
+
+ /* 320: [(32,1),(64,1),(128,-1),(160,-1),(224,-1)] */
+ out[2] -= (in[5] << 32);
+
+ /* 384: [(0,-1),(32,-1),(96,2),(128,2),(224,-1)] */
+ out[0] -= in[6];
+ out[0] -= (in[6] << 32);
+ out[1] += (in[6] << 33);
+ out[2] += (in[6] * 2);
+ out[3] -= (in[6] << 32);
+
+ /* 448: [(0,-1),(32,-1),(64,-1),(128,1),(160,2),(192,3)] */
+ out[0] -= in[7];
+ out[0] -= (in[7] << 32);
+ out[2] += (in[7] << 33);
+ out[3] += (in[7] * 3);
+}
+
+/*-
+ * felem_reduce converts a longfelem into an felem.
+ * To be called directly after felem_square or felem_mul.
+ * On entry:
+ * in[0] < 2^64, in[1] < 3*2^64, in[2] < 5*2^64, in[3] < 7*2^64
+ * in[4] < 7*2^64, in[5] < 5*2^64, in[6] < 3*2^64, in[7] < 2*64
+ * On exit:
+ * out[i] < 2^101
+ */
+static void felem_reduce(felem out, const longfelem in)
+{
+ out[0] = zero100[0] + in[0];
+ out[1] = zero100[1] + in[1];
+ out[2] = zero100[2] + in[2];
+ out[3] = zero100[3] + in[3];
+
+ felem_reduce_(out, in);
+
+ /*-
+ * out[0] > 2^100 - 2^36 - 2^4 - 3*2^64 - 3*2^96 - 2^64 - 2^96 > 0
+ * out[1] > 2^100 - 2^64 - 7*2^96 > 0
+ * out[2] > 2^100 - 2^36 + 2^4 - 5*2^64 - 5*2^96 > 0
+ * out[3] > 2^100 - 2^36 + 2^4 - 7*2^64 - 5*2^96 - 3*2^96 > 0
+ *
+ * out[0] < 2^100 + 2^64 + 7*2^64 + 5*2^96 < 2^101
+ * out[1] < 2^100 + 3*2^64 + 5*2^64 + 3*2^97 < 2^101
+ * out[2] < 2^100 + 5*2^64 + 2^64 + 3*2^65 + 2^97 < 2^101
+ * out[3] < 2^100 + 7*2^64 + 7*2^96 + 3*2^64 < 2^101
+ */
+}
+
+/*-
+ * felem_reduce_zero105 converts a larger longfelem into an felem.
+ * On entry:
+ * in[0] < 2^71
+ * On exit:
+ * out[i] < 2^106
+ */
+static void felem_reduce_zero105(felem out, const longfelem in)
+{
+ out[0] = zero105[0] + in[0];
+ out[1] = zero105[1] + in[1];
+ out[2] = zero105[2] + in[2];
+ out[3] = zero105[3] + in[3];
+
+ felem_reduce_(out, in);
+
+ /*-
+ * out[0] > 2^105 - 2^41 - 2^9 - 2^71 - 2^103 - 2^71 - 2^103 > 0
+ * out[1] > 2^105 - 2^71 - 2^103 > 0
+ * out[2] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 > 0
+ * out[3] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 - 2^103 > 0
+ *
+ * out[0] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
+ * out[1] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
+ * out[2] < 2^105 + 2^71 + 2^71 + 2^71 + 2^103 < 2^106
+ * out[3] < 2^105 + 2^71 + 2^103 + 2^71 < 2^106
+ */
+}
+
+/*
+ * subtract_u64 sets *result = *result - v and *carry to one if the
+ * subtraction underflowed.
+ */
+static void subtract_u64(u64 *result, u64 *carry, u64 v)
+{
+ uint128_t r = *result;
+ r -= v;
+ *carry = (r >> 64) & 1;
+ *result = (u64)r;
+}
+
+/*
+ * felem_contract converts |in| to its unique, minimal representation. On
+ * entry: in[i] < 2^109
+ */
+static void felem_contract(smallfelem out, const felem in)
+{
+ unsigned i;
+ u64 all_equal_so_far = 0, result = 0, carry;
+
+ felem_shrink(out, in);
+ /* small is minimal except that the value might be > p */
+
+ all_equal_so_far--;
+ /*
+ * We are doing a constant time test if out >= kPrime. We need to compare
+ * each u64, from most-significant to least significant. For each one, if
+ * all words so far have been equal (m is all ones) then a non-equal
+ * result is the answer. Otherwise we continue.
+ */
+ for (i = 3; i < 4; i--) {
+ u64 equal;
+ uint128_t a = ((uint128_t) kPrime[i]) - out[i];
+ /*
+ * if out[i] > kPrime[i] then a will underflow and the high 64-bits
+ * will all be set.
+ */
+ result |= all_equal_so_far & ((u64)(a >> 64));
+
+ /*
+ * if kPrime[i] == out[i] then |equal| will be all zeros and the
+ * decrement will make it all ones.
+ */
+ equal = kPrime[i] ^ out[i];
+ equal--;
+ equal &= equal << 32;
+ equal &= equal << 16;
+ equal &= equal << 8;
+ equal &= equal << 4;
+ equal &= equal << 2;
+ equal &= equal << 1;
+ equal = ((s64) equal) >> 63;
+
+ all_equal_so_far &= equal;
+ }
+
+ /*
+ * if all_equal_so_far is still all ones then the two values are equal
+ * and so out >= kPrime is true.
+ */
+ result |= all_equal_so_far;
+
+ /* if out >= kPrime then we subtract kPrime. */
+ subtract_u64(&out[0], &carry, result & kPrime[0]);
+ subtract_u64(&out[1], &carry, carry);
+ subtract_u64(&out[2], &carry, carry);
+ subtract_u64(&out[3], &carry, carry);
+
+ subtract_u64(&out[1], &carry, result & kPrime[1]);
+ subtract_u64(&out[2], &carry, carry);
+ subtract_u64(&out[3], &carry, carry);
+
+ subtract_u64(&out[2], &carry, result & kPrime[2]);
+ subtract_u64(&out[3], &carry, carry);
+
+ subtract_u64(&out[3], &carry, result & kPrime[3]);
+}
+
+static void smallfelem_square_contract(smallfelem out, const smallfelem in)
+{
+ longfelem longtmp;
+ felem tmp;
+
+ smallfelem_square(longtmp, in);
+ felem_reduce(tmp, longtmp);
+ felem_contract(out, tmp);
+}
+
+static void smallfelem_mul_contract(smallfelem out, const smallfelem in1,
+ const smallfelem in2)
+{
+ longfelem longtmp;
+ felem tmp;
+
+ smallfelem_mul(longtmp, in1, in2);
+ felem_reduce(tmp, longtmp);
+ felem_contract(out, tmp);
+}
+
+/*-
+ * felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
+ * otherwise.
+ * On entry:
+ * small[i] < 2^64
+ */
+static limb smallfelem_is_zero(const smallfelem small)
+{
+ limb result;
+ u64 is_p;
+
+ u64 is_zero = small[0] | small[1] | small[2] | small[3];
+ is_zero--;
+ is_zero &= is_zero << 32;
+ is_zero &= is_zero << 16;
+ is_zero &= is_zero << 8;
+ is_zero &= is_zero << 4;
+ is_zero &= is_zero << 2;
+ is_zero &= is_zero << 1;
+ is_zero = ((s64) is_zero) >> 63;
+
+ is_p = (small[0] ^ kPrime[0]) |
+ (small[1] ^ kPrime[1]) |
+ (small[2] ^ kPrime[2]) | (small[3] ^ kPrime[3]);
+ is_p--;
+ is_p &= is_p << 32;
+ is_p &= is_p << 16;
+ is_p &= is_p << 8;
+ is_p &= is_p << 4;
+ is_p &= is_p << 2;
+ is_p &= is_p << 1;
+ is_p = ((s64) is_p) >> 63;
+
+ is_zero |= is_p;
+
+ result = is_zero;
+ result |= ((limb) is_zero) << 64;
+ return result;
+}
+
+static int smallfelem_is_zero_int(const smallfelem small)
+{
+ return (int)(smallfelem_is_zero(small) & ((limb) 1));
+}
+
+/*-
+ * felem_inv calculates |out| = |in|^{-1}
+ *
+ * Based on Fermat's Little Theorem:
+ * a^p = a (mod p)
+ * a^{p-1} = 1 (mod p)
+ * a^{p-2} = a^{-1} (mod p)
+ */
+static void felem_inv(felem out, const felem in)
+{
+ felem ftmp, ftmp2;
+ /* each e_I will hold |in|^{2^I - 1} */
+ felem e2, e4, e8, e16, e32, e64;
+ longfelem tmp;
+ unsigned i;
+
+ felem_square(tmp, in);
+ felem_reduce(ftmp, tmp); /* 2^1 */
+ felem_mul(tmp, in, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^2 - 2^0 */
+ felem_assign(e2, ftmp);
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^3 - 2^1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^4 - 2^2 */
+ felem_mul(tmp, ftmp, e2);
+ felem_reduce(ftmp, tmp); /* 2^4 - 2^0 */
+ felem_assign(e4, ftmp);
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^5 - 2^1 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^6 - 2^2 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^7 - 2^3 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^8 - 2^4 */
+ felem_mul(tmp, ftmp, e4);
+ felem_reduce(ftmp, tmp); /* 2^8 - 2^0 */
+ felem_assign(e8, ftmp);
+ for (i = 0; i < 8; i++) {
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp);
+ } /* 2^16 - 2^8 */
+ felem_mul(tmp, ftmp, e8);
+ felem_reduce(ftmp, tmp); /* 2^16 - 2^0 */
+ felem_assign(e16, ftmp);
+ for (i = 0; i < 16; i++) {
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp);
+ } /* 2^32 - 2^16 */
+ felem_mul(tmp, ftmp, e16);
+ felem_reduce(ftmp, tmp); /* 2^32 - 2^0 */
+ felem_assign(e32, ftmp);
+ for (i = 0; i < 32; i++) {
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp);
+ } /* 2^64 - 2^32 */
+ felem_assign(e64, ftmp);
+ felem_mul(tmp, ftmp, in);
+ felem_reduce(ftmp, tmp); /* 2^64 - 2^32 + 2^0 */
+ for (i = 0; i < 192; i++) {
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp);
+ } /* 2^256 - 2^224 + 2^192 */
+
+ felem_mul(tmp, e64, e32);
+ felem_reduce(ftmp2, tmp); /* 2^64 - 2^0 */
+ for (i = 0; i < 16; i++) {
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp);
+ } /* 2^80 - 2^16 */
+ felem_mul(tmp, ftmp2, e16);
+ felem_reduce(ftmp2, tmp); /* 2^80 - 2^0 */
+ for (i = 0; i < 8; i++) {
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp);
+ } /* 2^88 - 2^8 */
+ felem_mul(tmp, ftmp2, e8);
+ felem_reduce(ftmp2, tmp); /* 2^88 - 2^0 */
+ for (i = 0; i < 4; i++) {
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp);
+ } /* 2^92 - 2^4 */
+ felem_mul(tmp, ftmp2, e4);
+ felem_reduce(ftmp2, tmp); /* 2^92 - 2^0 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp); /* 2^93 - 2^1 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp); /* 2^94 - 2^2 */
+ felem_mul(tmp, ftmp2, e2);
+ felem_reduce(ftmp2, tmp); /* 2^94 - 2^0 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp); /* 2^95 - 2^1 */
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp2, tmp); /* 2^96 - 2^2 */
+ felem_mul(tmp, ftmp2, in);
+ felem_reduce(ftmp2, tmp); /* 2^96 - 3 */
+
+ felem_mul(tmp, ftmp2, ftmp);
+ felem_reduce(out, tmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */
+}
+
+static void smallfelem_inv_contract(smallfelem out, const smallfelem in)
+{
+ felem tmp;
+
+ smallfelem_expand(tmp, in);
+ felem_inv(tmp, tmp);
+ felem_contract(out, tmp);
+}
+
+/*-
+ * Group operations
+ * ----------------
+ *
+ * Building on top of the field operations we have the operations on the
+ * elliptic curve group itself. Points on the curve are represented in Jacobian
+ * coordinates
+ */
+
+/*-
+ * point_double calculates 2*(x_in, y_in, z_in)
+ *
+ * The method is taken from:
+ * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
+ *
+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
+ * while x_out == y_in is not (maybe this works, but it's not tested).
+ */
+static void
+point_double(felem x_out, felem y_out, felem z_out,
+ const felem x_in, const felem y_in, const felem z_in)
+{
+ longfelem tmp, tmp2;
+ felem delta, gamma, beta, alpha, ftmp, ftmp2;
+ smallfelem small1, small2;
+
+ felem_assign(ftmp, x_in);
+ /* ftmp[i] < 2^106 */
+ felem_assign(ftmp2, x_in);
+ /* ftmp2[i] < 2^106 */
+
+ /* delta = z^2 */
+ felem_square(tmp, z_in);
+ felem_reduce(delta, tmp);
+ /* delta[i] < 2^101 */
+
+ /* gamma = y^2 */
+ felem_square(tmp, y_in);
+ felem_reduce(gamma, tmp);
+ /* gamma[i] < 2^101 */
+ felem_shrink(small1, gamma);
+
+ /* beta = x*gamma */
+ felem_small_mul(tmp, small1, x_in);
+ felem_reduce(beta, tmp);
+ /* beta[i] < 2^101 */
+
+ /* alpha = 3*(x-delta)*(x+delta) */
+ felem_diff(ftmp, delta);
+ /* ftmp[i] < 2^105 + 2^106 < 2^107 */
+ felem_sum(ftmp2, delta);
+ /* ftmp2[i] < 2^105 + 2^106 < 2^107 */
+ felem_scalar(ftmp2, 3);
+ /* ftmp2[i] < 3 * 2^107 < 2^109 */
+ felem_mul(tmp, ftmp, ftmp2);
+ felem_reduce(alpha, tmp);
+ /* alpha[i] < 2^101 */
+ felem_shrink(small2, alpha);
+
+ /* x' = alpha^2 - 8*beta */
+ smallfelem_square(tmp, small2);
+ felem_reduce(x_out, tmp);
+ felem_assign(ftmp, beta);
+ felem_scalar(ftmp, 8);
+ /* ftmp[i] < 8 * 2^101 = 2^104 */
+ felem_diff(x_out, ftmp);
+ /* x_out[i] < 2^105 + 2^101 < 2^106 */
+
+ /* z' = (y + z)^2 - gamma - delta */
+ felem_sum(delta, gamma);
+ /* delta[i] < 2^101 + 2^101 = 2^102 */
+ felem_assign(ftmp, y_in);
+ felem_sum(ftmp, z_in);
+ /* ftmp[i] < 2^106 + 2^106 = 2^107 */
+ felem_square(tmp, ftmp);
+ felem_reduce(z_out, tmp);
+ felem_diff(z_out, delta);
+ /* z_out[i] < 2^105 + 2^101 < 2^106 */
+
+ /* y' = alpha*(4*beta - x') - 8*gamma^2 */
+ felem_scalar(beta, 4);
+ /* beta[i] < 4 * 2^101 = 2^103 */
+ felem_diff_zero107(beta, x_out);
+ /* beta[i] < 2^107 + 2^103 < 2^108 */
+ felem_small_mul(tmp, small2, beta);
+ /* tmp[i] < 7 * 2^64 < 2^67 */
+ smallfelem_square(tmp2, small1);
+ /* tmp2[i] < 7 * 2^64 */
+ longfelem_scalar(tmp2, 8);
+ /* tmp2[i] < 8 * 7 * 2^64 = 7 * 2^67 */
+ longfelem_diff(tmp, tmp2);
+ /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
+ felem_reduce_zero105(y_out, tmp);
+ /* y_out[i] < 2^106 */
+}
+
+/*
+ * point_double_small is the same as point_double, except that it operates on
+ * smallfelems
+ */
+static void
+point_double_small(smallfelem x_out, smallfelem y_out, smallfelem z_out,
+ const smallfelem x_in, const smallfelem y_in,
+ const smallfelem z_in)
+{
+ felem felem_x_out, felem_y_out, felem_z_out;
+ felem felem_x_in, felem_y_in, felem_z_in;
+
+ smallfelem_expand(felem_x_in, x_in);
+ smallfelem_expand(felem_y_in, y_in);
+ smallfelem_expand(felem_z_in, z_in);
+ point_double(felem_x_out, felem_y_out, felem_z_out,
+ felem_x_in, felem_y_in, felem_z_in);
+ felem_shrink(x_out, felem_x_out);
+ felem_shrink(y_out, felem_y_out);
+ felem_shrink(z_out, felem_z_out);
+}
+
+/* copy_conditional copies in to out iff mask is all ones. */
+static void copy_conditional(felem out, const felem in, limb mask)
+{
+ unsigned i;
+ for (i = 0; i < NLIMBS; ++i) {
+ const limb tmp = mask & (in[i] ^ out[i]);
+ out[i] ^= tmp;
+ }
+}
+
+/* copy_small_conditional copies in to out iff mask is all ones. */
+static void copy_small_conditional(felem out, const smallfelem in, limb mask)
+{
+ unsigned i;
+ const u64 mask64 = mask;
+ for (i = 0; i < NLIMBS; ++i) {
+ out[i] = ((limb) (in[i] & mask64)) | (out[i] & ~mask);
+ }
+}
+
+/*-
+ * point_add calcuates (x1, y1, z1) + (x2, y2, z2)
+ *
+ * The method is taken from:
+ * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
+ * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
+ *
+ * This function includes a branch for checking whether the two input points
+ * are equal, (while not equal to the point at infinity). This case never
+ * happens during single point multiplication, so there is no timing leak for
+ * ECDH or ECDSA signing.
+ */
+static void point_add(felem x3, felem y3, felem z3,
+ const felem x1, const felem y1, const felem z1,
+ const int mixed, const smallfelem x2,
+ const smallfelem y2, const smallfelem z2)
+{
+ felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
+ longfelem tmp, tmp2;
+ smallfelem small1, small2, small3, small4, small5;
+ limb x_equal, y_equal, z1_is_zero, z2_is_zero;
+
+ felem_shrink(small3, z1);
+
+ z1_is_zero = smallfelem_is_zero(small3);
+ z2_is_zero = smallfelem_is_zero(z2);
+
+ /* ftmp = z1z1 = z1**2 */
+ smallfelem_square(tmp, small3);
+ felem_reduce(ftmp, tmp);
+ /* ftmp[i] < 2^101 */
+ felem_shrink(small1, ftmp);
+
+ if (!mixed) {
+ /* ftmp2 = z2z2 = z2**2 */
+ smallfelem_square(tmp, z2);
+ felem_reduce(ftmp2, tmp);
+ /* ftmp2[i] < 2^101 */
+ felem_shrink(small2, ftmp2);
+
+ felem_shrink(small5, x1);
+
+ /* u1 = ftmp3 = x1*z2z2 */
+ smallfelem_mul(tmp, small5, small2);
+ felem_reduce(ftmp3, tmp);
+ /* ftmp3[i] < 2^101 */
+
+ /* ftmp5 = z1 + z2 */
+ felem_assign(ftmp5, z1);
+ felem_small_sum(ftmp5, z2);
+ /* ftmp5[i] < 2^107 */
+
+ /* ftmp5 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 */
+ felem_square(tmp, ftmp5);
+ felem_reduce(ftmp5, tmp);
+ /* ftmp2 = z2z2 + z1z1 */
+ felem_sum(ftmp2, ftmp);
+ /* ftmp2[i] < 2^101 + 2^101 = 2^102 */
+ felem_diff(ftmp5, ftmp2);
+ /* ftmp5[i] < 2^105 + 2^101 < 2^106 */
+
+ /* ftmp2 = z2 * z2z2 */
+ smallfelem_mul(tmp, small2, z2);
+ felem_reduce(ftmp2, tmp);
+
+ /* s1 = ftmp2 = y1 * z2**3 */
+ felem_mul(tmp, y1, ftmp2);
+ felem_reduce(ftmp6, tmp);
+ /* ftmp6[i] < 2^101 */
+ } else {
+ /*
+ * We'll assume z2 = 1 (special case z2 = 0 is handled later)
+ */
+
+ /* u1 = ftmp3 = x1*z2z2 */
+ felem_assign(ftmp3, x1);
+ /* ftmp3[i] < 2^106 */
+
+ /* ftmp5 = 2z1z2 */
+ felem_assign(ftmp5, z1);
+ felem_scalar(ftmp5, 2);
+ /* ftmp5[i] < 2*2^106 = 2^107 */
+
+ /* s1 = ftmp2 = y1 * z2**3 */
+ felem_assign(ftmp6, y1);
+ /* ftmp6[i] < 2^106 */
+ }
+
+ /* u2 = x2*z1z1 */
+ smallfelem_mul(tmp, x2, small1);
+ felem_reduce(ftmp4, tmp);
+
+ /* h = ftmp4 = u2 - u1 */
+ felem_diff_zero107(ftmp4, ftmp3);
+ /* ftmp4[i] < 2^107 + 2^101 < 2^108 */
+ felem_shrink(small4, ftmp4);
+
+ x_equal = smallfelem_is_zero(small4);
+
+ /* z_out = ftmp5 * h */
+ felem_small_mul(tmp, small4, ftmp5);
+ felem_reduce(z_out, tmp);
+ /* z_out[i] < 2^101 */
+
+ /* ftmp = z1 * z1z1 */
+ smallfelem_mul(tmp, small1, small3);
+ felem_reduce(ftmp, tmp);
+
+ /* s2 = tmp = y2 * z1**3 */
+ felem_small_mul(tmp, y2, ftmp);
+ felem_reduce(ftmp5, tmp);
+
+ /* r = ftmp5 = (s2 - s1)*2 */
+ felem_diff_zero107(ftmp5, ftmp6);
+ /* ftmp5[i] < 2^107 + 2^107 = 2^108 */
+ felem_scalar(ftmp5, 2);
+ /* ftmp5[i] < 2^109 */
+ felem_shrink(small1, ftmp5);
+ y_equal = smallfelem_is_zero(small1);
+
+ if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
+ point_double(x3, y3, z3, x1, y1, z1);
+ return;
+ }
+
+ /* I = ftmp = (2h)**2 */
+ felem_assign(ftmp, ftmp4);
+ felem_scalar(ftmp, 2);
+ /* ftmp[i] < 2*2^108 = 2^109 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp);
+
+ /* J = ftmp2 = h * I */
+ felem_mul(tmp, ftmp4, ftmp);
+ felem_reduce(ftmp2, tmp);
+
+ /* V = ftmp4 = U1 * I */
+ felem_mul(tmp, ftmp3, ftmp);
+ felem_reduce(ftmp4, tmp);
+
+ /* x_out = r**2 - J - 2V */
+ smallfelem_square(tmp, small1);
+ felem_reduce(x_out, tmp);
+ felem_assign(ftmp3, ftmp4);
+ felem_scalar(ftmp4, 2);
+ felem_sum(ftmp4, ftmp2);
+ /* ftmp4[i] < 2*2^101 + 2^101 < 2^103 */
+ felem_diff(x_out, ftmp4);
+ /* x_out[i] < 2^105 + 2^101 */
+
+ /* y_out = r(V-x_out) - 2 * s1 * J */
+ felem_diff_zero107(ftmp3, x_out);
+ /* ftmp3[i] < 2^107 + 2^101 < 2^108 */
+ felem_small_mul(tmp, small1, ftmp3);
+ felem_mul(tmp2, ftmp6, ftmp2);
+ longfelem_scalar(tmp2, 2);
+ /* tmp2[i] < 2*2^67 = 2^68 */
+ longfelem_diff(tmp, tmp2);
+ /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
+ felem_reduce_zero105(y_out, tmp);
+ /* y_out[i] < 2^106 */
+
+ copy_small_conditional(x_out, x2, z1_is_zero);
+ copy_conditional(x_out, x1, z2_is_zero);
+ copy_small_conditional(y_out, y2, z1_is_zero);
+ copy_conditional(y_out, y1, z2_is_zero);
+ copy_small_conditional(z_out, z2, z1_is_zero);
+ copy_conditional(z_out, z1, z2_is_zero);
+ felem_assign(x3, x_out);
+ felem_assign(y3, y_out);
+ felem_assign(z3, z_out);
+}
+
+/*
+ * point_add_small is the same as point_add, except that it operates on
+ * smallfelems
+ */
+static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3,
+ smallfelem x1, smallfelem y1, smallfelem z1,
+ smallfelem x2, smallfelem y2, smallfelem z2)
+{
+ felem felem_x3, felem_y3, felem_z3;
+ felem felem_x1, felem_y1, felem_z1;
+ smallfelem_expand(felem_x1, x1);
+ smallfelem_expand(felem_y1, y1);
+ smallfelem_expand(felem_z1, z1);
+ point_add(felem_x3, felem_y3, felem_z3, felem_x1, felem_y1, felem_z1, 0,
+ x2, y2, z2);
+ felem_shrink(x3, felem_x3);
+ felem_shrink(y3, felem_y3);
+ felem_shrink(z3, felem_z3);
+}
+
+/*-
+ * Base point pre computation
+ * --------------------------
+ *
+ * Two different sorts of precomputed tables are used in the following code.
+ * Each contain various points on the curve, where each point is three field
+ * elements (x, y, z).
+ *
+ * For the base point table, z is usually 1 (0 for the point at infinity).
+ * This table has 2 * 16 elements, starting with the following:
+ * index | bits | point
+ * ------+---------+------------------------------
+ * 0 | 0 0 0 0 | 0G
+ * 1 | 0 0 0 1 | 1G
+ * 2 | 0 0 1 0 | 2^64G
+ * 3 | 0 0 1 1 | (2^64 + 1)G
+ * 4 | 0 1 0 0 | 2^128G
+ * 5 | 0 1 0 1 | (2^128 + 1)G
+ * 6 | 0 1 1 0 | (2^128 + 2^64)G
+ * 7 | 0 1 1 1 | (2^128 + 2^64 + 1)G
+ * 8 | 1 0 0 0 | 2^192G
+ * 9 | 1 0 0 1 | (2^192 + 1)G
+ * 10 | 1 0 1 0 | (2^192 + 2^64)G
+ * 11 | 1 0 1 1 | (2^192 + 2^64 + 1)G
+ * 12 | 1 1 0 0 | (2^192 + 2^128)G
+ * 13 | 1 1 0 1 | (2^192 + 2^128 + 1)G
+ * 14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G
+ * 15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G
+ * followed by a copy of this with each element multiplied by 2^32.
+ *
+ * The reason for this is so that we can clock bits into four different
+ * locations when doing simple scalar multiplies against the base point,
+ * and then another four locations using the second 16 elements.
+ *
+ * Tables for other points have table[i] = iG for i in 0 .. 16. */
+
+/* gmul is the table of precomputed base points */
+static const smallfelem gmul[2][16][3] = {
+ {{{0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+ {{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2,
+ 0x6b17d1f2e12c4247},
+ {0xcbb6406837bf51f5, 0x2bce33576b315ece, 0x8ee7eb4a7c0f9e16,
+ 0x4fe342e2fe1a7f9b},
+ {1, 0, 0, 0}},
+ {{0x90e75cb48e14db63, 0x29493baaad651f7e, 0x8492592e326e25de,
+ 0x0fa822bc2811aaa5},
+ {0xe41124545f462ee7, 0x34b1a65050fe82f5, 0x6f4ad4bcb3df188b,
+ 0xbff44ae8f5dba80d},
+ {1, 0, 0, 0}},
+ {{0x93391ce2097992af, 0xe96c98fd0d35f1fa, 0xb257c0de95e02789,
+ 0x300a4bbc89d6726f},
+ {0xaa54a291c08127a0, 0x5bb1eeada9d806a5, 0x7f1ddb25ff1e3c6f,
+ 0x72aac7e0d09b4644},
+ {1, 0, 0, 0}},
+ {{0x57c84fc9d789bd85, 0xfc35ff7dc297eac3, 0xfb982fd588c6766e,
+ 0x447d739beedb5e67},
+ {0x0c7e33c972e25b32, 0x3d349b95a7fae500, 0xe12e9d953a4aaff7,
+ 0x2d4825ab834131ee},
+ {1, 0, 0, 0}},
+ {{0x13949c932a1d367f, 0xef7fbd2b1a0a11b7, 0xddc6068bb91dfc60,
+ 0xef9519328a9c72ff},
+ {0x196035a77376d8a8, 0x23183b0895ca1740, 0xc1ee9807022c219c,
+ 0x611e9fc37dbb2c9b},
+ {1, 0, 0, 0}},
+ {{0xcae2b1920b57f4bc, 0x2936df5ec6c9bc36, 0x7dea6482e11238bf,
+ 0x550663797b51f5d8},
+ {0x44ffe216348a964c, 0x9fb3d576dbdefbe1, 0x0afa40018d9d50e5,
+ 0x157164848aecb851},
+ {1, 0, 0, 0}},
+ {{0xe48ecafffc5cde01, 0x7ccd84e70d715f26, 0xa2e8f483f43e4391,
+ 0xeb5d7745b21141ea},
+ {0xcac917e2731a3479, 0x85f22cfe2844b645, 0x0990e6a158006cee,
+ 0xeafd72ebdbecc17b},
+ {1, 0, 0, 0}},
+ {{0x6cf20ffb313728be, 0x96439591a3c6b94a, 0x2736ff8344315fc5,
+ 0xa6d39677a7849276},
+ {0xf2bab833c357f5f4, 0x824a920c2284059b, 0x66b8babd2d27ecdf,
+ 0x674f84749b0b8816},
+ {1, 0, 0, 0}},
+ {{0x2df48c04677c8a3e, 0x74e02f080203a56b, 0x31855f7db8c7fedb,
+ 0x4e769e7672c9ddad},
+ {0xa4c36165b824bbb0, 0xfb9ae16f3b9122a5, 0x1ec0057206947281,
+ 0x42b99082de830663},
+ {1, 0, 0, 0}},
+ {{0x6ef95150dda868b9, 0xd1f89e799c0ce131, 0x7fdc1ca008a1c478,
+ 0x78878ef61c6ce04d},
+ {0x9c62b9121fe0d976, 0x6ace570ebde08d4f, 0xde53142c12309def,
+ 0xb6cb3f5d7b72c321},
+ {1, 0, 0, 0}},
+ {{0x7f991ed2c31a3573, 0x5b82dd5bd54fb496, 0x595c5220812ffcae,
+ 0x0c88bc4d716b1287},
+ {0x3a57bf635f48aca8, 0x7c8181f4df2564f3, 0x18d1b5b39c04e6aa,
+ 0xdd5ddea3f3901dc6},
+ {1, 0, 0, 0}},
+ {{0xe96a79fb3e72ad0c, 0x43a0a28c42ba792f, 0xefe0a423083e49f3,
+ 0x68f344af6b317466},
+ {0xcdfe17db3fb24d4a, 0x668bfc2271f5c626, 0x604ed93c24d67ff3,
+ 0x31b9c405f8540a20},
+ {1, 0, 0, 0}},
+ {{0xd36b4789a2582e7f, 0x0d1a10144ec39c28, 0x663c62c3edbad7a0,
+ 0x4052bf4b6f461db9},
+ {0x235a27c3188d25eb, 0xe724f33999bfcc5b, 0x862be6bd71d70cc8,
+ 0xfecf4d5190b0fc61},
+ {1, 0, 0, 0}},
+ {{0x74346c10a1d4cfac, 0xafdf5cc08526a7a4, 0x123202a8f62bff7a,
+ 0x1eddbae2c802e41a},
+ {0x8fa0af2dd603f844, 0x36e06b7e4c701917, 0x0c45f45273db33a0,
+ 0x43104d86560ebcfc},
+ {1, 0, 0, 0}},
+ {{0x9615b5110d1d78e5, 0x66b0de3225c4744b, 0x0a4a46fb6aaf363a,
+ 0xb48e26b484f7a21c},
+ {0x06ebb0f621a01b2d, 0xc004e4048b7b0f98, 0x64131bcdfed6f668,
+ 0xfac015404d4d3dab},
+ {1, 0, 0, 0}}},
+ {{{0, 0, 0, 0},
+ {0, 0, 0, 0},
+ {0, 0, 0, 0}},
+ {{0x3a5a9e22185a5943, 0x1ab919365c65dfb6, 0x21656b32262c71da,
+ 0x7fe36b40af22af89},
+ {0xd50d152c699ca101, 0x74b3d5867b8af212, 0x9f09f40407dca6f1,
+ 0xe697d45825b63624},
+ {1, 0, 0, 0}},
+ {{0xa84aa9397512218e, 0xe9a521b074ca0141, 0x57880b3a18a2e902,
+ 0x4a5b506612a677a6},
+ {0x0beada7a4c4f3840, 0x626db15419e26d9d, 0xc42604fbe1627d40,
+ 0xeb13461ceac089f1},
+ {1, 0, 0, 0}},
+ {{0xf9faed0927a43281, 0x5e52c4144103ecbc, 0xc342967aa815c857,
+ 0x0781b8291c6a220a},
+ {0x5a8343ceeac55f80, 0x88f80eeee54a05e3, 0x97b2a14f12916434,
+ 0x690cde8df0151593},
+ {1, 0, 0, 0}},
+ {{0xaee9c75df7f82f2a, 0x9e4c35874afdf43a, 0xf5622df437371326,
+ 0x8a535f566ec73617},
+ {0xc5f9a0ac223094b7, 0xcde533864c8c7669, 0x37e02819085a92bf,
+ 0x0455c08468b08bd7},
+ {1, 0, 0, 0}},
+ {{0x0c0a6e2c9477b5d9, 0xf9a4bf62876dc444, 0x5050a949b6cdc279,
+ 0x06bada7ab77f8276},
+ {0xc8b4aed1ea48dac9, 0xdebd8a4b7ea1070f, 0x427d49101366eb70,
+ 0x5b476dfd0e6cb18a},
+ {1, 0, 0, 0}},
+ {{0x7c5c3e44278c340a, 0x4d54606812d66f3b, 0x29a751b1ae23c5d8,
+ 0x3e29864e8a2ec908},
+ {0x142d2a6626dbb850, 0xad1744c4765bd780, 0x1f150e68e322d1ed,
+ 0x239b90ea3dc31e7e},
+ {1, 0, 0, 0}},
+ {{0x78c416527a53322a, 0x305dde6709776f8e, 0xdbcab759f8862ed4,
+ 0x820f4dd949f72ff7},
+ {0x6cc544a62b5debd4, 0x75be5d937b4e8cc4, 0x1b481b1b215c14d3,
+ 0x140406ec783a05ec},
+ {1, 0, 0, 0}},
+ {{0x6a703f10e895df07, 0xfd75f3fa01876bd8, 0xeb5b06e70ce08ffe,
+ 0x68f6b8542783dfee},
+ {0x90c76f8a78712655, 0xcf5293d2f310bf7f, 0xfbc8044dfda45028,
+ 0xcbe1feba92e40ce6},
+ {1, 0, 0, 0}},
+ {{0xe998ceea4396e4c1, 0xfc82ef0b6acea274, 0x230f729f2250e927,
+ 0xd0b2f94d2f420109},
+ {0x4305adddb38d4966, 0x10b838f8624c3b45, 0x7db2636658954e7a,
+ 0x971459828b0719e5},
+ {1, 0, 0, 0}},
+ {{0x4bd6b72623369fc9, 0x57f2929e53d0b876, 0xc2d5cba4f2340687,
+ 0x961610004a866aba},
+ {0x49997bcd2e407a5e, 0x69ab197d92ddcb24, 0x2cf1f2438fe5131c,
+ 0x7acb9fadcee75e44},
+ {1, 0, 0, 0}},
+ {{0x254e839423d2d4c0, 0xf57f0c917aea685b, 0xa60d880f6f75aaea,
+ 0x24eb9acca333bf5b},
+ {0xe3de4ccb1cda5dea, 0xfeef9341c51a6b4f, 0x743125f88bac4c4d,
+ 0x69f891c5acd079cc},
+ {1, 0, 0, 0}},
+ {{0xeee44b35702476b5, 0x7ed031a0e45c2258, 0xb422d1e7bd6f8514,
+ 0xe51f547c5972a107},
+ {0xa25bcd6fc9cf343d, 0x8ca922ee097c184e, 0xa62f98b3a9fe9a06,
+ 0x1c309a2b25bb1387},
+ {1, 0, 0, 0}},
+ {{0x9295dbeb1967c459, 0xb00148833472c98e, 0xc504977708011828,
+ 0x20b87b8aa2c4e503},
+ {0x3063175de057c277, 0x1bd539338fe582dd, 0x0d11adef5f69a044,
+ 0xf5c6fa49919776be},
+ {1, 0, 0, 0}},
+ {{0x8c944e760fd59e11, 0x3876cba1102fad5f, 0xa454c3fad83faa56,
+ 0x1ed7d1b9332010b9},
+ {0xa1011a270024b889, 0x05e4d0dcac0cd344, 0x52b520f0eb6a2a24,
+ 0x3a2b03f03217257a},
+ {1, 0, 0, 0}},
+ {{0xf20fc2afdf1d043d, 0xf330240db58d5a62, 0xfc7d229ca0058c3b,
+ 0x15fee545c78dd9f6},
+ {0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb,
+ 0x4ab5b6b2b8753f81},
+ {1, 0, 0, 0}}}
+};
+
+/*
+ * select_point selects the |idx|th point from a precomputation table and
+ * copies it to out.
+ */
+static void select_point(const u64 idx, unsigned int size,
+ const smallfelem pre_comp[16][3], smallfelem out[3])
+{
+ unsigned i, j;
+ u64 *outlimbs = &out[0][0];
+ memset(outlimbs, 0, 3 * sizeof(smallfelem));
+
+ for (i = 0; i < size; i++) {
+ const u64 *inlimbs = (u64 *)&pre_comp[i][0][0];
+ u64 mask = i ^ idx;
+ mask |= mask >> 4;
+ mask |= mask >> 2;
+ mask |= mask >> 1;
+ mask &= 1;
+ mask--;
+ for (j = 0; j < NLIMBS * 3; j++)
+ outlimbs[j] |= inlimbs[j] & mask;
+ }
+}
+
+/* get_bit returns the |i|th bit in |in| */
+static char get_bit(const felem_bytearray in, int i)
+{
+ if ((i < 0) || (i >= 256))
+ return 0;
+ return (in[i >> 3] >> (i & 7)) & 1;
+}
+
+/*
+ * Interleaved point multiplication using precomputed point multiples: The
+ * small point multiples 0*P, 1*P, ..., 17*P are in pre_comp[], the scalars
+ * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the
+ * generator, using certain (large) precomputed multiples in g_pre_comp.
+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out
+ */
+static void batch_mul(felem x_out, felem y_out, felem z_out,
+ const felem_bytearray scalars[],
+ const unsigned num_points, const u8 *g_scalar,
+ const int mixed, const smallfelem pre_comp[][17][3],
+ const smallfelem g_pre_comp[2][16][3])
+{
+ int i, skip;
+ unsigned num, gen_mul = (g_scalar != NULL);
+ felem nq[3], ftmp;
+ smallfelem tmp[3];
+ u64 bits;
+ u8 sign, digit;
+
+ /* set nq to the point at infinity */
+ memset(nq, 0, 3 * sizeof(felem));
+
+ /*
+ * Loop over all scalars msb-to-lsb, interleaving additions of multiples
+ * of the generator (two in each of the last 32 rounds) and additions of
+ * other points multiples (every 5th round).
+ */
+ skip = 1; /* save two point operations in the first
+ * round */
+ for (i = (num_points ? 255 : 31); i >= 0; --i) {
+ /* double */
+ if (!skip)
+ point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+
+ /* add multiples of the generator */
+ if (gen_mul && (i <= 31)) {
+ /* first, look 32 bits upwards */
+ bits = get_bit(g_scalar, i + 224) << 3;
+ bits |= get_bit(g_scalar, i + 160) << 2;
+ bits |= get_bit(g_scalar, i + 96) << 1;
+ bits |= get_bit(g_scalar, i + 32);
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp[1], tmp);
+
+ if (!skip) {
+ /* Arg 1 below is for "mixed" */
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]);
+ } else {
+ smallfelem_expand(nq[0], tmp[0]);
+ smallfelem_expand(nq[1], tmp[1]);
+ smallfelem_expand(nq[2], tmp[2]);
+ skip = 0;
+ }
+
+ /* second, look at the current position */
+ bits = get_bit(g_scalar, i + 192) << 3;
+ bits |= get_bit(g_scalar, i + 128) << 2;
+ bits |= get_bit(g_scalar, i + 64) << 1;
+ bits |= get_bit(g_scalar, i);
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp[0], tmp);
+ /* Arg 1 below is for "mixed" */
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]);
+ }
+
+ /* do other additions every 5 doublings */
+ if (num_points && (i % 5 == 0)) {
+ /* loop over all scalars */
+ for (num = 0; num < num_points; ++num) {
+ bits = get_bit(scalars[num], i + 4) << 5;
+ bits |= get_bit(scalars[num], i + 3) << 4;
+ bits |= get_bit(scalars[num], i + 2) << 3;
+ bits |= get_bit(scalars[num], i + 1) << 2;
+ bits |= get_bit(scalars[num], i) << 1;
+ bits |= get_bit(scalars[num], i - 1);
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+ /*
+ * select the point to add or subtract, in constant time
+ */
+ select_point(digit, 17, pre_comp[num], tmp);
+ smallfelem_neg(ftmp, tmp[1]); /* (X, -Y, Z) is the negative
+ * point */
+ copy_small_conditional(ftmp, tmp[1], (((limb) sign) - 1));
+ felem_contract(tmp[1], ftmp);
+
+ if (!skip) {
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2],
+ mixed, tmp[0], tmp[1], tmp[2]);
+ } else {
+ smallfelem_expand(nq[0], tmp[0]);
+ smallfelem_expand(nq[1], tmp[1]);
+ smallfelem_expand(nq[2], tmp[2]);
+ skip = 0;
+ }
+ }
+ }
+ }
+ felem_assign(x_out, nq[0]);
+ felem_assign(y_out, nq[1]);
+ felem_assign(z_out, nq[2]);
+}
+
+/* Precomputation for the group generator. */
+typedef struct {
+ smallfelem g_pre_comp[2][16][3];
+ int references;
+} NISTP256_PRE_COMP;
+
+const EC_METHOD *EC_GFp_nistp256_method(void)
+{
+ static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
+ NID_X9_62_prime_field,
+ ec_GFp_nistp256_group_init,
+ ec_GFp_simple_group_finish,
+ ec_GFp_simple_group_clear_finish,
+ ec_GFp_nist_group_copy,
+ ec_GFp_nistp256_group_set_curve,
+ ec_GFp_simple_group_get_curve,
+ ec_GFp_simple_group_get_degree,
+ ec_GFp_simple_group_check_discriminant,
+ ec_GFp_simple_point_init,
+ ec_GFp_simple_point_finish,
+ ec_GFp_simple_point_clear_finish,
+ ec_GFp_simple_point_copy,
+ ec_GFp_simple_point_set_to_infinity,
+ ec_GFp_simple_set_Jprojective_coordinates_GFp,
+ ec_GFp_simple_get_Jprojective_coordinates_GFp,
+ ec_GFp_simple_point_set_affine_coordinates,
+ ec_GFp_nistp256_point_get_affine_coordinates,
+ 0 /* point_set_compressed_coordinates */ ,
+ 0 /* point2oct */ ,
+ 0 /* oct2point */ ,
+ ec_GFp_simple_add,
+ ec_GFp_simple_dbl,
+ ec_GFp_simple_invert,
+ ec_GFp_simple_is_at_infinity,
+ ec_GFp_simple_is_on_curve,
+ ec_GFp_simple_cmp,
+ ec_GFp_simple_make_affine,
+ ec_GFp_simple_points_make_affine,
+ ec_GFp_nistp256_points_mul,
+ ec_GFp_nistp256_precompute_mult,
+ ec_GFp_nistp256_have_precompute_mult,
+ ec_GFp_nist_field_mul,
+ ec_GFp_nist_field_sqr,
+ 0 /* field_div */ ,
+ 0 /* field_encode */ ,
+ 0 /* field_decode */ ,
+ 0 /* field_set_to_one */
+ };
+
+ return &ret;
+}
+
+/******************************************************************************/
+/*
+ * FUNCTIONS TO MANAGE PRECOMPUTATION
+ */
+
+static NISTP256_PRE_COMP *nistp256_pre_comp_new()
+{
+ NISTP256_PRE_COMP *ret = NULL;
+ ret = (NISTP256_PRE_COMP *) OPENSSL_malloc(sizeof *ret);
+ if (!ret) {
+ ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ return ret;
+ }
+ memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
+ ret->references = 1;
+ return ret;
+}
+
+static void *nistp256_pre_comp_dup(void *src_)
+{
+ NISTP256_PRE_COMP *src = src_;
+
+ /* no need to actually copy, these objects never change! */
+ CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+
+ return src_;
+}
+
+static void nistp256_pre_comp_free(void *pre_)
+{
+ int i;
+ NISTP256_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ OPENSSL_free(pre);
+}
+
+static void nistp256_pre_comp_clear_free(void *pre_)
+{
+ int i;
+ NISTP256_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ OPENSSL_cleanse(pre, sizeof *pre);
+ OPENSSL_free(pre);
+}
+
+/******************************************************************************/
+/*
+ * OPENSSL EC_METHOD FUNCTIONS
+ */
+
+int ec_GFp_nistp256_group_init(EC_GROUP *group)
+{
+ int ret;
+ ret = ec_GFp_simple_group_init(group);
+ group->a_is_minus3 = 1;
+ return ret;
+}
+
+int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *ctx)
+{
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *curve_p, *curve_a, *curve_b;
+
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+ return 0;
+ BN_CTX_start(ctx);
+ if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_a = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_b = BN_CTX_get(ctx)) == NULL))
+ goto err;
+ BN_bin2bn(nistp256_curve_params[0], sizeof(felem_bytearray), curve_p);
+ BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a);
+ BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b);
+ if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
+ ECerr(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE,
+ EC_R_WRONG_CURVE_PARAMETERS);
+ goto err;
+ }
+ group->field_mod_func = BN_nist_mod_256;
+ ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+/*
+ * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
+ * (X/Z^2, Y/Z^3)
+ */
+int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx)
+{
+ felem z1, z2, x_in, y_in;
+ smallfelem x_out, y_out;
+ longfelem tmp;
+
+ if (EC_POINT_is_at_infinity(group, point)) {
+ ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
+ EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+ if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
+ (!BN_to_felem(z1, &point->Z)))
+ return 0;
+ felem_inv(z2, z1);
+ felem_square(tmp, z2);
+ felem_reduce(z1, tmp);
+ felem_mul(tmp, x_in, z1);
+ felem_reduce(x_in, tmp);
+ felem_contract(x_out, x_in);
+ if (x != NULL) {
+ if (!smallfelem_to_BN(x, x_out)) {
+ ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
+ ERR_R_BN_LIB);
+ return 0;
+ }
+ }
+ felem_mul(tmp, z1, z2);
+ felem_reduce(z1, tmp);
+ felem_mul(tmp, y_in, z1);
+ felem_reduce(y_in, tmp);
+ felem_contract(y_out, y_in);
+ if (y != NULL) {
+ if (!smallfelem_to_BN(y, y_out)) {
+ ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
+ ERR_R_BN_LIB);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* points below is of size |num|, and tmp_smallfelems is of size |num+1| */
+static void make_points_affine(size_t num, smallfelem points[][3],
+ smallfelem tmp_smallfelems[])
+{
+ /*
+ * Runs in constant time, unless an input is the point at infinity (which
+ * normally shouldn't happen).
+ */
+ ec_GFp_nistp_points_make_affine_internal(num,
+ points,
+ sizeof(smallfelem),
+ tmp_smallfelems,
+ (void (*)(void *))smallfelem_one,
+ (int (*)(const void *))
+ smallfelem_is_zero_int,
+ (void (*)(void *, const void *))
+ smallfelem_assign,
+ (void (*)(void *, const void *))
+ smallfelem_square_contract,
+ (void (*)
+ (void *, const void *,
+ const void *))
+ smallfelem_mul_contract,
+ (void (*)(void *, const void *))
+ smallfelem_inv_contract,
+ /* nothing to contract */
+ (void (*)(void *, const void *))
+ smallfelem_assign);
+}
+
+/*
+ * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
+ * values Result is stored in r (r can equal one of the inputs).
+ */
+int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx)
+{
+ int ret = 0;
+ int j;
+ int mixed = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y, *z, *tmp_scalar;
+ felem_bytearray g_secret;
+ felem_bytearray *secrets = NULL;
+ smallfelem(*pre_comp)[17][3] = NULL;
+ smallfelem *tmp_smallfelems = NULL;
+ felem_bytearray tmp;
+ unsigned i, num_bytes;
+ int have_pre_comp = 0;
+ size_t num_points = num;
+ smallfelem x_in, y_in, z_in;
+ felem x_out, y_out, z_out;
+ NISTP256_PRE_COMP *pre = NULL;
+ const smallfelem(*g_pre_comp)[16][3] = NULL;
+ EC_POINT *generator = NULL;
+ const EC_POINT *p = NULL;
+ const BIGNUM *p_scalar = NULL;
+
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+ return 0;
+ BN_CTX_start(ctx);
+ if (((x = BN_CTX_get(ctx)) == NULL) ||
+ ((y = BN_CTX_get(ctx)) == NULL) ||
+ ((z = BN_CTX_get(ctx)) == NULL) ||
+ ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
+ goto err;
+
+ if (scalar != NULL) {
+ pre = EC_EX_DATA_get_data(group->extra_data,
+ nistp256_pre_comp_dup,
+ nistp256_pre_comp_free,
+ nistp256_pre_comp_clear_free);
+ if (pre)
+ /* we have precomputation, try to use it */
+ g_pre_comp = (const smallfelem(*)[16][3])pre->g_pre_comp;
+ else
+ /* try to use the standard precomputation */
+ g_pre_comp = &gmul[0];
+ generator = EC_POINT_new(group);
+ if (generator == NULL)
+ goto err;
+ /* get the generator from precomputation */
+ if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) ||
+ !smallfelem_to_BN(y, g_pre_comp[0][1][1]) ||
+ !smallfelem_to_BN(z, g_pre_comp[0][1][2])) {
+ ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
+ generator, x, y, z,
+ ctx))
+ goto err;
+ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
+ /* precomputation matches generator */
+ have_pre_comp = 1;
+ else
+ /*
+ * we don't have valid precomputation: treat the generator as a
+ * random point
+ */
+ num_points++;
+ }
+ if (num_points > 0) {
+ if (num_points >= 3) {
+ /*
+ * unless we precompute multiples for just one or two points,
+ * converting those into affine form is time well spent
+ */
+ mixed = 1;
+ }
+ secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
+ pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(smallfelem));
+ if (mixed)
+ tmp_smallfelems =
+ OPENSSL_malloc((num_points * 17 + 1) * sizeof(smallfelem));
+ if ((secrets == NULL) || (pre_comp == NULL)
+ || (mixed && (tmp_smallfelems == NULL))) {
+ ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /*
+ * we treat NULL scalars as 0, and NULL points as points at infinity,
+ * i.e., they contribute nothing to the linear combination
+ */
+ memset(secrets, 0, num_points * sizeof(felem_bytearray));
+ memset(pre_comp, 0, num_points * 17 * 3 * sizeof(smallfelem));
+ for (i = 0; i < num_points; ++i) {
+ if (i == num)
+ /*
+ * we didn't have a valid precomputation, so we pick the
+ * generator
+ */
+ {
+ p = EC_GROUP_get0_generator(group);
+ p_scalar = scalar;
+ } else
+ /* the i^th point */
+ {
+ p = points[i];
+ p_scalar = scalars[i];
+ }
+ if ((p_scalar != NULL) && (p != NULL)) {
+ /* reduce scalar to 0 <= scalar < 2^256 */
+ if ((BN_num_bits(p_scalar) > 256)
+ || (BN_is_negative(p_scalar))) {
+ /*
+ * this is an unusual input, and we don't guarantee
+ * constant-timeness
+ */
+ if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) {
+ ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ } else
+ num_bytes = BN_bn2bin(p_scalar, tmp);
+ flip_endian(secrets[i], tmp, num_bytes);
+ /* precompute multiples */
+ if ((!BN_to_felem(x_out, &p->X)) ||
+ (!BN_to_felem(y_out, &p->Y)) ||
+ (!BN_to_felem(z_out, &p->Z)))
+ goto err;
+ felem_shrink(pre_comp[i][1][0], x_out);
+ felem_shrink(pre_comp[i][1][1], y_out);
+ felem_shrink(pre_comp[i][1][2], z_out);
+ for (j = 2; j <= 16; ++j) {
+ if (j & 1) {
+ point_add_small(pre_comp[i][j][0], pre_comp[i][j][1],
+ pre_comp[i][j][2], pre_comp[i][1][0],
+ pre_comp[i][1][1], pre_comp[i][1][2],
+ pre_comp[i][j - 1][0],
+ pre_comp[i][j - 1][1],
+ pre_comp[i][j - 1][2]);
+ } else {
+ point_double_small(pre_comp[i][j][0],
+ pre_comp[i][j][1],
+ pre_comp[i][j][2],
+ pre_comp[i][j / 2][0],
+ pre_comp[i][j / 2][1],
+ pre_comp[i][j / 2][2]);
+ }
+ }
+ }
+ }
+ if (mixed)
+ make_points_affine(num_points * 17, pre_comp[0], tmp_smallfelems);
+ }
+
+ /* the scalar for the generator */
+ if ((scalar != NULL) && (have_pre_comp)) {
+ memset(g_secret, 0, sizeof(g_secret));
+ /* reduce scalar to 0 <= scalar < 2^256 */
+ if ((BN_num_bits(scalar) > 256) || (BN_is_negative(scalar))) {
+ /*
+ * this is an unusual input, and we don't guarantee
+ * constant-timeness
+ */
+ if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
+ ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ } else
+ num_bytes = BN_bn2bin(scalar, tmp);
+ flip_endian(g_secret, tmp, num_bytes);
+ /* do the multiplication with generator precomputation */
+ batch_mul(x_out, y_out, z_out,
+ (const felem_bytearray(*))secrets, num_points,
+ g_secret,
+ mixed, (const smallfelem(*)[17][3])pre_comp, g_pre_comp);
+ } else
+ /* do the multiplication without generator precomputation */
+ batch_mul(x_out, y_out, z_out,
+ (const felem_bytearray(*))secrets, num_points,
+ NULL, mixed, (const smallfelem(*)[17][3])pre_comp, NULL);
+ /* reduce the output to its unique minimal representation */
+ felem_contract(x_in, x_out);
+ felem_contract(y_in, y_out);
+ felem_contract(z_in, z_out);
+ if ((!smallfelem_to_BN(x, x_in)) || (!smallfelem_to_BN(y, y_in)) ||
+ (!smallfelem_to_BN(z, z_in))) {
+ ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+
+ err:
+ BN_CTX_end(ctx);
+ if (generator != NULL)
+ EC_POINT_free(generator);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (secrets != NULL)
+ OPENSSL_free(secrets);
+ if (pre_comp != NULL)
+ OPENSSL_free(pre_comp);
+ if (tmp_smallfelems != NULL)
+ OPENSSL_free(tmp_smallfelems);
+ return ret;
+}
+
+int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+{
+ int ret = 0;
+ NISTP256_PRE_COMP *pre = NULL;
+ int i, j;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y;
+ EC_POINT *generator = NULL;
+ smallfelem tmp_smallfelems[32];
+ felem x_tmp, y_tmp, z_tmp;
+
+ /* throw away old precomputation */
+ EC_EX_DATA_free_data(&group->extra_data, nistp256_pre_comp_dup,
+ nistp256_pre_comp_free,
+ nistp256_pre_comp_clear_free);
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+ return 0;
+ BN_CTX_start(ctx);
+ if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL))
+ goto err;
+ /* get the generator */
+ if (group->generator == NULL)
+ goto err;
+ generator = EC_POINT_new(group);
+ if (generator == NULL)
+ goto err;
+ BN_bin2bn(nistp256_curve_params[3], sizeof(felem_bytearray), x);
+ BN_bin2bn(nistp256_curve_params[4], sizeof(felem_bytearray), y);
+ if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
+ goto err;
+ if ((pre = nistp256_pre_comp_new()) == NULL)
+ goto err;
+ /*
+ * if the generator is the standard one, use built-in precomputation
+ */
+ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
+ memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
+ ret = 1;
+ goto err;
+ }
+ if ((!BN_to_felem(x_tmp, &group->generator->X)) ||
+ (!BN_to_felem(y_tmp, &group->generator->Y)) ||
+ (!BN_to_felem(z_tmp, &group->generator->Z)))
+ goto err;
+ felem_shrink(pre->g_pre_comp[0][1][0], x_tmp);
+ felem_shrink(pre->g_pre_comp[0][1][1], y_tmp);
+ felem_shrink(pre->g_pre_comp[0][1][2], z_tmp);
+ /*
+ * compute 2^64*G, 2^128*G, 2^192*G for the first table, 2^32*G, 2^96*G,
+ * 2^160*G, 2^224*G for the second one
+ */
+ for (i = 1; i <= 8; i <<= 1) {
+ point_double_small(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1],
+ pre->g_pre_comp[1][i][2], pre->g_pre_comp[0][i][0],
+ pre->g_pre_comp[0][i][1],
+ pre->g_pre_comp[0][i][2]);
+ for (j = 0; j < 31; ++j) {
+ point_double_small(pre->g_pre_comp[1][i][0],
+ pre->g_pre_comp[1][i][1],
+ pre->g_pre_comp[1][i][2],
+ pre->g_pre_comp[1][i][0],
+ pre->g_pre_comp[1][i][1],
+ pre->g_pre_comp[1][i][2]);
+ }
+ if (i == 8)
+ break;
+ point_double_small(pre->g_pre_comp[0][2 * i][0],
+ pre->g_pre_comp[0][2 * i][1],
+ pre->g_pre_comp[0][2 * i][2],
+ pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1],
+ pre->g_pre_comp[1][i][2]);
+ for (j = 0; j < 31; ++j) {
+ point_double_small(pre->g_pre_comp[0][2 * i][0],
+ pre->g_pre_comp[0][2 * i][1],
+ pre->g_pre_comp[0][2 * i][2],
+ pre->g_pre_comp[0][2 * i][0],
+ pre->g_pre_comp[0][2 * i][1],
+ pre->g_pre_comp[0][2 * i][2]);
+ }
+ }
+ for (i = 0; i < 2; i++) {
+ /* g_pre_comp[i][0] is the point at infinity */
+ memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
+ /* the remaining multiples */
+ /* 2^64*G + 2^128*G resp. 2^96*G + 2^160*G */
+ point_add_small(pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1],
+ pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0],
+ pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
+ pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+ pre->g_pre_comp[i][2][2]);
+ /* 2^64*G + 2^192*G resp. 2^96*G + 2^224*G */
+ point_add_small(pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1],
+ pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0],
+ pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
+ pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+ pre->g_pre_comp[i][2][2]);
+ /* 2^128*G + 2^192*G resp. 2^160*G + 2^224*G */
+ point_add_small(pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1],
+ pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0],
+ pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
+ pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1],
+ pre->g_pre_comp[i][4][2]);
+ /*
+ * 2^64*G + 2^128*G + 2^192*G resp. 2^96*G + 2^160*G + 2^224*G
+ */
+ point_add_small(pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1],
+ pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0],
+ pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
+ pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+ pre->g_pre_comp[i][2][2]);
+ for (j = 1; j < 8; ++j) {
+ /* odd multiples: add G resp. 2^32*G */
+ point_add_small(pre->g_pre_comp[i][2 * j + 1][0],
+ pre->g_pre_comp[i][2 * j + 1][1],
+ pre->g_pre_comp[i][2 * j + 1][2],
+ pre->g_pre_comp[i][2 * j][0],
+ pre->g_pre_comp[i][2 * j][1],
+ pre->g_pre_comp[i][2 * j][2],
+ pre->g_pre_comp[i][1][0],
+ pre->g_pre_comp[i][1][1],
+ pre->g_pre_comp[i][1][2]);
+ }
+ }
+ make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_smallfelems);
+
+ if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp256_pre_comp_dup,
+ nistp256_pre_comp_free,
+ nistp256_pre_comp_clear_free))
+ goto err;
+ ret = 1;
+ pre = NULL;
+ err:
+ BN_CTX_end(ctx);
+ if (generator != NULL)
+ EC_POINT_free(generator);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (pre)
+ nistp256_pre_comp_free(pre);
+ return ret;
+}
+
+int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group)
+{
+ if (EC_EX_DATA_get_data(group->extra_data, nistp256_pre_comp_dup,
+ nistp256_pre_comp_free,
+ nistp256_pre_comp_clear_free)
+ != NULL)
+ return 1;
+ else
+ return 0;
+}
+#else
+static void *dummy = &dummy;
+#endif
diff --git a/openssl/ec/ecp_nistp521.c b/openssl/ec/ecp_nistp521.c
new file mode 100644
index 0000000..cc76345
--- /dev/null
+++ b/openssl/ec/ecp_nistp521.c
@@ -0,0 +1,2148 @@
+/* crypto/ec/ecp_nistp521.c */
+/*
+ * Written by Adam Langley (Google) for the OpenSSL project
+ */
+/* Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ *
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * A 64-bit implementation of the NIST P-521 elliptic curve point multiplication
+ *
+ * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
+ * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
+ * work which got its smarts from Daniel J. Bernstein's work on the same.
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+
+# ifndef OPENSSL_SYS_VMS
+# include <stdint.h>
+# else
+# include <inttypes.h>
+# endif
+
+# include <string.h>
+# include <openssl/err.h>
+# include "ec_lcl.h"
+
+# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+ /* even with gcc, the typedef won't work for 32-bit platforms */
+typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit
+ * platforms */
+# else
+# error "Need GCC 3.1 or later to define type uint128_t"
+# endif
+
+typedef uint8_t u8;
+typedef uint64_t u64;
+typedef int64_t s64;
+
+/*
+ * The underlying field. P521 operates over GF(2^521-1). We can serialise an
+ * element of this field into 66 bytes where the most significant byte
+ * contains only a single bit. We call this an felem_bytearray.
+ */
+
+typedef u8 felem_bytearray[66];
+
+/*
+ * These are the parameters of P521, taken from FIPS 186-3, section D.1.2.5.
+ * These values are big-endian.
+ */
+static const felem_bytearray nistp521_curve_params[5] = {
+ {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* p */
+ 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* a = -3 */
+ 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, 0xfc},
+ {0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, /* b */
+ 0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85,
+ 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3,
+ 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1,
+ 0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
+ 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1,
+ 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c,
+ 0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50,
+ 0x3f, 0x00},
+ {0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, /* x */
+ 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95,
+ 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
+ 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d,
+ 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
+ 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
+ 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a,
+ 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5,
+ 0xbd, 0x66},
+ {0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, /* y */
+ 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d,
+ 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
+ 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e,
+ 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
+ 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
+ 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72,
+ 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1,
+ 0x66, 0x50}
+};
+
+/*-
+ * The representation of field elements.
+ * ------------------------------------
+ *
+ * We represent field elements with nine values. These values are either 64 or
+ * 128 bits and the field element represented is:
+ * v[0]*2^0 + v[1]*2^58 + v[2]*2^116 + ... + v[8]*2^464 (mod p)
+ * Each of the nine values is called a 'limb'. Since the limbs are spaced only
+ * 58 bits apart, but are greater than 58 bits in length, the most significant
+ * bits of each limb overlap with the least significant bits of the next.
+ *
+ * A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a
+ * 'largefelem' */
+
+# define NLIMBS 9
+
+typedef uint64_t limb;
+typedef limb felem[NLIMBS];
+typedef uint128_t largefelem[NLIMBS];
+
+static const limb bottom57bits = 0x1ffffffffffffff;
+static const limb bottom58bits = 0x3ffffffffffffff;
+
+/*
+ * bin66_to_felem takes a little-endian byte array and converts it into felem
+ * form. This assumes that the CPU is little-endian.
+ */
+static void bin66_to_felem(felem out, const u8 in[66])
+{
+ out[0] = (*((limb *) & in[0])) & bottom58bits;
+ out[1] = (*((limb *) & in[7]) >> 2) & bottom58bits;
+ out[2] = (*((limb *) & in[14]) >> 4) & bottom58bits;
+ out[3] = (*((limb *) & in[21]) >> 6) & bottom58bits;
+ out[4] = (*((limb *) & in[29])) & bottom58bits;
+ out[5] = (*((limb *) & in[36]) >> 2) & bottom58bits;
+ out[6] = (*((limb *) & in[43]) >> 4) & bottom58bits;
+ out[7] = (*((limb *) & in[50]) >> 6) & bottom58bits;
+ out[8] = (*((limb *) & in[58])) & bottom57bits;
+}
+
+/*
+ * felem_to_bin66 takes an felem and serialises into a little endian, 66 byte
+ * array. This assumes that the CPU is little-endian.
+ */
+static void felem_to_bin66(u8 out[66], const felem in)
+{
+ memset(out, 0, 66);
+ (*((limb *) & out[0])) = in[0];
+ (*((limb *) & out[7])) |= in[1] << 2;
+ (*((limb *) & out[14])) |= in[2] << 4;
+ (*((limb *) & out[21])) |= in[3] << 6;
+ (*((limb *) & out[29])) = in[4];
+ (*((limb *) & out[36])) |= in[5] << 2;
+ (*((limb *) & out[43])) |= in[6] << 4;
+ (*((limb *) & out[50])) |= in[7] << 6;
+ (*((limb *) & out[58])) = in[8];
+}
+
+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
+static void flip_endian(u8 *out, const u8 *in, unsigned len)
+{
+ unsigned i;
+ for (i = 0; i < len; ++i)
+ out[i] = in[len - 1 - i];
+}
+
+/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
+static int BN_to_felem(felem out, const BIGNUM *bn)
+{
+ felem_bytearray b_in;
+ felem_bytearray b_out;
+ unsigned num_bytes;
+
+ /* BN_bn2bin eats leading zeroes */
+ memset(b_out, 0, sizeof b_out);
+ num_bytes = BN_num_bytes(bn);
+ if (num_bytes > sizeof b_out) {
+ ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+ if (BN_is_negative(bn)) {
+ ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+ return 0;
+ }
+ num_bytes = BN_bn2bin(bn, b_in);
+ flip_endian(b_out, b_in, num_bytes);
+ bin66_to_felem(out, b_out);
+ return 1;
+}
+
+/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
+static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
+{
+ felem_bytearray b_in, b_out;
+ felem_to_bin66(b_in, in);
+ flip_endian(b_out, b_in, sizeof b_out);
+ return BN_bin2bn(b_out, sizeof b_out, out);
+}
+
+/*-
+ * Field operations
+ * ----------------
+ */
+
+static void felem_one(felem out)
+{
+ out[0] = 1;
+ out[1] = 0;
+ out[2] = 0;
+ out[3] = 0;
+ out[4] = 0;
+ out[5] = 0;
+ out[6] = 0;
+ out[7] = 0;
+ out[8] = 0;
+}
+
+static void felem_assign(felem out, const felem in)
+{
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+ out[4] = in[4];
+ out[5] = in[5];
+ out[6] = in[6];
+ out[7] = in[7];
+ out[8] = in[8];
+}
+
+/* felem_sum64 sets out = out + in. */
+static void felem_sum64(felem out, const felem in)
+{
+ out[0] += in[0];
+ out[1] += in[1];
+ out[2] += in[2];
+ out[3] += in[3];
+ out[4] += in[4];
+ out[5] += in[5];
+ out[6] += in[6];
+ out[7] += in[7];
+ out[8] += in[8];
+}
+
+/* felem_scalar sets out = in * scalar */
+static void felem_scalar(felem out, const felem in, limb scalar)
+{
+ out[0] = in[0] * scalar;
+ out[1] = in[1] * scalar;
+ out[2] = in[2] * scalar;
+ out[3] = in[3] * scalar;
+ out[4] = in[4] * scalar;
+ out[5] = in[5] * scalar;
+ out[6] = in[6] * scalar;
+ out[7] = in[7] * scalar;
+ out[8] = in[8] * scalar;
+}
+
+/* felem_scalar64 sets out = out * scalar */
+static void felem_scalar64(felem out, limb scalar)
+{
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+ out[4] *= scalar;
+ out[5] *= scalar;
+ out[6] *= scalar;
+ out[7] *= scalar;
+ out[8] *= scalar;
+}
+
+/* felem_scalar128 sets out = out * scalar */
+static void felem_scalar128(largefelem out, limb scalar)
+{
+ out[0] *= scalar;
+ out[1] *= scalar;
+ out[2] *= scalar;
+ out[3] *= scalar;
+ out[4] *= scalar;
+ out[5] *= scalar;
+ out[6] *= scalar;
+ out[7] *= scalar;
+ out[8] *= scalar;
+}
+
+/*-
+ * felem_neg sets |out| to |-in|
+ * On entry:
+ * in[i] < 2^59 + 2^14
+ * On exit:
+ * out[i] < 2^62
+ */
+static void felem_neg(felem out, const felem in)
+{
+ /* In order to prevent underflow, we subtract from 0 mod p. */
+ static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5);
+ static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4);
+
+ out[0] = two62m3 - in[0];
+ out[1] = two62m2 - in[1];
+ out[2] = two62m2 - in[2];
+ out[3] = two62m2 - in[3];
+ out[4] = two62m2 - in[4];
+ out[5] = two62m2 - in[5];
+ out[6] = two62m2 - in[6];
+ out[7] = two62m2 - in[7];
+ out[8] = two62m2 - in[8];
+}
+
+/*-
+ * felem_diff64 subtracts |in| from |out|
+ * On entry:
+ * in[i] < 2^59 + 2^14
+ * On exit:
+ * out[i] < out[i] + 2^62
+ */
+static void felem_diff64(felem out, const felem in)
+{
+ /*
+ * In order to prevent underflow, we add 0 mod p before subtracting.
+ */
+ static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5);
+ static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4);
+
+ out[0] += two62m3 - in[0];
+ out[1] += two62m2 - in[1];
+ out[2] += two62m2 - in[2];
+ out[3] += two62m2 - in[3];
+ out[4] += two62m2 - in[4];
+ out[5] += two62m2 - in[5];
+ out[6] += two62m2 - in[6];
+ out[7] += two62m2 - in[7];
+ out[8] += two62m2 - in[8];
+}
+
+/*-
+ * felem_diff_128_64 subtracts |in| from |out|
+ * On entry:
+ * in[i] < 2^62 + 2^17
+ * On exit:
+ * out[i] < out[i] + 2^63
+ */
+static void felem_diff_128_64(largefelem out, const felem in)
+{
+ /*
+ * In order to prevent underflow, we add 0 mod p before subtracting.
+ */
+ static const limb two63m6 = (((limb) 1) << 62) - (((limb) 1) << 5);
+ static const limb two63m5 = (((limb) 1) << 62) - (((limb) 1) << 4);
+
+ out[0] += two63m6 - in[0];
+ out[1] += two63m5 - in[1];
+ out[2] += two63m5 - in[2];
+ out[3] += two63m5 - in[3];
+ out[4] += two63m5 - in[4];
+ out[5] += two63m5 - in[5];
+ out[6] += two63m5 - in[6];
+ out[7] += two63m5 - in[7];
+ out[8] += two63m5 - in[8];
+}
+
+/*-
+ * felem_diff_128_64 subtracts |in| from |out|
+ * On entry:
+ * in[i] < 2^126
+ * On exit:
+ * out[i] < out[i] + 2^127 - 2^69
+ */
+static void felem_diff128(largefelem out, const largefelem in)
+{
+ /*
+ * In order to prevent underflow, we add 0 mod p before subtracting.
+ */
+ static const uint128_t two127m70 =
+ (((uint128_t) 1) << 127) - (((uint128_t) 1) << 70);
+ static const uint128_t two127m69 =
+ (((uint128_t) 1) << 127) - (((uint128_t) 1) << 69);
+
+ out[0] += (two127m70 - in[0]);
+ out[1] += (two127m69 - in[1]);
+ out[2] += (two127m69 - in[2]);
+ out[3] += (two127m69 - in[3]);
+ out[4] += (two127m69 - in[4]);
+ out[5] += (two127m69 - in[5]);
+ out[6] += (two127m69 - in[6]);
+ out[7] += (two127m69 - in[7]);
+ out[8] += (two127m69 - in[8]);
+}
+
+/*-
+ * felem_square sets |out| = |in|^2
+ * On entry:
+ * in[i] < 2^62
+ * On exit:
+ * out[i] < 17 * max(in[i]) * max(in[i])
+ */
+static void felem_square(largefelem out, const felem in)
+{
+ felem inx2, inx4;
+ felem_scalar(inx2, in, 2);
+ felem_scalar(inx4, in, 4);
+
+ /*-
+ * We have many cases were we want to do
+ * in[x] * in[y] +
+ * in[y] * in[x]
+ * This is obviously just
+ * 2 * in[x] * in[y]
+ * However, rather than do the doubling on the 128 bit result, we
+ * double one of the inputs to the multiplication by reading from
+ * |inx2|
+ */
+
+ out[0] = ((uint128_t) in[0]) * in[0];
+ out[1] = ((uint128_t) in[0]) * inx2[1];
+ out[2] = ((uint128_t) in[0]) * inx2[2] + ((uint128_t) in[1]) * in[1];
+ out[3] = ((uint128_t) in[0]) * inx2[3] + ((uint128_t) in[1]) * inx2[2];
+ out[4] = ((uint128_t) in[0]) * inx2[4] +
+ ((uint128_t) in[1]) * inx2[3] + ((uint128_t) in[2]) * in[2];
+ out[5] = ((uint128_t) in[0]) * inx2[5] +
+ ((uint128_t) in[1]) * inx2[4] + ((uint128_t) in[2]) * inx2[3];
+ out[6] = ((uint128_t) in[0]) * inx2[6] +
+ ((uint128_t) in[1]) * inx2[5] +
+ ((uint128_t) in[2]) * inx2[4] + ((uint128_t) in[3]) * in[3];
+ out[7] = ((uint128_t) in[0]) * inx2[7] +
+ ((uint128_t) in[1]) * inx2[6] +
+ ((uint128_t) in[2]) * inx2[5] + ((uint128_t) in[3]) * inx2[4];
+ out[8] = ((uint128_t) in[0]) * inx2[8] +
+ ((uint128_t) in[1]) * inx2[7] +
+ ((uint128_t) in[2]) * inx2[6] +
+ ((uint128_t) in[3]) * inx2[5] + ((uint128_t) in[4]) * in[4];
+
+ /*
+ * The remaining limbs fall above 2^521, with the first falling at 2^522.
+ * They correspond to locations one bit up from the limbs produced above
+ * so we would have to multiply by two to align them. Again, rather than
+ * operate on the 128-bit result, we double one of the inputs to the
+ * multiplication. If we want to double for both this reason, and the
+ * reason above, then we end up multiplying by four.
+ */
+
+ /* 9 */
+ out[0] += ((uint128_t) in[1]) * inx4[8] +
+ ((uint128_t) in[2]) * inx4[7] +
+ ((uint128_t) in[3]) * inx4[6] + ((uint128_t) in[4]) * inx4[5];
+
+ /* 10 */
+ out[1] += ((uint128_t) in[2]) * inx4[8] +
+ ((uint128_t) in[3]) * inx4[7] +
+ ((uint128_t) in[4]) * inx4[6] + ((uint128_t) in[5]) * inx2[5];
+
+ /* 11 */
+ out[2] += ((uint128_t) in[3]) * inx4[8] +
+ ((uint128_t) in[4]) * inx4[7] + ((uint128_t) in[5]) * inx4[6];
+
+ /* 12 */
+ out[3] += ((uint128_t) in[4]) * inx4[8] +
+ ((uint128_t) in[5]) * inx4[7] + ((uint128_t) in[6]) * inx2[6];
+
+ /* 13 */
+ out[4] += ((uint128_t) in[5]) * inx4[8] + ((uint128_t) in[6]) * inx4[7];
+
+ /* 14 */
+ out[5] += ((uint128_t) in[6]) * inx4[8] + ((uint128_t) in[7]) * inx2[7];
+
+ /* 15 */
+ out[6] += ((uint128_t) in[7]) * inx4[8];
+
+ /* 16 */
+ out[7] += ((uint128_t) in[8]) * inx2[8];
+}
+
+/*-
+ * felem_mul sets |out| = |in1| * |in2|
+ * On entry:
+ * in1[i] < 2^64
+ * in2[i] < 2^63
+ * On exit:
+ * out[i] < 17 * max(in1[i]) * max(in2[i])
+ */
+static void felem_mul(largefelem out, const felem in1, const felem in2)
+{
+ felem in2x2;
+ felem_scalar(in2x2, in2, 2);
+
+ out[0] = ((uint128_t) in1[0]) * in2[0];
+
+ out[1] = ((uint128_t) in1[0]) * in2[1] + ((uint128_t) in1[1]) * in2[0];
+
+ out[2] = ((uint128_t) in1[0]) * in2[2] +
+ ((uint128_t) in1[1]) * in2[1] + ((uint128_t) in1[2]) * in2[0];
+
+ out[3] = ((uint128_t) in1[0]) * in2[3] +
+ ((uint128_t) in1[1]) * in2[2] +
+ ((uint128_t) in1[2]) * in2[1] + ((uint128_t) in1[3]) * in2[0];
+
+ out[4] = ((uint128_t) in1[0]) * in2[4] +
+ ((uint128_t) in1[1]) * in2[3] +
+ ((uint128_t) in1[2]) * in2[2] +
+ ((uint128_t) in1[3]) * in2[1] + ((uint128_t) in1[4]) * in2[0];
+
+ out[5] = ((uint128_t) in1[0]) * in2[5] +
+ ((uint128_t) in1[1]) * in2[4] +
+ ((uint128_t) in1[2]) * in2[3] +
+ ((uint128_t) in1[3]) * in2[2] +
+ ((uint128_t) in1[4]) * in2[1] + ((uint128_t) in1[5]) * in2[0];
+
+ out[6] = ((uint128_t) in1[0]) * in2[6] +
+ ((uint128_t) in1[1]) * in2[5] +
+ ((uint128_t) in1[2]) * in2[4] +
+ ((uint128_t) in1[3]) * in2[3] +
+ ((uint128_t) in1[4]) * in2[2] +
+ ((uint128_t) in1[5]) * in2[1] + ((uint128_t) in1[6]) * in2[0];
+
+ out[7] = ((uint128_t) in1[0]) * in2[7] +
+ ((uint128_t) in1[1]) * in2[6] +
+ ((uint128_t) in1[2]) * in2[5] +
+ ((uint128_t) in1[3]) * in2[4] +
+ ((uint128_t) in1[4]) * in2[3] +
+ ((uint128_t) in1[5]) * in2[2] +
+ ((uint128_t) in1[6]) * in2[1] + ((uint128_t) in1[7]) * in2[0];
+
+ out[8] = ((uint128_t) in1[0]) * in2[8] +
+ ((uint128_t) in1[1]) * in2[7] +
+ ((uint128_t) in1[2]) * in2[6] +
+ ((uint128_t) in1[3]) * in2[5] +
+ ((uint128_t) in1[4]) * in2[4] +
+ ((uint128_t) in1[5]) * in2[3] +
+ ((uint128_t) in1[6]) * in2[2] +
+ ((uint128_t) in1[7]) * in2[1] + ((uint128_t) in1[8]) * in2[0];
+
+ /* See comment in felem_square about the use of in2x2 here */
+
+ out[0] += ((uint128_t) in1[1]) * in2x2[8] +
+ ((uint128_t) in1[2]) * in2x2[7] +
+ ((uint128_t) in1[3]) * in2x2[6] +
+ ((uint128_t) in1[4]) * in2x2[5] +
+ ((uint128_t) in1[5]) * in2x2[4] +
+ ((uint128_t) in1[6]) * in2x2[3] +
+ ((uint128_t) in1[7]) * in2x2[2] + ((uint128_t) in1[8]) * in2x2[1];
+
+ out[1] += ((uint128_t) in1[2]) * in2x2[8] +
+ ((uint128_t) in1[3]) * in2x2[7] +
+ ((uint128_t) in1[4]) * in2x2[6] +
+ ((uint128_t) in1[5]) * in2x2[5] +
+ ((uint128_t) in1[6]) * in2x2[4] +
+ ((uint128_t) in1[7]) * in2x2[3] + ((uint128_t) in1[8]) * in2x2[2];
+
+ out[2] += ((uint128_t) in1[3]) * in2x2[8] +
+ ((uint128_t) in1[4]) * in2x2[7] +
+ ((uint128_t) in1[5]) * in2x2[6] +
+ ((uint128_t) in1[6]) * in2x2[5] +
+ ((uint128_t) in1[7]) * in2x2[4] + ((uint128_t) in1[8]) * in2x2[3];
+
+ out[3] += ((uint128_t) in1[4]) * in2x2[8] +
+ ((uint128_t) in1[5]) * in2x2[7] +
+ ((uint128_t) in1[6]) * in2x2[6] +
+ ((uint128_t) in1[7]) * in2x2[5] + ((uint128_t) in1[8]) * in2x2[4];
+
+ out[4] += ((uint128_t) in1[5]) * in2x2[8] +
+ ((uint128_t) in1[6]) * in2x2[7] +
+ ((uint128_t) in1[7]) * in2x2[6] + ((uint128_t) in1[8]) * in2x2[5];
+
+ out[5] += ((uint128_t) in1[6]) * in2x2[8] +
+ ((uint128_t) in1[7]) * in2x2[7] + ((uint128_t) in1[8]) * in2x2[6];
+
+ out[6] += ((uint128_t) in1[7]) * in2x2[8] +
+ ((uint128_t) in1[8]) * in2x2[7];
+
+ out[7] += ((uint128_t) in1[8]) * in2x2[8];
+}
+
+static const limb bottom52bits = 0xfffffffffffff;
+
+/*-
+ * felem_reduce converts a largefelem to an felem.
+ * On entry:
+ * in[i] < 2^128
+ * On exit:
+ * out[i] < 2^59 + 2^14
+ */
+static void felem_reduce(felem out, const largefelem in)
+{
+ u64 overflow1, overflow2;
+
+ out[0] = ((limb) in[0]) & bottom58bits;
+ out[1] = ((limb) in[1]) & bottom58bits;
+ out[2] = ((limb) in[2]) & bottom58bits;
+ out[3] = ((limb) in[3]) & bottom58bits;
+ out[4] = ((limb) in[4]) & bottom58bits;
+ out[5] = ((limb) in[5]) & bottom58bits;
+ out[6] = ((limb) in[6]) & bottom58bits;
+ out[7] = ((limb) in[7]) & bottom58bits;
+ out[8] = ((limb) in[8]) & bottom58bits;
+
+ /* out[i] < 2^58 */
+
+ out[1] += ((limb) in[0]) >> 58;
+ out[1] += (((limb) (in[0] >> 64)) & bottom52bits) << 6;
+ /*-
+ * out[1] < 2^58 + 2^6 + 2^58
+ * = 2^59 + 2^6
+ */
+ out[2] += ((limb) (in[0] >> 64)) >> 52;
+
+ out[2] += ((limb) in[1]) >> 58;
+ out[2] += (((limb) (in[1] >> 64)) & bottom52bits) << 6;
+ out[3] += ((limb) (in[1] >> 64)) >> 52;
+
+ out[3] += ((limb) in[2]) >> 58;
+ out[3] += (((limb) (in[2] >> 64)) & bottom52bits) << 6;
+ out[4] += ((limb) (in[2] >> 64)) >> 52;
+
+ out[4] += ((limb) in[3]) >> 58;
+ out[4] += (((limb) (in[3] >> 64)) & bottom52bits) << 6;
+ out[5] += ((limb) (in[3] >> 64)) >> 52;
+
+ out[5] += ((limb) in[4]) >> 58;
+ out[5] += (((limb) (in[4] >> 64)) & bottom52bits) << 6;
+ out[6] += ((limb) (in[4] >> 64)) >> 52;
+
+ out[6] += ((limb) in[5]) >> 58;
+ out[6] += (((limb) (in[5] >> 64)) & bottom52bits) << 6;
+ out[7] += ((limb) (in[5] >> 64)) >> 52;
+
+ out[7] += ((limb) in[6]) >> 58;
+ out[7] += (((limb) (in[6] >> 64)) & bottom52bits) << 6;
+ out[8] += ((limb) (in[6] >> 64)) >> 52;
+
+ out[8] += ((limb) in[7]) >> 58;
+ out[8] += (((limb) (in[7] >> 64)) & bottom52bits) << 6;
+ /*-
+ * out[x > 1] < 2^58 + 2^6 + 2^58 + 2^12
+ * < 2^59 + 2^13
+ */
+ overflow1 = ((limb) (in[7] >> 64)) >> 52;
+
+ overflow1 += ((limb) in[8]) >> 58;
+ overflow1 += (((limb) (in[8] >> 64)) & bottom52bits) << 6;
+ overflow2 = ((limb) (in[8] >> 64)) >> 52;
+
+ overflow1 <<= 1; /* overflow1 < 2^13 + 2^7 + 2^59 */
+ overflow2 <<= 1; /* overflow2 < 2^13 */
+
+ out[0] += overflow1; /* out[0] < 2^60 */
+ out[1] += overflow2; /* out[1] < 2^59 + 2^6 + 2^13 */
+
+ out[1] += out[0] >> 58;
+ out[0] &= bottom58bits;
+ /*-
+ * out[0] < 2^58
+ * out[1] < 2^59 + 2^6 + 2^13 + 2^2
+ * < 2^59 + 2^14
+ */
+}
+
+static void felem_square_reduce(felem out, const felem in)
+{
+ largefelem tmp;
+ felem_square(tmp, in);
+ felem_reduce(out, tmp);
+}
+
+static void felem_mul_reduce(felem out, const felem in1, const felem in2)
+{
+ largefelem tmp;
+ felem_mul(tmp, in1, in2);
+ felem_reduce(out, tmp);
+}
+
+/*-
+ * felem_inv calculates |out| = |in|^{-1}
+ *
+ * Based on Fermat's Little Theorem:
+ * a^p = a (mod p)
+ * a^{p-1} = 1 (mod p)
+ * a^{p-2} = a^{-1} (mod p)
+ */
+static void felem_inv(felem out, const felem in)
+{
+ felem ftmp, ftmp2, ftmp3, ftmp4;
+ largefelem tmp;
+ unsigned i;
+
+ felem_square(tmp, in);
+ felem_reduce(ftmp, tmp); /* 2^1 */
+ felem_mul(tmp, in, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^2 - 2^0 */
+ felem_assign(ftmp2, ftmp);
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^3 - 2^1 */
+ felem_mul(tmp, in, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^3 - 2^0 */
+ felem_square(tmp, ftmp);
+ felem_reduce(ftmp, tmp); /* 2^4 - 2^1 */
+
+ felem_square(tmp, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^3 - 2^1 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp); /* 2^4 - 2^2 */
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^4 - 2^0 */
+
+ felem_assign(ftmp2, ftmp3);
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp); /* 2^5 - 2^1 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp); /* 2^6 - 2^2 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp); /* 2^7 - 2^3 */
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp); /* 2^8 - 2^4 */
+ felem_assign(ftmp4, ftmp3);
+ felem_mul(tmp, ftmp3, ftmp);
+ felem_reduce(ftmp4, tmp); /* 2^8 - 2^1 */
+ felem_square(tmp, ftmp4);
+ felem_reduce(ftmp4, tmp); /* 2^9 - 2^2 */
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^8 - 2^0 */
+ felem_assign(ftmp2, ftmp3);
+
+ for (i = 0; i < 8; i++) {
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp); /* 2^16 - 2^8 */
+ }
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^16 - 2^0 */
+ felem_assign(ftmp2, ftmp3);
+
+ for (i = 0; i < 16; i++) {
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp); /* 2^32 - 2^16 */
+ }
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^32 - 2^0 */
+ felem_assign(ftmp2, ftmp3);
+
+ for (i = 0; i < 32; i++) {
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp); /* 2^64 - 2^32 */
+ }
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^64 - 2^0 */
+ felem_assign(ftmp2, ftmp3);
+
+ for (i = 0; i < 64; i++) {
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp); /* 2^128 - 2^64 */
+ }
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^128 - 2^0 */
+ felem_assign(ftmp2, ftmp3);
+
+ for (i = 0; i < 128; i++) {
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp); /* 2^256 - 2^128 */
+ }
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^256 - 2^0 */
+ felem_assign(ftmp2, ftmp3);
+
+ for (i = 0; i < 256; i++) {
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp); /* 2^512 - 2^256 */
+ }
+ felem_mul(tmp, ftmp3, ftmp2);
+ felem_reduce(ftmp3, tmp); /* 2^512 - 2^0 */
+
+ for (i = 0; i < 9; i++) {
+ felem_square(tmp, ftmp3);
+ felem_reduce(ftmp3, tmp); /* 2^521 - 2^9 */
+ }
+ felem_mul(tmp, ftmp3, ftmp4);
+ felem_reduce(ftmp3, tmp); /* 2^512 - 2^2 */
+ felem_mul(tmp, ftmp3, in);
+ felem_reduce(out, tmp); /* 2^512 - 3 */
+}
+
+/* This is 2^521-1, expressed as an felem */
+static const felem kPrime = {
+ 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
+ 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
+ 0x03ffffffffffffff, 0x03ffffffffffffff, 0x01ffffffffffffff
+};
+
+/*-
+ * felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
+ * otherwise.
+ * On entry:
+ * in[i] < 2^59 + 2^14
+ */
+static limb felem_is_zero(const felem in)
+{
+ felem ftmp;
+ limb is_zero, is_p;
+ felem_assign(ftmp, in);
+
+ ftmp[0] += ftmp[8] >> 57;
+ ftmp[8] &= bottom57bits;
+ /* ftmp[8] < 2^57 */
+ ftmp[1] += ftmp[0] >> 58;
+ ftmp[0] &= bottom58bits;
+ ftmp[2] += ftmp[1] >> 58;
+ ftmp[1] &= bottom58bits;
+ ftmp[3] += ftmp[2] >> 58;
+ ftmp[2] &= bottom58bits;
+ ftmp[4] += ftmp[3] >> 58;
+ ftmp[3] &= bottom58bits;
+ ftmp[5] += ftmp[4] >> 58;
+ ftmp[4] &= bottom58bits;
+ ftmp[6] += ftmp[5] >> 58;
+ ftmp[5] &= bottom58bits;
+ ftmp[7] += ftmp[6] >> 58;
+ ftmp[6] &= bottom58bits;
+ ftmp[8] += ftmp[7] >> 58;
+ ftmp[7] &= bottom58bits;
+ /* ftmp[8] < 2^57 + 4 */
+
+ /*
+ * The ninth limb of 2*(2^521-1) is 0x03ffffffffffffff, which is greater
+ * than our bound for ftmp[8]. Therefore we only have to check if the
+ * zero is zero or 2^521-1.
+ */
+
+ is_zero = 0;
+ is_zero |= ftmp[0];
+ is_zero |= ftmp[1];
+ is_zero |= ftmp[2];
+ is_zero |= ftmp[3];
+ is_zero |= ftmp[4];
+ is_zero |= ftmp[5];
+ is_zero |= ftmp[6];
+ is_zero |= ftmp[7];
+ is_zero |= ftmp[8];
+
+ is_zero--;
+ /*
+ * We know that ftmp[i] < 2^63, therefore the only way that the top bit
+ * can be set is if is_zero was 0 before the decrement.
+ */
+ is_zero = ((s64) is_zero) >> 63;
+
+ is_p = ftmp[0] ^ kPrime[0];
+ is_p |= ftmp[1] ^ kPrime[1];
+ is_p |= ftmp[2] ^ kPrime[2];
+ is_p |= ftmp[3] ^ kPrime[3];
+ is_p |= ftmp[4] ^ kPrime[4];
+ is_p |= ftmp[5] ^ kPrime[5];
+ is_p |= ftmp[6] ^ kPrime[6];
+ is_p |= ftmp[7] ^ kPrime[7];
+ is_p |= ftmp[8] ^ kPrime[8];
+
+ is_p--;
+ is_p = ((s64) is_p) >> 63;
+
+ is_zero |= is_p;
+ return is_zero;
+}
+
+static int felem_is_zero_int(const felem in)
+{
+ return (int)(felem_is_zero(in) & ((limb) 1));
+}
+
+/*-
+ * felem_contract converts |in| to its unique, minimal representation.
+ * On entry:
+ * in[i] < 2^59 + 2^14
+ */
+static void felem_contract(felem out, const felem in)
+{
+ limb is_p, is_greater, sign;
+ static const limb two58 = ((limb) 1) << 58;
+
+ felem_assign(out, in);
+
+ out[0] += out[8] >> 57;
+ out[8] &= bottom57bits;
+ /* out[8] < 2^57 */
+ out[1] += out[0] >> 58;
+ out[0] &= bottom58bits;
+ out[2] += out[1] >> 58;
+ out[1] &= bottom58bits;
+ out[3] += out[2] >> 58;
+ out[2] &= bottom58bits;
+ out[4] += out[3] >> 58;
+ out[3] &= bottom58bits;
+ out[5] += out[4] >> 58;
+ out[4] &= bottom58bits;
+ out[6] += out[5] >> 58;
+ out[5] &= bottom58bits;
+ out[7] += out[6] >> 58;
+ out[6] &= bottom58bits;
+ out[8] += out[7] >> 58;
+ out[7] &= bottom58bits;
+ /* out[8] < 2^57 + 4 */
+
+ /*
+ * If the value is greater than 2^521-1 then we have to subtract 2^521-1
+ * out. See the comments in felem_is_zero regarding why we don't test for
+ * other multiples of the prime.
+ */
+
+ /*
+ * First, if |out| is equal to 2^521-1, we subtract it out to get zero.
+ */
+
+ is_p = out[0] ^ kPrime[0];
+ is_p |= out[1] ^ kPrime[1];
+ is_p |= out[2] ^ kPrime[2];
+ is_p |= out[3] ^ kPrime[3];
+ is_p |= out[4] ^ kPrime[4];
+ is_p |= out[5] ^ kPrime[5];
+ is_p |= out[6] ^ kPrime[6];
+ is_p |= out[7] ^ kPrime[7];
+ is_p |= out[8] ^ kPrime[8];
+
+ is_p--;
+ is_p &= is_p << 32;
+ is_p &= is_p << 16;
+ is_p &= is_p << 8;
+ is_p &= is_p << 4;
+ is_p &= is_p << 2;
+ is_p &= is_p << 1;
+ is_p = ((s64) is_p) >> 63;
+ is_p = ~is_p;
+
+ /* is_p is 0 iff |out| == 2^521-1 and all ones otherwise */
+
+ out[0] &= is_p;
+ out[1] &= is_p;
+ out[2] &= is_p;
+ out[3] &= is_p;
+ out[4] &= is_p;
+ out[5] &= is_p;
+ out[6] &= is_p;
+ out[7] &= is_p;
+ out[8] &= is_p;
+
+ /*
+ * In order to test that |out| >= 2^521-1 we need only test if out[8] >>
+ * 57 is greater than zero as (2^521-1) + x >= 2^522
+ */
+ is_greater = out[8] >> 57;
+ is_greater |= is_greater << 32;
+ is_greater |= is_greater << 16;
+ is_greater |= is_greater << 8;
+ is_greater |= is_greater << 4;
+ is_greater |= is_greater << 2;
+ is_greater |= is_greater << 1;
+ is_greater = ((s64) is_greater) >> 63;
+
+ out[0] -= kPrime[0] & is_greater;
+ out[1] -= kPrime[1] & is_greater;
+ out[2] -= kPrime[2] & is_greater;
+ out[3] -= kPrime[3] & is_greater;
+ out[4] -= kPrime[4] & is_greater;
+ out[5] -= kPrime[5] & is_greater;
+ out[6] -= kPrime[6] & is_greater;
+ out[7] -= kPrime[7] & is_greater;
+ out[8] -= kPrime[8] & is_greater;
+
+ /* Eliminate negative coefficients */
+ sign = -(out[0] >> 63);
+ out[0] += (two58 & sign);
+ out[1] -= (1 & sign);
+ sign = -(out[1] >> 63);
+ out[1] += (two58 & sign);
+ out[2] -= (1 & sign);
+ sign = -(out[2] >> 63);
+ out[2] += (two58 & sign);
+ out[3] -= (1 & sign);
+ sign = -(out[3] >> 63);
+ out[3] += (two58 & sign);
+ out[4] -= (1 & sign);
+ sign = -(out[4] >> 63);
+ out[4] += (two58 & sign);
+ out[5] -= (1 & sign);
+ sign = -(out[0] >> 63);
+ out[5] += (two58 & sign);
+ out[6] -= (1 & sign);
+ sign = -(out[6] >> 63);
+ out[6] += (two58 & sign);
+ out[7] -= (1 & sign);
+ sign = -(out[7] >> 63);
+ out[7] += (two58 & sign);
+ out[8] -= (1 & sign);
+ sign = -(out[5] >> 63);
+ out[5] += (two58 & sign);
+ out[6] -= (1 & sign);
+ sign = -(out[6] >> 63);
+ out[6] += (two58 & sign);
+ out[7] -= (1 & sign);
+ sign = -(out[7] >> 63);
+ out[7] += (two58 & sign);
+ out[8] -= (1 & sign);
+}
+
+/*-
+ * Group operations
+ * ----------------
+ *
+ * Building on top of the field operations we have the operations on the
+ * elliptic curve group itself. Points on the curve are represented in Jacobian
+ * coordinates */
+
+/*-
+ * point_double calcuates 2*(x_in, y_in, z_in)
+ *
+ * The method is taken from:
+ * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
+ *
+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
+ * while x_out == y_in is not (maybe this works, but it's not tested). */
+static void
+point_double(felem x_out, felem y_out, felem z_out,
+ const felem x_in, const felem y_in, const felem z_in)
+{
+ largefelem tmp, tmp2;
+ felem delta, gamma, beta, alpha, ftmp, ftmp2;
+
+ felem_assign(ftmp, x_in);
+ felem_assign(ftmp2, x_in);
+
+ /* delta = z^2 */
+ felem_square(tmp, z_in);
+ felem_reduce(delta, tmp); /* delta[i] < 2^59 + 2^14 */
+
+ /* gamma = y^2 */
+ felem_square(tmp, y_in);
+ felem_reduce(gamma, tmp); /* gamma[i] < 2^59 + 2^14 */
+
+ /* beta = x*gamma */
+ felem_mul(tmp, x_in, gamma);
+ felem_reduce(beta, tmp); /* beta[i] < 2^59 + 2^14 */
+
+ /* alpha = 3*(x-delta)*(x+delta) */
+ felem_diff64(ftmp, delta);
+ /* ftmp[i] < 2^61 */
+ felem_sum64(ftmp2, delta);
+ /* ftmp2[i] < 2^60 + 2^15 */
+ felem_scalar64(ftmp2, 3);
+ /* ftmp2[i] < 3*2^60 + 3*2^15 */
+ felem_mul(tmp, ftmp, ftmp2);
+ /*-
+ * tmp[i] < 17(3*2^121 + 3*2^76)
+ * = 61*2^121 + 61*2^76
+ * < 64*2^121 + 64*2^76
+ * = 2^127 + 2^82
+ * < 2^128
+ */
+ felem_reduce(alpha, tmp);
+
+ /* x' = alpha^2 - 8*beta */
+ felem_square(tmp, alpha);
+ /*
+ * tmp[i] < 17*2^120 < 2^125
+ */
+ felem_assign(ftmp, beta);
+ felem_scalar64(ftmp, 8);
+ /* ftmp[i] < 2^62 + 2^17 */
+ felem_diff_128_64(tmp, ftmp);
+ /* tmp[i] < 2^125 + 2^63 + 2^62 + 2^17 */
+ felem_reduce(x_out, tmp);
+
+ /* z' = (y + z)^2 - gamma - delta */
+ felem_sum64(delta, gamma);
+ /* delta[i] < 2^60 + 2^15 */
+ felem_assign(ftmp, y_in);
+ felem_sum64(ftmp, z_in);
+ /* ftmp[i] < 2^60 + 2^15 */
+ felem_square(tmp, ftmp);
+ /*
+ * tmp[i] < 17(2^122) < 2^127
+ */
+ felem_diff_128_64(tmp, delta);
+ /* tmp[i] < 2^127 + 2^63 */
+ felem_reduce(z_out, tmp);
+
+ /* y' = alpha*(4*beta - x') - 8*gamma^2 */
+ felem_scalar64(beta, 4);
+ /* beta[i] < 2^61 + 2^16 */
+ felem_diff64(beta, x_out);
+ /* beta[i] < 2^61 + 2^60 + 2^16 */
+ felem_mul(tmp, alpha, beta);
+ /*-
+ * tmp[i] < 17*((2^59 + 2^14)(2^61 + 2^60 + 2^16))
+ * = 17*(2^120 + 2^75 + 2^119 + 2^74 + 2^75 + 2^30)
+ * = 17*(2^120 + 2^119 + 2^76 + 2^74 + 2^30)
+ * < 2^128
+ */
+ felem_square(tmp2, gamma);
+ /*-
+ * tmp2[i] < 17*(2^59 + 2^14)^2
+ * = 17*(2^118 + 2^74 + 2^28)
+ */
+ felem_scalar128(tmp2, 8);
+ /*-
+ * tmp2[i] < 8*17*(2^118 + 2^74 + 2^28)
+ * = 2^125 + 2^121 + 2^81 + 2^77 + 2^35 + 2^31
+ * < 2^126
+ */
+ felem_diff128(tmp, tmp2);
+ /*-
+ * tmp[i] < 2^127 - 2^69 + 17(2^120 + 2^119 + 2^76 + 2^74 + 2^30)
+ * = 2^127 + 2^124 + 2^122 + 2^120 + 2^118 + 2^80 + 2^78 + 2^76 +
+ * 2^74 + 2^69 + 2^34 + 2^30
+ * < 2^128
+ */
+ felem_reduce(y_out, tmp);
+}
+
+/* copy_conditional copies in to out iff mask is all ones. */
+static void copy_conditional(felem out, const felem in, limb mask)
+{
+ unsigned i;
+ for (i = 0; i < NLIMBS; ++i) {
+ const limb tmp = mask & (in[i] ^ out[i]);
+ out[i] ^= tmp;
+ }
+}
+
+/*-
+ * point_add calcuates (x1, y1, z1) + (x2, y2, z2)
+ *
+ * The method is taken from
+ * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
+ * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
+ *
+ * This function includes a branch for checking whether the two input points
+ * are equal (while not equal to the point at infinity). This case never
+ * happens during single point multiplication, so there is no timing leak for
+ * ECDH or ECDSA signing. */
+static void point_add(felem x3, felem y3, felem z3,
+ const felem x1, const felem y1, const felem z1,
+ const int mixed, const felem x2, const felem y2,
+ const felem z2)
+{
+ felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
+ largefelem tmp, tmp2;
+ limb x_equal, y_equal, z1_is_zero, z2_is_zero;
+
+ z1_is_zero = felem_is_zero(z1);
+ z2_is_zero = felem_is_zero(z2);
+
+ /* ftmp = z1z1 = z1**2 */
+ felem_square(tmp, z1);
+ felem_reduce(ftmp, tmp);
+
+ if (!mixed) {
+ /* ftmp2 = z2z2 = z2**2 */
+ felem_square(tmp, z2);
+ felem_reduce(ftmp2, tmp);
+
+ /* u1 = ftmp3 = x1*z2z2 */
+ felem_mul(tmp, x1, ftmp2);
+ felem_reduce(ftmp3, tmp);
+
+ /* ftmp5 = z1 + z2 */
+ felem_assign(ftmp5, z1);
+ felem_sum64(ftmp5, z2);
+ /* ftmp5[i] < 2^61 */
+
+ /* ftmp5 = (z1 + z2)**2 - z1z1 - z2z2 = 2*z1z2 */
+ felem_square(tmp, ftmp5);
+ /* tmp[i] < 17*2^122 */
+ felem_diff_128_64(tmp, ftmp);
+ /* tmp[i] < 17*2^122 + 2^63 */
+ felem_diff_128_64(tmp, ftmp2);
+ /* tmp[i] < 17*2^122 + 2^64 */
+ felem_reduce(ftmp5, tmp);
+
+ /* ftmp2 = z2 * z2z2 */
+ felem_mul(tmp, ftmp2, z2);
+ felem_reduce(ftmp2, tmp);
+
+ /* s1 = ftmp6 = y1 * z2**3 */
+ felem_mul(tmp, y1, ftmp2);
+ felem_reduce(ftmp6, tmp);
+ } else {
+ /*
+ * We'll assume z2 = 1 (special case z2 = 0 is handled later)
+ */
+
+ /* u1 = ftmp3 = x1*z2z2 */
+ felem_assign(ftmp3, x1);
+
+ /* ftmp5 = 2*z1z2 */
+ felem_scalar(ftmp5, z1, 2);
+
+ /* s1 = ftmp6 = y1 * z2**3 */
+ felem_assign(ftmp6, y1);
+ }
+
+ /* u2 = x2*z1z1 */
+ felem_mul(tmp, x2, ftmp);
+ /* tmp[i] < 17*2^120 */
+
+ /* h = ftmp4 = u2 - u1 */
+ felem_diff_128_64(tmp, ftmp3);
+ /* tmp[i] < 17*2^120 + 2^63 */
+ felem_reduce(ftmp4, tmp);
+
+ x_equal = felem_is_zero(ftmp4);
+
+ /* z_out = ftmp5 * h */
+ felem_mul(tmp, ftmp5, ftmp4);
+ felem_reduce(z_out, tmp);
+
+ /* ftmp = z1 * z1z1 */
+ felem_mul(tmp, ftmp, z1);
+ felem_reduce(ftmp, tmp);
+
+ /* s2 = tmp = y2 * z1**3 */
+ felem_mul(tmp, y2, ftmp);
+ /* tmp[i] < 17*2^120 */
+
+ /* r = ftmp5 = (s2 - s1)*2 */
+ felem_diff_128_64(tmp, ftmp6);
+ /* tmp[i] < 17*2^120 + 2^63 */
+ felem_reduce(ftmp5, tmp);
+ y_equal = felem_is_zero(ftmp5);
+ felem_scalar64(ftmp5, 2);
+ /* ftmp5[i] < 2^61 */
+
+ if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
+ point_double(x3, y3, z3, x1, y1, z1);
+ return;
+ }
+
+ /* I = ftmp = (2h)**2 */
+ felem_assign(ftmp, ftmp4);
+ felem_scalar64(ftmp, 2);
+ /* ftmp[i] < 2^61 */
+ felem_square(tmp, ftmp);
+ /* tmp[i] < 17*2^122 */
+ felem_reduce(ftmp, tmp);
+
+ /* J = ftmp2 = h * I */
+ felem_mul(tmp, ftmp4, ftmp);
+ felem_reduce(ftmp2, tmp);
+
+ /* V = ftmp4 = U1 * I */
+ felem_mul(tmp, ftmp3, ftmp);
+ felem_reduce(ftmp4, tmp);
+
+ /* x_out = r**2 - J - 2V */
+ felem_square(tmp, ftmp5);
+ /* tmp[i] < 17*2^122 */
+ felem_diff_128_64(tmp, ftmp2);
+ /* tmp[i] < 17*2^122 + 2^63 */
+ felem_assign(ftmp3, ftmp4);
+ felem_scalar64(ftmp4, 2);
+ /* ftmp4[i] < 2^61 */
+ felem_diff_128_64(tmp, ftmp4);
+ /* tmp[i] < 17*2^122 + 2^64 */
+ felem_reduce(x_out, tmp);
+
+ /* y_out = r(V-x_out) - 2 * s1 * J */
+ felem_diff64(ftmp3, x_out);
+ /*
+ * ftmp3[i] < 2^60 + 2^60 = 2^61
+ */
+ felem_mul(tmp, ftmp5, ftmp3);
+ /* tmp[i] < 17*2^122 */
+ felem_mul(tmp2, ftmp6, ftmp2);
+ /* tmp2[i] < 17*2^120 */
+ felem_scalar128(tmp2, 2);
+ /* tmp2[i] < 17*2^121 */
+ felem_diff128(tmp, tmp2);
+ /*-
+ * tmp[i] < 2^127 - 2^69 + 17*2^122
+ * = 2^126 - 2^122 - 2^6 - 2^2 - 1
+ * < 2^127
+ */
+ felem_reduce(y_out, tmp);
+
+ copy_conditional(x_out, x2, z1_is_zero);
+ copy_conditional(x_out, x1, z2_is_zero);
+ copy_conditional(y_out, y2, z1_is_zero);
+ copy_conditional(y_out, y1, z2_is_zero);
+ copy_conditional(z_out, z2, z1_is_zero);
+ copy_conditional(z_out, z1, z2_is_zero);
+ felem_assign(x3, x_out);
+ felem_assign(y3, y_out);
+ felem_assign(z3, z_out);
+}
+
+/*-
+ * Base point pre computation
+ * --------------------------
+ *
+ * Two different sorts of precomputed tables are used in the following code.
+ * Each contain various points on the curve, where each point is three field
+ * elements (x, y, z).
+ *
+ * For the base point table, z is usually 1 (0 for the point at infinity).
+ * This table has 16 elements:
+ * index | bits | point
+ * ------+---------+------------------------------
+ * 0 | 0 0 0 0 | 0G
+ * 1 | 0 0 0 1 | 1G
+ * 2 | 0 0 1 0 | 2^130G
+ * 3 | 0 0 1 1 | (2^130 + 1)G
+ * 4 | 0 1 0 0 | 2^260G
+ * 5 | 0 1 0 1 | (2^260 + 1)G
+ * 6 | 0 1 1 0 | (2^260 + 2^130)G
+ * 7 | 0 1 1 1 | (2^260 + 2^130 + 1)G
+ * 8 | 1 0 0 0 | 2^390G
+ * 9 | 1 0 0 1 | (2^390 + 1)G
+ * 10 | 1 0 1 0 | (2^390 + 2^130)G
+ * 11 | 1 0 1 1 | (2^390 + 2^130 + 1)G
+ * 12 | 1 1 0 0 | (2^390 + 2^260)G
+ * 13 | 1 1 0 1 | (2^390 + 2^260 + 1)G
+ * 14 | 1 1 1 0 | (2^390 + 2^260 + 2^130)G
+ * 15 | 1 1 1 1 | (2^390 + 2^260 + 2^130 + 1)G
+ *
+ * The reason for this is so that we can clock bits into four different
+ * locations when doing simple scalar multiplies against the base point.
+ *
+ * Tables for other points have table[i] = iG for i in 0 .. 16. */
+
+/* gmul is the table of precomputed base points */
+static const felem gmul[16][3] = { {{0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x017e7e31c2e5bd66, 0x022cf0615a90a6fe, 0x00127a2ffa8de334,
+ 0x01dfbf9d64a3f877, 0x006b4d3dbaa14b5e, 0x014fed487e0a2bd8,
+ 0x015b4429c6481390, 0x03a73678fb2d988e, 0x00c6858e06b70404},
+ {0x00be94769fd16650, 0x031c21a89cb09022, 0x039013fad0761353,
+ 0x02657bd099031542, 0x03273e662c97ee72, 0x01e6d11a05ebef45,
+ 0x03d1bd998f544495, 0x03001172297ed0b1, 0x011839296a789a3b},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x0373faacbc875bae, 0x00f325023721c671, 0x00f666fd3dbde5ad,
+ 0x01a6932363f88ea7, 0x01fc6d9e13f9c47b, 0x03bcbffc2bbf734e,
+ 0x013ee3c3647f3a92, 0x029409fefe75d07d, 0x00ef9199963d85e5},
+ {0x011173743ad5b178, 0x02499c7c21bf7d46, 0x035beaeabb8b1a58,
+ 0x00f989c4752ea0a3, 0x0101e1de48a9c1a3, 0x01a20076be28ba6c,
+ 0x02f8052e5eb2de95, 0x01bfe8f82dea117c, 0x0160074d3c36ddb7},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x012f3fc373393b3b, 0x03d3d6172f1419fa, 0x02adc943c0b86873,
+ 0x00d475584177952b, 0x012a4d1673750ee2, 0x00512517a0f13b0c,
+ 0x02b184671a7b1734, 0x0315b84236f1a50a, 0x00a4afc472edbdb9},
+ {0x00152a7077f385c4, 0x03044007d8d1c2ee, 0x0065829d61d52b52,
+ 0x00494ff6b6631d0d, 0x00a11d94d5f06bcf, 0x02d2f89474d9282e,
+ 0x0241c5727c06eeb9, 0x0386928710fbdb9d, 0x01f883f727b0dfbe},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x019b0c3c9185544d, 0x006243a37c9d97db, 0x02ee3cbe030a2ad2,
+ 0x00cfdd946bb51e0d, 0x0271c00932606b91, 0x03f817d1ec68c561,
+ 0x03f37009806a369c, 0x03c1f30baf184fd5, 0x01091022d6d2f065},
+ {0x0292c583514c45ed, 0x0316fca51f9a286c, 0x00300af507c1489a,
+ 0x0295f69008298cf1, 0x02c0ed8274943d7b, 0x016509b9b47a431e,
+ 0x02bc9de9634868ce, 0x005b34929bffcb09, 0x000c1a0121681524},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x0286abc0292fb9f2, 0x02665eee9805b3f7, 0x01ed7455f17f26d6,
+ 0x0346355b83175d13, 0x006284944cd0a097, 0x0191895bcdec5e51,
+ 0x02e288370afda7d9, 0x03b22312bfefa67a, 0x01d104d3fc0613fe},
+ {0x0092421a12f7e47f, 0x0077a83fa373c501, 0x03bd25c5f696bd0d,
+ 0x035c41e4d5459761, 0x01ca0d1742b24f53, 0x00aaab27863a509c,
+ 0x018b6de47df73917, 0x025c0b771705cd01, 0x01fd51d566d760a7},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x01dd92ff6b0d1dbd, 0x039c5e2e8f8afa69, 0x0261ed13242c3b27,
+ 0x0382c6e67026e6a0, 0x01d60b10be2089f9, 0x03c15f3dce86723f,
+ 0x03c764a32d2a062d, 0x017307eac0fad056, 0x018207c0b96c5256},
+ {0x0196a16d60e13154, 0x03e6ce74c0267030, 0x00ddbf2b4e52a5aa,
+ 0x012738241bbf31c8, 0x00ebe8dc04685a28, 0x024c2ad6d380d4a2,
+ 0x035ee062a6e62d0e, 0x0029ed74af7d3a0f, 0x00eef32aec142ebd},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x00c31ec398993b39, 0x03a9f45bcda68253, 0x00ac733c24c70890,
+ 0x00872b111401ff01, 0x01d178c23195eafb, 0x03bca2c816b87f74,
+ 0x0261a9af46fbad7a, 0x0324b2a8dd3d28f9, 0x00918121d8f24e23},
+ {0x032bc8c1ca983cd7, 0x00d869dfb08fc8c6, 0x01693cb61fce1516,
+ 0x012a5ea68f4e88a8, 0x010869cab88d7ae3, 0x009081ad277ceee1,
+ 0x033a77166d064cdc, 0x03955235a1fb3a95, 0x01251a4a9b25b65e},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x00148a3a1b27f40b, 0x0123186df1b31fdc, 0x00026e7beaad34ce,
+ 0x01db446ac1d3dbba, 0x0299c1a33437eaec, 0x024540610183cbb7,
+ 0x0173bb0e9ce92e46, 0x02b937e43921214b, 0x01ab0436a9bf01b5},
+ {0x0383381640d46948, 0x008dacbf0e7f330f, 0x03602122bcc3f318,
+ 0x01ee596b200620d6, 0x03bd0585fda430b3, 0x014aed77fd123a83,
+ 0x005ace749e52f742, 0x0390fe041da2b842, 0x0189a8ceb3299242},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x012a19d6b3282473, 0x00c0915918b423ce, 0x023a954eb94405ae,
+ 0x00529f692be26158, 0x0289fa1b6fa4b2aa, 0x0198ae4ceea346ef,
+ 0x0047d8cdfbdedd49, 0x00cc8c8953f0f6b8, 0x001424abbff49203},
+ {0x0256732a1115a03a, 0x0351bc38665c6733, 0x03f7b950fb4a6447,
+ 0x000afffa94c22155, 0x025763d0a4dab540, 0x000511e92d4fc283,
+ 0x030a7e9eda0ee96c, 0x004c3cd93a28bf0a, 0x017edb3a8719217f},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x011de5675a88e673, 0x031d7d0f5e567fbe, 0x0016b2062c970ae5,
+ 0x03f4a2be49d90aa7, 0x03cef0bd13822866, 0x03f0923dcf774a6c,
+ 0x0284bebc4f322f72, 0x016ab2645302bb2c, 0x01793f95dace0e2a},
+ {0x010646e13527a28f, 0x01ca1babd59dc5e7, 0x01afedfd9a5595df,
+ 0x01f15785212ea6b1, 0x0324e5d64f6ae3f4, 0x02d680f526d00645,
+ 0x0127920fadf627a7, 0x03b383f75df4f684, 0x0089e0057e783b0a},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x00f334b9eb3c26c6, 0x0298fdaa98568dce, 0x01c2d24843a82292,
+ 0x020bcb24fa1b0711, 0x02cbdb3d2b1875e6, 0x0014907598f89422,
+ 0x03abe3aa43b26664, 0x02cbf47f720bc168, 0x0133b5e73014b79b},
+ {0x034aab5dab05779d, 0x00cdc5d71fee9abb, 0x0399f16bd4bd9d30,
+ 0x03582fa592d82647, 0x02be1cdfb775b0e9, 0x0034f7cea32e94cb,
+ 0x0335a7f08f56f286, 0x03b707e9565d1c8b, 0x0015c946ea5b614f},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x024676f6cff72255, 0x00d14625cac96378, 0x00532b6008bc3767,
+ 0x01fc16721b985322, 0x023355ea1b091668, 0x029de7afdc0317c3,
+ 0x02fc8a7ca2da037c, 0x02de1217d74a6f30, 0x013f7173175b73bf},
+ {0x0344913f441490b5, 0x0200f9e272b61eca, 0x0258a246b1dd55d2,
+ 0x03753db9ea496f36, 0x025e02937a09c5ef, 0x030cbd3d14012692,
+ 0x01793a67e70dc72a, 0x03ec1d37048a662e, 0x006550f700c32a8d},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x00d3f48a347eba27, 0x008e636649b61bd8, 0x00d3b93716778fb3,
+ 0x004d1915757bd209, 0x019d5311a3da44e0, 0x016d1afcbbe6aade,
+ 0x0241bf5f73265616, 0x0384672e5d50d39b, 0x005009fee522b684},
+ {0x029b4fab064435fe, 0x018868ee095bbb07, 0x01ea3d6936cc92b8,
+ 0x000608b00f78a2f3, 0x02db911073d1c20f, 0x018205938470100a,
+ 0x01f1e4964cbe6ff2, 0x021a19a29eed4663, 0x01414485f42afa81},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x01612b3a17f63e34, 0x03813992885428e6, 0x022b3c215b5a9608,
+ 0x029b4057e19f2fcb, 0x0384059a587af7e6, 0x02d6400ace6fe610,
+ 0x029354d896e8e331, 0x00c047ee6dfba65e, 0x0037720542e9d49d},
+ {0x02ce9eed7c5e9278, 0x0374ed703e79643b, 0x01316c54c4072006,
+ 0x005aaa09054b2ee8, 0x002824000c840d57, 0x03d4eba24771ed86,
+ 0x0189c50aabc3bdae, 0x0338c01541e15510, 0x00466d56e38eed42},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x007efd8330ad8bd6, 0x02465ed48047710b, 0x0034c6606b215e0c,
+ 0x016ae30c53cbf839, 0x01fa17bd37161216, 0x018ead4e61ce8ab9,
+ 0x005482ed5f5dee46, 0x037543755bba1d7f, 0x005e5ac7e70a9d0f},
+ {0x0117e1bb2fdcb2a2, 0x03deea36249f40c4, 0x028d09b4a6246cb7,
+ 0x03524b8855bcf756, 0x023d7d109d5ceb58, 0x0178e43e3223ef9c,
+ 0x0154536a0c6e966a, 0x037964d1286ee9fe, 0x0199bcd90e125055},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}}
+};
+
+/*
+ * select_point selects the |idx|th point from a precomputation table and
+ * copies it to out.
+ */
+ /* pre_comp below is of the size provided in |size| */
+static void select_point(const limb idx, unsigned int size,
+ const felem pre_comp[][3], felem out[3])
+{
+ unsigned i, j;
+ limb *outlimbs = &out[0][0];
+ memset(outlimbs, 0, 3 * sizeof(felem));
+
+ for (i = 0; i < size; i++) {
+ const limb *inlimbs = &pre_comp[i][0][0];
+ limb mask = i ^ idx;
+ mask |= mask >> 4;
+ mask |= mask >> 2;
+ mask |= mask >> 1;
+ mask &= 1;
+ mask--;
+ for (j = 0; j < NLIMBS * 3; j++)
+ outlimbs[j] |= inlimbs[j] & mask;
+ }
+}
+
+/* get_bit returns the |i|th bit in |in| */
+static char get_bit(const felem_bytearray in, int i)
+{
+ if (i < 0)
+ return 0;
+ return (in[i >> 3] >> (i & 7)) & 1;
+}
+
+/*
+ * Interleaved point multiplication using precomputed point multiples: The
+ * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars
+ * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the
+ * generator, using certain (large) precomputed multiples in g_pre_comp.
+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out
+ */
+static void batch_mul(felem x_out, felem y_out, felem z_out,
+ const felem_bytearray scalars[],
+ const unsigned num_points, const u8 *g_scalar,
+ const int mixed, const felem pre_comp[][17][3],
+ const felem g_pre_comp[16][3])
+{
+ int i, skip;
+ unsigned num, gen_mul = (g_scalar != NULL);
+ felem nq[3], tmp[4];
+ limb bits;
+ u8 sign, digit;
+
+ /* set nq to the point at infinity */
+ memset(nq, 0, 3 * sizeof(felem));
+
+ /*
+ * Loop over all scalars msb-to-lsb, interleaving additions of multiples
+ * of the generator (last quarter of rounds) and additions of other
+ * points multiples (every 5th round).
+ */
+ skip = 1; /* save two point operations in the first
+ * round */
+ for (i = (num_points ? 520 : 130); i >= 0; --i) {
+ /* double */
+ if (!skip)
+ point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+
+ /* add multiples of the generator */
+ if (gen_mul && (i <= 130)) {
+ bits = get_bit(g_scalar, i + 390) << 3;
+ if (i < 130) {
+ bits |= get_bit(g_scalar, i + 260) << 2;
+ bits |= get_bit(g_scalar, i + 130) << 1;
+ bits |= get_bit(g_scalar, i);
+ }
+ /* select the point to add, in constant time */
+ select_point(bits, 16, g_pre_comp, tmp);
+ if (!skip) {
+ /* The 1 argument below is for "mixed" */
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]);
+ } else {
+ memcpy(nq, tmp, 3 * sizeof(felem));
+ skip = 0;
+ }
+ }
+
+ /* do other additions every 5 doublings */
+ if (num_points && (i % 5 == 0)) {
+ /* loop over all scalars */
+ for (num = 0; num < num_points; ++num) {
+ bits = get_bit(scalars[num], i + 4) << 5;
+ bits |= get_bit(scalars[num], i + 3) << 4;
+ bits |= get_bit(scalars[num], i + 2) << 3;
+ bits |= get_bit(scalars[num], i + 1) << 2;
+ bits |= get_bit(scalars[num], i) << 1;
+ bits |= get_bit(scalars[num], i - 1);
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+ /*
+ * select the point to add or subtract, in constant time
+ */
+ select_point(digit, 17, pre_comp[num], tmp);
+ felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative
+ * point */
+ copy_conditional(tmp[1], tmp[3], (-(limb) sign));
+
+ if (!skip) {
+ point_add(nq[0], nq[1], nq[2],
+ nq[0], nq[1], nq[2],
+ mixed, tmp[0], tmp[1], tmp[2]);
+ } else {
+ memcpy(nq, tmp, 3 * sizeof(felem));
+ skip = 0;
+ }
+ }
+ }
+ }
+ felem_assign(x_out, nq[0]);
+ felem_assign(y_out, nq[1]);
+ felem_assign(z_out, nq[2]);
+}
+
+/* Precomputation for the group generator. */
+typedef struct {
+ felem g_pre_comp[16][3];
+ int references;
+} NISTP521_PRE_COMP;
+
+const EC_METHOD *EC_GFp_nistp521_method(void)
+{
+ static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
+ NID_X9_62_prime_field,
+ ec_GFp_nistp521_group_init,
+ ec_GFp_simple_group_finish,
+ ec_GFp_simple_group_clear_finish,
+ ec_GFp_nist_group_copy,
+ ec_GFp_nistp521_group_set_curve,
+ ec_GFp_simple_group_get_curve,
+ ec_GFp_simple_group_get_degree,
+ ec_GFp_simple_group_check_discriminant,
+ ec_GFp_simple_point_init,
+ ec_GFp_simple_point_finish,
+ ec_GFp_simple_point_clear_finish,
+ ec_GFp_simple_point_copy,
+ ec_GFp_simple_point_set_to_infinity,
+ ec_GFp_simple_set_Jprojective_coordinates_GFp,
+ ec_GFp_simple_get_Jprojective_coordinates_GFp,
+ ec_GFp_simple_point_set_affine_coordinates,
+ ec_GFp_nistp521_point_get_affine_coordinates,
+ 0 /* point_set_compressed_coordinates */ ,
+ 0 /* point2oct */ ,
+ 0 /* oct2point */ ,
+ ec_GFp_simple_add,
+ ec_GFp_simple_dbl,
+ ec_GFp_simple_invert,
+ ec_GFp_simple_is_at_infinity,
+ ec_GFp_simple_is_on_curve,
+ ec_GFp_simple_cmp,
+ ec_GFp_simple_make_affine,
+ ec_GFp_simple_points_make_affine,
+ ec_GFp_nistp521_points_mul,
+ ec_GFp_nistp521_precompute_mult,
+ ec_GFp_nistp521_have_precompute_mult,
+ ec_GFp_nist_field_mul,
+ ec_GFp_nist_field_sqr,
+ 0 /* field_div */ ,
+ 0 /* field_encode */ ,
+ 0 /* field_decode */ ,
+ 0 /* field_set_to_one */
+ };
+
+ return &ret;
+}
+
+/******************************************************************************/
+/*
+ * FUNCTIONS TO MANAGE PRECOMPUTATION
+ */
+
+static NISTP521_PRE_COMP *nistp521_pre_comp_new()
+{
+ NISTP521_PRE_COMP *ret = NULL;
+ ret = (NISTP521_PRE_COMP *) OPENSSL_malloc(sizeof(NISTP521_PRE_COMP));
+ if (!ret) {
+ ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+ return ret;
+ }
+ memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp));
+ ret->references = 1;
+ return ret;
+}
+
+static void *nistp521_pre_comp_dup(void *src_)
+{
+ NISTP521_PRE_COMP *src = src_;
+
+ /* no need to actually copy, these objects never change! */
+ CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+
+ return src_;
+}
+
+static void nistp521_pre_comp_free(void *pre_)
+{
+ int i;
+ NISTP521_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ OPENSSL_free(pre);
+}
+
+static void nistp521_pre_comp_clear_free(void *pre_)
+{
+ int i;
+ NISTP521_PRE_COMP *pre = pre_;
+
+ if (!pre)
+ return;
+
+ i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
+ if (i > 0)
+ return;
+
+ OPENSSL_cleanse(pre, sizeof(*pre));
+ OPENSSL_free(pre);
+}
+
+/******************************************************************************/
+/*
+ * OPENSSL EC_METHOD FUNCTIONS
+ */
+
+int ec_GFp_nistp521_group_init(EC_GROUP *group)
+{
+ int ret;
+ ret = ec_GFp_simple_group_init(group);
+ group->a_is_minus3 = 1;
+ return ret;
+}
+
+int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+ const BIGNUM *a, const BIGNUM *b,
+ BN_CTX *ctx)
+{
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *curve_p, *curve_a, *curve_b;
+
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+ return 0;
+ BN_CTX_start(ctx);
+ if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_a = BN_CTX_get(ctx)) == NULL) ||
+ ((curve_b = BN_CTX_get(ctx)) == NULL))
+ goto err;
+ BN_bin2bn(nistp521_curve_params[0], sizeof(felem_bytearray), curve_p);
+ BN_bin2bn(nistp521_curve_params[1], sizeof(felem_bytearray), curve_a);
+ BN_bin2bn(nistp521_curve_params[2], sizeof(felem_bytearray), curve_b);
+ if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
+ ECerr(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE,
+ EC_R_WRONG_CURVE_PARAMETERS);
+ goto err;
+ }
+ group->field_mod_func = BN_nist_mod_521;
+ ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+/*
+ * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
+ * (X/Z^2, Y/Z^3)
+ */
+int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx)
+{
+ felem z1, z2, x_in, y_in, x_out, y_out;
+ largefelem tmp;
+
+ if (EC_POINT_is_at_infinity(group, point)) {
+ ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
+ EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+ if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) ||
+ (!BN_to_felem(z1, &point->Z)))
+ return 0;
+ felem_inv(z2, z1);
+ felem_square(tmp, z2);
+ felem_reduce(z1, tmp);
+ felem_mul(tmp, x_in, z1);
+ felem_reduce(x_in, tmp);
+ felem_contract(x_out, x_in);
+ if (x != NULL) {
+ if (!felem_to_BN(x, x_out)) {
+ ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
+ ERR_R_BN_LIB);
+ return 0;
+ }
+ }
+ felem_mul(tmp, z1, z2);
+ felem_reduce(z1, tmp);
+ felem_mul(tmp, y_in, z1);
+ felem_reduce(y_in, tmp);
+ felem_contract(y_out, y_in);
+ if (y != NULL) {
+ if (!felem_to_BN(y, y_out)) {
+ ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
+ ERR_R_BN_LIB);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* points below is of size |num|, and tmp_felems is of size |num+1/ */
+static void make_points_affine(size_t num, felem points[][3],
+ felem tmp_felems[])
+{
+ /*
+ * Runs in constant time, unless an input is the point at infinity (which
+ * normally shouldn't happen).
+ */
+ ec_GFp_nistp_points_make_affine_internal(num,
+ points,
+ sizeof(felem),
+ tmp_felems,
+ (void (*)(void *))felem_one,
+ (int (*)(const void *))
+ felem_is_zero_int,
+ (void (*)(void *, const void *))
+ felem_assign,
+ (void (*)(void *, const void *))
+ felem_square_reduce, (void (*)
+ (void *,
+ const void
+ *,
+ const void
+ *))
+ felem_mul_reduce,
+ (void (*)(void *, const void *))
+ felem_inv,
+ (void (*)(void *, const void *))
+ felem_contract);
+}
+
+/*
+ * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
+ * values Result is stored in r (r can equal one of the inputs).
+ */
+int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
+ const BIGNUM *scalar, size_t num,
+ const EC_POINT *points[],
+ const BIGNUM *scalars[], BN_CTX *ctx)
+{
+ int ret = 0;
+ int j;
+ int mixed = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y, *z, *tmp_scalar;
+ felem_bytearray g_secret;
+ felem_bytearray *secrets = NULL;
+ felem(*pre_comp)[17][3] = NULL;
+ felem *tmp_felems = NULL;
+ felem_bytearray tmp;
+ unsigned i, num_bytes;
+ int have_pre_comp = 0;
+ size_t num_points = num;
+ felem x_in, y_in, z_in, x_out, y_out, z_out;
+ NISTP521_PRE_COMP *pre = NULL;
+ felem(*g_pre_comp)[3] = NULL;
+ EC_POINT *generator = NULL;
+ const EC_POINT *p = NULL;
+ const BIGNUM *p_scalar = NULL;
+
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+ return 0;
+ BN_CTX_start(ctx);
+ if (((x = BN_CTX_get(ctx)) == NULL) ||
+ ((y = BN_CTX_get(ctx)) == NULL) ||
+ ((z = BN_CTX_get(ctx)) == NULL) ||
+ ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
+ goto err;
+
+ if (scalar != NULL) {
+ pre = EC_EX_DATA_get_data(group->extra_data,
+ nistp521_pre_comp_dup,
+ nistp521_pre_comp_free,
+ nistp521_pre_comp_clear_free);
+ if (pre)
+ /* we have precomputation, try to use it */
+ g_pre_comp = &pre->g_pre_comp[0];
+ else
+ /* try to use the standard precomputation */
+ g_pre_comp = (felem(*)[3]) gmul;
+ generator = EC_POINT_new(group);
+ if (generator == NULL)
+ goto err;
+ /* get the generator from precomputation */
+ if (!felem_to_BN(x, g_pre_comp[1][0]) ||
+ !felem_to_BN(y, g_pre_comp[1][1]) ||
+ !felem_to_BN(z, g_pre_comp[1][2])) {
+ ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
+ generator, x, y, z,
+ ctx))
+ goto err;
+ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
+ /* precomputation matches generator */
+ have_pre_comp = 1;
+ else
+ /*
+ * we don't have valid precomputation: treat the generator as a
+ * random point
+ */
+ num_points++;
+ }
+
+ if (num_points > 0) {
+ if (num_points >= 2) {
+ /*
+ * unless we precompute multiples for just one point, converting
+ * those into affine form is time well spent
+ */
+ mixed = 1;
+ }
+ secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
+ pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
+ if (mixed)
+ tmp_felems =
+ OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
+ if ((secrets == NULL) || (pre_comp == NULL)
+ || (mixed && (tmp_felems == NULL))) {
+ ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /*
+ * we treat NULL scalars as 0, and NULL points as points at infinity,
+ * i.e., they contribute nothing to the linear combination
+ */
+ memset(secrets, 0, num_points * sizeof(felem_bytearray));
+ memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem));
+ for (i = 0; i < num_points; ++i) {
+ if (i == num)
+ /*
+ * we didn't have a valid precomputation, so we pick the
+ * generator
+ */
+ {
+ p = EC_GROUP_get0_generator(group);
+ p_scalar = scalar;
+ } else
+ /* the i^th point */
+ {
+ p = points[i];
+ p_scalar = scalars[i];
+ }
+ if ((p_scalar != NULL) && (p != NULL)) {
+ /* reduce scalar to 0 <= scalar < 2^521 */
+ if ((BN_num_bits(p_scalar) > 521)
+ || (BN_is_negative(p_scalar))) {
+ /*
+ * this is an unusual input, and we don't guarantee
+ * constant-timeness
+ */
+ if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) {
+ ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ } else
+ num_bytes = BN_bn2bin(p_scalar, tmp);
+ flip_endian(secrets[i], tmp, num_bytes);
+ /* precompute multiples */
+ if ((!BN_to_felem(x_out, &p->X)) ||
+ (!BN_to_felem(y_out, &p->Y)) ||
+ (!BN_to_felem(z_out, &p->Z)))
+ goto err;
+ memcpy(pre_comp[i][1][0], x_out, sizeof(felem));
+ memcpy(pre_comp[i][1][1], y_out, sizeof(felem));
+ memcpy(pre_comp[i][1][2], z_out, sizeof(felem));
+ for (j = 2; j <= 16; ++j) {
+ if (j & 1) {
+ point_add(pre_comp[i][j][0], pre_comp[i][j][1],
+ pre_comp[i][j][2], pre_comp[i][1][0],
+ pre_comp[i][1][1], pre_comp[i][1][2], 0,
+ pre_comp[i][j - 1][0],
+ pre_comp[i][j - 1][1],
+ pre_comp[i][j - 1][2]);
+ } else {
+ point_double(pre_comp[i][j][0], pre_comp[i][j][1],
+ pre_comp[i][j][2], pre_comp[i][j / 2][0],
+ pre_comp[i][j / 2][1],
+ pre_comp[i][j / 2][2]);
+ }
+ }
+ }
+ }
+ if (mixed)
+ make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
+ }
+
+ /* the scalar for the generator */
+ if ((scalar != NULL) && (have_pre_comp)) {
+ memset(g_secret, 0, sizeof(g_secret));
+ /* reduce scalar to 0 <= scalar < 2^521 */
+ if ((BN_num_bits(scalar) > 521) || (BN_is_negative(scalar))) {
+ /*
+ * this is an unusual input, and we don't guarantee
+ * constant-timeness
+ */
+ if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
+ ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ num_bytes = BN_bn2bin(tmp_scalar, tmp);
+ } else
+ num_bytes = BN_bn2bin(scalar, tmp);
+ flip_endian(g_secret, tmp, num_bytes);
+ /* do the multiplication with generator precomputation */
+ batch_mul(x_out, y_out, z_out,
+ (const felem_bytearray(*))secrets, num_points,
+ g_secret,
+ mixed, (const felem(*)[17][3])pre_comp,
+ (const felem(*)[3])g_pre_comp);
+ } else
+ /* do the multiplication without generator precomputation */
+ batch_mul(x_out, y_out, z_out,
+ (const felem_bytearray(*))secrets, num_points,
+ NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
+ /* reduce the output to its unique minimal representation */
+ felem_contract(x_in, x_out);
+ felem_contract(y_in, y_out);
+ felem_contract(z_in, z_out);
+ if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
+ (!felem_to_BN(z, z_in))) {
+ ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+ goto err;
+ }
+ ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+
+ err:
+ BN_CTX_end(ctx);
+ if (generator != NULL)
+ EC_POINT_free(generator);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (secrets != NULL)
+ OPENSSL_free(secrets);
+ if (pre_comp != NULL)
+ OPENSSL_free(pre_comp);
+ if (tmp_felems != NULL)
+ OPENSSL_free(tmp_felems);
+ return ret;
+}
+
+int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+{
+ int ret = 0;
+ NISTP521_PRE_COMP *pre = NULL;
+ int i, j;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *x, *y;
+ EC_POINT *generator = NULL;
+ felem tmp_felems[16];
+
+ /* throw away old precomputation */
+ EC_EX_DATA_free_data(&group->extra_data, nistp521_pre_comp_dup,
+ nistp521_pre_comp_free,
+ nistp521_pre_comp_clear_free);
+ if (ctx == NULL)
+ if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+ return 0;
+ BN_CTX_start(ctx);
+ if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL))
+ goto err;
+ /* get the generator */
+ if (group->generator == NULL)
+ goto err;
+ generator = EC_POINT_new(group);
+ if (generator == NULL)
+ goto err;
+ BN_bin2bn(nistp521_curve_params[3], sizeof(felem_bytearray), x);
+ BN_bin2bn(nistp521_curve_params[4], sizeof(felem_bytearray), y);
+ if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
+ goto err;
+ if ((pre = nistp521_pre_comp_new()) == NULL)
+ goto err;
+ /*
+ * if the generator is the standard one, use built-in precomputation
+ */
+ if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
+ memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
+ ret = 1;
+ goto err;
+ }
+ if ((!BN_to_felem(pre->g_pre_comp[1][0], &group->generator->X)) ||
+ (!BN_to_felem(pre->g_pre_comp[1][1], &group->generator->Y)) ||
+ (!BN_to_felem(pre->g_pre_comp[1][2], &group->generator->Z)))
+ goto err;
+ /* compute 2^130*G, 2^260*G, 2^390*G */
+ for (i = 1; i <= 4; i <<= 1) {
+ point_double(pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1],
+ pre->g_pre_comp[2 * i][2], pre->g_pre_comp[i][0],
+ pre->g_pre_comp[i][1], pre->g_pre_comp[i][2]);
+ for (j = 0; j < 129; ++j) {
+ point_double(pre->g_pre_comp[2 * i][0],
+ pre->g_pre_comp[2 * i][1],
+ pre->g_pre_comp[2 * i][2],
+ pre->g_pre_comp[2 * i][0],
+ pre->g_pre_comp[2 * i][1],
+ pre->g_pre_comp[2 * i][2]);
+ }
+ }
+ /* g_pre_comp[0] is the point at infinity */
+ memset(pre->g_pre_comp[0], 0, sizeof(pre->g_pre_comp[0]));
+ /* the remaining multiples */
+ /* 2^130*G + 2^260*G */
+ point_add(pre->g_pre_comp[6][0], pre->g_pre_comp[6][1],
+ pre->g_pre_comp[6][2], pre->g_pre_comp[4][0],
+ pre->g_pre_comp[4][1], pre->g_pre_comp[4][2],
+ 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
+ pre->g_pre_comp[2][2]);
+ /* 2^130*G + 2^390*G */
+ point_add(pre->g_pre_comp[10][0], pre->g_pre_comp[10][1],
+ pre->g_pre_comp[10][2], pre->g_pre_comp[8][0],
+ pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
+ 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
+ pre->g_pre_comp[2][2]);
+ /* 2^260*G + 2^390*G */
+ point_add(pre->g_pre_comp[12][0], pre->g_pre_comp[12][1],
+ pre->g_pre_comp[12][2], pre->g_pre_comp[8][0],
+ pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
+ 0, pre->g_pre_comp[4][0], pre->g_pre_comp[4][1],
+ pre->g_pre_comp[4][2]);
+ /* 2^130*G + 2^260*G + 2^390*G */
+ point_add(pre->g_pre_comp[14][0], pre->g_pre_comp[14][1],
+ pre->g_pre_comp[14][2], pre->g_pre_comp[12][0],
+ pre->g_pre_comp[12][1], pre->g_pre_comp[12][2],
+ 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
+ pre->g_pre_comp[2][2]);
+ for (i = 1; i < 8; ++i) {
+ /* odd multiples: add G */
+ point_add(pre->g_pre_comp[2 * i + 1][0],
+ pre->g_pre_comp[2 * i + 1][1],
+ pre->g_pre_comp[2 * i + 1][2], pre->g_pre_comp[2 * i][0],
+ pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2], 0,
+ pre->g_pre_comp[1][0], pre->g_pre_comp[1][1],
+ pre->g_pre_comp[1][2]);
+ }
+ make_points_affine(15, &(pre->g_pre_comp[1]), tmp_felems);
+
+ if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp521_pre_comp_dup,
+ nistp521_pre_comp_free,
+ nistp521_pre_comp_clear_free))
+ goto err;
+ ret = 1;
+ pre = NULL;
+ err:
+ BN_CTX_end(ctx);
+ if (generator != NULL)
+ EC_POINT_free(generator);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (pre)
+ nistp521_pre_comp_free(pre);
+ return ret;
+}
+
+int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group)
+{
+ if (EC_EX_DATA_get_data(group->extra_data, nistp521_pre_comp_dup,
+ nistp521_pre_comp_free,
+ nistp521_pre_comp_clear_free)
+ != NULL)
+ return 1;
+ else
+ return 0;
+}
+
+#else
+static void *dummy = &dummy;
+#endif
diff --git a/openssl/ec/ecp_nistputil.c b/openssl/ec/ecp_nistputil.c
new file mode 100644
index 0000000..8ba2a25
--- /dev/null
+++ b/openssl/ec/ecp_nistputil.c
@@ -0,0 +1,218 @@
+/* crypto/ec/ecp_nistputil.c */
+/*
+ * Written by Bodo Moeller for the OpenSSL project.
+ */
+/* Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ *
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+
+/*
+ * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c.
+ */
+
+# include <stddef.h>
+# include "ec_lcl.h"
+
+/*
+ * Convert an array of points into affine coordinates. (If the point at
+ * infinity is found (Z = 0), it remains unchanged.) This function is
+ * essentially an equivalent to EC_POINTs_make_affine(), but works with the
+ * internal representation of points as used by ecp_nistp###.c rather than
+ * with (BIGNUM-based) EC_POINT data structures. point_array is the
+ * input/output buffer ('num' points in projective form, i.e. three
+ * coordinates each), based on an internal representation of field elements
+ * of size 'felem_size'. tmp_felems needs to point to a temporary array of
+ * 'num'+1 field elements for storage of intermediate values.
+ */
+void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
+ size_t felem_size,
+ void *tmp_felems,
+ void (*felem_one) (void *out),
+ int (*felem_is_zero) (const void
+ *in),
+ void (*felem_assign) (void *out,
+ const void
+ *in),
+ void (*felem_square) (void *out,
+ const void
+ *in),
+ void (*felem_mul) (void *out,
+ const void
+ *in1,
+ const void
+ *in2),
+ void (*felem_inv) (void *out,
+ const void
+ *in),
+ void (*felem_contract) (void
+ *out,
+ const
+ void
+ *in))
+{
+ int i = 0;
+
+# define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size])
+# define X(I) (&((char *)point_array)[3*(I) * felem_size])
+# define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size])
+# define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size])
+
+ if (!felem_is_zero(Z(0)))
+ felem_assign(tmp_felem(0), Z(0));
+ else
+ felem_one(tmp_felem(0));
+ for (i = 1; i < (int)num; i++) {
+ if (!felem_is_zero(Z(i)))
+ felem_mul(tmp_felem(i), tmp_felem(i - 1), Z(i));
+ else
+ felem_assign(tmp_felem(i), tmp_felem(i - 1));
+ }
+ /*
+ * Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any
+ * zero-valued factors: if Z(i) = 0, we essentially pretend that Z(i) = 1
+ */
+
+ felem_inv(tmp_felem(num - 1), tmp_felem(num - 1));
+ for (i = num - 1; i >= 0; i--) {
+ if (i > 0)
+ /*
+ * tmp_felem(i-1) is the product of Z(0) .. Z(i-1), tmp_felem(i)
+ * is the inverse of the product of Z(0) .. Z(i)
+ */
+ /* 1/Z(i) */
+ felem_mul(tmp_felem(num), tmp_felem(i - 1), tmp_felem(i));
+ else
+ felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */
+
+ if (!felem_is_zero(Z(i))) {
+ if (i > 0)
+ /*
+ * For next iteration, replace tmp_felem(i-1) by its inverse
+ */
+ felem_mul(tmp_felem(i - 1), tmp_felem(i), Z(i));
+
+ /*
+ * Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1)
+ */
+ felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */
+ felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */
+ felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */
+ felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */
+ felem_contract(X(i), X(i));
+ felem_contract(Y(i), Y(i));
+ felem_one(Z(i));
+ } else {
+ if (i > 0)
+ /*
+ * For next iteration, replace tmp_felem(i-1) by its inverse
+ */
+ felem_assign(tmp_felem(i - 1), tmp_felem(i));
+ }
+ }
+}
+
+/*-
+ * This function looks at 5+1 scalar bits (5 current, 1 adjacent less
+ * significant bit), and recodes them into a signed digit for use in fast point
+ * multiplication: the use of signed rather than unsigned digits means that
+ * fewer points need to be precomputed, given that point inversion is easy
+ * (a precomputed point dP makes -dP available as well).
+ *
+ * BACKGROUND:
+ *
+ * Signed digits for multiplication were introduced by Booth ("A signed binary
+ * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV,
+ * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers.
+ * Booth's original encoding did not generally improve the density of nonzero
+ * digits over the binary representation, and was merely meant to simplify the
+ * handling of signed factors given in two's complement; but it has since been
+ * shown to be the basis of various signed-digit representations that do have
+ * further advantages, including the wNAF, using the following general approach:
+ *
+ * (1) Given a binary representation
+ *
+ * b_k ... b_2 b_1 b_0,
+ *
+ * of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1
+ * by using bit-wise subtraction as follows:
+ *
+ * b_k b_(k-1) ... b_2 b_1 b_0
+ * - b_k ... b_3 b_2 b_1 b_0
+ * -------------------------------------
+ * s_k b_(k-1) ... s_3 s_2 s_1 s_0
+ *
+ * A left-shift followed by subtraction of the original value yields a new
+ * representation of the same value, using signed bits s_i = b_(i+1) - b_i.
+ * This representation from Booth's paper has since appeared in the
+ * literature under a variety of different names including "reversed binary
+ * form", "alternating greedy expansion", "mutual opposite form", and
+ * "sign-alternating {+-1}-representation".
+ *
+ * An interesting property is that among the nonzero bits, values 1 and -1
+ * strictly alternate.
+ *
+ * (2) Various window schemes can be applied to the Booth representation of
+ * integers: for example, right-to-left sliding windows yield the wNAF
+ * (a signed-digit encoding independently discovered by various researchers
+ * in the 1990s), and left-to-right sliding windows yield a left-to-right
+ * equivalent of the wNAF (independently discovered by various researchers
+ * around 2004).
+ *
+ * To prevent leaking information through side channels in point multiplication,
+ * we need to recode the given integer into a regular pattern: sliding windows
+ * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few
+ * decades older: we'll be using the so-called "modified Booth encoding" due to
+ * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49
+ * (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five
+ * signed bits into a signed digit:
+ *
+ * s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j)
+ *
+ * The sign-alternating property implies that the resulting digit values are
+ * integers from -16 to 16.
+ *
+ * Of course, we don't actually need to compute the signed digits s_i as an
+ * intermediate step (that's just a nice way to see how this scheme relates
+ * to the wNAF): a direct computation obtains the recoded digit from the
+ * six bits b_(4j + 4) ... b_(4j - 1).
+ *
+ * This function takes those five bits as an integer (0 .. 63), writing the
+ * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute
+ * value, in the range 0 .. 8). Note that this integer essentially provides the
+ * input bits "shifted to the left" by one position: for example, the input to
+ * compute the least significant recoded digit, given that there's no bit b_-1,
+ * has to be b_4 b_3 b_2 b_1 b_0 0.
+ *
+ */
+void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
+ unsigned char *digit, unsigned char in)
+{
+ unsigned char s, d;
+
+ s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as
+ * 6-bit value */
+ d = (1 << 6) - in - 1;
+ d = (d & s) | (in & ~s);
+ d = (d >> 1) + (d & 1);
+
+ *sign = s & 1;
+ *digit = d;
+}
+#else
+static void *dummy = &dummy;
+#endif
diff --git a/openssl/ec/ecp_oct.c b/openssl/ec/ecp_oct.c
new file mode 100644
index 0000000..e5cec8b
--- /dev/null
+++ b/openssl/ec/ecp_oct.c
@@ -0,0 +1,428 @@
+/* crypto/ec/ecp_oct.c */
+/*
+ * Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
+ * for the OpenSSL project. Includes code written by Bodo Moeller 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 this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <openssl/err.h>
+#include <openssl/symhacks.h>
+
+#include "ec_lcl.h"
+
+int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
+ EC_POINT *point,
+ const BIGNUM *x_, int y_bit,
+ BN_CTX *ctx)
+{
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp1, *tmp2, *x, *y;
+ int ret = 0;
+
+ /* clear error queue */
+ ERR_clear_error();
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ y_bit = (y_bit != 0);
+
+ BN_CTX_start(ctx);
+ tmp1 = BN_CTX_get(ctx);
+ tmp2 = BN_CTX_get(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (y == NULL)
+ goto err;
+
+ /*-
+ * Recover y. We have a Weierstrass equation
+ * y^2 = x^3 + a*x + b,
+ * so y is one of the square roots of x^3 + a*x + b.
+ */
+
+ /* tmp1 := x^3 */
+ if (!BN_nnmod(x, x_, &group->field, ctx))
+ goto err;
+ if (group->meth->field_decode == 0) {
+ /* field_{sqr,mul} work on standard representation */
+ if (!group->meth->field_sqr(group, tmp2, x_, ctx))
+ goto err;
+ if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx))
+ goto err;
+ } else {
+ if (!BN_mod_sqr(tmp2, x_, &group->field, ctx))
+ goto err;
+ if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx))
+ goto err;
+ }
+
+ /* tmp1 := tmp1 + a*x */
+ if (group->a_is_minus3) {
+ if (!BN_mod_lshift1_quick(tmp2, x, &group->field))
+ goto err;
+ if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field))
+ goto err;
+ if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field))
+ goto err;
+ } else {
+ if (group->meth->field_decode) {
+ if (!group->meth->field_decode(group, tmp2, &group->a, ctx))
+ goto err;
+ if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx))
+ goto err;
+ } else {
+ /* field_mul works on standard representation */
+ if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx))
+ goto err;
+ }
+
+ if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field))
+ goto err;
+ }
+
+ /* tmp1 := tmp1 + b */
+ if (group->meth->field_decode) {
+ if (!group->meth->field_decode(group, tmp2, &group->b, ctx))
+ goto err;
+ if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field))
+ goto err;
+ } else {
+ if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field))
+ goto err;
+ }
+
+ if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) {
+ unsigned long err = ERR_peek_last_error();
+
+ if (ERR_GET_LIB(err) == ERR_LIB_BN
+ && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
+ ERR_clear_error();
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
+ EC_R_INVALID_COMPRESSED_POINT);
+ } else
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
+ ERR_R_BN_LIB);
+ goto err;
+ }
+
+ if (y_bit != BN_is_odd(y)) {
+ if (BN_is_zero(y)) {
+ int kron;
+
+ kron = BN_kronecker(x, &group->field, ctx);
+ if (kron == -2)
+ goto err;
+
+ if (kron == 1)
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
+ EC_R_INVALID_COMPRESSION_BIT);
+ else
+ /*
+ * BN_mod_sqrt() should have cought this error (not a square)
+ */
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
+ EC_R_INVALID_COMPRESSED_POINT);
+ goto err;
+ }
+ if (!BN_usub(y, &group->field, y))
+ goto err;
+ }
+ if (y_bit != BN_is_odd(y)) {
+ ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
+ ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GFp(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;
+}
+
+size_t ec_GFp_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;
+ size_t field_len, i, skip;
+
+ if ((form != POINT_CONVERSION_COMPRESSED)
+ && (form != POINT_CONVERSION_UNCOMPRESSED)
+ && (form != POINT_CONVERSION_HYBRID)) {
+ ECerr(EC_F_EC_GFP_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_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ buf[0] = 0;
+ }
+ return 1;
+ }
+
+ /* ret := required output buffer length */
+ field_len = BN_num_bytes(&group->field);
+ 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_GFP_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);
+ if (y == NULL)
+ goto err;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
+ goto err;
+
+ if ((form == POINT_CONVERSION_COMPRESSED
+ || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
+ buf[0] = form + 1;
+ else
+ buf[0] = form;
+
+ i = 1;
+
+ skip = field_len - BN_num_bytes(x);
+ if (skip > field_len) {
+ ECerr(EC_F_EC_GFP_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_GFP_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_GFP_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_GFP_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;
+}
+
+int ec_GFp_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;
+ size_t field_len, enc_len;
+ int ret = 0;
+
+ if (len == 0) {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ form = buf[0];
+ y_bit = form & 1;
+ form = form & ~1U;
+ if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
+ && (form != POINT_CONVERSION_UNCOMPRESSED)
+ && (form != POINT_CONVERSION_HYBRID)) {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+ if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ if (form == 0) {
+ if (len != 1) {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ return EC_POINT_set_to_infinity(group, point);
+ }
+
+ field_len = BN_num_bytes(&group->field);
+ enc_len =
+ (form ==
+ POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
+
+ if (len != enc_len) {
+ ECerr(EC_F_EC_GFP_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);
+ if (y == NULL)
+ goto err;
+
+ if (!BN_bin2bn(buf + 1, field_len, x))
+ goto err;
+ if (BN_ucmp(x, &group->field) >= 0) {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+
+ if (form == POINT_CONVERSION_COMPRESSED) {
+ if (!EC_POINT_set_compressed_coordinates_GFp
+ (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_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+ if (form == POINT_CONVERSION_HYBRID) {
+ if (y_bit != BN_is_odd(y)) {
+ ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+ goto err;
+ }
+ }
+
+ if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
+ goto err;
+ }
+
+ /* test required by X9.62 */
+ if (!EC_POINT_is_on_curve(group, point, ctx)) {
+ ECerr(EC_F_EC_GFP_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;
+}
diff --git a/openssl/ec/ecp_smpl.c b/openssl/ec/ecp_smpl.c
new file mode 100644
index 0000000..5f52800
--- /dev/null
+++ b/openssl/ec/ecp_smpl.c
@@ -0,0 +1,1476 @@
+/* crypto/ec/ecp_smpl.c */
+/*
+ * Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
+ * for the OpenSSL project. Includes code written by Bodo Moeller 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 this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <openssl/err.h>
+#include <openssl/symhacks.h>
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+#include "ec_lcl.h"
+
+const EC_METHOD *EC_GFp_simple_method(void)
+{
+ static const EC_METHOD ret = {
+ EC_FLAGS_DEFAULT_OCT,
+ NID_X9_62_prime_field,
+ ec_GFp_simple_group_init,
+ ec_GFp_simple_group_finish,
+ ec_GFp_simple_group_clear_finish,
+ ec_GFp_simple_group_copy,
+ ec_GFp_simple_group_set_curve,
+#ifdef DISABLE_UNUSED_EC_FUNCTS
+ 0,
+ 0,
+ 0,
+#else /* DISABLE_UNUSED_EC_FUNCTS */
+ ec_GFp_simple_group_get_curve,
+ ec_GFp_simple_group_get_degree,
+ ec_GFp_simple_group_check_discriminant,
+#endif /* DISABLE_UNUSED_EC_FUNCTS */
+ ec_GFp_simple_point_init,
+ ec_GFp_simple_point_finish,
+ ec_GFp_simple_point_clear_finish,
+ ec_GFp_simple_point_copy,
+ ec_GFp_simple_point_set_to_infinity,
+ ec_GFp_simple_set_Jprojective_coordinates_GFp,
+ ec_GFp_simple_get_Jprojective_coordinates_GFp,
+ ec_GFp_simple_point_set_affine_coordinates,
+ ec_GFp_simple_point_get_affine_coordinates,
+ 0, 0, 0,
+ ec_GFp_simple_add,
+ ec_GFp_simple_dbl,
+ ec_GFp_simple_invert,
+ ec_GFp_simple_is_at_infinity,
+ ec_GFp_simple_is_on_curve,
+#ifdef DISABLE_UNUSED_EC_FUNCTS
+ 0,
+#else /* DISABLE_UNUSED_EC_FUNCTS */
+ ec_GFp_simple_cmp,
+#endif /* DISABLE_UNUSED_EC_FUNCTS */
+ ec_GFp_simple_make_affine,
+ ec_GFp_simple_points_make_affine,
+ 0 /* mul */ ,
+ 0 /* precompute_mult */ ,
+ 0 /* have_precompute_mult */ ,
+ ec_GFp_simple_field_mul,
+ ec_GFp_simple_field_sqr,
+ 0 /* field_div */ ,
+ 0 /* field_encode */ ,
+ 0 /* field_decode */ ,
+ 0 /* field_set_to_one */
+ };
+
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return fips_ec_gfp_simple_method();
+#endif
+
+ return &ret;
+}
+
+/*
+ * Most method functions in this file are designed to work with
+ * non-trivial representations of field elements if necessary
+ * (see ecp_mont.c): while standard modular addition and subtraction
+ * are used, the field_mul and field_sqr methods will be used for
+ * multiplication, and field_encode and field_decode (if defined)
+ * will be used for converting between representations.
+ *
+ * Functions ec_GFp_simple_points_make_affine() and
+ * ec_GFp_simple_point_get_affine_coordinates() specifically assume
+ * that if a non-trivial representation is used, it is a Montgomery
+ * representation (i.e. 'encoding' means multiplying by some factor R).
+ */
+
+int ec_GFp_simple_group_init(EC_GROUP *group)
+{
+ BN_init(&group->field);
+ BN_init(&group->a);
+ BN_init(&group->b);
+ group->a_is_minus3 = 0;
+ return 1;
+}
+
+void ec_GFp_simple_group_finish(EC_GROUP *group)
+{
+ BN_free(&group->field);
+ BN_free(&group->a);
+ BN_free(&group->b);
+}
+
+void ec_GFp_simple_group_clear_finish(EC_GROUP *group)
+{
+ BN_clear_free(&group->field);
+ BN_clear_free(&group->a);
+ BN_clear_free(&group->b);
+}
+
+int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+{
+ 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->a_is_minus3 = src->a_is_minus3;
+
+ return 1;
+}
+
+int ec_GFp_simple_group_set_curve(EC_GROUP *group,
+ const BIGNUM *p, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx)
+{
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp_a;
+
+ /* p must be a prime > 3 */
+ if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
+ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
+ return 0;
+ }
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ tmp_a = BN_CTX_get(ctx);
+ if (tmp_a == NULL)
+ goto err;
+
+ /* group->field */
+ if (!BN_copy(&group->field, p))
+ goto err;
+ BN_set_negative(&group->field, 0);
+
+ /* group->a */
+ if (!BN_nnmod(tmp_a, a, p, ctx))
+ goto err;
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode) {
+ if (!group->meth->field_encode(group, &group->a, tmp_a, ctx))
+ goto err;
+ } else
+#endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ if (!BN_copy(&group->a, tmp_a))
+ goto err;
+
+ /* group->b */
+ if (!BN_nnmod(&group->b, b, p, ctx))
+ goto err;
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode)
+ if (!group->meth->field_encode(group, &group->b, &group->b, ctx))
+ goto err;
+#endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+
+ /* group->a_is_minus3 */
+ if (!BN_add_word(tmp_a, 3))
+ goto err;
+ group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+ BIGNUM *b, BN_CTX *ctx)
+{
+ int ret = 0;
+ BN_CTX *new_ctx = NULL;
+
+ if (p != NULL) {
+ if (!BN_copy(p, &group->field))
+ return 0;
+ }
+
+ if (a != NULL || b != NULL) {
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_decode) {
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+ if (a != NULL) {
+ if (!group->meth->field_decode(group, a, &group->a, ctx))
+ goto err;
+ }
+ if (b != NULL) {
+ if (!group->meth->field_decode(group, b, &group->b, ctx))
+ goto err;
+ }
+ } else
+#endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ {
+ 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:
+ if (new_ctx)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
+{
+ return BN_num_bits(&group->field);
+}
+
+int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
+{
+ int ret = 0;
+ BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
+ const BIGNUM *p = &group->field;
+ BN_CTX *new_ctx = NULL;
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ BN_CTX_start(ctx);
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ tmp_1 = BN_CTX_get(ctx);
+ tmp_2 = BN_CTX_get(ctx);
+ order = BN_CTX_get(ctx);
+ if (order == NULL)
+ goto err;
+
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_decode) {
+ if (!group->meth->field_decode(group, a, &group->a, ctx))
+ goto err;
+ if (!group->meth->field_decode(group, b, &group->b, ctx))
+ goto err;
+ } else
+#endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ {
+ if (!BN_copy(a, &group->a))
+ goto err;
+ if (!BN_copy(b, &group->b))
+ goto err;
+ }
+
+ /*-
+ * check the discriminant:
+ * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
+ * 0 =< a, b < p
+ */
+ if (BN_is_zero(a)) {
+ if (BN_is_zero(b))
+ goto err;
+ } else if (!BN_is_zero(b)) {
+ if (!BN_mod_sqr(tmp_1, a, p, ctx))
+ goto err;
+ if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx))
+ goto err;
+ if (!BN_lshift(tmp_1, tmp_2, 2))
+ goto err;
+ /* tmp_1 = 4*a^3 */
+
+ if (!BN_mod_sqr(tmp_2, b, p, ctx))
+ goto err;
+ if (!BN_mul_word(tmp_2, 27))
+ goto err;
+ /* tmp_2 = 27*b^2 */
+
+ if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx))
+ goto err;
+ if (BN_is_zero(a))
+ goto err;
+ }
+ ret = 1;
+
+ err:
+ if (ctx != NULL)
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int ec_GFp_simple_point_init(EC_POINT *point)
+{
+ BN_init(&point->X);
+ BN_init(&point->Y);
+ BN_init(&point->Z);
+ point->Z_is_one = 0;
+
+ return 1;
+}
+
+void ec_GFp_simple_point_finish(EC_POINT *point)
+{
+ BN_free(&point->X);
+ BN_free(&point->Y);
+ BN_free(&point->Z);
+}
+
+void ec_GFp_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;
+}
+
+int ec_GFp_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;
+}
+
+int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
+ EC_POINT *point)
+{
+ point->Z_is_one = 0;
+ BN_zero(&point->Z);
+ return 1;
+}
+
+int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
+ EC_POINT *point,
+ const BIGNUM *x,
+ const BIGNUM *y,
+ const BIGNUM *z,
+ BN_CTX *ctx)
+{
+ BN_CTX *new_ctx = NULL;
+ int ret = 0;
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ if (x != NULL) {
+ if (!BN_nnmod(&point->X, x, &group->field, ctx))
+ goto err;
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode) {
+ if (!group->meth->field_encode(group, &point->X, &point->X, ctx))
+ goto err;
+ }
+#endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ }
+
+ if (y != NULL) {
+ if (!BN_nnmod(&point->Y, y, &group->field, ctx))
+ goto err;
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode) {
+ if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx))
+ goto err;
+ }
+#endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ }
+
+ if (z != NULL) {
+ int Z_is_one;
+
+ if (!BN_nnmod(&point->Z, z, &group->field, ctx))
+ goto err;
+ Z_is_one = BN_is_one(&point->Z);
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode) {
+ if (Z_is_one && (group->meth->field_set_to_one != 0)) {
+ if (!group->meth->field_set_to_one(group, &point->Z, ctx))
+ goto err;
+ } else {
+ if (!group->
+ meth->field_encode(group, &point->Z, &point->Z, ctx))
+ goto err;
+ }
+ }
+#endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ point->Z_is_one = Z_is_one;
+ }
+
+ ret = 1;
+
+ err:
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BIGNUM *z, BN_CTX *ctx)
+{
+ BN_CTX *new_ctx = NULL;
+ int ret = 0;
+
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_decode != 0) {
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ if (x != NULL) {
+ if (!group->meth->field_decode(group, x, &point->X, ctx))
+ goto err;
+ }
+ if (y != NULL) {
+ if (!group->meth->field_decode(group, y, &point->Y, ctx))
+ goto err;
+ }
+ if (z != NULL) {
+ if (!group->meth->field_decode(group, z, &point->Z, ctx))
+ goto err;
+ }
+ } else
+#endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ {
+ if (x != NULL) {
+ if (!BN_copy(x, &point->X))
+ goto err;
+ }
+ if (y != NULL) {
+ if (!BN_copy(y, &point->Y))
+ goto err;
+ }
+ if (z != NULL) {
+ if (!BN_copy(z, &point->Z))
+ goto err;
+ }
+ }
+
+ ret = 1;
+
+ err:
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
+ EC_POINT *point,
+ const BIGNUM *x,
+ const BIGNUM *y, BN_CTX *ctx)
+{
+ if (x == NULL || y == NULL) {
+ /*
+ * unlike for projective coordinates, we do not tolerate this
+ */
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES,
+ ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y,
+ BN_value_one(), ctx);
+}
+
+int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
+ const EC_POINT *point,
+ BIGNUM *x, BIGNUM *y,
+ BN_CTX *ctx)
+{
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *Z, *Z_1, *Z_2, *Z_3;
+ const BIGNUM *Z_;
+ int ret = 0;
+
+ if (EC_POINT_is_at_infinity(group, point)) {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
+ EC_R_POINT_AT_INFINITY);
+ return 0;
+ }
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ Z = BN_CTX_get(ctx);
+ Z_1 = BN_CTX_get(ctx);
+ Z_2 = BN_CTX_get(ctx);
+ Z_3 = BN_CTX_get(ctx);
+ if (Z_3 == NULL)
+ goto err;
+
+ /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
+
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_decode) {
+ if (!group->meth->field_decode(group, Z, &point->Z, ctx))
+ goto err;
+ Z_ = Z;
+ } else
+#endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ {
+ Z_ = &point->Z;
+ }
+
+ if (BN_is_one(Z_)) {
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_decode) {
+ if (x != NULL) {
+ if (!group->meth->field_decode(group, x, &point->X, ctx))
+ goto err;
+ }
+ if (y != NULL) {
+ if (!group->meth->field_decode(group, y, &point->Y, ctx))
+ goto err;
+ }
+ } else
+#endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ {
+ if (x != NULL) {
+ if (!BN_copy(x, &point->X))
+ goto err;
+ }
+ if (y != NULL) {
+ if (!BN_copy(y, &point->Y))
+ goto err;
+ }
+ }
+ } else {
+ if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
+ ERR_R_BN_LIB);
+ goto err;
+ }
+
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode == 0) {
+ /* field_sqr works on standard representation */
+ if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
+ goto err;
+ } else
+#endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ {
+ if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx))
+ goto err;
+ }
+
+ if (x != NULL) {
+ /*
+ * in the Montgomery case, field_mul will cancel out Montgomery
+ * factor in X:
+ */
+ if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx))
+ goto err;
+ }
+
+ if (y != NULL) {
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode == 0) {
+ /*
+ * field_mul works on standard representation
+ */
+ if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
+ goto err;
+ } else
+#endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ {
+ if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx))
+ goto err;
+ }
+
+ /*
+ * in the Montgomery case, field_mul will cancel out Montgomery
+ * factor in Y:
+ */
+ if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx))
+ goto err;
+ }
+ }
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *ctx)
+{
+ int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
+ const BIGNUM *, BN_CTX *);
+ int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+ const BIGNUM *p;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
+ int ret = 0;
+
+ if (a == b)
+ return EC_POINT_dbl(group, r, a, ctx);
+ if (EC_POINT_is_at_infinity(group, a))
+ return EC_POINT_copy(r, b);
+ if (EC_POINT_is_at_infinity(group, b))
+ return EC_POINT_copy(r, a);
+
+ field_mul = group->meth->field_mul;
+ field_sqr = group->meth->field_sqr;
+ p = &group->field;
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ n0 = BN_CTX_get(ctx);
+ n1 = BN_CTX_get(ctx);
+ n2 = BN_CTX_get(ctx);
+ n3 = BN_CTX_get(ctx);
+ n4 = BN_CTX_get(ctx);
+ n5 = BN_CTX_get(ctx);
+ n6 = BN_CTX_get(ctx);
+ if (n6 == NULL)
+ goto end;
+
+ /*
+ * Note that in this function we must not read components of 'a' or 'b'
+ * once we have written the corresponding components of 'r'. ('r' might
+ * be one of 'a' or 'b'.)
+ */
+
+ /* n1, n2 */
+ if (b->Z_is_one) {
+ if (!BN_copy(n1, &a->X))
+ goto end;
+ if (!BN_copy(n2, &a->Y))
+ goto end;
+ /* n1 = X_a */
+ /* n2 = Y_a */
+ } else {
+ if (!field_sqr(group, n0, &b->Z, ctx))
+ goto end;
+ if (!field_mul(group, n1, &a->X, n0, ctx))
+ goto end;
+ /* n1 = X_a * Z_b^2 */
+
+ if (!field_mul(group, n0, n0, &b->Z, ctx))
+ goto end;
+ if (!field_mul(group, n2, &a->Y, n0, ctx))
+ goto end;
+ /* n2 = Y_a * Z_b^3 */
+ }
+
+ /* n3, n4 */
+ if (a->Z_is_one) {
+ if (!BN_copy(n3, &b->X))
+ goto end;
+ if (!BN_copy(n4, &b->Y))
+ goto end;
+ /* n3 = X_b */
+ /* n4 = Y_b */
+ } else {
+ if (!field_sqr(group, n0, &a->Z, ctx))
+ goto end;
+ if (!field_mul(group, n3, &b->X, n0, ctx))
+ goto end;
+ /* n3 = X_b * Z_a^2 */
+
+ if (!field_mul(group, n0, n0, &a->Z, ctx))
+ goto end;
+ if (!field_mul(group, n4, &b->Y, n0, ctx))
+ goto end;
+ /* n4 = Y_b * Z_a^3 */
+ }
+
+ /* n5, n6 */
+ if (!BN_mod_sub_quick(n5, n1, n3, p))
+ goto end;
+ if (!BN_mod_sub_quick(n6, n2, n4, p))
+ goto end;
+ /* n5 = n1 - n3 */
+ /* n6 = n2 - n4 */
+
+ if (BN_is_zero(n5)) {
+ if (BN_is_zero(n6)) {
+ /* a is the same point as b */
+ BN_CTX_end(ctx);
+ ret = EC_POINT_dbl(group, r, a, ctx);
+ ctx = NULL;
+ goto end;
+ } else {
+ /* a is the inverse of b */
+ BN_zero(&r->Z);
+ r->Z_is_one = 0;
+ ret = 1;
+ goto end;
+ }
+ }
+
+ /* 'n7', 'n8' */
+ if (!BN_mod_add_quick(n1, n1, n3, p))
+ goto end;
+ if (!BN_mod_add_quick(n2, n2, n4, p))
+ goto end;
+ /* 'n7' = n1 + n3 */
+ /* 'n8' = n2 + n4 */
+
+ /* Z_r */
+ if (a->Z_is_one && b->Z_is_one) {
+ if (!BN_copy(&r->Z, n5))
+ goto end;
+ } else {
+ if (a->Z_is_one) {
+ if (!BN_copy(n0, &b->Z))
+ goto end;
+ } else if (b->Z_is_one) {
+ if (!BN_copy(n0, &a->Z))
+ goto end;
+ } else {
+ if (!field_mul(group, n0, &a->Z, &b->Z, ctx))
+ goto end;
+ }
+ if (!field_mul(group, &r->Z, n0, n5, ctx))
+ goto end;
+ }
+ r->Z_is_one = 0;
+ /* Z_r = Z_a * Z_b * n5 */
+
+ /* X_r */
+ if (!field_sqr(group, n0, n6, ctx))
+ goto end;
+ if (!field_sqr(group, n4, n5, ctx))
+ goto end;
+ if (!field_mul(group, n3, n1, n4, ctx))
+ goto end;
+ if (!BN_mod_sub_quick(&r->X, n0, n3, p))
+ goto end;
+ /* X_r = n6^2 - n5^2 * 'n7' */
+
+ /* 'n9' */
+ if (!BN_mod_lshift1_quick(n0, &r->X, p))
+ goto end;
+ if (!BN_mod_sub_quick(n0, n3, n0, p))
+ goto end;
+ /* n9 = n5^2 * 'n7' - 2 * X_r */
+
+ /* Y_r */
+ if (!field_mul(group, n0, n0, n6, ctx))
+ goto end;
+ if (!field_mul(group, n5, n4, n5, ctx))
+ goto end; /* now n5 is n5^3 */
+ if (!field_mul(group, n1, n2, n5, ctx))
+ goto end;
+ if (!BN_mod_sub_quick(n0, n0, n1, p))
+ goto end;
+ if (BN_is_odd(n0))
+ if (!BN_add(n0, n0, p))
+ goto end;
+ /* now 0 <= n0 < 2*p, and n0 is even */
+ if (!BN_rshift1(&r->Y, n0))
+ goto end;
+ /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
+
+ ret = 1;
+
+ end:
+ if (ctx) /* otherwise we already called BN_CTX_end */
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+ BN_CTX *ctx)
+{
+ int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
+ const BIGNUM *, BN_CTX *);
+ int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+ const BIGNUM *p;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *n0, *n1, *n2, *n3;
+ int ret = 0;
+
+ if (EC_POINT_is_at_infinity(group, a)) {
+ BN_zero(&r->Z);
+ r->Z_is_one = 0;
+ return 1;
+ }
+
+ field_mul = group->meth->field_mul;
+ field_sqr = group->meth->field_sqr;
+ p = &group->field;
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ n0 = BN_CTX_get(ctx);
+ n1 = BN_CTX_get(ctx);
+ n2 = BN_CTX_get(ctx);
+ n3 = BN_CTX_get(ctx);
+ if (n3 == NULL)
+ goto err;
+
+ /*
+ * Note that in this function we must not read components of 'a' once we
+ * have written the corresponding components of 'r'. ('r' might the same
+ * as 'a'.)
+ */
+
+ /* n1 */
+ if (a->Z_is_one) {
+ if (!field_sqr(group, n0, &a->X, ctx))
+ goto err;
+ if (!BN_mod_lshift1_quick(n1, n0, p))
+ goto err;
+ if (!BN_mod_add_quick(n0, n0, n1, p))
+ goto err;
+ if (!BN_mod_add_quick(n1, n0, &group->a, p))
+ goto err;
+ /* n1 = 3 * X_a^2 + a_curve */
+ } else if (group->a_is_minus3) {
+ if (!field_sqr(group, n1, &a->Z, ctx))
+ goto err;
+ if (!BN_mod_add_quick(n0, &a->X, n1, p))
+ goto err;
+ if (!BN_mod_sub_quick(n2, &a->X, n1, p))
+ goto err;
+ if (!field_mul(group, n1, n0, n2, ctx))
+ goto err;
+ if (!BN_mod_lshift1_quick(n0, n1, p))
+ goto err;
+ if (!BN_mod_add_quick(n1, n0, n1, p))
+ goto err;
+ /*-
+ * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
+ * = 3 * X_a^2 - 3 * Z_a^4
+ */
+ } else {
+ if (!field_sqr(group, n0, &a->X, ctx))
+ goto err;
+ if (!BN_mod_lshift1_quick(n1, n0, p))
+ goto err;
+ if (!BN_mod_add_quick(n0, n0, n1, p))
+ goto err;
+ if (!field_sqr(group, n1, &a->Z, ctx))
+ goto err;
+ if (!field_sqr(group, n1, n1, ctx))
+ goto err;
+ if (!field_mul(group, n1, n1, &group->a, ctx))
+ goto err;
+ if (!BN_mod_add_quick(n1, n1, n0, p))
+ goto err;
+ /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
+ }
+
+ /* Z_r */
+ if (a->Z_is_one) {
+ if (!BN_copy(n0, &a->Y))
+ goto err;
+ } else {
+ if (!field_mul(group, n0, &a->Y, &a->Z, ctx))
+ goto err;
+ }
+ if (!BN_mod_lshift1_quick(&r->Z, n0, p))
+ goto err;
+ r->Z_is_one = 0;
+ /* Z_r = 2 * Y_a * Z_a */
+
+ /* n2 */
+ if (!field_sqr(group, n3, &a->Y, ctx))
+ goto err;
+ if (!field_mul(group, n2, &a->X, n3, ctx))
+ goto err;
+ if (!BN_mod_lshift_quick(n2, n2, 2, p))
+ goto err;
+ /* n2 = 4 * X_a * Y_a^2 */
+
+ /* X_r */
+ if (!BN_mod_lshift1_quick(n0, n2, p))
+ goto err;
+ if (!field_sqr(group, &r->X, n1, ctx))
+ goto err;
+ if (!BN_mod_sub_quick(&r->X, &r->X, n0, p))
+ goto err;
+ /* X_r = n1^2 - 2 * n2 */
+
+ /* n3 */
+ if (!field_sqr(group, n0, n3, ctx))
+ goto err;
+ if (!BN_mod_lshift_quick(n3, n0, 3, p))
+ goto err;
+ /* n3 = 8 * Y_a^4 */
+
+ /* Y_r */
+ if (!BN_mod_sub_quick(n0, n2, &r->X, p))
+ goto err;
+ if (!field_mul(group, n0, n1, n0, ctx))
+ goto err;
+ if (!BN_mod_sub_quick(&r->Y, n0, n3, p))
+ goto err;
+ /* Y_r = n1 * (n2 - X_r) - n3 */
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int ec_GFp_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;
+
+ return BN_usub(&point->Y, &group->field, &point->Y);
+}
+
+int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
+{
+ return BN_is_zero(&point->Z);
+}
+
+int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
+ BN_CTX *ctx)
+{
+ int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
+ const BIGNUM *, BN_CTX *);
+ int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+ const BIGNUM *p;
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *rh, *tmp, *Z4, *Z6;
+ int ret = -1;
+
+ if (EC_POINT_is_at_infinity(group, point))
+ return 1;
+
+ field_mul = group->meth->field_mul;
+ field_sqr = group->meth->field_sqr;
+ p = &group->field;
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return -1;
+ }
+
+ BN_CTX_start(ctx);
+ rh = BN_CTX_get(ctx);
+ tmp = BN_CTX_get(ctx);
+ Z4 = BN_CTX_get(ctx);
+ Z6 = BN_CTX_get(ctx);
+ if (Z6 == NULL)
+ goto err;
+
+ /*-
+ * We have a curve defined by a Weierstrass equation
+ * y^2 = x^3 + a*x + b.
+ * The point to consider is given in Jacobian projective coordinates
+ * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
+ * Substituting this and multiplying by Z^6 transforms the above equation into
+ * Y^2 = X^3 + a*X*Z^4 + b*Z^6.
+ * To test this, we add up the right-hand side in 'rh'.
+ */
+
+ /* rh := X^2 */
+ if (!field_sqr(group, rh, &point->X, ctx))
+ goto err;
+
+ if (!point->Z_is_one) {
+ if (!field_sqr(group, tmp, &point->Z, ctx))
+ goto err;
+ if (!field_sqr(group, Z4, tmp, ctx))
+ goto err;
+ if (!field_mul(group, Z6, Z4, tmp, ctx))
+ goto err;
+
+ /* rh := (rh + a*Z^4)*X */
+ if (group->a_is_minus3) {
+ if (!BN_mod_lshift1_quick(tmp, Z4, p))
+ goto err;
+ if (!BN_mod_add_quick(tmp, tmp, Z4, p))
+ goto err;
+ if (!BN_mod_sub_quick(rh, rh, tmp, p))
+ goto err;
+ if (!field_mul(group, rh, rh, &point->X, ctx))
+ goto err;
+ } else {
+ if (!field_mul(group, tmp, Z4, &group->a, ctx))
+ goto err;
+ if (!BN_mod_add_quick(rh, rh, tmp, p))
+ goto err;
+ if (!field_mul(group, rh, rh, &point->X, ctx))
+ goto err;
+ }
+
+ /* rh := rh + b*Z^6 */
+ if (!field_mul(group, tmp, &group->b, Z6, ctx))
+ goto err;
+ if (!BN_mod_add_quick(rh, rh, tmp, p))
+ goto err;
+ } else {
+ /* point->Z_is_one */
+
+ /* rh := (rh + a)*X */
+ if (!BN_mod_add_quick(rh, rh, &group->a, p))
+ goto err;
+ if (!field_mul(group, rh, rh, &point->X, ctx))
+ goto err;
+ /* rh := rh + b */
+ if (!BN_mod_add_quick(rh, rh, &group->b, p))
+ goto err;
+ }
+
+ /* 'lh' := Y^2 */
+ if (!field_sqr(group, tmp, &point->Y, ctx))
+ goto err;
+
+ ret = (0 == BN_ucmp(tmp, rh));
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
+ const EC_POINT *b, BN_CTX *ctx)
+{
+ /*-
+ * return values:
+ * -1 error
+ * 0 equal (in affine coordinates)
+ * 1 not equal
+ */
+
+ int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
+ const BIGNUM *, BN_CTX *);
+ int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
+ const BIGNUM *tmp1_, *tmp2_;
+ int ret = -1;
+
+ if (EC_POINT_is_at_infinity(group, a)) {
+ return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
+ }
+
+ if (EC_POINT_is_at_infinity(group, b))
+ return 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;
+ }
+
+ field_mul = group->meth->field_mul;
+ field_sqr = group->meth->field_sqr;
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return -1;
+ }
+
+ BN_CTX_start(ctx);
+ tmp1 = BN_CTX_get(ctx);
+ tmp2 = BN_CTX_get(ctx);
+ Za23 = BN_CTX_get(ctx);
+ Zb23 = BN_CTX_get(ctx);
+ if (Zb23 == NULL)
+ goto end;
+
+ /*-
+ * We have to decide whether
+ * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
+ * or equivalently, whether
+ * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
+ */
+
+ if (!b->Z_is_one) {
+ if (!field_sqr(group, Zb23, &b->Z, ctx))
+ goto end;
+ if (!field_mul(group, tmp1, &a->X, Zb23, ctx))
+ goto end;
+ tmp1_ = tmp1;
+ } else
+ tmp1_ = &a->X;
+ if (!a->Z_is_one) {
+ if (!field_sqr(group, Za23, &a->Z, ctx))
+ goto end;
+ if (!field_mul(group, tmp2, &b->X, Za23, ctx))
+ goto end;
+ tmp2_ = tmp2;
+ } else
+ tmp2_ = &b->X;
+
+ /* compare X_a*Z_b^2 with X_b*Z_a^2 */
+ if (BN_cmp(tmp1_, tmp2_) != 0) {
+ ret = 1; /* points differ */
+ goto end;
+ }
+
+ if (!b->Z_is_one) {
+ if (!field_mul(group, Zb23, Zb23, &b->Z, ctx))
+ goto end;
+ if (!field_mul(group, tmp1, &a->Y, Zb23, ctx))
+ goto end;
+ /* tmp1_ = tmp1 */
+ } else
+ tmp1_ = &a->Y;
+ if (!a->Z_is_one) {
+ if (!field_mul(group, Za23, Za23, &a->Z, ctx))
+ goto end;
+ if (!field_mul(group, tmp2, &b->Y, Za23, ctx))
+ goto end;
+ /* tmp2_ = tmp2 */
+ } else
+ tmp2_ = &b->Y;
+
+ /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
+ if (BN_cmp(tmp1_, tmp2_) != 0) {
+ ret = 1; /* points differ */
+ goto end;
+ }
+
+ /* points are equal */
+ ret = 0;
+
+ end:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int ec_GFp_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_GFp(group, point, x, y, ctx))
+ goto err;
+ if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
+ goto err;
+ if (!point->Z_is_one) {
+ ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ return ret;
+}
+
+int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
+ EC_POINT *points[], BN_CTX *ctx)
+{
+#ifdef SIMPLIFIED_MAKE_AFFINE
+ int ret = 1;
+ size_t i;
+
+ for (i = 0; i < num; i++)
+ {
+ ret = ec_GFp_simple_make_affine(group, points[i], ctx);
+ if (!ret)
+ break;
+ }
+
+ return ret;
+#else /* SIMPLIFIED_MAKE_AFFINE */
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp, *tmp_Z;
+ BIGNUM **prod_Z = NULL;
+ size_t i;
+ int ret = 0;
+
+ if (num == 0)
+ return 1;
+
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ }
+
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+ tmp_Z = BN_CTX_get(ctx);
+ if (tmp == NULL || tmp_Z == NULL)
+ goto err;
+
+ prod_Z = OPENSSL_malloc(num * sizeof prod_Z[0]);
+ if (prod_Z == NULL)
+ goto err;
+ for (i = 0; i < num; i++) {
+ prod_Z[i] = BN_new();
+ if (prod_Z[i] == NULL)
+ goto err;
+ }
+
+ /*
+ * Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z,
+ * skipping any zero-valued inputs (pretend that they're 1).
+ */
+
+ if (!BN_is_zero(&points[0]->Z)) {
+ if (!BN_copy(prod_Z[0], &points[0]->Z))
+ goto err;
+ } else {
+ if (group->meth->field_set_to_one != 0) {
+ if (!group->meth->field_set_to_one(group, prod_Z[0], ctx))
+ goto err;
+ } else {
+ if (!BN_one(prod_Z[0]))
+ goto err;
+ }
+ }
+
+ for (i = 1; i < num; i++) {
+ if (!BN_is_zero(&points[i]->Z)) {
+ if (!group->meth->field_mul(group, prod_Z[i], prod_Z[i - 1],
+ &points[i]->Z, ctx))
+ goto err;
+ } else {
+ if (!BN_copy(prod_Z[i], prod_Z[i - 1]))
+ goto err;
+ }
+ }
+
+ /*
+ * Now use a single explicit inversion to replace every non-zero
+ * points[i]->Z by its inverse.
+ */
+
+ if (!BN_mod_inverse(tmp, prod_Z[num - 1], &group->field, ctx)) {
+ ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
+ goto err;
+ }
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode != 0) {
+ /*
+ * In the Montgomery case, we just turned R*H (representing H) into
+ * 1/(R*H), but we need R*(1/H) (representing 1/H); i.e. we need to
+ * multiply by the Montgomery factor twice.
+ */
+ if (!group->meth->field_encode(group, tmp, tmp, ctx))
+ goto err;
+ if (!group->meth->field_encode(group, tmp, tmp, ctx))
+ goto err;
+ }
+#endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+
+ for (i = num - 1; i > 0; --i) {
+ /*
+ * Loop invariant: tmp is the product of the inverses of points[0]->Z
+ * .. points[i]->Z (zero-valued inputs skipped).
+ */
+ if (!BN_is_zero(&points[i]->Z)) {
+ /*
+ * Set tmp_Z to the inverse of points[i]->Z (as product of Z
+ * inverses 0 .. i, Z values 0 .. i - 1).
+ */
+ if (!group->
+ meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx))
+ goto err;
+ /*
+ * Update tmp to satisfy the loop invariant for i - 1.
+ */
+ if (!group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx))
+ goto err;
+ /* Replace points[i]->Z by its inverse. */
+ if (!BN_copy(&points[i]->Z, tmp_Z))
+ goto err;
+ }
+ }
+
+ if (!BN_is_zero(&points[0]->Z)) {
+ /* Replace points[0]->Z by its inverse. */
+ if (!BN_copy(&points[0]->Z, tmp))
+ goto err;
+ }
+
+ /* Finally, fix up the X and Y coordinates for all points. */
+
+ for (i = 0; i < num; i++) {
+ EC_POINT *p = points[i];
+
+ if (!BN_is_zero(&p->Z)) {
+ /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
+
+ if (!group->meth->field_sqr(group, tmp, &p->Z, ctx))
+ goto err;
+ if (!group->meth->field_mul(group, &p->X, &p->X, tmp, ctx))
+ goto err;
+
+ if (!group->meth->field_mul(group, tmp, tmp, &p->Z, ctx))
+ goto err;
+ if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx))
+ goto err;
+
+ if (group->meth->field_set_to_one != 0) {
+ if (!group->meth->field_set_to_one(group, &p->Z, ctx))
+ goto err;
+ } else {
+ if (!BN_one(&p->Z))
+ goto err;
+ }
+ p->Z_is_one = 1;
+ }
+ }
+
+ ret = 1;
+
+ err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (prod_Z != NULL) {
+ for (i = 0; i < num; i++) {
+ if (prod_Z[i] == NULL)
+ break;
+ BN_clear_free(prod_Z[i]);
+ }
+ OPENSSL_free(prod_Z);
+ }
+ return ret;
+#endif /* !SIMPLIFIED_MAKE_AFFINE */
+}
+
+int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+ const BIGNUM *b, BN_CTX *ctx)
+{
+ return BN_mod_mul(r, a, b, &group->field, ctx);
+}
+
+int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+ BN_CTX *ctx)
+{
+ return BN_mod_sqr(r, a, &group->field, ctx);
+}
diff --git a/openssl/ec/ectest.c b/openssl/ec/ectest.c
new file mode 100644
index 0000000..a18b327
--- /dev/null
+++ b/openssl/ec/ectest.c
@@ -0,0 +1,1861 @@
+/* crypto/ec/ectest.c */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef FLAT_INC
+# include "e_os.h"
+#else
+# include "../e_os.h"
+#endif
+#include <string.h>
+#include <time.h>
+
+#ifdef OPENSSL_NO_EC
+int main(int argc, char *argv[])
+{
+ puts("Elliptic curves are disabled.");
+ return 0;
+}
+#else
+
+# include <openssl/ec.h>
+# ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+# endif
+# include <openssl/err.h>
+# include <openssl/obj_mac.h>
+# include <openssl/objects.h>
+# include <openssl/rand.h>
+# include <openssl/bn.h>
+# include <openssl/opensslconf.h>
+
+# if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12)
+/* suppress "too big too optimize" warning */
+# pragma warning(disable:4959)
+# endif
+
+# define ABORT do { \
+ fflush(stdout); \
+ fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \
+ ERR_print_errors_fp(stderr); \
+ EXIT(1); \
+} while (0)
+
+# define TIMING_BASE_PT 0
+# define TIMING_RAND_PT 1
+# define TIMING_SIMUL 2
+
+# if 0
+static void timings(EC_GROUP *group, int type, BN_CTX *ctx)
+{
+ clock_t clck;
+ int i, j;
+ BIGNUM *s;
+ BIGNUM *r[10], *r0[10];
+ EC_POINT *P;
+
+ s = BN_new();
+ if (s == NULL)
+ ABORT;
+
+ fprintf(stdout, "Timings for %d-bit field, ", EC_GROUP_get_degree(group));
+ if (!EC_GROUP_get_order(group, s, ctx))
+ ABORT;
+ fprintf(stdout, "%d-bit scalars ", (int)BN_num_bits(s));
+ fflush(stdout);
+
+ P = EC_POINT_new(group);
+ if (P == NULL)
+ ABORT;
+ EC_POINT_copy(P, EC_GROUP_get0_generator(group));
+
+ for (i = 0; i < 10; i++) {
+ if ((r[i] = BN_new()) == NULL)
+ ABORT;
+ if (!BN_pseudo_rand(r[i], BN_num_bits(s), 0, 0))
+ ABORT;
+ if (type != TIMING_BASE_PT) {
+ if ((r0[i] = BN_new()) == NULL)
+ ABORT;
+ if (!BN_pseudo_rand(r0[i], BN_num_bits(s), 0, 0))
+ ABORT;
+ }
+ }
+
+ clck = clock();
+ for (i = 0; i < 10; i++) {
+ for (j = 0; j < 10; j++) {
+ if (!EC_POINT_mul
+ (group, P, (type != TIMING_RAND_PT) ? r[i] : NULL,
+ (type != TIMING_BASE_PT) ? P : NULL,
+ (type != TIMING_BASE_PT) ? r0[i] : NULL, ctx))
+ ABORT;
+ }
+ }
+ clck = clock() - clck;
+
+ fprintf(stdout, "\n");
+
+# ifdef CLOCKS_PER_SEC
+ /*
+ * "To determine the time in seconds, the value returned by the clock
+ * function should be divided by the value of the macro CLOCKS_PER_SEC."
+ * -- ISO/IEC 9899
+ */
+# define UNIT "s"
+# else
+ /*
+ * "`CLOCKS_PER_SEC' undeclared (first use this function)" -- cc on
+ * NeXTstep/OpenStep
+ */
+# define UNIT "units"
+# define CLOCKS_PER_SEC 1
+# endif
+
+ if (type == TIMING_BASE_PT) {
+ fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j,
+ "base point multiplications", (double)clck / CLOCKS_PER_SEC);
+ } else if (type == TIMING_RAND_PT) {
+ fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j,
+ "random point multiplications",
+ (double)clck / CLOCKS_PER_SEC);
+ } else if (type == TIMING_SIMUL) {
+ fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j,
+ "s*P+t*Q operations", (double)clck / CLOCKS_PER_SEC);
+ }
+ fprintf(stdout, "average: %.4f " UNIT "\n",
+ (double)clck / (CLOCKS_PER_SEC * i * j));
+
+ EC_POINT_free(P);
+ BN_free(s);
+ for (i = 0; i < 10; i++) {
+ BN_free(r[i]);
+ if (type != TIMING_BASE_PT)
+ BN_free(r0[i]);
+ }
+}
+# endif
+
+/* test multiplication with group order, long and negative scalars */
+static void group_order_tests(EC_GROUP *group)
+{
+ BIGNUM *n1, *n2, *order;
+ EC_POINT *P = EC_POINT_new(group);
+ EC_POINT *Q = EC_POINT_new(group);
+ BN_CTX *ctx = BN_CTX_new();
+ int i;
+
+ n1 = BN_new();
+ n2 = BN_new();
+ order = BN_new();
+ fprintf(stdout, "verify group order ...");
+ fflush(stdout);
+ if (!EC_GROUP_get_order(group, order, ctx))
+ ABORT;
+ if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, Q))
+ ABORT;
+ fprintf(stdout, ".");
+ fflush(stdout);
+ if (!EC_GROUP_precompute_mult(group, ctx))
+ ABORT;
+ if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, Q))
+ ABORT;
+ fprintf(stdout, " ok\n");
+ fprintf(stdout, "long/negative scalar tests ");
+ for (i = 1; i <= 2; i++) {
+ const BIGNUM *scalars[6];
+ const EC_POINT *points[6];
+
+ fprintf(stdout, i == 1 ?
+ "allowing precomputation ... " :
+ "without precomputation ... ");
+ if (!BN_set_word(n1, i))
+ ABORT;
+ /*
+ * If i == 1, P will be the predefined generator for which
+ * EC_GROUP_precompute_mult has set up precomputation.
+ */
+ if (!EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
+ ABORT;
+
+ if (!BN_one(n1))
+ ABORT;
+ /* n1 = 1 - order */
+ if (!BN_sub(n1, n1, order))
+ ABORT;
+ if (!EC_POINT_mul(group, Q, NULL, P, n1, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, Q, P, ctx))
+ ABORT;
+
+ /* n2 = 1 + order */
+ if (!BN_add(n2, order, BN_value_one()))
+ ABORT;
+ if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, Q, P, ctx))
+ ABORT;
+
+ /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
+ if (!BN_mul(n2, n1, n2, ctx))
+ ABORT;
+ if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, Q, P, ctx))
+ ABORT;
+
+ /* n2 = order^2 - 1 */
+ BN_set_negative(n2, 0);
+ if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx))
+ ABORT;
+ /* Add P to verify the result. */
+ if (!EC_POINT_add(group, Q, Q, P, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, Q))
+ ABORT;
+
+ /* Exercise EC_POINTs_mul, including corner cases. */
+ if (EC_POINT_is_at_infinity(group, P))
+ ABORT;
+ scalars[0] = n1;
+ points[0] = Q; /* => infinity */
+ scalars[1] = n2;
+ points[1] = P; /* => -P */
+ scalars[2] = n1;
+ points[2] = Q; /* => infinity */
+ scalars[3] = n2;
+ points[3] = Q; /* => infinity */
+ scalars[4] = n1;
+ points[4] = P; /* => P */
+ scalars[5] = n2;
+ points[5] = Q; /* => infinity */
+ if (!EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, P))
+ ABORT;
+ }
+ fprintf(stdout, "ok\n");
+
+ EC_POINT_free(P);
+ EC_POINT_free(Q);
+ BN_free(n1);
+ BN_free(n2);
+ BN_free(order);
+ BN_CTX_free(ctx);
+}
+
+static void prime_field_tests(void)
+{
+ BN_CTX *ctx = NULL;
+ BIGNUM *p, *a, *b;
+ EC_GROUP *group;
+ EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 =
+ NULL, *P_384 = NULL, *P_521 = NULL;
+ EC_POINT *P, *Q, *R;
+ BIGNUM *x, *y, *z;
+ unsigned char buf[100];
+ size_t i, len;
+ int k;
+
+# if 1 /* optional */
+ ctx = BN_CTX_new();
+ if (!ctx)
+ ABORT;
+# endif
+
+ p = BN_new();
+ a = BN_new();
+ b = BN_new();
+ if (!p || !a || !b)
+ ABORT;
+
+ if (!BN_hex2bn(&p, "17"))
+ ABORT;
+ if (!BN_hex2bn(&a, "1"))
+ ABORT;
+ if (!BN_hex2bn(&b, "1"))
+ ABORT;
+
+ group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use
+ * EC_GROUP_new_curve_GFp so
+ * that the library gets to
+ * choose the EC_METHOD */
+ if (!group)
+ ABORT;
+
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
+ ABORT;
+
+ {
+ EC_GROUP *tmp;
+ tmp = EC_GROUP_new(EC_GROUP_method_of(group));
+ if (!tmp)
+ ABORT;
+ if (!EC_GROUP_copy(tmp, group))
+ ABORT;
+ EC_GROUP_free(group);
+ group = tmp;
+ }
+
+ if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx))
+ ABORT;
+
+ fprintf(stdout,
+ "Curve defined by Weierstrass equation\n y^2 = x^3 + a*x + b (mod 0x");
+ BN_print_fp(stdout, p);
+ fprintf(stdout, ")\n a = 0x");
+ BN_print_fp(stdout, a);
+ fprintf(stdout, "\n b = 0x");
+ BN_print_fp(stdout, b);
+ fprintf(stdout, "\n");
+
+ P = EC_POINT_new(group);
+ Q = EC_POINT_new(group);
+ R = EC_POINT_new(group);
+ if (!P || !Q || !R)
+ ABORT;
+
+ if (!EC_POINT_set_to_infinity(group, P))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, P))
+ ABORT;
+
+ buf[0] = 0;
+ if (!EC_POINT_oct2point(group, Q, buf, 1, ctx))
+ ABORT;
+
+ if (!EC_POINT_add(group, P, P, Q, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, P))
+ ABORT;
+
+ x = BN_new();
+ y = BN_new();
+ z = BN_new();
+ if (!x || !y || !z)
+ ABORT;
+
+ if (!BN_hex2bn(&x, "D"))
+ ABORT;
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx))
+ ABORT;
+ if (!EC_POINT_is_on_curve(group, Q, ctx)) {
+ if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx))
+ ABORT;
+ fprintf(stderr, "Point is not on curve: x = 0x");
+ BN_print_fp(stderr, x);
+ fprintf(stderr, ", y = 0x");
+ BN_print_fp(stderr, y);
+ fprintf(stderr, "\n");
+ ABORT;
+ }
+
+ fprintf(stdout, "A cyclic subgroup:\n");
+ k = 100;
+ do {
+ if (k-- == 0)
+ ABORT;
+
+ if (EC_POINT_is_at_infinity(group, P))
+ fprintf(stdout, " point at infinity\n");
+ else {
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
+ ABORT;
+
+ fprintf(stdout, " x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, ", y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ }
+
+ if (!EC_POINT_copy(R, P))
+ ABORT;
+ if (!EC_POINT_add(group, P, P, Q, ctx))
+ ABORT;
+
+# if 0 /* optional */
+ {
+ EC_POINT *points[3];
+
+ points[0] = R;
+ points[1] = Q;
+ points[2] = P;
+ if (!EC_POINTs_make_affine(group, 2, points, ctx))
+ ABORT;
+ }
+# endif
+
+ }
+ while (!EC_POINT_is_at_infinity(group, P));
+
+ if (!EC_POINT_add(group, P, Q, R, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, P))
+ ABORT;
+
+ len =
+ EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
+ sizeof buf, ctx);
+ if (len == 0)
+ ABORT;
+ if (!EC_POINT_oct2point(group, P, buf, len, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, P, Q, ctx))
+ ABORT;
+ fprintf(stdout, "Generator as octet string, compressed form:\n ");
+ for (i = 0; i < len; i++)
+ fprintf(stdout, "%02X", buf[i]);
+
+ len =
+ EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf,
+ sizeof buf, ctx);
+ if (len == 0)
+ ABORT;
+ if (!EC_POINT_oct2point(group, P, buf, len, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, P, Q, ctx))
+ ABORT;
+ fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n ");
+ for (i = 0; i < len; i++)
+ fprintf(stdout, "%02X", buf[i]);
+
+ len =
+ EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf,
+ ctx);
+ if (len == 0)
+ ABORT;
+ if (!EC_POINT_oct2point(group, P, buf, len, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, P, Q, ctx))
+ ABORT;
+ fprintf(stdout, "\nGenerator as octet string, hybrid form:\n ");
+ for (i = 0; i < len; i++)
+ fprintf(stdout, "%02X", buf[i]);
+
+ if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx))
+ ABORT;
+ fprintf(stdout,
+ "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n X = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, ", Y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, ", Z = 0x");
+ BN_print_fp(stdout, z);
+ fprintf(stdout, "\n");
+
+ if (!EC_POINT_invert(group, P, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, P, R, ctx))
+ ABORT;
+
+ /*
+ * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2,
+ * 2000) -- not a NIST curve, but commonly used
+ */
+
+ if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))
+ ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
+ ABORT;
+ if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))
+ ABORT;
+ if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"))
+ ABORT;
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
+ ABORT;
+
+ if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82"))
+ ABORT;
+ if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32"))
+ ABORT;
+ if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx))
+ ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx))
+ ABORT;
+ if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257"))
+ ABORT;
+ if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
+ ABORT;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
+ ABORT;
+ fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, "\n y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ /* G_y value taken from the standard: */
+ if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32"))
+ ABORT;
+ if (0 != BN_cmp(y, z))
+ ABORT;
+
+ fprintf(stdout, "verify degree ...");
+ if (EC_GROUP_get_degree(group) != 160)
+ ABORT;
+ fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
+
+ if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group))))
+ ABORT;
+ if (!EC_GROUP_copy(P_160, group))
+ ABORT;
+
+ /* Curve P-192 (FIPS PUB 186-2, App. 6) */
+
+ if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))
+ ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
+ ABORT;
+ if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))
+ ABORT;
+ if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"))
+ ABORT;
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
+ ABORT;
+
+ if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"))
+ ABORT;
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx))
+ ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx))
+ ABORT;
+ if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"))
+ ABORT;
+ if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
+ ABORT;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
+ ABORT;
+ fprintf(stdout, "\nNIST curve P-192 -- Generator:\n x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, "\n y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ /* G_y value taken from the standard: */
+ if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"))
+ ABORT;
+ if (0 != BN_cmp(y, z))
+ ABORT;
+
+ fprintf(stdout, "verify degree ...");
+ if (EC_GROUP_get_degree(group) != 192)
+ ABORT;
+ fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
+
+ if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group))))
+ ABORT;
+ if (!EC_GROUP_copy(P_192, group))
+ ABORT;
+
+ /* Curve P-224 (FIPS PUB 186-2, App. 6) */
+
+ if (!BN_hex2bn
+ (&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"))
+ ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
+ ABORT;
+ if (!BN_hex2bn
+ (&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
+ ABORT;
+ if (!BN_hex2bn
+ (&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"))
+ ABORT;
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
+ ABORT;
+
+ if (!BN_hex2bn
+ (&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"))
+ ABORT;
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx))
+ ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx))
+ ABORT;
+ if (!BN_hex2bn
+ (&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"))
+ ABORT;
+ if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
+ ABORT;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
+ ABORT;
+ fprintf(stdout, "\nNIST curve P-224 -- Generator:\n x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, "\n y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ /* G_y value taken from the standard: */
+ if (!BN_hex2bn
+ (&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"))
+ ABORT;
+ if (0 != BN_cmp(y, z))
+ ABORT;
+
+ fprintf(stdout, "verify degree ...");
+ if (EC_GROUP_get_degree(group) != 224)
+ ABORT;
+ fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
+
+ if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group))))
+ ABORT;
+ if (!EC_GROUP_copy(P_224, group))
+ ABORT;
+
+ /* Curve P-256 (FIPS PUB 186-2, App. 6) */
+
+ if (!BN_hex2bn
+ (&p,
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"))
+ ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
+ ABORT;
+ if (!BN_hex2bn
+ (&a,
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"))
+ ABORT;
+ if (!BN_hex2bn
+ (&b,
+ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"))
+ ABORT;
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
+ ABORT;
+
+ if (!BN_hex2bn
+ (&x,
+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"))
+ ABORT;
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx))
+ ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx))
+ ABORT;
+ if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
+ "84F3B9CAC2FC632551"))
+ ABORT;
+ if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
+ ABORT;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
+ ABORT;
+ fprintf(stdout, "\nNIST curve P-256 -- Generator:\n x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, "\n y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ /* G_y value taken from the standard: */
+ if (!BN_hex2bn
+ (&z,
+ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"))
+ ABORT;
+ if (0 != BN_cmp(y, z))
+ ABORT;
+
+ fprintf(stdout, "verify degree ...");
+ if (EC_GROUP_get_degree(group) != 256)
+ ABORT;
+ fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
+
+ if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group))))
+ ABORT;
+ if (!EC_GROUP_copy(P_256, group))
+ ABORT;
+
+ /* Curve P-384 (FIPS PUB 186-2, App. 6) */
+
+ if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"))
+ ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
+ ABORT;
+ if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC"))
+ ABORT;
+ if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141"
+ "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF"))
+ ABORT;
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
+ ABORT;
+
+ if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
+ "9859F741E082542A385502F25DBF55296C3A545E3872760AB7"))
+ ABORT;
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx))
+ ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx))
+ ABORT;
+ if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"))
+ ABORT;
+ if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
+ ABORT;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
+ ABORT;
+ fprintf(stdout, "\nNIST curve P-384 -- Generator:\n x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, "\n y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ /* G_y value taken from the standard: */
+ if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14"
+ "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"))
+ ABORT;
+ if (0 != BN_cmp(y, z))
+ ABORT;
+
+ fprintf(stdout, "verify degree ...");
+ if (EC_GROUP_get_degree(group) != 384)
+ ABORT;
+ fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
+
+ if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group))))
+ ABORT;
+ if (!EC_GROUP_copy(P_384, group))
+ ABORT;
+
+ /* Curve P-521 (FIPS PUB 186-2, App. 6) */
+
+ if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
+ ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
+ ABORT;
+ if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
+ ABORT;
+ if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B"
+ "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573"
+ "DF883D2C34F1EF451FD46B503F00"))
+ ABORT;
+ if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx))
+ ABORT;
+
+ if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F"
+ "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
+ "3C1856A429BF97E7E31C2E5BD66"))
+ ABORT;
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx))
+ ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx))
+ ABORT;
+ if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
+ "C9B8899C47AEBB6FB71E91386409"))
+ ABORT;
+ if (!EC_GROUP_set_generator(group, P, z, BN_value_one()))
+ ABORT;
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx))
+ ABORT;
+ fprintf(stdout, "\nNIST curve P-521 -- Generator:\n x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, "\n y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ /* G_y value taken from the standard: */
+ if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579"
+ "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C"
+ "7086A272C24088BE94769FD16650"))
+ ABORT;
+ if (0 != BN_cmp(y, z))
+ ABORT;
+
+ fprintf(stdout, "verify degree ...");
+ if (EC_GROUP_get_degree(group) != 521)
+ ABORT;
+ fprintf(stdout, " ok\n");
+
+ group_order_tests(group);
+
+ if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group))))
+ ABORT;
+ if (!EC_GROUP_copy(P_521, group))
+ ABORT;
+
+ /* more tests using the last curve */
+
+ if (!EC_POINT_copy(Q, P))
+ ABORT;
+ if (EC_POINT_is_at_infinity(group, Q))
+ ABORT;
+ if (!EC_POINT_dbl(group, P, P, ctx))
+ ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx))
+ ABORT;
+ if (!EC_POINT_invert(group, Q, ctx))
+ ABORT; /* P = -2Q */
+
+ if (!EC_POINT_add(group, R, P, Q, ctx))
+ ABORT;
+ if (!EC_POINT_add(group, R, R, Q, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, R))
+ ABORT; /* R = P + 2Q */
+
+ {
+ const EC_POINT *points[4];
+ const BIGNUM *scalars[4];
+ BIGNUM scalar3;
+
+ if (EC_POINT_is_at_infinity(group, Q))
+ ABORT;
+ points[0] = Q;
+ points[1] = Q;
+ points[2] = Q;
+ points[3] = Q;
+
+ if (!EC_GROUP_get_order(group, z, ctx))
+ ABORT;
+ if (!BN_add(y, z, BN_value_one()))
+ ABORT;
+ if (BN_is_odd(y))
+ ABORT;
+ if (!BN_rshift1(y, y))
+ ABORT;
+ scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
+ scalars[1] = y;
+
+ fprintf(stdout, "combined multiplication ...");
+ fflush(stdout);
+
+ /* z is still the group order */
+ if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
+ ABORT;
+ if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, P, R, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, R, Q, ctx))
+ ABORT;
+
+ fprintf(stdout, ".");
+ fflush(stdout);
+
+ if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0))
+ ABORT;
+ if (!BN_add(z, z, y))
+ ABORT;
+ BN_set_negative(z, 1);
+ scalars[0] = y;
+ scalars[1] = z; /* z = -(order + y) */
+
+ if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, P))
+ ABORT;
+
+ fprintf(stdout, ".");
+ fflush(stdout);
+
+ if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0))
+ ABORT;
+ if (!BN_add(z, x, y))
+ ABORT;
+ BN_set_negative(z, 1);
+ scalars[0] = x;
+ scalars[1] = y;
+ scalars[2] = z; /* z = -(x+y) */
+
+ BN_init(&scalar3);
+ BN_zero(&scalar3);
+ scalars[3] = &scalar3;
+
+ if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, P))
+ ABORT;
+
+ fprintf(stdout, " ok\n\n");
+
+ BN_free(&scalar3);
+ }
+
+# if 0
+ timings(P_160, TIMING_BASE_PT, ctx);
+ timings(P_160, TIMING_RAND_PT, ctx);
+ timings(P_160, TIMING_SIMUL, ctx);
+ timings(P_192, TIMING_BASE_PT, ctx);
+ timings(P_192, TIMING_RAND_PT, ctx);
+ timings(P_192, TIMING_SIMUL, ctx);
+ timings(P_224, TIMING_BASE_PT, ctx);
+ timings(P_224, TIMING_RAND_PT, ctx);
+ timings(P_224, TIMING_SIMUL, ctx);
+ timings(P_256, TIMING_BASE_PT, ctx);
+ timings(P_256, TIMING_RAND_PT, ctx);
+ timings(P_256, TIMING_SIMUL, ctx);
+ timings(P_384, TIMING_BASE_PT, ctx);
+ timings(P_384, TIMING_RAND_PT, ctx);
+ timings(P_384, TIMING_SIMUL, ctx);
+ timings(P_521, TIMING_BASE_PT, ctx);
+ timings(P_521, TIMING_RAND_PT, ctx);
+ timings(P_521, TIMING_SIMUL, ctx);
+# endif
+
+ if (ctx)
+ BN_CTX_free(ctx);
+ BN_free(p);
+ BN_free(a);
+ BN_free(b);
+ EC_GROUP_free(group);
+ EC_POINT_free(P);
+ EC_POINT_free(Q);
+ EC_POINT_free(R);
+ BN_free(x);
+ BN_free(y);
+ BN_free(z);
+
+ if (P_160)
+ EC_GROUP_free(P_160);
+ if (P_192)
+ EC_GROUP_free(P_192);
+ if (P_224)
+ EC_GROUP_free(P_224);
+ if (P_256)
+ EC_GROUP_free(P_256);
+ if (P_384)
+ EC_GROUP_free(P_384);
+ if (P_521)
+ EC_GROUP_free(P_521);
+
+}
+
+/* Change test based on whether binary point compression is enabled or not. */
+# ifdef OPENSSL_EC_BIN_PT_COMP
+# define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
+ if (!BN_hex2bn(&x, _x)) ABORT; \
+ if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \
+ if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
+ if (!BN_hex2bn(&z, _order)) ABORT; \
+ if (!BN_hex2bn(&cof, _cof)) ABORT; \
+ if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
+ fprintf(stdout, "\n%s -- Generator:\n x = 0x", _name); \
+ BN_print_fp(stdout, x); \
+ fprintf(stdout, "\n y = 0x"); \
+ BN_print_fp(stdout, y); \
+ fprintf(stdout, "\n"); \
+ /* G_y value taken from the standard: */ \
+ if (!BN_hex2bn(&z, _y)) ABORT; \
+ if (0 != BN_cmp(y, z)) ABORT;
+# else
+# define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
+ if (!BN_hex2bn(&x, _x)) ABORT; \
+ if (!BN_hex2bn(&y, _y)) ABORT; \
+ if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
+ if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
+ if (!BN_hex2bn(&z, _order)) ABORT; \
+ if (!BN_hex2bn(&cof, _cof)) ABORT; \
+ if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
+ fprintf(stdout, "\n%s -- Generator:\n x = 0x", _name); \
+ BN_print_fp(stdout, x); \
+ fprintf(stdout, "\n y = 0x"); \
+ BN_print_fp(stdout, y); \
+ fprintf(stdout, "\n");
+# endif
+
+# define CHAR2_CURVE_TEST(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
+ if (!BN_hex2bn(&p, _p)) ABORT; \
+ if (!BN_hex2bn(&a, _a)) ABORT; \
+ if (!BN_hex2bn(&b, _b)) ABORT; \
+ if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT; \
+ CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
+ fprintf(stdout, "verify degree ..."); \
+ if (EC_GROUP_get_degree(group) != _degree) ABORT; \
+ fprintf(stdout, " ok\n"); \
+ group_order_tests(group); \
+ if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \
+ if (!EC_GROUP_copy(_variable, group)) ABORT; \
+
+# ifndef OPENSSL_NO_EC2M
+
+static void char2_field_tests(void)
+{
+ BN_CTX *ctx = NULL;
+ BIGNUM *p, *a, *b;
+ EC_GROUP *group;
+ EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 =
+ NULL, *C2_K571 = NULL;
+ EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 =
+ NULL, *C2_B571 = NULL;
+ EC_POINT *P, *Q, *R;
+ BIGNUM *x, *y, *z, *cof;
+ unsigned char buf[100];
+ size_t i, len;
+ int k;
+
+# if 1 /* optional */
+ ctx = BN_CTX_new();
+ if (!ctx)
+ ABORT;
+# endif
+
+ p = BN_new();
+ a = BN_new();
+ b = BN_new();
+ if (!p || !a || !b)
+ ABORT;
+
+ if (!BN_hex2bn(&p, "13"))
+ ABORT;
+ if (!BN_hex2bn(&a, "3"))
+ ABORT;
+ if (!BN_hex2bn(&b, "1"))
+ ABORT;
+
+ group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use
+ * EC_GROUP_new_curve_GF2m
+ * so that the library gets
+ * to choose the EC_METHOD */
+ if (!group)
+ ABORT;
+ if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx))
+ ABORT;
+
+ {
+ EC_GROUP *tmp;
+ tmp = EC_GROUP_new(EC_GROUP_method_of(group));
+ if (!tmp)
+ ABORT;
+ if (!EC_GROUP_copy(tmp, group))
+ ABORT;
+ EC_GROUP_free(group);
+ group = tmp;
+ }
+
+ if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx))
+ ABORT;
+
+ fprintf(stdout,
+ "Curve defined by Weierstrass equation\n y^2 + x*y = x^3 + a*x^2 + b (mod 0x");
+ BN_print_fp(stdout, p);
+ fprintf(stdout, ")\n a = 0x");
+ BN_print_fp(stdout, a);
+ fprintf(stdout, "\n b = 0x");
+ BN_print_fp(stdout, b);
+ fprintf(stdout, "\n(0x... means binary polynomial)\n");
+
+ P = EC_POINT_new(group);
+ Q = EC_POINT_new(group);
+ R = EC_POINT_new(group);
+ if (!P || !Q || !R)
+ ABORT;
+
+ if (!EC_POINT_set_to_infinity(group, P))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, P))
+ ABORT;
+
+ buf[0] = 0;
+ if (!EC_POINT_oct2point(group, Q, buf, 1, ctx))
+ ABORT;
+
+ if (!EC_POINT_add(group, P, P, Q, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, P))
+ ABORT;
+
+ x = BN_new();
+ y = BN_new();
+ z = BN_new();
+ cof = BN_new();
+ if (!x || !y || !z || !cof)
+ ABORT;
+
+ if (!BN_hex2bn(&x, "6"))
+ ABORT;
+/* Change test based on whether binary point compression is enabled or not. */
+# ifdef OPENSSL_EC_BIN_PT_COMP
+ if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx))
+ ABORT;
+# else
+ if (!BN_hex2bn(&y, "8"))
+ ABORT;
+ if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx))
+ ABORT;
+# endif
+ if (!EC_POINT_is_on_curve(group, Q, ctx)) {
+/* Change test based on whether binary point compression is enabled or not. */
+# ifdef OPENSSL_EC_BIN_PT_COMP
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx))
+ ABORT;
+# endif
+ fprintf(stderr, "Point is not on curve: x = 0x");
+ BN_print_fp(stderr, x);
+ fprintf(stderr, ", y = 0x");
+ BN_print_fp(stderr, y);
+ fprintf(stderr, "\n");
+ ABORT;
+ }
+
+ fprintf(stdout, "A cyclic subgroup:\n");
+ k = 100;
+ do {
+ if (k-- == 0)
+ ABORT;
+
+ if (EC_POINT_is_at_infinity(group, P))
+ fprintf(stdout, " point at infinity\n");
+ else {
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx))
+ ABORT;
+
+ fprintf(stdout, " x = 0x");
+ BN_print_fp(stdout, x);
+ fprintf(stdout, ", y = 0x");
+ BN_print_fp(stdout, y);
+ fprintf(stdout, "\n");
+ }
+
+ if (!EC_POINT_copy(R, P))
+ ABORT;
+ if (!EC_POINT_add(group, P, P, Q, ctx))
+ ABORT;
+ }
+ while (!EC_POINT_is_at_infinity(group, P));
+
+ if (!EC_POINT_add(group, P, Q, R, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, P))
+ ABORT;
+
+/* Change test based on whether binary point compression is enabled or not. */
+# ifdef OPENSSL_EC_BIN_PT_COMP
+ len =
+ EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,
+ sizeof buf, ctx);
+ if (len == 0)
+ ABORT;
+ if (!EC_POINT_oct2point(group, P, buf, len, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, P, Q, ctx))
+ ABORT;
+ fprintf(stdout, "Generator as octet string, compressed form:\n ");
+ for (i = 0; i < len; i++)
+ fprintf(stdout, "%02X", buf[i]);
+# endif
+
+ len =
+ EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf,
+ sizeof buf, ctx);
+ if (len == 0)
+ ABORT;
+ if (!EC_POINT_oct2point(group, P, buf, len, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, P, Q, ctx))
+ ABORT;
+ fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n ");
+ for (i = 0; i < len; i++)
+ fprintf(stdout, "%02X", buf[i]);
+
+/* Change test based on whether binary point compression is enabled or not. */
+# ifdef OPENSSL_EC_BIN_PT_COMP
+ len =
+ EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf,
+ ctx);
+ if (len == 0)
+ ABORT;
+ if (!EC_POINT_oct2point(group, P, buf, len, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, P, Q, ctx))
+ ABORT;
+ fprintf(stdout, "\nGenerator as octet string, hybrid form:\n ");
+ for (i = 0; i < len; i++)
+ fprintf(stdout, "%02X", buf[i]);
+# endif
+
+ fprintf(stdout, "\n");
+
+ if (!EC_POINT_invert(group, P, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, P, R, ctx))
+ ABORT;
+
+ /* Curve K-163 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ ("NIST curve K-163",
+ "0800000000000000000000000000000000000000C9",
+ "1",
+ "1",
+ "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",
+ "0289070FB05D38FF58321F2E800536D538CCDAA3D9",
+ 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163, C2_K163);
+
+ /* Curve B-163 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ ("NIST curve B-163",
+ "0800000000000000000000000000000000000000C9",
+ "1",
+ "020A601907B8C953CA1481EB10512F78744A3205FD",
+ "03F0EBA16286A2D57EA0991168D4994637E8343E36",
+ "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
+ 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163, C2_B163);
+
+ /* Curve K-233 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ ("NIST curve K-233",
+ "020000000000000000000000000000000000000004000000000000000001",
+ "0",
+ "1",
+ "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",
+ "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
+ 0,
+ "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
+ "4", 233, C2_K233);
+
+ /* Curve B-233 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ ("NIST curve B-233",
+ "020000000000000000000000000000000000000004000000000000000001",
+ "000000000000000000000000000000000000000000000000000000000001",
+ "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
+ "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",
+ "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
+ 1,
+ "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
+ "2", 233, C2_B233);
+
+ /* Curve K-283 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ ("NIST curve K-283",
+ "0800000000000000000000000000000000000000000000000000000000000000000010A1",
+ "0",
+ "1",
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",
+ "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
+ 0,
+ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
+ "4", 283, C2_K283);
+
+ /* Curve B-283 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ ("NIST curve B-283",
+ "0800000000000000000000000000000000000000000000000000000000000000000010A1",
+ "000000000000000000000000000000000000000000000000000000000000000000000001",
+ "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",
+ "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
+ 1,
+ "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
+ "2", 283, C2_B283);
+
+ /* Curve K-409 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ ("NIST curve K-409",
+ "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+ "0",
+ "1",
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",
+ "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
+ 1,
+ "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
+ "4", 409, C2_K409);
+
+ /* Curve B-409 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ ("NIST curve B-409",
+ "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",
+ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+ "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",
+ "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
+ 1,
+ "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
+ "2", 409, C2_B409);
+
+ /* Curve K-571 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ ("NIST curve K-571",
+ "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+ "0",
+ "1",
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",
+ "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
+ 0,
+ "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
+ "4", 571, C2_K571);
+
+ /* Curve B-571 (FIPS PUB 186-2, App. 6) */
+ CHAR2_CURVE_TEST
+ ("NIST curve B-571",
+ "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",
+ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
+ "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",
+ "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
+ 1,
+ "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
+ "2", 571, C2_B571);
+
+ /* more tests using the last curve */
+
+ if (!EC_POINT_copy(Q, P))
+ ABORT;
+ if (EC_POINT_is_at_infinity(group, Q))
+ ABORT;
+ if (!EC_POINT_dbl(group, P, P, ctx))
+ ABORT;
+ if (!EC_POINT_is_on_curve(group, P, ctx))
+ ABORT;
+ if (!EC_POINT_invert(group, Q, ctx))
+ ABORT; /* P = -2Q */
+
+ if (!EC_POINT_add(group, R, P, Q, ctx))
+ ABORT;
+ if (!EC_POINT_add(group, R, R, Q, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, R))
+ ABORT; /* R = P + 2Q */
+
+ {
+ const EC_POINT *points[3];
+ const BIGNUM *scalars[3];
+
+ if (EC_POINT_is_at_infinity(group, Q))
+ ABORT;
+ points[0] = Q;
+ points[1] = Q;
+ points[2] = Q;
+
+ if (!BN_add(y, z, BN_value_one()))
+ ABORT;
+ if (BN_is_odd(y))
+ ABORT;
+ if (!BN_rshift1(y, y))
+ ABORT;
+ scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
+ scalars[1] = y;
+
+ fprintf(stdout, "combined multiplication ...");
+ fflush(stdout);
+
+ /* z is still the group order */
+ if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
+ ABORT;
+ if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, P, R, ctx))
+ ABORT;
+ if (0 != EC_POINT_cmp(group, R, Q, ctx))
+ ABORT;
+
+ fprintf(stdout, ".");
+ fflush(stdout);
+
+ if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0))
+ ABORT;
+ if (!BN_add(z, z, y))
+ ABORT;
+ BN_set_negative(z, 1);
+ scalars[0] = y;
+ scalars[1] = z; /* z = -(order + y) */
+
+ if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, P))
+ ABORT;
+
+ fprintf(stdout, ".");
+ fflush(stdout);
+
+ if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0))
+ ABORT;
+ if (!BN_add(z, x, y))
+ ABORT;
+ BN_set_negative(z, 1);
+ scalars[0] = x;
+ scalars[1] = y;
+ scalars[2] = z; /* z = -(x+y) */
+
+ if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
+ ABORT;
+ if (!EC_POINT_is_at_infinity(group, P))
+ ABORT;
+
+ fprintf(stdout, " ok\n\n");
+ }
+
+# if 0
+ timings(C2_K163, TIMING_BASE_PT, ctx);
+ timings(C2_K163, TIMING_RAND_PT, ctx);
+ timings(C2_K163, TIMING_SIMUL, ctx);
+ timings(C2_B163, TIMING_BASE_PT, ctx);
+ timings(C2_B163, TIMING_RAND_PT, ctx);
+ timings(C2_B163, TIMING_SIMUL, ctx);
+ timings(C2_K233, TIMING_BASE_PT, ctx);
+ timings(C2_K233, TIMING_RAND_PT, ctx);
+ timings(C2_K233, TIMING_SIMUL, ctx);
+ timings(C2_B233, TIMING_BASE_PT, ctx);
+ timings(C2_B233, TIMING_RAND_PT, ctx);
+ timings(C2_B233, TIMING_SIMUL, ctx);
+ timings(C2_K283, TIMING_BASE_PT, ctx);
+ timings(C2_K283, TIMING_RAND_PT, ctx);
+ timings(C2_K283, TIMING_SIMUL, ctx);
+ timings(C2_B283, TIMING_BASE_PT, ctx);
+ timings(C2_B283, TIMING_RAND_PT, ctx);
+ timings(C2_B283, TIMING_SIMUL, ctx);
+ timings(C2_K409, TIMING_BASE_PT, ctx);
+ timings(C2_K409, TIMING_RAND_PT, ctx);
+ timings(C2_K409, TIMING_SIMUL, ctx);
+ timings(C2_B409, TIMING_BASE_PT, ctx);
+ timings(C2_B409, TIMING_RAND_PT, ctx);
+ timings(C2_B409, TIMING_SIMUL, ctx);
+ timings(C2_K571, TIMING_BASE_PT, ctx);
+ timings(C2_K571, TIMING_RAND_PT, ctx);
+ timings(C2_K571, TIMING_SIMUL, ctx);
+ timings(C2_B571, TIMING_BASE_PT, ctx);
+ timings(C2_B571, TIMING_RAND_PT, ctx);
+ timings(C2_B571, TIMING_SIMUL, ctx);
+# endif
+
+ if (ctx)
+ BN_CTX_free(ctx);
+ BN_free(p);
+ BN_free(a);
+ BN_free(b);
+ EC_GROUP_free(group);
+ EC_POINT_free(P);
+ EC_POINT_free(Q);
+ EC_POINT_free(R);
+ BN_free(x);
+ BN_free(y);
+ BN_free(z);
+ BN_free(cof);
+
+ if (C2_K163)
+ EC_GROUP_free(C2_K163);
+ if (C2_B163)
+ EC_GROUP_free(C2_B163);
+ if (C2_K233)
+ EC_GROUP_free(C2_K233);
+ if (C2_B233)
+ EC_GROUP_free(C2_B233);
+ if (C2_K283)
+ EC_GROUP_free(C2_K283);
+ if (C2_B283)
+ EC_GROUP_free(C2_B283);
+ if (C2_K409)
+ EC_GROUP_free(C2_K409);
+ if (C2_B409)
+ EC_GROUP_free(C2_B409);
+ if (C2_K571)
+ EC_GROUP_free(C2_K571);
+ if (C2_B571)
+ EC_GROUP_free(C2_B571);
+
+}
+# endif
+
+static void internal_curve_test(void)
+{
+ EC_builtin_curve *curves = NULL;
+ size_t crv_len = 0, n = 0;
+ int ok = 1;
+
+ crv_len = EC_get_builtin_curves(NULL, 0);
+
+ curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
+
+ if (curves == NULL)
+ return;
+
+ if (!EC_get_builtin_curves(curves, crv_len)) {
+ OPENSSL_free(curves);
+ return;
+ }
+
+ fprintf(stdout, "testing internal curves: ");
+
+ for (n = 0; n < crv_len; n++) {
+ EC_GROUP *group = NULL;
+ int nid = curves[n].nid;
+ if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) {
+ ok = 0;
+ fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with"
+ " curve %s\n", OBJ_nid2sn(nid));
+ /* try next curve */
+ continue;
+ }
+ if (!EC_GROUP_check(group, NULL)) {
+ ok = 0;
+ fprintf(stdout, "\nEC_GROUP_check() failed with"
+ " curve %s\n", OBJ_nid2sn(nid));
+ EC_GROUP_free(group);
+ /* try the next curve */
+ continue;
+ }
+ fprintf(stdout, ".");
+ fflush(stdout);
+ EC_GROUP_free(group);
+ }
+ if (ok)
+ fprintf(stdout, " ok\n\n");
+ else {
+ fprintf(stdout, " failed\n\n");
+ ABORT;
+ }
+ OPENSSL_free(curves);
+ return;
+}
+
+# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+/*
+ * nistp_test_params contains magic numbers for testing our optimized
+ * implementations of several NIST curves with characteristic > 3.
+ */
+struct nistp_test_params {
+ const EC_METHOD *(*meth) ();
+ int degree;
+ /*
+ * Qx, Qy and D are taken from
+ * http://csrcdocut.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
+ * Otherwise, values are standard curve parameters from FIPS 180-3
+ */
+ const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
+};
+
+static const struct nistp_test_params nistp_tests_params[] = {
+ {
+ /* P-224 */
+ EC_GFp_nistp224_method,
+ 224,
+ /* p */
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
+ /* a */
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
+ /* b */
+ "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
+ /* Qx */
+ "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
+ /* Qy */
+ "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
+ /* Gx */
+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
+ /* Gy */
+ "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
+ /* order */
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
+ /* d */
+ "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
+ },
+ {
+ /* P-256 */
+ EC_GFp_nistp256_method,
+ 256,
+ /* p */
+ "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+ /* a */
+ "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
+ /* b */
+ "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
+ /* Qx */
+ "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
+ /* Qy */
+ "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
+ /* Gx */
+ "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
+ /* Gy */
+ "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
+ /* order */
+ "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+ /* d */
+ "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
+ },
+ {
+ /* P-521 */
+ EC_GFp_nistp521_method,
+ 521,
+ /* p */
+ "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ /* a */
+ "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
+ /* b */
+ "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
+ /* Qx */
+ "0098e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
+ /* Qy */
+ "0164350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
+ /* Gx */
+ "c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
+ /* Gy */
+ "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
+ /* order */
+ "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+ /* d */
+ "0100085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eeedf09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
+ },
+};
+
+static void nistp_single_test(const struct nistp_test_params *test)
+{
+ BN_CTX *ctx;
+ BIGNUM *p, *a, *b, *x, *y, *n, *m, *order;
+ EC_GROUP *NISTP;
+ EC_POINT *G, *P, *Q, *Q_CHECK;
+
+ fprintf(stdout, "\nNIST curve P-%d (optimised implementation):\n",
+ test->degree);
+ ctx = BN_CTX_new();
+ p = BN_new();
+ a = BN_new();
+ b = BN_new();
+ x = BN_new();
+ y = BN_new();
+ m = BN_new();
+ n = BN_new();
+ order = BN_new();
+
+ NISTP = EC_GROUP_new(test->meth());
+ if (!NISTP)
+ ABORT;
+ if (!BN_hex2bn(&p, test->p))
+ ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
+ ABORT;
+ if (!BN_hex2bn(&a, test->a))
+ ABORT;
+ if (!BN_hex2bn(&b, test->b))
+ ABORT;
+ if (!EC_GROUP_set_curve_GFp(NISTP, p, a, b, ctx))
+ ABORT;
+ G = EC_POINT_new(NISTP);
+ P = EC_POINT_new(NISTP);
+ Q = EC_POINT_new(NISTP);
+ Q_CHECK = EC_POINT_new(NISTP);
+ if (!BN_hex2bn(&x, test->Qx))
+ ABORT;
+ if (!BN_hex2bn(&y, test->Qy))
+ ABORT;
+ if (!EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y, ctx))
+ ABORT;
+ if (!BN_hex2bn(&x, test->Gx))
+ ABORT;
+ if (!BN_hex2bn(&y, test->Gy))
+ ABORT;
+ if (!EC_POINT_set_affine_coordinates_GFp(NISTP, G, x, y, ctx))
+ ABORT;
+ if (!BN_hex2bn(&order, test->order))
+ ABORT;
+ if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
+ ABORT;
+
+ fprintf(stdout, "verify degree ... ");
+ if (EC_GROUP_get_degree(NISTP) != test->degree)
+ ABORT;
+ fprintf(stdout, "ok\n");
+
+ fprintf(stdout, "NIST test vectors ... ");
+ if (!BN_hex2bn(&n, test->d))
+ ABORT;
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
+ ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
+ ABORT;
+
+ /* set generator to P = 2*G, where G is the standard generator */
+ if (!EC_POINT_dbl(NISTP, P, G, ctx))
+ ABORT;
+ if (!EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
+ ABORT;
+ /* set the scalar to m=n/2, where n is the NIST test scalar */
+ if (!BN_rshift(m, n, 1))
+ ABORT;
+
+ /* test the non-standard generator */
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
+ ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
+ ABORT;
+
+ /* now repeat all tests with precomputation */
+ if (!EC_GROUP_precompute_mult(NISTP, ctx))
+ ABORT;
+
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
+ ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
+ ABORT;
+
+ /* reset generator */
+ if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
+ ABORT;
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
+ ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
+ if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
+ ABORT;
+
+ fprintf(stdout, "ok\n");
+ group_order_tests(NISTP);
+# if 0
+ timings(NISTP, TIMING_BASE_PT, ctx);
+ timings(NISTP, TIMING_RAND_PT, ctx);
+# endif
+ EC_GROUP_free(NISTP);
+ EC_POINT_free(G);
+ EC_POINT_free(P);
+ EC_POINT_free(Q);
+ EC_POINT_free(Q_CHECK);
+ BN_free(n);
+ BN_free(m);
+ BN_free(p);
+ BN_free(a);
+ BN_free(b);
+ BN_free(x);
+ BN_free(y);
+ BN_free(order);
+ BN_CTX_free(ctx);
+}
+
+static void nistp_tests()
+{
+ unsigned i;
+
+ for (i = 0;
+ i < sizeof(nistp_tests_params) / sizeof(struct nistp_test_params);
+ i++) {
+ nistp_single_test(&nistp_tests_params[i]);
+ }
+}
+# endif
+
+static const char rnd_seed[] =
+ "string to make the random number generator think it has entropy";
+
+int main(int argc, char *argv[])
+{
+
+ /* enable memory leak checking unless explicitly disabled */
+ if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL)
+ && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) {
+ CRYPTO_malloc_debug_init();
+ CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+ } else {
+ /* OPENSSL_DEBUG_MEMORY=off */
+ CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
+ }
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+ ERR_load_crypto_strings();
+
+ RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
+
+ prime_field_tests();
+ puts("");
+# ifndef OPENSSL_NO_EC2M
+ char2_field_tests();
+# endif
+# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+ nistp_tests();
+# endif
+ /* test the internal curves */
+ internal_curve_test();
+
+# ifndef OPENSSL_NO_ENGINE
+ ENGINE_cleanup();
+# endif
+ CRYPTO_cleanup_all_ex_data();
+ ERR_free_strings();
+ ERR_remove_thread_state(NULL);
+ CRYPTO_mem_leaks_fp(stderr);
+
+ return 0;
+}
+#endif
diff --git a/openssl/ecdh.h b/openssl/ecdh.h
new file mode 120000
index 0000000..6648f8e
--- /dev/null
+++ b/openssl/ecdh.h
@@ -0,0 +1 @@
+ecdh/ecdh.h
\ No newline at end of file
diff --git a/openssl/ecdh/Makefile b/openssl/ecdh/Makefile
new file mode 100644
index 0000000..8dc74fa
--- /dev/null
+++ b/openssl/ecdh/Makefile
@@ -0,0 +1,49 @@
+# Copyright 2010 by Nest Labs, Inc. All rights reserved.
+#
+# This program is confidential and proprietary to Nest Labs, Inc.,
+# and may not be reproduced, published or disclosed to others without
+# company authorization.
+#
+
+DEPTH = ../../
+
+include $(DEPTH)Makefile.config
+
+OUTDIR = $(OBJ_DIR)
+SRCDIR = ./
+INCDIR = ./
+
+OBJECT_FILES = \
+ ech_err \
+ ech_key \
+ ech_lib \
+ ech_ossl
+
+HEADER_FILES = \
+ ech_locl
+
+OBJECTS = $(OBJECT_FILES:%=$(OUTDIR)/%.o)
+HEADERS = $(HEADER_FILES:%=$(INCDIR)/%.h)
+
+all: $(OUTDIR) $(LIB_DIR)/libecdh.a
+
+$(OUTDIR):
+ $(MKDIR) $(OUTDIR)
+
+clean:
+ $(RM) $(OUTDIR)
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.c $(HEADERS)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.cpp $(HEADERS)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(OUTDIR)/libecdh.a: $(OBJECTS)
+ $(ARCHIVE) $@ $(OBJECTS)
+ $(RANLIB) $@
+
+$(LIB_DIR)/libecdh.a: $(OUTDIR)/libecdh.a
+ $(MKDIR) $(dir $@)
+ $(CP) $< $@
+
diff --git a/openssl/ecdh/ecdh.h b/openssl/ecdh/ecdh.h
new file mode 100644
index 0000000..a9b811a
--- /dev/null
+++ b/openssl/ecdh/ecdh.h
@@ -0,0 +1,127 @@
+/* crypto/ecdh/ecdh.h */
+/* ====================================================================
+ * 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 ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * 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
+ * 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).
+ *
+ */
+#ifndef HEADER_ECDH_H
+# define HEADER_ECDH_H
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_ECDH
+# error ECDH is disabled.
+# endif
+
+# include <openssl/ec.h>
+# include <openssl/ossl_typ.h>
+# ifndef OPENSSL_NO_DEPRECATED
+# include <openssl/bn.h>
+# endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const ECDH_METHOD *ECDH_OpenSSL(void);
+
+void ECDH_set_default_method(const ECDH_METHOD *);
+const ECDH_METHOD *ECDH_get_default_method(void);
+int ECDH_set_method(EC_KEY *, const ECDH_METHOD *);
+
+int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
+ EC_KEY *ecdh, void *(*KDF) (const void *in, size_t inlen,
+ void *out, size_t *outlen));
+
+int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new
+ *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func);
+int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg);
+void *ECDH_get_ex_data(EC_KEY *d, int idx);
+
+/* 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.
+ */
+void ERR_load_ECDH_strings(void);
+
+/* Error codes for the ECDH functions. */
+
+/* Function codes. */
+# define ECDH_F_ECDH_CHECK 102
+# define ECDH_F_ECDH_COMPUTE_KEY 100
+# define ECDH_F_ECDH_DATA_NEW_METHOD 101
+
+/* Reason codes. */
+# define ECDH_R_KDF_FAILED 102
+# define ECDH_R_NON_FIPS_METHOD 103
+# define ECDH_R_NO_PRIVATE_VALUE 100
+# define ECDH_R_POINT_ARITHMETIC_FAILURE 101
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/ecdh/ecdhtest.c b/openssl/ecdh/ecdhtest.c
new file mode 100644
index 0000000..996321d
--- /dev/null
+++ b/openssl/ecdh/ecdhtest.c
@@ -0,0 +1,410 @@
+/* crypto/ecdh/ecdhtest.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 ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../e_os.h"
+
+#include <openssl/opensslconf.h> /* for OPENSSL_NO_ECDH */
+#include <openssl/crypto.h>
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+#include <openssl/err.h>
+
+#ifdef OPENSSL_NO_ECDH
+int main(int argc, char *argv[])
+{
+ printf("No ECDH support\n");
+ return (0);
+}
+#else
+# include <openssl/ec.h>
+# include <openssl/ecdh.h>
+
+# ifdef OPENSSL_SYS_WIN16
+# define MS_CALLBACK _far _loadds
+# else
+# define MS_CALLBACK
+# endif
+
+# if 0
+static void MS_CALLBACK cb(int p, int n, void *arg);
+# endif
+
+static const char rnd_seed[] =
+ "string to make the random number generator think it has entropy";
+
+static const int KDF1_SHA1_len = 20;
+static void *KDF1_SHA1(const void *in, size_t inlen, void *out,
+ size_t *outlen)
+{
+# ifndef OPENSSL_NO_SHA
+ if (*outlen < SHA_DIGEST_LENGTH)
+ return NULL;
+ else
+ *outlen = SHA_DIGEST_LENGTH;
+ return SHA1(in, inlen, out);
+# else
+ return NULL;
+# endif
+}
+
+static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
+{
+ EC_KEY *a = NULL;
+ EC_KEY *b = NULL;
+ BIGNUM *x_a = NULL, *y_a = NULL, *x_b = NULL, *y_b = NULL;
+ char buf[12];
+ unsigned char *abuf = NULL, *bbuf = NULL;
+ int i, alen, blen, aout, bout, ret = 0;
+ const EC_GROUP *group;
+
+ a = EC_KEY_new_by_curve_name(nid);
+ b = EC_KEY_new_by_curve_name(nid);
+ if (a == NULL || b == NULL)
+ goto err;
+
+ group = EC_KEY_get0_group(a);
+
+ if ((x_a = BN_new()) == NULL)
+ goto err;
+ if ((y_a = BN_new()) == NULL)
+ goto err;
+ if ((x_b = BN_new()) == NULL)
+ goto err;
+ if ((y_b = BN_new()) == NULL)
+ goto err;
+
+ BIO_puts(out, "Testing key generation with ");
+ BIO_puts(out, text);
+# ifdef NOISY
+ BIO_puts(out, "\n");
+# else
+ (void)BIO_flush(out);
+# endif
+
+ if (!EC_KEY_generate_key(a))
+ goto err;
+
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
+ NID_X9_62_prime_field) {
+ if (!EC_POINT_get_affine_coordinates_GFp
+ (group, EC_KEY_get0_public_key(a), x_a, y_a, ctx))
+ goto err;
+ }
+# ifndef OPENSSL_NO_EC2M
+ else {
+ if (!EC_POINT_get_affine_coordinates_GF2m(group,
+ EC_KEY_get0_public_key(a),
+ x_a, y_a, ctx))
+ goto err;
+ }
+# endif
+# ifdef NOISY
+ BIO_puts(out, " pri 1=");
+ BN_print(out, a->priv_key);
+ BIO_puts(out, "\n pub 1=");
+ BN_print(out, x_a);
+ BIO_puts(out, ",");
+ BN_print(out, y_a);
+ BIO_puts(out, "\n");
+# else
+ BIO_printf(out, " .");
+ (void)BIO_flush(out);
+# endif
+
+ if (!EC_KEY_generate_key(b))
+ goto err;
+
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
+ NID_X9_62_prime_field) {
+ if (!EC_POINT_get_affine_coordinates_GFp
+ (group, EC_KEY_get0_public_key(b), x_b, y_b, ctx))
+ goto err;
+ }
+# ifndef OPENSSL_NO_EC2M
+ else {
+ if (!EC_POINT_get_affine_coordinates_GF2m(group,
+ EC_KEY_get0_public_key(b),
+ x_b, y_b, ctx))
+ goto err;
+ }
+# endif
+
+# ifdef NOISY
+ BIO_puts(out, " pri 2=");
+ BN_print(out, b->priv_key);
+ BIO_puts(out, "\n pub 2=");
+ BN_print(out, x_b);
+ BIO_puts(out, ",");
+ BN_print(out, y_b);
+ BIO_puts(out, "\n");
+# else
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+# endif
+
+ alen = KDF1_SHA1_len;
+ abuf = (unsigned char *)OPENSSL_malloc(alen);
+ aout =
+ ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), a, KDF1_SHA1);
+
+# ifdef NOISY
+ BIO_puts(out, " key1 =");
+ for (i = 0; i < aout; i++) {
+ sprintf(buf, "%02X", abuf[i]);
+ BIO_puts(out, buf);
+ }
+ BIO_puts(out, "\n");
+# else
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+# endif
+
+ blen = KDF1_SHA1_len;
+ bbuf = (unsigned char *)OPENSSL_malloc(blen);
+ bout =
+ ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(a), b, KDF1_SHA1);
+
+# ifdef NOISY
+ BIO_puts(out, " key2 =");
+ for (i = 0; i < bout; i++) {
+ sprintf(buf, "%02X", bbuf[i]);
+ BIO_puts(out, buf);
+ }
+ BIO_puts(out, "\n");
+# else
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+# endif
+
+ if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) {
+# ifndef NOISY
+ BIO_printf(out, " failed\n\n");
+ BIO_printf(out, "key a:\n");
+ BIO_printf(out, "private key: ");
+ BN_print(out, EC_KEY_get0_private_key(a));
+ BIO_printf(out, "\n");
+ BIO_printf(out, "public key (x,y): ");
+ BN_print(out, x_a);
+ BIO_printf(out, ",");
+ BN_print(out, y_a);
+ BIO_printf(out, "\nkey b:\n");
+ BIO_printf(out, "private key: ");
+ BN_print(out, EC_KEY_get0_private_key(b));
+ BIO_printf(out, "\n");
+ BIO_printf(out, "public key (x,y): ");
+ BN_print(out, x_b);
+ BIO_printf(out, ",");
+ BN_print(out, y_b);
+ BIO_printf(out, "\n");
+ BIO_printf(out, "generated key a: ");
+ for (i = 0; i < bout; i++) {
+ sprintf(buf, "%02X", bbuf[i]);
+ BIO_puts(out, buf);
+ }
+ BIO_printf(out, "\n");
+ BIO_printf(out, "generated key b: ");
+ for (i = 0; i < aout; i++) {
+ sprintf(buf, "%02X", abuf[i]);
+ BIO_puts(out, buf);
+ }
+ BIO_printf(out, "\n");
+# endif
+ fprintf(stderr, "Error in ECDH routines\n");
+ ret = 0;
+ } else {
+# ifndef NOISY
+ BIO_printf(out, " ok\n");
+# endif
+ ret = 1;
+ }
+ err:
+ ERR_print_errors_fp(stderr);
+
+ if (abuf != NULL)
+ OPENSSL_free(abuf);
+ if (bbuf != NULL)
+ OPENSSL_free(bbuf);
+ if (x_a)
+ BN_free(x_a);
+ if (y_a)
+ BN_free(y_a);
+ if (x_b)
+ BN_free(x_b);
+ if (y_b)
+ BN_free(y_b);
+ if (b)
+ EC_KEY_free(b);
+ if (a)
+ EC_KEY_free(a);
+ return (ret);
+}
+
+int main(int argc, char *argv[])
+{
+ BN_CTX *ctx = NULL;
+ int ret = 1;
+ BIO *out;
+
+ CRYPTO_malloc_debug_init();
+ CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+# ifdef OPENSSL_SYS_WIN32
+ CRYPTO_malloc_init();
+# endif
+
+ RAND_seed(rnd_seed, sizeof rnd_seed);
+
+ out = BIO_new(BIO_s_file());
+ if (out == NULL)
+ EXIT(1);
+ BIO_set_fp(out, stdout, BIO_NOCLOSE);
+
+ if ((ctx = BN_CTX_new()) == NULL)
+ goto err;
+
+ /* NIST PRIME CURVES TESTS */
+ if (!test_ecdh_curve
+ (NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out))
+ goto err;
+ if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out))
+ goto err;
+ if (!test_ecdh_curve
+ (NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out))
+ goto err;
+ if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out))
+ goto err;
+ if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out))
+ goto err;
+# ifndef OPENSSL_NO_EC2M
+ /* NIST BINARY CURVES TESTS */
+ if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out))
+ goto err;
+ if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out))
+ goto err;
+ if (!test_ecdh_curve(NID_sect233k1, "NIST Binary-Curve K-233", ctx, out))
+ goto err;
+ if (!test_ecdh_curve(NID_sect233r1, "NIST Binary-Curve B-233", ctx, out))
+ goto err;
+ if (!test_ecdh_curve(NID_sect283k1, "NIST Binary-Curve K-283", ctx, out))
+ goto err;
+ if (!test_ecdh_curve(NID_sect283r1, "NIST Binary-Curve B-283", ctx, out))
+ goto err;
+ if (!test_ecdh_curve(NID_sect409k1, "NIST Binary-Curve K-409", ctx, out))
+ goto err;
+ if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out))
+ goto err;
+ if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out))
+ goto err;
+ if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out))
+ goto err;
+# endif
+
+ ret = 0;
+
+ err:
+ ERR_print_errors_fp(stderr);
+ if (ctx)
+ BN_CTX_free(ctx);
+ BIO_free(out);
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_thread_state(NULL);
+ CRYPTO_mem_leaks_fp(stderr);
+ EXIT(ret);
+ return (ret);
+}
+
+# if 0
+static void MS_CALLBACK cb(int p, int n, void *arg)
+{
+ char c = '*';
+
+ if (p == 0)
+ c = '.';
+ if (p == 1)
+ c = '+';
+ if (p == 2)
+ c = '*';
+ if (p == 3)
+ c = '\n';
+ BIO_write((BIO *)arg, &c, 1);
+ (void)BIO_flush((BIO *)arg);
+# ifdef LINT
+ p = n;
+# endif
+}
+# endif
+#endif
diff --git a/openssl/ecdh/ech_err.c b/openssl/ecdh/ech_err.c
new file mode 100644
index 0000000..af9f625
--- /dev/null
+++ b/openssl/ecdh/ech_err.c
@@ -0,0 +1,98 @@
+/* crypto/ecdh/ech_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2011 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).
+ *
+ */
+
+/*
+ * NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ecdh.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDH,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDH,0,reason)
+
+static ERR_STRING_DATA ECDH_str_functs[] = {
+ {ERR_FUNC(ECDH_F_ECDH_CHECK), "ECDH_CHECK"},
+ {ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"},
+ {ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD), "ECDH_DATA_new_method"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA ECDH_str_reasons[] = {
+ {ERR_REASON(ECDH_R_KDF_FAILED), "KDF failed"},
+ {ERR_REASON(ECDH_R_NON_FIPS_METHOD), "non fips method"},
+ {ERR_REASON(ECDH_R_NO_PRIVATE_VALUE), "no private value"},
+ {ERR_REASON(ECDH_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_ECDH_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(ECDH_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, ECDH_str_functs);
+ ERR_load_strings(0, ECDH_str_reasons);
+ }
+#endif
+}
diff --git a/openssl/ecdh/ech_key.c b/openssl/ecdh/ech_key.c
new file mode 100644
index 0000000..4f14498
--- /dev/null
+++ b/openssl/ecdh/ech_key.c
@@ -0,0 +1,81 @@
+/* crypto/ecdh/ecdh_key.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 ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 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 "ech_locl.h"
+
+int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
+ EC_KEY *eckey,
+ void *(*KDF) (const void *in, size_t inlen, void *out,
+ size_t *outlen))
+{
+ ECDH_DATA *ecdh = ecdh_check(eckey);
+ if (ecdh == NULL)
+ return 0;
+ return ecdh->meth->compute_key(out, outlen, pub_key, eckey, KDF);
+}
diff --git a/openssl/ecdh/ech_lib.c b/openssl/ecdh/ech_lib.c
new file mode 100644
index 0000000..cbc21d1
--- /dev/null
+++ b/openssl/ecdh/ech_lib.c
@@ -0,0 +1,265 @@
+/* crypto/ecdh/ech_lib.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 ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 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 "ech_locl.h"
+#include <string.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+const char ECDH_version[] = "ECDH" OPENSSL_VERSION_PTEXT;
+
+static const ECDH_METHOD *default_ECDH_method = NULL;
+
+static void *ecdh_data_new(void);
+static void *ecdh_data_dup(void *);
+static void ecdh_data_free(void *);
+
+void ECDH_set_default_method(const ECDH_METHOD *meth)
+{
+ default_ECDH_method = meth;
+}
+
+const ECDH_METHOD *ECDH_get_default_method(void)
+{
+ if (!default_ECDH_method) {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_ecdh_openssl();
+ else
+ return ECDH_OpenSSL();
+#else
+ default_ECDH_method = ECDH_OpenSSL();
+#endif
+ }
+ return default_ECDH_method;
+}
+
+int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth)
+{
+ ECDH_DATA *ecdh;
+
+ ecdh = ecdh_check(eckey);
+
+ if (ecdh == NULL)
+ return 0;
+
+#if 0
+ mtmp = ecdh->meth;
+ if (mtmp->finish)
+ mtmp->finish(eckey);
+#endif
+#ifndef OPENSSL_NO_ENGINE
+ if (ecdh->engine) {
+ ENGINE_finish(ecdh->engine);
+ ecdh->engine = NULL;
+ }
+#endif
+ ecdh->meth = meth;
+#if 0
+ if (meth->init)
+ meth->init(eckey);
+#endif
+ return 1;
+}
+
+static ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
+{
+ ECDH_DATA *ret;
+
+ ret = (ECDH_DATA *)OPENSSL_malloc(sizeof(ECDH_DATA));
+ if (ret == NULL) {
+ ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+
+ ret->init = NULL;
+
+ ret->meth = ECDH_get_default_method();
+ ret->engine = engine;
+#ifndef OPENSSL_NO_ENGINE
+ if (!ret->engine)
+ ret->engine = ENGINE_get_default_ECDH();
+ if (ret->engine) {
+ ret->meth = ENGINE_get_ECDH(ret->engine);
+ if (!ret->meth) {
+ ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_ENGINE_LIB);
+ ENGINE_finish(ret->engine);
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ }
+#endif
+
+ ret->flags = ret->meth->flags;
+ CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data);
+#if 0
+ if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data);
+ OPENSSL_free(ret);
+ ret = NULL;
+ }
+#endif
+ return (ret);
+}
+
+static void *ecdh_data_new(void)
+{
+ return (void *)ECDH_DATA_new_method(NULL);
+}
+
+static void *ecdh_data_dup(void *data)
+{
+ ECDH_DATA *r = (ECDH_DATA *)data;
+
+ /* XXX: dummy operation */
+ if (r == NULL)
+ return NULL;
+
+ return (void *)ecdh_data_new();
+}
+
+void ecdh_data_free(void *data)
+{
+ ECDH_DATA *r = (ECDH_DATA *)data;
+
+#ifndef OPENSSL_NO_ENGINE
+ if (r->engine)
+ ENGINE_finish(r->engine);
+#endif
+
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, r, &r->ex_data);
+
+ OPENSSL_cleanse((void *)r, sizeof(ECDH_DATA));
+
+ OPENSSL_free(r);
+}
+
+ECDH_DATA *ecdh_check(EC_KEY *key)
+{
+ ECDH_DATA *ecdh_data;
+
+ void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup,
+ ecdh_data_free, ecdh_data_free);
+ if (data == NULL) {
+ ecdh_data = (ECDH_DATA *)ecdh_data_new();
+ if (ecdh_data == NULL)
+ return NULL;
+ data = EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
+ ecdh_data_dup, ecdh_data_free,
+ ecdh_data_free);
+ if (data != NULL) {
+ /*
+ * Another thread raced us to install the key_method data and
+ * won.
+ */
+ ecdh_data_free(ecdh_data);
+ ecdh_data = (ECDH_DATA *)data;
+ }
+ } else
+ ecdh_data = (ECDH_DATA *)data;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(ecdh_data->flags & ECDH_FLAG_FIPS_METHOD)
+ && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) {
+ ECDHerr(ECDH_F_ECDH_CHECK, ECDH_R_NON_FIPS_METHOD);
+ return NULL;
+ }
+#endif
+
+ return ecdh_data;
+}
+
+int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+ return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDH, argl, argp,
+ new_func, dup_func, free_func);
+}
+
+int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg)
+{
+ ECDH_DATA *ecdh;
+ ecdh = ecdh_check(d);
+ if (ecdh == NULL)
+ return 0;
+ return (CRYPTO_set_ex_data(&ecdh->ex_data, idx, arg));
+}
+
+void *ECDH_get_ex_data(EC_KEY *d, int idx)
+{
+ ECDH_DATA *ecdh;
+ ecdh = ecdh_check(d);
+ if (ecdh == NULL)
+ return NULL;
+ return (CRYPTO_get_ex_data(&ecdh->ex_data, idx));
+}
diff --git a/openssl/ecdh/ech_locl.h b/openssl/ecdh/ech_locl.h
new file mode 100644
index 0000000..4e66024
--- /dev/null
+++ b/openssl/ecdh/ech_locl.h
@@ -0,0 +1,104 @@
+/* crypto/ecdh/ech_locl.h */
+/* ====================================================================
+ * Copyright (c) 2000-2005 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).
+ *
+ */
+
+#ifndef HEADER_ECH_LOCL_H
+# define HEADER_ECH_LOCL_H
+
+# include <openssl/ecdh.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ecdh_method {
+ const char *name;
+ int (*compute_key) (void *key, size_t outlen, const EC_POINT *pub_key,
+ EC_KEY *ecdh, void *(*KDF) (const void *in,
+ size_t inlen, void *out,
+ size_t *outlen));
+# if 0
+ int (*init) (EC_KEY *eckey);
+ int (*finish) (EC_KEY *eckey);
+# endif
+ int flags;
+ char *app_data;
+};
+
+/*
+ * If this flag is set the ECDH method is FIPS compliant and can be used in
+ * FIPS mode. This is set in the validated module method. If an application
+ * sets this flag in its own methods it is its responsibility to ensure the
+ * result is compliant.
+ */
+
+# define ECDH_FLAG_FIPS_METHOD 0x1
+
+typedef struct ecdh_data_st {
+ /* EC_KEY_METH_DATA part */
+ int (*init) (EC_KEY *);
+ /* method specific part */
+ ENGINE *engine;
+ int flags;
+ const ECDH_METHOD *meth;
+ CRYPTO_EX_DATA ex_data;
+} ECDH_DATA;
+
+ECDH_DATA *ecdh_check(EC_KEY *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HEADER_ECH_LOCL_H */
diff --git a/openssl/ecdh/ech_ossl.c b/openssl/ecdh/ech_ossl.c
new file mode 100644
index 0000000..d448b19
--- /dev/null
+++ b/openssl/ecdh/ech_ossl.c
@@ -0,0 +1,208 @@
+/* crypto/ecdh/ech_ossl.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 ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 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 <string.h>
+#include <limits.h>
+
+#include "cryptlib.h"
+
+#include "ech_locl.h"
+#include <openssl/err.h>
+#include <openssl/sha.h>
+#include <openssl/obj_mac.h>
+#include <openssl/bn.h>
+
+static int ecdh_compute_key(void *out, size_t len, const EC_POINT *pub_key,
+ EC_KEY *ecdh,
+ void *(*KDF) (const void *in, size_t inlen,
+ void *out, size_t *outlen));
+
+static ECDH_METHOD openssl_ecdh_meth = {
+ "OpenSSL ECDH method",
+ ecdh_compute_key,
+#if 0
+ NULL, /* init */
+ NULL, /* finish */
+#endif
+ 0, /* flags */
+ NULL /* app_data */
+};
+
+const ECDH_METHOD *ECDH_OpenSSL(void)
+{
+ return &openssl_ecdh_meth;
+}
+
+/*-
+ * This implementation is based on the following primitives in the IEEE 1363 standard:
+ * - ECKAS-DH1
+ * - ECSVDP-DH
+ * Finally an optional KDF is applied.
+ */
+static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
+ EC_KEY *ecdh,
+ void *(*KDF) (const void *in, size_t inlen,
+ void *out, size_t *outlen))
+{
+ BN_CTX *ctx;
+ EC_POINT *tmp = NULL;
+ BIGNUM *x = NULL, *y = NULL;
+ const BIGNUM *priv_key;
+ const EC_GROUP *group;
+ int ret = -1;
+ size_t buflen, len;
+ unsigned char *buf = NULL;
+
+ if (outlen > INT_MAX) {
+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); /* sort of,
+ * anyway */
+ return -1;
+ }
+
+ if ((ctx = BN_CTX_new()) == NULL)
+ goto err;
+ BN_CTX_start(ctx);
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+
+ priv_key = EC_KEY_get0_private_key(ecdh);
+ if (priv_key == NULL) {
+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_NO_PRIVATE_VALUE);
+ goto err;
+ }
+
+ group = EC_KEY_get0_group(ecdh);
+ if ((tmp = EC_POINT_new(group)) == NULL) {
+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) {
+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE);
+ goto err;
+ }
+
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
+ NID_X9_62_prime_field) {
+ if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) {
+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE);
+ goto err;
+ }
+ }
+#ifndef OPENSSL_NO_EC2M
+ else {
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) {
+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE);
+ goto err;
+ }
+ }
+#endif
+
+ buflen = (EC_GROUP_get_degree(group) + 7) / 8;
+ len = BN_num_bytes(x);
+ if (len > buflen) {
+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ if ((buf = OPENSSL_malloc(buflen)) == NULL) {
+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ memset(buf, 0, buflen - len);
+ if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) {
+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ if (KDF != 0) {
+ if (KDF(buf, buflen, out, &outlen) == NULL) {
+ ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_KDF_FAILED);
+ goto err;
+ }
+ ret = outlen;
+ } else {
+ /* no KDF, just copy as much as we can */
+ if (outlen > buflen)
+ outlen = buflen;
+ memcpy(out, buf, outlen);
+ ret = outlen;
+ }
+
+ err:
+ if (tmp)
+ EC_POINT_free(tmp);
+ if (ctx)
+ BN_CTX_end(ctx);
+ if (ctx)
+ BN_CTX_free(ctx);
+ if (buf)
+ OPENSSL_free(buf);
+ return (ret);
+}
diff --git a/openssl/ecdsa.h b/openssl/ecdsa.h
new file mode 120000
index 0000000..dc4c546
--- /dev/null
+++ b/openssl/ecdsa.h
@@ -0,0 +1 @@
+ecdsa/ecdsa.h
\ No newline at end of file
diff --git a/openssl/ecdsa/Makefile b/openssl/ecdsa/Makefile
new file mode 100644
index 0000000..7865c45
--- /dev/null
+++ b/openssl/ecdsa/Makefile
@@ -0,0 +1,54 @@
+# Copyright 2010 by Nest Labs, Inc. All rights reserved.
+#
+# This program is confidential and proprietary to Nest Labs, Inc.,
+# and may not be reproduced, published or disclosed to others without
+# company authorization.
+#
+
+DEPTH = ../../
+
+include $(DEPTH)Makefile.config
+
+CFLAGS += -Os
+
+OUTDIR = $(OBJ_DIR)
+SRCDIR = ./
+INCDIR = ./
+
+OBJECT_FILES = \
+ ecs_err \
+ ecs_sign \
+ ecs_lib \
+ ecs_ossl \
+ ecs_vrf
+
+# ecs_asn1
+
+HEADER_FILES = \
+ ecs_locl
+
+OBJECTS = $(OBJECT_FILES:%=$(OUTDIR)/%.o)
+HEADERS = $(HEADER_FILES:%=$(INCDIR)/%.h)
+
+all: $(OUTDIR) $(LIB_DIR)/libecdsa.a
+
+$(OUTDIR):
+ $(MKDIR) $(OUTDIR)
+
+clean:
+ $(RM) $(OUTDIR)
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.c $(HEADERS)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.cpp $(HEADERS)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(OUTDIR)/libecdsa.a: $(OBJECTS)
+ $(ARCHIVE) $@ $(OBJECTS)
+ $(RANLIB) $@
+
+$(LIB_DIR)/libecdsa.a: $(OUTDIR)/libecdsa.a
+ $(MKDIR) $(dir $@)
+ $(CP) $< $@
+
diff --git a/openssl/ecdsa/ecdsa.h b/openssl/ecdsa/ecdsa.h
new file mode 100644
index 0000000..faf76b1
--- /dev/null
+++ b/openssl/ecdsa/ecdsa.h
@@ -0,0 +1,260 @@
+/* crypto/ecdsa/ecdsa.h */
+/**
+ * \file crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions
+ * \author Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 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).
+ *
+ */
+#ifndef HEADER_ECDSA_H
+# define HEADER_ECDSA_H
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_ECDSA
+# error ECDSA is disabled.
+# endif
+
+# include <openssl/ec.h>
+# include <openssl/ossl_typ.h>
+# ifndef OPENSSL_NO_DEPRECATED
+# include <openssl/bn.h>
+# endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ECDSA_SIG_st {
+ BIGNUM *r;
+ BIGNUM *s;
+} ECDSA_SIG;
+
+/** Allocates and initialize a ECDSA_SIG structure
+ * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_SIG_new(void);
+
+/** frees a ECDSA_SIG structure
+ * \param sig pointer to the ECDSA_SIG structure
+ */
+void ECDSA_SIG_free(ECDSA_SIG *sig);
+
+/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
+ * (*pp += length of the DER encoded signature)).
+ * \param sig pointer to the ECDSA_SIG object
+ * \param pp pointer to a unsigned char pointer for the output or NULL
+ * \return the length of the DER encoded ECDSA_SIG object or 0
+ */
+int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
+
+/** Decodes a DER encoded ECDSA signature (note: this function changes *pp
+ * (*pp += len)).
+ * \param sig pointer to ECDSA_SIG pointer (may be NULL)
+ * \param pp memory buffer with the DER encoded signature
+ * \param len length of the buffer
+ * \return pointer to the decoded ECDSA_SIG structure (or NULL)
+ */
+ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);
+
+/** Computes the ECDSA signature of the given hash value using
+ * the supplied private key and returns the created signature.
+ * \param dgst pointer to the hash value
+ * \param dgst_len length of the hash value
+ * \param eckey EC_KEY object containing a private EC key
+ * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dgst_len,
+ EC_KEY *eckey);
+
+/** Computes ECDSA signature of a given hash value using the supplied
+ * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ * \param dgst pointer to the hash value to sign
+ * \param dgstlen length of the hash value
+ * \param kinv BIGNUM with a pre-computed inverse k (optional)
+ * \param rp BIGNUM with a pre-computed rp value (optioanl),
+ * see ECDSA_sign_setup
+ * \param eckey EC_KEY object containing a private EC key
+ * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen,
+ const BIGNUM *kinv, const BIGNUM *rp,
+ EC_KEY *eckey);
+
+/** Verifies that the supplied signature is a valid ECDSA
+ * signature of the supplied hash value using the supplied public key.
+ * \param dgst pointer to the hash value
+ * \param dgst_len length of the hash value
+ * \param sig ECDSA_SIG structure
+ * \param eckey EC_KEY object containing a public EC key
+ * \return 1 if the signature is valid, 0 if the signature is invalid
+ * and -1 on error
+ */
+int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
+ const ECDSA_SIG *sig, EC_KEY *eckey);
+
+const ECDSA_METHOD *ECDSA_OpenSSL(void);
+
+/** Sets the default ECDSA method
+ * \param meth new default ECDSA_METHOD
+ */
+void ECDSA_set_default_method(const ECDSA_METHOD *meth);
+
+/** Returns the default ECDSA method
+ * \return pointer to ECDSA_METHOD structure containing the default method
+ */
+const ECDSA_METHOD *ECDSA_get_default_method(void);
+
+/** Sets method to be used for the ECDSA operations
+ * \param eckey EC_KEY object
+ * \param meth new method
+ * \return 1 on success and 0 otherwise
+ */
+int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth);
+
+/** Returns the maximum length of the DER encoded signature
+ * \param eckey EC_KEY object
+ * \return numbers of bytes required for the DER encoded signature
+ */
+int ECDSA_size(const EC_KEY *eckey);
+
+/** Precompute parts of the signing operation
+ * \param eckey EC_KEY object containing a private EC key
+ * \param ctx BN_CTX object (optional)
+ * \param kinv BIGNUM pointer for the inverse of k
+ * \param rp BIGNUM pointer for x coordinate of k * generator
+ * \return 1 on success and 0 otherwise
+ */
+int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp);
+
+/** Computes ECDSA signature of a given hash value using the supplied
+ * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ * \param type this parameter is ignored
+ * \param dgst pointer to the hash value to sign
+ * \param dgstlen length of the hash value
+ * \param sig memory for the DER encoded created signature
+ * \param siglen pointer to the length of the returned signature
+ * \param eckey EC_KEY object containing a private EC key
+ * \return 1 on success and 0 otherwise
+ */
+int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen,
+ unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
+
+/** Computes ECDSA signature of a given hash value using the supplied
+ * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ * \param type this parameter is ignored
+ * \param dgst pointer to the hash value to sign
+ * \param dgstlen length of the hash value
+ * \param sig buffer to hold the DER encoded signature
+ * \param siglen pointer to the length of the returned signature
+ * \param kinv BIGNUM with a pre-computed inverse k (optional)
+ * \param rp BIGNUM with a pre-computed rp value (optioanl),
+ * see ECDSA_sign_setup
+ * \param eckey EC_KEY object containing a private EC key
+ * \return 1 on success and 0 otherwise
+ */
+int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen,
+ unsigned char *sig, unsigned int *siglen,
+ const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);
+
+/** Verifies that the given signature is valid ECDSA signature
+ * of the supplied hash value using the specified public key.
+ * \param type this parameter is ignored
+ * \param dgst pointer to the hash value
+ * \param dgstlen length of the hash value
+ * \param sig pointer to the DER encoded signature
+ * \param siglen length of the DER encoded signature
+ * \param eckey EC_KEY object containing a public EC key
+ * \return 1 if the signature is valid, 0 if the signature is invalid
+ * and -1 on error
+ */
+int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen,
+ const unsigned char *sig, int siglen, EC_KEY *eckey);
+
+/* the standard ex_data functions */
+int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new
+ *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func);
+int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
+void *ECDSA_get_ex_data(EC_KEY *d, int idx);
+
+/* 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.
+ */
+void ERR_load_ECDSA_strings(void);
+
+/* Error codes for the ECDSA functions. */
+
+/* Function codes. */
+# define ECDSA_F_ECDSA_CHECK 104
+# define ECDSA_F_ECDSA_DATA_NEW_METHOD 100
+# define ECDSA_F_ECDSA_DO_SIGN 101
+# define ECDSA_F_ECDSA_DO_VERIFY 102
+# define ECDSA_F_ECDSA_SIGN_SETUP 103
+
+/* Reason codes. */
+# define ECDSA_R_BAD_SIGNATURE 100
+# define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 101
+# define ECDSA_R_ERR_EC_LIB 102
+# define ECDSA_R_MISSING_PARAMETERS 103
+# define ECDSA_R_NEED_NEW_SETUP_VALUES 106
+# define ECDSA_R_NON_FIPS_METHOD 107
+# define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104
+# define ECDSA_R_SIGNATURE_MALLOC_FAILED 105
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/ecdsa/ecdsatest.c b/openssl/ecdsa/ecdsatest.c
new file mode 100644
index 0000000..b2d78f3
--- /dev/null
+++ b/openssl/ecdsa/ecdsatest.c
@@ -0,0 +1,556 @@
+/* crypto/ecdsa/ecdsatest.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 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).
+ *
+ */
+/* ====================================================================
+ * 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.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_ECDSA is defined */
+
+#ifdef OPENSSL_NO_ECDSA
+int main(int argc, char *argv[])
+{
+ puts("Elliptic curves are disabled.");
+ return 0;
+}
+#else
+
+# include <openssl/crypto.h>
+# include <openssl/bio.h>
+# include <openssl/evp.h>
+# include <openssl/bn.h>
+# include <openssl/ecdsa.h>
+# ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+# endif
+# include <openssl/err.h>
+# include <openssl/rand.h>
+
+static const char rnd_seed[] = "string to make the random number generator "
+ "think it has entropy";
+
+/* declaration of the test functions */
+int x9_62_tests(BIO *);
+int x9_62_test_internal(BIO *out, int nid, const char *r, const char *s);
+int test_builtin(BIO *);
+
+/* functions to change the RAND_METHOD */
+int change_rand(void);
+int restore_rand(void);
+int fbytes(unsigned char *buf, int num);
+
+RAND_METHOD fake_rand;
+const RAND_METHOD *old_rand;
+
+int change_rand(void)
+{
+ /* save old rand method */
+ if ((old_rand = RAND_get_rand_method()) == NULL)
+ return 0;
+
+ fake_rand.seed = old_rand->seed;
+ fake_rand.cleanup = old_rand->cleanup;
+ fake_rand.add = old_rand->add;
+ fake_rand.status = old_rand->status;
+ /* use own random function */
+ fake_rand.bytes = fbytes;
+ fake_rand.pseudorand = old_rand->bytes;
+ /* set new RAND_METHOD */
+ if (!RAND_set_rand_method(&fake_rand))
+ return 0;
+ return 1;
+}
+
+int restore_rand(void)
+{
+ if (!RAND_set_rand_method(old_rand))
+ return 0;
+ else
+ return 1;
+}
+
+static int fbytes_counter = 0;
+static const char *numbers[8] = {
+ "651056770906015076056810763456358567190100156695615665659",
+ "6140507067065001063065065565667405560006161556565665656654",
+ "8763001015071075675010661307616710783570106710677817767166"
+ "71676178726717",
+ "7000000175690566466555057817571571075705015757757057795755"
+ "55657156756655",
+ "1275552191113212300012030439187146164646146646466749494799",
+ "1542725565216523985789236956265265265235675811949404040041",
+ "1456427555219115346513212300075341203043918714616464614664"
+ "64667494947990",
+ "1712787255652165239672857892369562652652652356758119494040"
+ "40041670216363"
+};
+
+int fbytes(unsigned char *buf, int num)
+{
+ int ret;
+ BIGNUM *tmp = NULL;
+
+ if (fbytes_counter >= 8)
+ return 0;
+ tmp = BN_new();
+ if (!tmp)
+ return 0;
+ if (!BN_dec2bn(&tmp, numbers[fbytes_counter])) {
+ BN_free(tmp);
+ return 0;
+ }
+ fbytes_counter++;
+ if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf))
+ ret = 0;
+ else
+ ret = 1;
+ if (tmp)
+ BN_free(tmp);
+ return ret;
+}
+
+/* some tests from the X9.62 draft */
+int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
+{
+ int ret = 0;
+ const char message[] = "abc";
+ unsigned char digest[20];
+ unsigned int dgst_len = 0;
+ EVP_MD_CTX md_ctx;
+ EC_KEY *key = NULL;
+ ECDSA_SIG *signature = NULL;
+ BIGNUM *r = NULL, *s = NULL;
+
+ EVP_MD_CTX_init(&md_ctx);
+ /* get the message digest */
+ EVP_DigestInit(&md_ctx, EVP_ecdsa());
+ EVP_DigestUpdate(&md_ctx, (const void *)message, 3);
+ EVP_DigestFinal(&md_ctx, digest, &dgst_len);
+
+ BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid));
+ /* create the key */
+ if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
+ goto x962_int_err;
+ if (!EC_KEY_generate_key(key))
+ goto x962_int_err;
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* create the signature */
+ signature = ECDSA_do_sign(digest, 20, key);
+ if (signature == NULL)
+ goto x962_int_err;
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* compare the created signature with the expected signature */
+ if ((r = BN_new()) == NULL || (s = BN_new()) == NULL)
+ goto x962_int_err;
+ if (!BN_dec2bn(&r, r_in) || !BN_dec2bn(&s, s_in))
+ goto x962_int_err;
+ if (BN_cmp(signature->r, r) || BN_cmp(signature->s, s))
+ goto x962_int_err;
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* verify the signature */
+ if (ECDSA_do_verify(digest, 20, signature, key) != 1)
+ goto x962_int_err;
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+
+ BIO_printf(out, " ok\n");
+ ret = 1;
+ x962_int_err:
+ if (!ret)
+ BIO_printf(out, " failed\n");
+ if (key)
+ EC_KEY_free(key);
+ if (signature)
+ ECDSA_SIG_free(signature);
+ if (r)
+ BN_free(r);
+ if (s)
+ BN_free(s);
+ EVP_MD_CTX_cleanup(&md_ctx);
+ return ret;
+}
+
+int x9_62_tests(BIO *out)
+{
+ int ret = 0;
+
+ BIO_printf(out, "some tests from X9.62:\n");
+
+ /* set own rand method */
+ if (!change_rand())
+ goto x962_err;
+
+ if (!x9_62_test_internal(out, NID_X9_62_prime192v1,
+ "3342403536405981729393488334694600415596881826869351677613",
+ "5735822328888155254683894997897571951568553642892029982342"))
+ goto x962_err;
+ if (!x9_62_test_internal(out, NID_X9_62_prime239v1,
+ "3086361431751678114926225473006680188549593787585317781474"
+ "62058306432176",
+ "3238135532097973577080787768312505059318910517550078427819"
+ "78505179448783"))
+ goto x962_err;
+# ifndef OPENSSL_NO_EC2M
+ if (!x9_62_test_internal(out, NID_X9_62_c2tnb191v1,
+ "87194383164871543355722284926904419997237591535066528048",
+ "308992691965804947361541664549085895292153777025772063598"))
+ goto x962_err;
+ if (!x9_62_test_internal(out, NID_X9_62_c2tnb239v1,
+ "2159633321041961198501834003903461262881815148684178964245"
+ "5876922391552",
+ "1970303740007316867383349976549972270528498040721988191026"
+ "49413465737174"))
+ goto x962_err;
+# endif
+ ret = 1;
+ x962_err:
+ if (!restore_rand())
+ ret = 0;
+ return ret;
+}
+
+int test_builtin(BIO *out)
+{
+ EC_builtin_curve *curves = NULL;
+ size_t crv_len = 0, n = 0;
+ EC_KEY *eckey = NULL, *wrong_eckey = NULL;
+ EC_GROUP *group;
+ ECDSA_SIG *ecdsa_sig = NULL;
+ unsigned char digest[20], wrong_digest[20];
+ unsigned char *signature = NULL;
+ const unsigned char *sig_ptr;
+ unsigned char *sig_ptr2;
+ unsigned char *raw_buf = NULL;
+ unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len;
+ int nid, ret = 0;
+
+ /* fill digest values with some random data */
+ if (!RAND_pseudo_bytes(digest, 20) ||
+ !RAND_pseudo_bytes(wrong_digest, 20)) {
+ BIO_printf(out, "ERROR: unable to get random data\n");
+ goto builtin_err;
+ }
+
+ /*
+ * create and verify a ecdsa signature with every availble curve (with )
+ */
+ BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() "
+ "with some internal curves:\n");
+
+ /* get a list of all internal curves */
+ crv_len = EC_get_builtin_curves(NULL, 0);
+
+ curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len);
+
+ if (curves == NULL) {
+ BIO_printf(out, "malloc error\n");
+ goto builtin_err;
+ }
+
+ if (!EC_get_builtin_curves(curves, crv_len)) {
+ BIO_printf(out, "unable to get internal curves\n");
+ goto builtin_err;
+ }
+
+ /* now create and verify a signature for every curve */
+ for (n = 0; n < crv_len; n++) {
+ unsigned char dirt, offset;
+
+ nid = curves[n].nid;
+ if (nid == NID_ipsec4)
+ continue;
+ /* create new ecdsa key (== EC_KEY) */
+ if ((eckey = EC_KEY_new()) == NULL)
+ goto builtin_err;
+ group = EC_GROUP_new_by_curve_name(nid);
+ if (group == NULL)
+ goto builtin_err;
+ if (EC_KEY_set_group(eckey, group) == 0)
+ goto builtin_err;
+ EC_GROUP_free(group);
+ degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
+ if (degree < 160)
+ /* drop the curve */
+ {
+ EC_KEY_free(eckey);
+ eckey = NULL;
+ continue;
+ }
+ BIO_printf(out, "%s: ", OBJ_nid2sn(nid));
+ /* create key */
+ if (!EC_KEY_generate_key(eckey)) {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ /* create second key */
+ if ((wrong_eckey = EC_KEY_new()) == NULL)
+ goto builtin_err;
+ group = EC_GROUP_new_by_curve_name(nid);
+ if (group == NULL)
+ goto builtin_err;
+ if (EC_KEY_set_group(wrong_eckey, group) == 0)
+ goto builtin_err;
+ EC_GROUP_free(group);
+ if (!EC_KEY_generate_key(wrong_eckey)) {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* check key */
+ if (!EC_KEY_check_key(eckey)) {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* create signature */
+ sig_len = ECDSA_size(eckey);
+ if ((signature = OPENSSL_malloc(sig_len)) == NULL)
+ goto builtin_err;
+ if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* verify signature */
+ if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* verify signature with the wrong key */
+ if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* wrong digest */
+ if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+ /* wrong length */
+ if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+
+ /*
+ * Modify a single byte of the signature: to ensure we don't garble
+ * the ASN1 structure, we read the raw signature and modify a byte in
+ * one of the bignums directly.
+ */
+ sig_ptr = signature;
+ if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL) {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+
+ /* Store the two BIGNUMs in raw_buf. */
+ r_len = BN_num_bytes(ecdsa_sig->r);
+ s_len = BN_num_bytes(ecdsa_sig->s);
+ bn_len = (degree + 7) / 8;
+ if ((r_len > bn_len) || (s_len > bn_len)) {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ buf_len = 2 * bn_len;
+ if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL)
+ goto builtin_err;
+ /* Pad the bignums with leading zeroes. */
+ memset(raw_buf, 0, buf_len);
+ BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len);
+ BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len);
+
+ /* Modify a single byte in the buffer. */
+ offset = raw_buf[10] % buf_len;
+ dirt = raw_buf[11] ? raw_buf[11] : 1;
+ raw_buf[offset] ^= dirt;
+ /* Now read the BIGNUMs back in from raw_buf. */
+ if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
+ (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
+ goto builtin_err;
+
+ sig_ptr2 = signature;
+ sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
+ if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ /*
+ * Sanity check: undo the modification and verify signature.
+ */
+ raw_buf[offset] ^= dirt;
+ if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
+ (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
+ goto builtin_err;
+
+ sig_ptr2 = signature;
+ sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
+ if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+
+ BIO_printf(out, " ok\n");
+ /* cleanup */
+ /* clean bogus errors */
+ ERR_clear_error();
+ OPENSSL_free(signature);
+ signature = NULL;
+ EC_KEY_free(eckey);
+ eckey = NULL;
+ EC_KEY_free(wrong_eckey);
+ wrong_eckey = NULL;
+ ECDSA_SIG_free(ecdsa_sig);
+ ecdsa_sig = NULL;
+ OPENSSL_free(raw_buf);
+ raw_buf = NULL;
+ }
+
+ ret = 1;
+ builtin_err:
+ if (eckey)
+ EC_KEY_free(eckey);
+ if (wrong_eckey)
+ EC_KEY_free(wrong_eckey);
+ if (ecdsa_sig)
+ ECDSA_SIG_free(ecdsa_sig);
+ if (signature)
+ OPENSSL_free(signature);
+ if (raw_buf)
+ OPENSSL_free(raw_buf);
+ if (curves)
+ OPENSSL_free(curves);
+
+ return ret;
+}
+
+int main(void)
+{
+ int ret = 1;
+ BIO *out;
+
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+
+ /* enable memory leak checking unless explicitly disabled */
+ if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) &&
+ (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) {
+ CRYPTO_malloc_debug_init();
+ CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
+ } else {
+ /* OPENSSL_DEBUG_MEMORY=off */
+ CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
+ }
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+ ERR_load_crypto_strings();
+
+ /* initialize the prng */
+ RAND_seed(rnd_seed, sizeof(rnd_seed));
+
+ /* the tests */
+ if (!x9_62_tests(out))
+ goto err;
+ if (!test_builtin(out))
+ goto err;
+
+ ret = 0;
+ err:
+ if (ret)
+ BIO_printf(out, "\nECDSA test failed\n");
+ else
+ BIO_printf(out, "\nECDSA test passed\n");
+ if (ret)
+ ERR_print_errors(out);
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_thread_state(NULL);
+ ERR_free_strings();
+ CRYPTO_mem_leaks(out);
+ if (out != NULL)
+ BIO_free(out);
+ return ret;
+}
+#endif
diff --git a/openssl/ecdsa/ecs_asn1.c b/openssl/ecdsa/ecs_asn1.c
new file mode 100644
index 0000000..508b079
--- /dev/null
+++ b/openssl/ecdsa/ecs_asn1.c
@@ -0,0 +1,67 @@
+/* crypto/ecdsa/ecs_asn1.c */
+/* ====================================================================
+ * 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
+ * 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 "ecs_locl.h"
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+
+ASN1_SEQUENCE(ECDSA_SIG) = {
+ ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
+ ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM)
+} ASN1_SEQUENCE_END(ECDSA_SIG)
+
+DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG)
+IMPLEMENT_ASN1_FUNCTIONS_const(ECDSA_SIG)
diff --git a/openssl/ecdsa/ecs_err.c b/openssl/ecdsa/ecs_err.c
new file mode 100644
index 0000000..6fc64a0
--- /dev/null
+++ b/openssl/ecdsa/ecs_err.c
@@ -0,0 +1,106 @@
+/* crypto/ecdsa/ecs_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2011 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).
+ *
+ */
+
+/*
+ * NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ecdsa.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDSA,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDSA,0,reason)
+
+static ERR_STRING_DATA ECDSA_str_functs[] = {
+ {ERR_FUNC(ECDSA_F_ECDSA_CHECK), "ECDSA_CHECK"},
+ {ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD), "ECDSA_DATA_NEW_METHOD"},
+ {ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN), "ECDSA_do_sign"},
+ {ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"},
+ {ERR_FUNC(ECDSA_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA ECDSA_str_reasons[] = {
+ {ERR_REASON(ECDSA_R_BAD_SIGNATURE), "bad signature"},
+ {ERR_REASON(ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),
+ "data too large for key size"},
+ {ERR_REASON(ECDSA_R_ERR_EC_LIB), "err ec lib"},
+ {ERR_REASON(ECDSA_R_MISSING_PARAMETERS), "missing parameters"},
+ {ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES), "need new setup values"},
+ {ERR_REASON(ECDSA_R_NON_FIPS_METHOD), "non fips method"},
+ {ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED),
+ "random number generation failed"},
+ {ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED), "signature malloc failed"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_ECDSA_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(ECDSA_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, ECDSA_str_functs);
+ ERR_load_strings(0, ECDSA_str_reasons);
+ }
+#endif
+}
diff --git a/openssl/ecdsa/ecs_lib.c b/openssl/ecdsa/ecs_lib.c
new file mode 100644
index 0000000..0f2d343
--- /dev/null
+++ b/openssl/ecdsa/ecs_lib.c
@@ -0,0 +1,277 @@
+/* crypto/ecdsa/ecs_lib.c */
+/* ====================================================================
+ * Copyright (c) 1998-2005 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 <string.h>
+#include "ecs_locl.h"
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+const char ECDSA_version[] = "ECDSA" OPENSSL_VERSION_PTEXT;
+
+static const ECDSA_METHOD *default_ECDSA_method = NULL;
+
+static void *ecdsa_data_new(void);
+static void *ecdsa_data_dup(void *);
+static void ecdsa_data_free(void *);
+
+void ECDSA_set_default_method(const ECDSA_METHOD *meth)
+{
+ default_ECDSA_method = meth;
+}
+
+const ECDSA_METHOD *ECDSA_get_default_method(void)
+{
+ if (!default_ECDSA_method) {
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_ecdsa_openssl();
+ else
+ return ECDSA_OpenSSL();
+#else
+ default_ECDSA_method = ECDSA_OpenSSL();
+#endif
+ }
+ return default_ECDSA_method;
+}
+
+int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth)
+{
+ ECDSA_DATA *ecdsa;
+
+ ecdsa = ecdsa_check(eckey);
+
+ if (ecdsa == NULL)
+ return 0;
+
+#ifndef OPENSSL_NO_ENGINE
+ if (ecdsa->engine) {
+ ENGINE_finish(ecdsa->engine);
+ ecdsa->engine = NULL;
+ }
+#endif
+ ecdsa->meth = meth;
+
+ return 1;
+}
+
+static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine)
+{
+ ECDSA_DATA *ret;
+
+ ret = (ECDSA_DATA *)OPENSSL_malloc(sizeof(ECDSA_DATA));
+ if (ret == NULL) {
+ ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+ return (NULL);
+ }
+
+ ret->init = NULL;
+
+ ret->meth = ECDSA_get_default_method();
+ ret->engine = engine;
+#ifndef OPENSSL_NO_ENGINE
+ if (!ret->engine)
+ ret->engine = ENGINE_get_default_ECDSA();
+ if (ret->engine) {
+ ret->meth = ENGINE_get_ECDSA(ret->engine);
+ if (!ret->meth) {
+ ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_ENGINE_LIB);
+ ENGINE_finish(ret->engine);
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ }
+#endif
+
+ ret->flags = ret->meth->flags;
+ CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
+#if 0
+ if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
+ OPENSSL_free(ret);
+ ret = NULL;
+ }
+#endif
+ return (ret);
+}
+
+static void *ecdsa_data_new(void)
+{
+ return (void *)ECDSA_DATA_new_method(NULL);
+}
+
+static void *ecdsa_data_dup(void *data)
+{
+ ECDSA_DATA *r = (ECDSA_DATA *)data;
+
+ /* XXX: dummy operation */
+ if (r == NULL)
+ return NULL;
+
+ return ecdsa_data_new();
+}
+
+static void ecdsa_data_free(void *data)
+{
+ ECDSA_DATA *r = (ECDSA_DATA *)data;
+
+#ifndef OPENSSL_NO_ENGINE
+ if (r->engine)
+ ENGINE_finish(r->engine);
+#endif
+ CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data);
+
+ OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA));
+
+ OPENSSL_free(r);
+}
+
+ECDSA_DATA *ecdsa_check(EC_KEY *key)
+{
+ ECDSA_DATA *ecdsa_data;
+
+ void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup,
+ ecdsa_data_free, ecdsa_data_free);
+ if (data == NULL) {
+ ecdsa_data = (ECDSA_DATA *)ecdsa_data_new();
+ if (ecdsa_data == NULL)
+ return NULL;
+ data = EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
+ ecdsa_data_dup, ecdsa_data_free,
+ ecdsa_data_free);
+ if (data != NULL) {
+ /*
+ * Another thread raced us to install the key_method data and
+ * won.
+ */
+ ecdsa_data_free(ecdsa_data);
+ ecdsa_data = (ECDSA_DATA *)data;
+ }
+ } else
+ ecdsa_data = (ECDSA_DATA *)data;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode() && !(ecdsa_data->flags & ECDSA_FLAG_FIPS_METHOD)
+ && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) {
+ ECDSAerr(ECDSA_F_ECDSA_CHECK, ECDSA_R_NON_FIPS_METHOD);
+ return NULL;
+ }
+#endif
+
+ return ecdsa_data;
+}
+
+int ECDSA_size(const EC_KEY *r)
+{
+ int ret, i;
+ ASN1_INTEGER bs;
+ BIGNUM *order = NULL;
+ unsigned char buf[4];
+ const EC_GROUP *group;
+
+ if (r == NULL)
+ return 0;
+ group = EC_KEY_get0_group(r);
+ if (group == NULL)
+ return 0;
+
+ if ((order = BN_new()) == NULL)
+ return 0;
+ if (!EC_GROUP_get_order(group, order, NULL)) {
+ BN_clear_free(order);
+ return 0;
+ }
+ i = BN_num_bits(order);
+ bs.length = (i + 7) / 8;
+ bs.data = buf;
+ bs.type = V_ASN1_INTEGER;
+ /* If the top bit is set the asn1 encoding is 1 larger. */
+ buf[0] = 0xff;
+
+ i = i2d_ASN1_INTEGER(&bs, NULL);
+ i += i; /* r and s */
+ ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
+ BN_clear_free(order);
+ return (ret);
+}
+
+int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+{
+ return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp,
+ new_func, dup_func, free_func);
+}
+
+int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg)
+{
+ ECDSA_DATA *ecdsa;
+ ecdsa = ecdsa_check(d);
+ if (ecdsa == NULL)
+ return 0;
+ return (CRYPTO_set_ex_data(&ecdsa->ex_data, idx, arg));
+}
+
+void *ECDSA_get_ex_data(EC_KEY *d, int idx)
+{
+ ECDSA_DATA *ecdsa;
+ ecdsa = ecdsa_check(d);
+ if (ecdsa == NULL)
+ return NULL;
+ return (CRYPTO_get_ex_data(&ecdsa->ex_data, idx));
+}
diff --git a/openssl/ecdsa/ecs_locl.h b/openssl/ecdsa/ecs_locl.h
new file mode 100644
index 0000000..76b2caf
--- /dev/null
+++ b/openssl/ecdsa/ecs_locl.h
@@ -0,0 +1,116 @@
+/* crypto/ecdsa/ecs_locl.h */
+/*
+ * Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2005 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).
+ *
+ */
+
+#ifndef HEADER_ECS_LOCL_H
+# define HEADER_ECS_LOCL_H
+
+# include <openssl/ecdsa.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ecdsa_method {
+ const char *name;
+ ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char *dgst, int dgst_len,
+ const BIGNUM *inv, const BIGNUM *rp,
+ EC_KEY *eckey);
+ int (*ecdsa_sign_setup) (EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
+ BIGNUM **r);
+ int (*ecdsa_do_verify) (const unsigned char *dgst, int dgst_len,
+ const ECDSA_SIG *sig, EC_KEY *eckey);
+# if 0
+ int (*init) (EC_KEY *eckey);
+ int (*finish) (EC_KEY *eckey);
+# endif
+ int flags;
+ char *app_data;
+};
+
+/*
+ * If this flag is set the ECDSA method is FIPS compliant and can be used in
+ * FIPS mode. This is set in the validated module method. If an application
+ * sets this flag in its own methods it is its responsibility to ensure the
+ * result is compliant.
+ */
+
+# define ECDSA_FLAG_FIPS_METHOD 0x1
+
+typedef struct ecdsa_data_st {
+ /* EC_KEY_METH_DATA part */
+ int (*init) (EC_KEY *);
+ /* method (ECDSA) specific part */
+ ENGINE *engine;
+ int flags;
+ const ECDSA_METHOD *meth;
+ CRYPTO_EX_DATA ex_data;
+} ECDSA_DATA;
+
+/** ecdsa_check
+ * checks whether ECKEY->meth_data is a pointer to a ECDSA_DATA structure
+ * and if not it removes the old meth_data and creates a ECDSA_DATA structure.
+ * \param eckey pointer to a EC_KEY object
+ * \return pointer to a ECDSA_DATA structure
+ */
+ECDSA_DATA *ecdsa_check(EC_KEY *eckey);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HEADER_ECS_LOCL_H */
diff --git a/openssl/ecdsa/ecs_ossl.c b/openssl/ecdsa/ecs_ossl.c
new file mode 100644
index 0000000..4c5fa6b
--- /dev/null
+++ b/openssl/ecdsa/ecs_ossl.c
@@ -0,0 +1,442 @@
+/* crypto/ecdsa/ecs_ossl.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2004 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 "ecs_locl.h"
+#include <openssl/err.h>
+#include <openssl/obj_mac.h>
+#include <openssl/bn.h>
+
+static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen,
+ const BIGNUM *, const BIGNUM *,
+ EC_KEY *eckey);
+static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+ BIGNUM **rp);
+static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
+ const ECDSA_SIG *sig, EC_KEY *eckey);
+
+static ECDSA_METHOD openssl_ecdsa_meth = {
+ "OpenSSL ECDSA method",
+ ecdsa_do_sign,
+ ecdsa_sign_setup,
+ ecdsa_do_verify,
+#if 0
+ NULL, /* init */
+ NULL, /* finish */
+#endif
+ 0, /* flags */
+ NULL /* app_data */
+};
+
+const ECDSA_METHOD *ECDSA_OpenSSL(void)
+{
+ return &openssl_ecdsa_meth;
+}
+
+static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+ BIGNUM **rp)
+{
+ BN_CTX *ctx = NULL;
+ BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
+ EC_POINT *tmp_point = NULL;
+ const EC_GROUP *group;
+ int ret = 0;
+
+ if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if (ctx_in == NULL) {
+ if ((ctx = BN_CTX_new()) == NULL) {
+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ } else
+ ctx = ctx_in;
+
+ k = BN_new(); /* this value is later returned in *kinvp */
+ r = BN_new(); /* this value is later returned in *rp */
+ order = BN_new();
+ X = BN_new();
+ if (!k || !r || !order || !X) {
+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if ((tmp_point = EC_POINT_new(group)) == NULL) {
+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+ goto err;
+ }
+ if (!EC_GROUP_get_order(group, order, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ do {
+ /* get random k */
+ do
+ if (!BN_rand_range(k, order)) {
+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
+ ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
+ goto err;
+ }
+ while (BN_is_zero(k)) ;
+
+ /*
+ * We do not want timing information to leak the length of k, so we
+ * compute G*k using an equivalent scalar of fixed bit-length.
+ */
+
+ if (!BN_add(k, k, order))
+ goto err;
+ if (BN_num_bits(k) <= BN_num_bits(order))
+ if (!BN_add(k, k, order))
+ goto err;
+
+ /* compute r the x-coordinate of generator * k */
+ if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+ goto err;
+ }
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
+ NID_X9_62_prime_field) {
+ if (!EC_POINT_get_affine_coordinates_GFp
+ (group, tmp_point, X, NULL, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+#ifndef OPENSSL_NO_EC2M
+ else { /* NID_X9_62_characteristic_two_field */
+
+ if (!EC_POINT_get_affine_coordinates_GF2m(group,
+ tmp_point, X, NULL,
+ ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+#endif
+ if (!BN_nnmod(r, X, order, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+ goto err;
+ }
+ }
+ while (BN_is_zero(r));
+
+ /* compute the inverse of k */
+ if (!BN_mod_inverse(k, k, order, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+ goto err;
+ }
+ /* clear old values if necessary */
+ if (*rp != NULL)
+ BN_clear_free(*rp);
+ if (*kinvp != NULL)
+ BN_clear_free(*kinvp);
+ /* save the pre-computed values */
+ *rp = r;
+ *kinvp = k;
+ ret = 1;
+ err:
+ if (!ret) {
+ if (k != NULL)
+ BN_clear_free(k);
+ if (r != NULL)
+ BN_clear_free(r);
+ }
+ if (ctx_in == NULL)
+ BN_CTX_free(ctx);
+ if (order != NULL)
+ BN_free(order);
+ if (tmp_point != NULL)
+ EC_POINT_free(tmp_point);
+ if (X)
+ BN_clear_free(X);
+ return (ret);
+}
+
+static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
+ const BIGNUM *in_kinv, const BIGNUM *in_r,
+ EC_KEY *eckey)
+{
+ int ok = 0, i;
+ BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL;
+ const BIGNUM *ckinv;
+ BN_CTX *ctx = NULL;
+ const EC_GROUP *group;
+ ECDSA_SIG *ret;
+ ECDSA_DATA *ecdsa;
+ const BIGNUM *priv_key;
+
+ ecdsa = ecdsa_check(eckey);
+ group = EC_KEY_get0_group(eckey);
+ priv_key = EC_KEY_get0_private_key(eckey);
+
+ if (group == NULL || priv_key == NULL || ecdsa == NULL) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+
+ ret = ECDSA_SIG_new();
+ if (!ret) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ s = ret->s;
+
+ if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
+ (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!EC_GROUP_get_order(group, order, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
+ goto err;
+ }
+ i = BN_num_bits(order);
+ /*
+ * Need to truncate digest if it is too long: first truncate whole bytes.
+ */
+ if (8 * dgst_len > i)
+ dgst_len = (i + 7) / 8;
+ if (!BN_bin2bn(dgst, dgst_len, m)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+ goto err;
+ }
+ /* If still too long truncate remaining bits with a shift */
+ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+ goto err;
+ }
+ do {
+ if (in_kinv == NULL || in_r == NULL) {
+ if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_ECDSA_LIB);
+ goto err;
+ }
+ ckinv = kinv;
+ } else {
+ ckinv = in_kinv;
+ if (BN_copy(ret->r, in_r) == NULL) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+ goto err;
+ }
+ if (!BN_mod_add_quick(s, tmp, m, order)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+ goto err;
+ }
+ if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
+ goto err;
+ }
+ if (BN_is_zero(s)) {
+ /*
+ * if kinv and r have been supplied by the caller don't to
+ * generate new kinv and r values
+ */
+ if (in_kinv != NULL && in_r != NULL) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,
+ ECDSA_R_NEED_NEW_SETUP_VALUES);
+ goto err;
+ }
+ } else
+ /* s != 0 => we have a valid signature */
+ break;
+ }
+ while (1);
+
+ ok = 1;
+ err:
+ if (!ok) {
+ ECDSA_SIG_free(ret);
+ ret = NULL;
+ }
+ if (ctx)
+ BN_CTX_free(ctx);
+ if (m)
+ BN_clear_free(m);
+ if (tmp)
+ BN_clear_free(tmp);
+ if (order)
+ BN_free(order);
+ if (kinv)
+ BN_clear_free(kinv);
+ return ret;
+}
+
+static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
+ const ECDSA_SIG *sig, EC_KEY *eckey)
+{
+ int ret = -1, i;
+ BN_CTX *ctx;
+ BIGNUM *order, *u1, *u2, *m, *X;
+ EC_POINT *point = NULL;
+ const EC_GROUP *group;
+ const EC_POINT *pub_key;
+
+ /* check input values */
+ if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
+ (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
+ return -1;
+ }
+
+ ctx = BN_CTX_new();
+ if (!ctx) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ BN_CTX_start(ctx);
+ order = BN_CTX_get(ctx);
+ u1 = BN_CTX_get(ctx);
+ u2 = BN_CTX_get(ctx);
+ m = BN_CTX_get(ctx);
+ X = BN_CTX_get(ctx);
+ if (!X) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ if (!EC_GROUP_get_order(group, order, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
+ BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
+ BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
+ ret = 0; /* signature is invalid */
+ goto err;
+ }
+ /* calculate tmp1 = inv(S) mod order */
+ if (!BN_mod_inverse(u2, sig->s, order, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+ goto err;
+ }
+ /* digest -> m */
+ i = BN_num_bits(order);
+ /*
+ * Need to truncate digest if it is too long: first truncate whole bytes.
+ */
+ if (8 * dgst_len > i)
+ dgst_len = (i + 7) / 8;
+ if (!BN_bin2bn(dgst, dgst_len, m)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+ goto err;
+ }
+ /* If still too long truncate remaining bits with a shift */
+ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+ goto err;
+ }
+ /* u1 = m * tmp mod order */
+ if (!BN_mod_mul(u1, m, u2, order, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+ goto err;
+ }
+ /* u2 = r * w mod q */
+ if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ if ((point = EC_POINT_new(group)) == NULL) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
+ goto err;
+ }
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
+ NID_X9_62_prime_field) {
+ if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+#ifndef OPENSSL_NO_EC2M
+ else { /* NID_X9_62_characteristic_two_field */
+
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, point, X, NULL, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+#endif
+ if (!BN_nnmod(u1, X, order, ctx)) {
+ ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
+ goto err;
+ }
+ /* if the signature is correct u1 is equal to sig->r */
+ ret = (BN_ucmp(u1, sig->r) == 0);
+ err:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ if (point)
+ EC_POINT_free(point);
+ return ret;
+}
diff --git a/openssl/ecdsa/ecs_sign.c b/openssl/ecdsa/ecs_sign.c
new file mode 100644
index 0000000..28652d4
--- /dev/null
+++ b/openssl/ecdsa/ecs_sign.c
@@ -0,0 +1,106 @@
+/* crypto/ecdsa/ecdsa_sign.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).
+ *
+ */
+
+#include "ecs_locl.h"
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+#include <openssl/rand.h>
+
+ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
+{
+ return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey);
+}
+
+ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen,
+ const BIGNUM *kinv, const BIGNUM *rp,
+ EC_KEY *eckey)
+{
+ ECDSA_DATA *ecdsa = ecdsa_check(eckey);
+ if (ecdsa == NULL)
+ return NULL;
+ return ecdsa->meth->ecdsa_do_sign(dgst, dlen, kinv, rp, eckey);
+}
+
+int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char
+ *sig, unsigned int *siglen, EC_KEY *eckey)
+{
+ return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey);
+}
+
+int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char
+ *sig, unsigned int *siglen, const BIGNUM *kinv,
+ const BIGNUM *r, EC_KEY *eckey)
+{
+ ECDSA_SIG *s;
+ RAND_seed(dgst, dlen);
+ s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
+ if (s == NULL) {
+ *siglen = 0;
+ return 0;
+ }
+ *siglen = i2d_ECDSA_SIG(s, &sig);
+ ECDSA_SIG_free(s);
+ return 1;
+}
+
+int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+ BIGNUM **rp)
+{
+ ECDSA_DATA *ecdsa = ecdsa_check(eckey);
+ if (ecdsa == NULL)
+ return 0;
+ return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp);
+}
diff --git a/openssl/ecdsa/ecs_vrf.c b/openssl/ecdsa/ecs_vrf.c
new file mode 100644
index 0000000..e909aeb
--- /dev/null
+++ b/openssl/ecdsa/ecs_vrf.c
@@ -0,0 +1,112 @@
+/* crypto/ecdsa/ecdsa_vrf.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).
+ *
+ */
+
+#include "ecs_locl.h"
+#include <string.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+/*-
+ * returns
+ * 1: correct signature
+ * 0: incorrect signature
+ * -1: error
+ */
+int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
+ const ECDSA_SIG *sig, EC_KEY *eckey)
+{
+ ECDSA_DATA *ecdsa = ecdsa_check(eckey);
+ if (ecdsa == NULL)
+ return 0;
+ return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey);
+}
+
+/*-
+ * returns
+ * 1: correct signature
+ * 0: incorrect signature
+ * -1: error
+ */
+int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
+ const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
+{
+ ECDSA_SIG *s;
+ const unsigned char *p = sigbuf;
+ unsigned char *der = NULL;
+ int derlen = -1;
+ int ret = -1;
+
+ s = ECDSA_SIG_new();
+ if (s == NULL)
+ return (ret);
+ if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
+ goto err;
+ /* Ensure signature uses DER and doesn't have trailing garbage */
+ derlen = i2d_ECDSA_SIG(s, &der);
+ if (derlen != sig_len || memcmp(sigbuf, der, derlen))
+ goto err;
+ ret = ECDSA_do_verify(dgst, dgst_len, s, eckey);
+ err:
+ if (derlen > 0) {
+ OPENSSL_cleanse(der, derlen);
+ OPENSSL_free(der);
+ }
+ ECDSA_SIG_free(s);
+ return (ret);
+}
diff --git a/openssl/emssl-custom/die.c b/openssl/emssl-custom/die.c
new file mode 100644
index 0000000..7426f8a
--- /dev/null
+++ b/openssl/emssl-custom/die.c
@@ -0,0 +1,23 @@
+/*
+ *
+ * Copyright (c) 2011-2015 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * This document is the property of Nest. It is considered
+ * confidential and proprietary information.
+ *
+ * This document may not be reproduced or transmitted in any form,
+ * in whole or in part, without the express written permission of
+ * Nest.
+ *
+ * Description:
+ * Custom implemenation of OpenSSL's OpenSSLDie function.
+ */
+
+#include "crypto.h"
+
+void OpenSSLDie(const char *file,int line,const char *assertion)
+{
+ while (1) ;
+}
+
diff --git a/openssl/emssl-custom/ecdsa_sig.c b/openssl/emssl-custom/ecdsa_sig.c
new file mode 100644
index 0000000..0a724ee
--- /dev/null
+++ b/openssl/emssl-custom/ecdsa_sig.c
@@ -0,0 +1,48 @@
+/*
+ *
+ * Copyright (c) 2011-2015 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * This document is the property of Nest. It is considered
+ * confidential and proprietary information.
+ *
+ * This document may not be reproduced or transmitted in any form,
+ * in whole or in part, without the express written permission of
+ * Nest.
+ *
+ * Description:
+ * Simplified implementation of OpenSSL's ECDSA_SIG functions.
+ *
+ * These avoid references to OpenSSL's ASN1 infrastructure, which is bloated
+ * and unnecessary in this context.
+ */
+
+#include <stdlib.h>
+
+#include <openssl/ecdsa.h>
+#include <openssl/bn.h>
+
+ECDSA_SIG *ECDSA_SIG_new(void)
+{
+ ECDSA_SIG *sig = (ECDSA_SIG *)CRYPTO_malloc(sizeof(ECDSA_SIG), __FILE__, __LINE__);
+
+ if (sig != NULL)
+ {
+ sig->r = BN_new();
+ sig->s = BN_new();
+ }
+
+ return sig;
+}
+
+void ECDSA_SIG_free(ECDSA_SIG *sig)
+{
+ if (sig != NULL)
+ {
+ BN_free(sig->r);
+ BN_free(sig->s);
+
+ CRYPTO_free(sig);
+ }
+}
+
diff --git a/openssl/emssl-custom/err.c b/openssl/emssl-custom/err.c
new file mode 100644
index 0000000..edc7430
--- /dev/null
+++ b/openssl/emssl-custom/err.c
@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright (c) 2011-2015 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * This document is the property of Nest. It is considered
+ * confidential and proprietary information.
+ *
+ * This document may not be reproduced or transmitted in any form,
+ * in whole or in part, without the express written permission of
+ * Nest.
+ *
+ * Description:
+ * Simplified implementation of OpenSSL's error handling functions
+ * that avoids dynamic memory allocation.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <openssl/err.h>
+
+static unsigned long sErrorStack[ERR_NUM_ERRORS];
+size_t sTop = 0;
+size_t sBottom = 0;
+
+unsigned long ERR_get_error(void)
+{
+ if (sTop == sBottom)
+ return 0;
+
+ unsigned long err = sErrorStack[sBottom++];
+ if (sBottom == ERR_NUM_ERRORS)
+ sBottom = 0;
+
+ return err;
+}
+
+unsigned long ERR_peek_error(void)
+{
+ if (sTop == sBottom)
+ return 0;
+ return sErrorStack[sBottom];
+}
+
+unsigned long ERR_peek_last_error(void)
+{
+ if (sTop == sBottom)
+ return 0;
+ size_t last = (sTop != 0) ? sTop - 1 : ERR_NUM_ERRORS - 1;
+ return sErrorStack[last];
+}
+
+void ERR_put_error(int lib, int func, int reason, const char *file, int line)
+{
+ sErrorStack[sTop++] = ERR_PACK(lib, func, reason);
+ if (sTop == ERR_NUM_ERRORS)
+ sTop = 0;
+ if (sTop == sBottom)
+ {
+ sBottom++;
+ if (sBottom == ERR_NUM_ERRORS)
+ sBottom = 0;
+ }
+}
+
+void ERR_clear_error(void)
+{
+ sTop = sBottom = 0;
+}
+
+void ERR_print_errors_fp(FILE *fp)
+{
+ unsigned long err;
+
+ while ((err = ERR_get_error()) != 0)
+ {
+ fprintf(fp, "Error %08lX (lib %d, func %d, reason %d)\n", err, ERR_GET_LIB(err), ERR_GET_FUNC(err),
+ ERR_GET_REASON(err));
+ }
+}
diff --git a/openssl/emssl-custom/mem.c b/openssl/emssl-custom/mem.c
new file mode 100644
index 0000000..e2a09a3
--- /dev/null
+++ b/openssl/emssl-custom/mem.c
@@ -0,0 +1,45 @@
+/*
+ *
+ * Copyright (c) 2011-2015 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * This document is the property of Nest. It is considered
+ * confidential and proprietary information.
+ *
+ * This document may not be reproduced or transmitted in any form,
+ * in whole or in part, without the express written permission of
+ * Nest.
+ *
+ * Description:
+ * Implementation of OpenSSL's memory allocation functions
+ * that maps onto the Pumise nlemalloc library.
+ */
+
+#include "stdlib.h"
+
+extern void *nlemalloc(size_t aNeeded);
+extern void *nlerealloc(void *aExisting, size_t aNeeded);
+extern void *nlecalloc(size_t aCount, size_t aNeeded);
+extern void nlefree(void *aToFree);
+extern char *nlestrdup(const char *aToCopy);
+
+void *CRYPTO_malloc(size_t needed)
+{
+ return nlemalloc(needed);
+}
+
+void *CRYPTO_realloc(void *existing, size_t needed)
+{
+ return nlerealloc(existing, needed);
+}
+
+void CRYPTO_free(void *tofree)
+{
+ nlefree(tofree);
+}
+
+char *CRYPTO_strdup(const char *s1)
+{
+ return nlestrdup(s1);
+}
+
diff --git a/openssl/emssl-custom/mem_clr.c b/openssl/emssl-custom/mem_clr.c
new file mode 100644
index 0000000..1166cba
--- /dev/null
+++ b/openssl/emssl-custom/mem_clr.c
@@ -0,0 +1,23 @@
+/*
+ *
+ * Copyright (c) 2011-2015 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * This document is the property of Nest. It is considered
+ * confidential and proprietary information.
+ *
+ * This document may not be reproduced or transmitted in any form,
+ * in whole or in part, without the express written permission of
+ * Nest.
+ *
+ * Description:
+ * Simplified implementation of OpenSSL's OPENSSL_cleanse function.
+ */
+
+#include <string.h>
+#include <openssl/crypto.h>
+
+void OPENSSL_cleanse(void *ptr, size_t len)
+{
+ memset(ptr, 0, len);
+}
diff --git a/openssl/emssl-custom/rand.c b/openssl/emssl-custom/rand.c
new file mode 100644
index 0000000..cb5b723
--- /dev/null
+++ b/openssl/emssl-custom/rand.c
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright (c) 2011-2015 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * This document is the property of Nest. It is considered
+ * confidential and proprietary information.
+ *
+ * This document may not be reproduced or transmitted in any form,
+ * in whole or in part, without the express written permission of
+ * Nest.
+ *
+ * Description:
+ * Custom implemenation of OpenSSL's random number API that maps
+ * these functions onto the system's random number source (gCTRDRBG_ctx),
+ * which is an instance of the PolarSSL AES_CTR DRBG fed by the
+ * hardware random number source.
+ */
+
+#include <rand.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+extern int GetSecureRandomData(unsigned char *, uint16_t);
+
+int RAND_bytes(unsigned char *buf, int num)
+{
+ int retval = 0, err;
+
+ err = GetSecureRandomData(buf, num);
+
+ if (err == 0)
+ {
+ retval = 1;
+ }else{
+ RANDerr(RAND_F_RAND_GET_RAND_METHOD, RAND_R_PRNG_ERROR);
+ }
+
+ return retval;
+}
+
+void RAND_add(const void *buf, int num, double entropy)
+{
+ /* Do nothing. This function is used to add additionaly entropy into the OpenSSL entropy pool.
+ * In the context of Pumice, all entropy comes from the system hardware RNG, making this
+ * function unnecessary.
+ */
+}
+
+int RAND_pseudo_bytes(unsigned char *buf, int num)
+{
+ return RAND_bytes(buf, num);
+}
+
diff --git a/openssl/err.h b/openssl/err.h
new file mode 120000
index 0000000..14299bd
--- /dev/null
+++ b/openssl/err.h
@@ -0,0 +1 @@
+err/err.h
\ No newline at end of file
diff --git a/openssl/err/err.h b/openssl/err/err.h
new file mode 100644
index 0000000..585aa8b
--- /dev/null
+++ b/openssl/err/err.h
@@ -0,0 +1,389 @@
+/* crypto/err/err.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 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 HEADER_ERR_H
+# define HEADER_ERR_H
+
+# include <openssl/e_os2.h>
+
+# ifndef OPENSSL_NO_FP_API
+# include <stdio.h>
+# include <stdlib.h>
+# endif
+
+# include <openssl/ossl_typ.h>
+# ifndef OPENSSL_NO_BIO
+# include <openssl/bio.h>
+# endif
+# ifndef OPENSSL_NO_LHASH
+# include <openssl/lhash.h>
+# endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# ifndef OPENSSL_NO_ERR
+# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,d,e)
+# else
+# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,NULL,0)
+# endif
+
+# include <errno.h>
+
+# define ERR_TXT_MALLOCED 0x01
+# define ERR_TXT_STRING 0x02
+
+# define ERR_FLAG_MARK 0x01
+
+# define ERR_NUM_ERRORS 16
+typedef struct err_state_st {
+ CRYPTO_THREADID tid;
+ int err_flags[ERR_NUM_ERRORS];
+ unsigned long err_buffer[ERR_NUM_ERRORS];
+ char *err_data[ERR_NUM_ERRORS];
+ int err_data_flags[ERR_NUM_ERRORS];
+ const char *err_file[ERR_NUM_ERRORS];
+ int err_line[ERR_NUM_ERRORS];
+ int top, bottom;
+} ERR_STATE;
+
+/* library */
+# define ERR_LIB_NONE 1
+# define ERR_LIB_SYS 2
+# define ERR_LIB_BN 3
+# define ERR_LIB_RSA 4
+# define ERR_LIB_DH 5
+# define ERR_LIB_EVP 6
+# define ERR_LIB_BUF 7
+# define ERR_LIB_OBJ 8
+# define ERR_LIB_PEM 9
+# define ERR_LIB_DSA 10
+# define ERR_LIB_X509 11
+/* #define ERR_LIB_METH 12 */
+# define ERR_LIB_ASN1 13
+# define ERR_LIB_CONF 14
+# define ERR_LIB_CRYPTO 15
+# define ERR_LIB_EC 16
+# define ERR_LIB_SSL 20
+/* #define ERR_LIB_SSL23 21 */
+/* #define ERR_LIB_SSL2 22 */
+/* #define ERR_LIB_SSL3 23 */
+/* #define ERR_LIB_RSAREF 30 */
+/* #define ERR_LIB_PROXY 31 */
+# define ERR_LIB_BIO 32
+# define ERR_LIB_PKCS7 33
+# define ERR_LIB_X509V3 34
+# define ERR_LIB_PKCS12 35
+# define ERR_LIB_RAND 36
+# define ERR_LIB_DSO 37
+# define ERR_LIB_ENGINE 38
+# define ERR_LIB_OCSP 39
+# define ERR_LIB_UI 40
+# define ERR_LIB_COMP 41
+# define ERR_LIB_ECDSA 42
+# define ERR_LIB_ECDH 43
+# define ERR_LIB_STORE 44
+# define ERR_LIB_FIPS 45
+# define ERR_LIB_CMS 46
+# define ERR_LIB_TS 47
+# define ERR_LIB_HMAC 48
+# define ERR_LIB_JPAKE 49
+
+# define ERR_LIB_USER 128
+
+# define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__)
+# define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__)
+# define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__)
+# define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__)
+# define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__)
+# define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__)
+# define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__)
+# define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__)
+# define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__)
+# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__)
+# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__)
+# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__)
+# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__)
+# define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__)
+# define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__)
+# define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__)
+# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__)
+# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__)
+# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__)
+# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__)
+# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__)
+# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__)
+# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__)
+# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__)
+# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__)
+# define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__)
+# define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__)
+# define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__)
+# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__)
+# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__)
+# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__)
+# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__)
+# define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__)
+
+/*
+ * Borland C seems too stupid to be able to shift and do longs in the
+ * pre-processor :-(
+ */
+# define ERR_PACK(l,f,r) (((((unsigned long)l)&0xffL)*0x1000000)| \
+ ((((unsigned long)f)&0xfffL)*0x1000)| \
+ ((((unsigned long)r)&0xfffL)))
+# define ERR_GET_LIB(l) (int)((((unsigned long)l)>>24L)&0xffL)
+# define ERR_GET_FUNC(l) (int)((((unsigned long)l)>>12L)&0xfffL)
+# define ERR_GET_REASON(l) (int)((l)&0xfffL)
+# define ERR_FATAL_ERROR(l) (int)((l)&ERR_R_FATAL)
+
+/* OS functions */
+# define SYS_F_FOPEN 1
+# define SYS_F_CONNECT 2
+# define SYS_F_GETSERVBYNAME 3
+# define SYS_F_SOCKET 4
+# define SYS_F_IOCTLSOCKET 5
+# define SYS_F_BIND 6
+# define SYS_F_LISTEN 7
+# define SYS_F_ACCEPT 8
+# define SYS_F_WSASTARTUP 9/* Winsock stuff */
+# define SYS_F_OPENDIR 10
+# define SYS_F_FREAD 11
+
+/* reasons */
+# define ERR_R_SYS_LIB ERR_LIB_SYS/* 2 */
+# define ERR_R_BN_LIB ERR_LIB_BN/* 3 */
+# define ERR_R_RSA_LIB ERR_LIB_RSA/* 4 */
+# define ERR_R_DH_LIB ERR_LIB_DH/* 5 */
+# define ERR_R_EVP_LIB ERR_LIB_EVP/* 6 */
+# define ERR_R_BUF_LIB ERR_LIB_BUF/* 7 */
+# define ERR_R_OBJ_LIB ERR_LIB_OBJ/* 8 */
+# define ERR_R_PEM_LIB ERR_LIB_PEM/* 9 */
+# define ERR_R_DSA_LIB ERR_LIB_DSA/* 10 */
+# define ERR_R_X509_LIB ERR_LIB_X509/* 11 */
+# define ERR_R_ASN1_LIB ERR_LIB_ASN1/* 13 */
+# define ERR_R_CONF_LIB ERR_LIB_CONF/* 14 */
+# define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO/* 15 */
+# define ERR_R_EC_LIB ERR_LIB_EC/* 16 */
+# define ERR_R_SSL_LIB ERR_LIB_SSL/* 20 */
+# define ERR_R_BIO_LIB ERR_LIB_BIO/* 32 */
+# define ERR_R_PKCS7_LIB ERR_LIB_PKCS7/* 33 */
+# define ERR_R_X509V3_LIB ERR_LIB_X509V3/* 34 */
+# define ERR_R_PKCS12_LIB ERR_LIB_PKCS12/* 35 */
+# define ERR_R_RAND_LIB ERR_LIB_RAND/* 36 */
+# define ERR_R_DSO_LIB ERR_LIB_DSO/* 37 */
+# define ERR_R_ENGINE_LIB ERR_LIB_ENGINE/* 38 */
+# define ERR_R_OCSP_LIB ERR_LIB_OCSP/* 39 */
+# define ERR_R_UI_LIB ERR_LIB_UI/* 40 */
+# define ERR_R_COMP_LIB ERR_LIB_COMP/* 41 */
+# define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */
+# define ERR_R_ECDH_LIB ERR_LIB_ECDH/* 43 */
+# define ERR_R_STORE_LIB ERR_LIB_STORE/* 44 */
+# define ERR_R_TS_LIB ERR_LIB_TS/* 45 */
+
+# define ERR_R_NESTED_ASN1_ERROR 58
+# define ERR_R_BAD_ASN1_OBJECT_HEADER 59
+# define ERR_R_BAD_GET_ASN1_OBJECT_CALL 60
+# define ERR_R_EXPECTING_AN_ASN1_SEQUENCE 61
+# define ERR_R_ASN1_LENGTH_MISMATCH 62
+# define ERR_R_MISSING_ASN1_EOS 63
+
+/* fatal error */
+# define ERR_R_FATAL 64
+# define ERR_R_MALLOC_FAILURE (1|ERR_R_FATAL)
+# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2|ERR_R_FATAL)
+# define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL)
+# define ERR_R_INTERNAL_ERROR (4|ERR_R_FATAL)
+# define ERR_R_DISABLED (5|ERR_R_FATAL)
+
+/*
+ * 99 is the maximum possible ERR_R_... code, higher values are reserved for
+ * the individual libraries
+ */
+
+typedef struct ERR_string_data_st {
+ unsigned long error;
+ const char *string;
+} ERR_STRING_DATA;
+
+void ERR_put_error(int lib, int func, int reason, const char *file, int line);
+void ERR_set_error_data(char *data, int flags);
+
+unsigned long ERR_get_error(void);
+unsigned long ERR_get_error_line(const char **file, int *line);
+unsigned long ERR_get_error_line_data(const char **file, int *line,
+ const char **data, int *flags);
+unsigned long ERR_peek_error(void);
+unsigned long ERR_peek_error_line(const char **file, int *line);
+unsigned long ERR_peek_error_line_data(const char **file, int *line,
+ const char **data, int *flags);
+unsigned long ERR_peek_last_error(void);
+unsigned long ERR_peek_last_error_line(const char **file, int *line);
+unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
+ const char **data, int *flags);
+void ERR_clear_error(void);
+char *ERR_error_string(unsigned long e, char *buf);
+void ERR_error_string_n(unsigned long e, char *buf, size_t len);
+const char *ERR_lib_error_string(unsigned long e);
+const char *ERR_func_error_string(unsigned long e);
+const char *ERR_reason_error_string(unsigned long e);
+void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u),
+ void *u);
+# ifndef OPENSSL_NO_FP_API
+void ERR_print_errors_fp(FILE *fp);
+# endif
+# ifndef OPENSSL_NO_BIO
+void ERR_print_errors(BIO *bp);
+# endif
+void ERR_add_error_data(int num, ...);
+void ERR_add_error_vdata(int num, va_list args);
+void ERR_load_strings(int lib, ERR_STRING_DATA str[]);
+void ERR_unload_strings(int lib, ERR_STRING_DATA str[]);
+void ERR_load_ERR_strings(void);
+void ERR_load_crypto_strings(void);
+void ERR_free_strings(void);
+
+void ERR_remove_thread_state(const CRYPTO_THREADID *tid);
+# ifndef OPENSSL_NO_DEPRECATED
+void ERR_remove_state(unsigned long pid); /* if zero we look it up */
+# endif
+ERR_STATE *ERR_get_state(void);
+
+# ifndef OPENSSL_NO_LHASH
+LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void);
+LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void);
+void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash);
+# endif
+
+int ERR_get_next_error_library(void);
+
+int ERR_set_mark(void);
+int ERR_pop_to_mark(void);
+
+/* Already defined in ossl_typ.h */
+/* typedef struct st_ERR_FNS ERR_FNS; */
+/*
+ * An application can use this function and provide the return value to
+ * loaded modules that should use the application's ERR state/functionality
+ */
+const ERR_FNS *ERR_get_implementation(void);
+/*
+ * A loaded module should call this function prior to any ERR operations
+ * using the application's "ERR_FNS".
+ */
+int ERR_set_implementation(const ERR_FNS *fns);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/evp.h b/openssl/evp.h
new file mode 120000
index 0000000..a2ec7f7
--- /dev/null
+++ b/openssl/evp.h
@@ -0,0 +1 @@
+evp/evp.h
\ No newline at end of file
diff --git a/openssl/evp/evp.h b/openssl/evp/evp.h
new file mode 100644
index 0000000..b00997b
--- /dev/null
+++ b/openssl/evp/evp.h
@@ -0,0 +1,1478 @@
+/* crypto/evp/evp.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ENVELOPE_H
+# define HEADER_ENVELOPE_H
+
+# ifdef OPENSSL_ALGORITHM_DEFINES
+# include <openssl/opensslconf.h>
+# else
+# define OPENSSL_ALGORITHM_DEFINES
+# include <openssl/opensslconf.h>
+# undef OPENSSL_ALGORITHM_DEFINES
+# endif
+
+# include <openssl/ossl_typ.h>
+
+# include <openssl/symhacks.h>
+
+# ifndef OPENSSL_NO_BIO
+# include <openssl/bio.h>
+# endif
+
+/*-
+#define EVP_RC2_KEY_SIZE 16
+#define EVP_RC4_KEY_SIZE 16
+#define EVP_BLOWFISH_KEY_SIZE 16
+#define EVP_CAST5_KEY_SIZE 16
+#define EVP_RC5_32_12_16_KEY_SIZE 16
+*/
+# define EVP_MAX_MD_SIZE 64/* longest known is SHA512 */
+# define EVP_MAX_KEY_LENGTH 64
+# define EVP_MAX_IV_LENGTH 16
+# define EVP_MAX_BLOCK_LENGTH 32
+
+# define PKCS5_SALT_LEN 8
+/* Default PKCS#5 iteration count */
+# define PKCS5_DEFAULT_ITER 2048
+
+# include <openssl/objects.h>
+
+# define EVP_PK_RSA 0x0001
+# define EVP_PK_DSA 0x0002
+# define EVP_PK_DH 0x0004
+# define EVP_PK_EC 0x0008
+# define EVP_PKT_SIGN 0x0010
+# define EVP_PKT_ENC 0x0020
+# define EVP_PKT_EXCH 0x0040
+# define EVP_PKS_RSA 0x0100
+# define EVP_PKS_DSA 0x0200
+# define EVP_PKS_EC 0x0400
+# define EVP_PKT_EXP 0x1000 /* <= 512 bit key */
+
+# define EVP_PKEY_NONE NID_undef
+# define EVP_PKEY_RSA NID_rsaEncryption
+# define EVP_PKEY_RSA2 NID_rsa
+# define EVP_PKEY_DSA NID_dsa
+# define EVP_PKEY_DSA1 NID_dsa_2
+# define EVP_PKEY_DSA2 NID_dsaWithSHA
+# define EVP_PKEY_DSA3 NID_dsaWithSHA1
+# define EVP_PKEY_DSA4 NID_dsaWithSHA1_2
+# define EVP_PKEY_DH NID_dhKeyAgreement
+# define EVP_PKEY_EC NID_X9_62_id_ecPublicKey
+# define EVP_PKEY_HMAC NID_hmac
+# define EVP_PKEY_CMAC NID_cmac
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Type needs to be a bit field Sub-type needs to be for variations on the
+ * method, as in, can it do arbitrary encryption....
+ */
+struct evp_pkey_st {
+ int type;
+ int save_type;
+ int references;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ ENGINE *engine;
+ union {
+ char *ptr;
+# ifndef OPENSSL_NO_RSA
+ struct rsa_st *rsa; /* RSA */
+# endif
+# ifndef OPENSSL_NO_DSA
+ struct dsa_st *dsa; /* DSA */
+# endif
+# ifndef OPENSSL_NO_DH
+ struct dh_st *dh; /* DH */
+# endif
+# ifndef OPENSSL_NO_EC
+ struct ec_key_st *ec; /* ECC */
+# endif
+ } pkey;
+ int save_parameters;
+ STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+} /* EVP_PKEY */ ;
+
+# define EVP_PKEY_MO_SIGN 0x0001
+# define EVP_PKEY_MO_VERIFY 0x0002
+# define EVP_PKEY_MO_ENCRYPT 0x0004
+# define EVP_PKEY_MO_DECRYPT 0x0008
+
+# ifndef EVP_MD
+struct env_md_st {
+ int type;
+ int pkey_type;
+ int md_size;
+ unsigned long flags;
+ int (*init) (EVP_MD_CTX *ctx);
+ int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
+ int (*final) (EVP_MD_CTX *ctx, unsigned char *md);
+ int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from);
+ int (*cleanup) (EVP_MD_CTX *ctx);
+ /* FIXME: prototype these some day */
+ int (*sign) (int type, const unsigned char *m, unsigned int m_length,
+ unsigned char *sigret, unsigned int *siglen, void *key);
+ int (*verify) (int type, const unsigned char *m, unsigned int m_length,
+ const unsigned char *sigbuf, unsigned int siglen,
+ void *key);
+ int required_pkey_type[5]; /* EVP_PKEY_xxx */
+ int block_size;
+ int ctx_size; /* how big does the ctx->md_data need to be */
+ /* control function */
+ int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
+} /* EVP_MD */ ;
+
+typedef int evp_sign_method(int type, const unsigned char *m,
+ unsigned int m_length, unsigned char *sigret,
+ unsigned int *siglen, void *key);
+typedef int evp_verify_method(int type, const unsigned char *m,
+ unsigned int m_length,
+ const unsigned char *sigbuf,
+ unsigned int siglen, void *key);
+
+/* digest can only handle a single block */
+# define EVP_MD_FLAG_ONESHOT 0x0001
+
+/*
+ * digest is a "clone" digest used
+ * which is a copy of an existing
+ * one for a specific public key type.
+ * EVP_dss1() etc
+ */
+# define EVP_MD_FLAG_PKEY_DIGEST 0x0002
+
+/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */
+
+# define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE 0x0004
+
+/* DigestAlgorithmIdentifier flags... */
+
+# define EVP_MD_FLAG_DIGALGID_MASK 0x0018
+
+/* NULL or absent parameter accepted. Use NULL */
+
+# define EVP_MD_FLAG_DIGALGID_NULL 0x0000
+
+/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */
+
+# define EVP_MD_FLAG_DIGALGID_ABSENT 0x0008
+
+/* Custom handling via ctrl */
+
+# define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018
+
+/* Note if suitable for use in FIPS mode */
+# define EVP_MD_FLAG_FIPS 0x0400
+
+/* Digest ctrls */
+
+# define EVP_MD_CTRL_DIGALGID 0x1
+# define EVP_MD_CTRL_MICALG 0x2
+
+/* Minimum Algorithm specific ctrl value */
+
+# define EVP_MD_CTRL_ALG_CTRL 0x1000
+
+# define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0}
+
+# ifndef OPENSSL_NO_DSA
+# define EVP_PKEY_DSA_method (evp_sign_method *)DSA_sign, \
+ (evp_verify_method *)DSA_verify, \
+ {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \
+ EVP_PKEY_DSA4,0}
+# else
+# define EVP_PKEY_DSA_method EVP_PKEY_NULL_method
+# endif
+
+# ifndef OPENSSL_NO_ECDSA
+# define EVP_PKEY_ECDSA_method (evp_sign_method *)ECDSA_sign, \
+ (evp_verify_method *)ECDSA_verify, \
+ {EVP_PKEY_EC,0,0,0}
+# else
+# define EVP_PKEY_ECDSA_method EVP_PKEY_NULL_method
+# endif
+
+# ifndef OPENSSL_NO_RSA
+# define EVP_PKEY_RSA_method (evp_sign_method *)RSA_sign, \
+ (evp_verify_method *)RSA_verify, \
+ {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+# define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \
+ (evp_sign_method *)RSA_sign_ASN1_OCTET_STRING, \
+ (evp_verify_method *)RSA_verify_ASN1_OCTET_STRING, \
+ {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+# else
+# define EVP_PKEY_RSA_method EVP_PKEY_NULL_method
+# define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method
+# endif
+
+# endif /* !EVP_MD */
+
+struct env_md_ctx_st {
+ const EVP_MD *digest;
+ ENGINE *engine; /* functional reference if 'digest' is
+ * ENGINE-provided */
+ unsigned long flags;
+ void *md_data;
+ /* Public key context for sign/verify */
+ EVP_PKEY_CTX *pctx;
+ /* Update function: usually copied from EVP_MD */
+ int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
+} /* EVP_MD_CTX */ ;
+
+/* values for EVP_MD_CTX flags */
+
+# define EVP_MD_CTX_FLAG_ONESHOT 0x0001/* digest update will be
+ * called once only */
+# define EVP_MD_CTX_FLAG_CLEANED 0x0002/* context has already been
+ * cleaned */
+# define EVP_MD_CTX_FLAG_REUSE 0x0004/* Don't free up ctx->md_data
+ * in EVP_MD_CTX_cleanup */
+/*
+ * FIPS and pad options are ignored in 1.0.0, definitions are here so we
+ * don't accidentally reuse the values for other purposes.
+ */
+
+# define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008/* Allow use of non FIPS
+ * digest in FIPS mode */
+
+/*
+ * The following PAD options are also currently ignored in 1.0.0, digest
+ * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*()
+ * instead.
+ */
+# define EVP_MD_CTX_FLAG_PAD_MASK 0xF0/* RSA mode to use */
+# define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00/* PKCS#1 v1.5 mode */
+# define EVP_MD_CTX_FLAG_PAD_X931 0x10/* X9.31 mode */
+# define EVP_MD_CTX_FLAG_PAD_PSS 0x20/* PSS mode */
+
+# define EVP_MD_CTX_FLAG_NO_INIT 0x0100/* Don't initialize md_data */
+
+struct evp_cipher_st {
+ int nid;
+ int block_size;
+ /* Default value for variable length ciphers */
+ int key_len;
+ int iv_len;
+ /* Various flags */
+ unsigned long flags;
+ /* init key */
+ int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key,
+ const unsigned char *iv, int enc);
+ /* encrypt/decrypt data */
+ int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out,
+ const unsigned char *in, size_t inl);
+ /* cleanup ctx */
+ int (*cleanup) (EVP_CIPHER_CTX *);
+ /* how big ctx->cipher_data needs to be */
+ int ctx_size;
+ /* Populate a ASN1_TYPE with parameters */
+ int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *);
+ /* Get parameters from a ASN1_TYPE */
+ int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *);
+ /* Miscellaneous operations */
+ int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr);
+ /* Application data */
+ void *app_data;
+} /* EVP_CIPHER */ ;
+
+/* Values for cipher flags */
+
+/* Modes for ciphers */
+
+# define EVP_CIPH_STREAM_CIPHER 0x0
+# define EVP_CIPH_ECB_MODE 0x1
+# define EVP_CIPH_CBC_MODE 0x2
+# define EVP_CIPH_CFB_MODE 0x3
+# define EVP_CIPH_OFB_MODE 0x4
+# define EVP_CIPH_CTR_MODE 0x5
+# define EVP_CIPH_GCM_MODE 0x6
+# define EVP_CIPH_CCM_MODE 0x7
+# define EVP_CIPH_XTS_MODE 0x10001
+# define EVP_CIPH_MODE 0xF0007
+/* Set if variable length cipher */
+# define EVP_CIPH_VARIABLE_LENGTH 0x8
+/* Set if the iv handling should be done by the cipher itself */
+# define EVP_CIPH_CUSTOM_IV 0x10
+/* Set if the cipher's init() function should be called if key is NULL */
+# define EVP_CIPH_ALWAYS_CALL_INIT 0x20
+/* Call ctrl() to init cipher parameters */
+# define EVP_CIPH_CTRL_INIT 0x40
+/* Don't use standard key length function */
+# define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80
+/* Don't use standard block padding */
+# define EVP_CIPH_NO_PADDING 0x100
+/* cipher handles random key generation */
+# define EVP_CIPH_RAND_KEY 0x200
+/* cipher has its own additional copying logic */
+# define EVP_CIPH_CUSTOM_COPY 0x400
+/* Allow use default ASN1 get/set iv */
+# define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000
+/* Buffer length in bits not bytes: CFB1 mode only */
+# define EVP_CIPH_FLAG_LENGTH_BITS 0x2000
+/* Note if suitable for use in FIPS mode */
+# define EVP_CIPH_FLAG_FIPS 0x4000
+/* Allow non FIPS cipher in FIPS mode */
+# define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000
+/*
+ * Cipher handles any and all padding logic as well as finalisation.
+ */
+# define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000
+# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000
+
+/* ctrl() values */
+
+# define EVP_CTRL_INIT 0x0
+# define EVP_CTRL_SET_KEY_LENGTH 0x1
+# define EVP_CTRL_GET_RC2_KEY_BITS 0x2
+# define EVP_CTRL_SET_RC2_KEY_BITS 0x3
+# define EVP_CTRL_GET_RC5_ROUNDS 0x4
+# define EVP_CTRL_SET_RC5_ROUNDS 0x5
+# define EVP_CTRL_RAND_KEY 0x6
+# define EVP_CTRL_PBE_PRF_NID 0x7
+# define EVP_CTRL_COPY 0x8
+# define EVP_CTRL_GCM_SET_IVLEN 0x9
+# define EVP_CTRL_GCM_GET_TAG 0x10
+# define EVP_CTRL_GCM_SET_TAG 0x11
+# define EVP_CTRL_GCM_SET_IV_FIXED 0x12
+# define EVP_CTRL_GCM_IV_GEN 0x13
+# define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN
+# define EVP_CTRL_CCM_GET_TAG EVP_CTRL_GCM_GET_TAG
+# define EVP_CTRL_CCM_SET_TAG EVP_CTRL_GCM_SET_TAG
+# define EVP_CTRL_CCM_SET_L 0x14
+# define EVP_CTRL_CCM_SET_MSGLEN 0x15
+/*
+ * AEAD cipher deduces payload length and returns number of bytes required to
+ * store MAC and eventual padding. Subsequent call to EVP_Cipher even
+ * appends/verifies MAC.
+ */
+# define EVP_CTRL_AEAD_TLS1_AAD 0x16
+/* Used by composite AEAD ciphers, no-op in GCM, CCM... */
+# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17
+/* Set the GCM invocation field, decrypt only */
+# define EVP_CTRL_GCM_SET_IV_INV 0x18
+
+/* GCM TLS constants */
+/* Length of fixed part of IV derived from PRF */
+# define EVP_GCM_TLS_FIXED_IV_LEN 4
+/* Length of explicit part of IV part of TLS records */
+# define EVP_GCM_TLS_EXPLICIT_IV_LEN 8
+/* Length of tag for TLS */
+# define EVP_GCM_TLS_TAG_LEN 16
+
+typedef struct evp_cipher_info_st {
+ const EVP_CIPHER *cipher;
+ unsigned char iv[EVP_MAX_IV_LENGTH];
+} EVP_CIPHER_INFO;
+
+struct evp_cipher_ctx_st {
+ const EVP_CIPHER *cipher;
+ ENGINE *engine; /* functional reference if 'cipher' is
+ * ENGINE-provided */
+ int encrypt; /* encrypt or decrypt */
+ int buf_len; /* number we have left */
+ unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */
+ unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */
+ unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */
+ int num; /* used by cfb/ofb/ctr mode */
+ void *app_data; /* application stuff */
+ int key_len; /* May change for variable length cipher */
+ unsigned long flags; /* Various flags */
+ void *cipher_data; /* per EVP data */
+ int final_used;
+ int block_mask;
+ unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */
+} /* EVP_CIPHER_CTX */ ;
+
+typedef struct evp_Encode_Ctx_st {
+ /* number saved in a partial encode/decode */
+ int num;
+ /*
+ * The length is either the output line length (in input bytes) or the
+ * shortest input line length that is ok. Once decoding begins, the
+ * length is adjusted up each time a longer line is decoded
+ */
+ int length;
+ /* data to encode */
+ unsigned char enc_data[80];
+ /* number read on current line */
+ int line_num;
+ int expect_nl;
+} EVP_ENCODE_CTX;
+
+/* Password based encryption function */
+typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass,
+ int passlen, ASN1_TYPE *param,
+ const EVP_CIPHER *cipher, const EVP_MD *md,
+ int en_de);
+
+# ifndef OPENSSL_NO_RSA
+# define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
+ (char *)(rsa))
+# endif
+
+# ifndef OPENSSL_NO_DSA
+# define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
+ (char *)(dsa))
+# endif
+
+# ifndef OPENSSL_NO_DH
+# define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\
+ (char *)(dh))
+# endif
+
+# ifndef OPENSSL_NO_EC
+# define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\
+ (char *)(eckey))
+# endif
+
+/* Add some extra combinations */
+# define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
+# define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
+# define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
+# define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
+
+int EVP_MD_type(const EVP_MD *md);
+# define EVP_MD_nid(e) EVP_MD_type(e)
+# define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e))
+int EVP_MD_pkey_type(const EVP_MD *md);
+int EVP_MD_size(const EVP_MD *md);
+int EVP_MD_block_size(const EVP_MD *md);
+unsigned long EVP_MD_flags(const EVP_MD *md);
+
+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
+# define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e))
+# define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e))
+# define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e))
+
+int EVP_CIPHER_nid(const EVP_CIPHER *cipher);
+# define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e))
+int EVP_CIPHER_block_size(const EVP_CIPHER *cipher);
+int EVP_CIPHER_key_length(const EVP_CIPHER *cipher);
+int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher);
+unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher);
+# define EVP_CIPHER_mode(e) (EVP_CIPHER_flags(e) & EVP_CIPH_MODE)
+
+const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
+void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
+void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
+# define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
+unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx);
+# define EVP_CIPHER_CTX_mode(e) (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE)
+
+# define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80)
+# define EVP_DECODE_LENGTH(l) ((l+3)/4*3+80)
+
+# define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c)
+# define EVP_SignInit(a,b) EVP_DigestInit(a,b)
+# define EVP_SignUpdate(a,b,c) EVP_DigestUpdate(a,b,c)
+# define EVP_VerifyInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c)
+# define EVP_VerifyInit(a,b) EVP_DigestInit(a,b)
+# define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c)
+# define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e)
+# define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e)
+# define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c)
+# define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c)
+
+# ifdef CONST_STRICT
+void BIO_set_md(BIO *, const EVP_MD *md);
+# else
+# define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md)
+# endif
+# define BIO_get_md(b,mdp) BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp)
+# define BIO_get_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp)
+# define BIO_set_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp)
+# define BIO_get_cipher_status(b) BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL)
+# define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp)
+
+int EVP_Cipher(EVP_CIPHER_CTX *c,
+ unsigned char *out, const unsigned char *in, unsigned int inl);
+
+# define EVP_add_cipher_alias(n,alias) \
+ OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n))
+# define EVP_add_digest_alias(n,alias) \
+ OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n))
+# define EVP_delete_cipher_alias(alias) \
+ OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS);
+# define EVP_delete_digest_alias(alias) \
+ OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS);
+
+void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
+int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
+EVP_MD_CTX *EVP_MD_CTX_create(void);
+void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
+int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in);
+void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags);
+void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags);
+int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags);
+int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
+int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
+int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s);
+int EVP_Digest(const void *data, size_t count,
+ unsigned char *md, unsigned int *size, const EVP_MD *type,
+ ENGINE *impl);
+
+int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in);
+int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s);
+
+int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify);
+int EVP_read_pw_string_min(char *buf, int minlen, int maxlen,
+ const char *prompt, int verify);
+void EVP_set_pw_prompt(const char *prompt);
+char *EVP_get_pw_prompt(void);
+
+int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
+ const unsigned char *salt, const unsigned char *data,
+ int datal, int count, unsigned char *key,
+ unsigned char *iv);
+
+void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags);
+void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags);
+int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags);
+
+int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key, const unsigned char *iv);
+int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ ENGINE *impl, const unsigned char *key,
+ const unsigned char *iv);
+int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl);
+int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key, const unsigned char *iv);
+int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ ENGINE *impl, const unsigned char *key,
+ const unsigned char *iv);
+int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl);
+int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+
+int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key, const unsigned char *iv,
+ int enc);
+int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ ENGINE *impl, const unsigned char *key,
+ const unsigned char *iv, int enc);
+int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl);
+int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+
+int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s,
+ EVP_PKEY *pkey);
+
+int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
+ unsigned int siglen, EVP_PKEY *pkey);
+
+int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+ const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
+int EVP_DigestSignFinal(EVP_MD_CTX *ctx,
+ unsigned char *sigret, size_t *siglen);
+
+int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+ const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey);
+int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen);
+
+int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+ const unsigned char *ek, int ekl, const unsigned char *iv,
+ EVP_PKEY *priv);
+int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+ unsigned char **ek, int *ekl, unsigned char *iv,
+ EVP_PKEY **pubk, int npubk);
+int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
+void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl);
+void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl);
+int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+void EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
+int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+ const unsigned char *in, int inl);
+int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned
+ char *out, int *outl);
+int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
+int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
+EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a);
+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
+int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad);
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
+int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key);
+
+# ifndef OPENSSL_NO_BIO
+BIO_METHOD *BIO_f_md(void);
+BIO_METHOD *BIO_f_base64(void);
+BIO_METHOD *BIO_f_cipher(void);
+BIO_METHOD *BIO_f_reliable(void);
+void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
+ const unsigned char *i, int enc);
+# endif
+
+const EVP_MD *EVP_md_null(void);
+# ifndef OPENSSL_NO_MD2
+const EVP_MD *EVP_md2(void);
+# endif
+# ifndef OPENSSL_NO_MD4
+const EVP_MD *EVP_md4(void);
+# endif
+# ifndef OPENSSL_NO_MD5
+const EVP_MD *EVP_md5(void);
+# endif
+# ifndef OPENSSL_NO_SHA
+const EVP_MD *EVP_sha(void);
+const EVP_MD *EVP_sha1(void);
+const EVP_MD *EVP_dss(void);
+const EVP_MD *EVP_dss1(void);
+const EVP_MD *EVP_ecdsa(void);
+# endif
+# ifndef OPENSSL_NO_SHA256
+const EVP_MD *EVP_sha224(void);
+const EVP_MD *EVP_sha256(void);
+# endif
+# ifndef OPENSSL_NO_SHA512
+const EVP_MD *EVP_sha384(void);
+const EVP_MD *EVP_sha512(void);
+# endif
+# ifndef OPENSSL_NO_MDC2
+const EVP_MD *EVP_mdc2(void);
+# endif
+# ifndef OPENSSL_NO_RIPEMD
+const EVP_MD *EVP_ripemd160(void);
+# endif
+# ifndef OPENSSL_NO_WHIRLPOOL
+const EVP_MD *EVP_whirlpool(void);
+# endif
+const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */
+# ifndef OPENSSL_NO_DES
+const EVP_CIPHER *EVP_des_ecb(void);
+const EVP_CIPHER *EVP_des_ede(void);
+const EVP_CIPHER *EVP_des_ede3(void);
+const EVP_CIPHER *EVP_des_ede_ecb(void);
+const EVP_CIPHER *EVP_des_ede3_ecb(void);
+const EVP_CIPHER *EVP_des_cfb64(void);
+# define EVP_des_cfb EVP_des_cfb64
+const EVP_CIPHER *EVP_des_cfb1(void);
+const EVP_CIPHER *EVP_des_cfb8(void);
+const EVP_CIPHER *EVP_des_ede_cfb64(void);
+# define EVP_des_ede_cfb EVP_des_ede_cfb64
+# if 0
+const EVP_CIPHER *EVP_des_ede_cfb1(void);
+const EVP_CIPHER *EVP_des_ede_cfb8(void);
+# endif
+const EVP_CIPHER *EVP_des_ede3_cfb64(void);
+# define EVP_des_ede3_cfb EVP_des_ede3_cfb64
+const EVP_CIPHER *EVP_des_ede3_cfb1(void);
+const EVP_CIPHER *EVP_des_ede3_cfb8(void);
+const EVP_CIPHER *EVP_des_ofb(void);
+const EVP_CIPHER *EVP_des_ede_ofb(void);
+const EVP_CIPHER *EVP_des_ede3_ofb(void);
+const EVP_CIPHER *EVP_des_cbc(void);
+const EVP_CIPHER *EVP_des_ede_cbc(void);
+const EVP_CIPHER *EVP_des_ede3_cbc(void);
+const EVP_CIPHER *EVP_desx_cbc(void);
+/*
+ * This should now be supported through the dev_crypto ENGINE. But also, why
+ * are rc4 and md5 declarations made here inside a "NO_DES" precompiler
+ * branch?
+ */
+# if 0
+# ifdef OPENSSL_OPENBSD_DEV_CRYPTO
+const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void);
+const EVP_CIPHER *EVP_dev_crypto_rc4(void);
+const EVP_MD *EVP_dev_crypto_md5(void);
+# endif
+# endif
+# endif
+# ifndef OPENSSL_NO_RC4
+const EVP_CIPHER *EVP_rc4(void);
+const EVP_CIPHER *EVP_rc4_40(void);
+# ifndef OPENSSL_NO_MD5
+const EVP_CIPHER *EVP_rc4_hmac_md5(void);
+# endif
+# endif
+# ifndef OPENSSL_NO_IDEA
+const EVP_CIPHER *EVP_idea_ecb(void);
+const EVP_CIPHER *EVP_idea_cfb64(void);
+# define EVP_idea_cfb EVP_idea_cfb64
+const EVP_CIPHER *EVP_idea_ofb(void);
+const EVP_CIPHER *EVP_idea_cbc(void);
+# endif
+# ifndef OPENSSL_NO_RC2
+const EVP_CIPHER *EVP_rc2_ecb(void);
+const EVP_CIPHER *EVP_rc2_cbc(void);
+const EVP_CIPHER *EVP_rc2_40_cbc(void);
+const EVP_CIPHER *EVP_rc2_64_cbc(void);
+const EVP_CIPHER *EVP_rc2_cfb64(void);
+# define EVP_rc2_cfb EVP_rc2_cfb64
+const EVP_CIPHER *EVP_rc2_ofb(void);
+# endif
+# ifndef OPENSSL_NO_BF
+const EVP_CIPHER *EVP_bf_ecb(void);
+const EVP_CIPHER *EVP_bf_cbc(void);
+const EVP_CIPHER *EVP_bf_cfb64(void);
+# define EVP_bf_cfb EVP_bf_cfb64
+const EVP_CIPHER *EVP_bf_ofb(void);
+# endif
+# ifndef OPENSSL_NO_CAST
+const EVP_CIPHER *EVP_cast5_ecb(void);
+const EVP_CIPHER *EVP_cast5_cbc(void);
+const EVP_CIPHER *EVP_cast5_cfb64(void);
+# define EVP_cast5_cfb EVP_cast5_cfb64
+const EVP_CIPHER *EVP_cast5_ofb(void);
+# endif
+# ifndef OPENSSL_NO_RC5
+const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void);
+# define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64
+const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void);
+# endif
+# ifndef OPENSSL_NO_AES
+const EVP_CIPHER *EVP_aes_128_ecb(void);
+const EVP_CIPHER *EVP_aes_128_cbc(void);
+const EVP_CIPHER *EVP_aes_128_cfb1(void);
+const EVP_CIPHER *EVP_aes_128_cfb8(void);
+const EVP_CIPHER *EVP_aes_128_cfb128(void);
+# define EVP_aes_128_cfb EVP_aes_128_cfb128
+const EVP_CIPHER *EVP_aes_128_ofb(void);
+const EVP_CIPHER *EVP_aes_128_ctr(void);
+const EVP_CIPHER *EVP_aes_128_ccm(void);
+const EVP_CIPHER *EVP_aes_128_gcm(void);
+const EVP_CIPHER *EVP_aes_128_xts(void);
+const EVP_CIPHER *EVP_aes_192_ecb(void);
+const EVP_CIPHER *EVP_aes_192_cbc(void);
+const EVP_CIPHER *EVP_aes_192_cfb1(void);
+const EVP_CIPHER *EVP_aes_192_cfb8(void);
+const EVP_CIPHER *EVP_aes_192_cfb128(void);
+# define EVP_aes_192_cfb EVP_aes_192_cfb128
+const EVP_CIPHER *EVP_aes_192_ofb(void);
+const EVP_CIPHER *EVP_aes_192_ctr(void);
+const EVP_CIPHER *EVP_aes_192_ccm(void);
+const EVP_CIPHER *EVP_aes_192_gcm(void);
+const EVP_CIPHER *EVP_aes_256_ecb(void);
+const EVP_CIPHER *EVP_aes_256_cbc(void);
+const EVP_CIPHER *EVP_aes_256_cfb1(void);
+const EVP_CIPHER *EVP_aes_256_cfb8(void);
+const EVP_CIPHER *EVP_aes_256_cfb128(void);
+# define EVP_aes_256_cfb EVP_aes_256_cfb128
+const EVP_CIPHER *EVP_aes_256_ofb(void);
+const EVP_CIPHER *EVP_aes_256_ctr(void);
+const EVP_CIPHER *EVP_aes_256_ccm(void);
+const EVP_CIPHER *EVP_aes_256_gcm(void);
+const EVP_CIPHER *EVP_aes_256_xts(void);
+# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void);
+# endif
+# endif
+# ifndef OPENSSL_NO_CAMELLIA
+const EVP_CIPHER *EVP_camellia_128_ecb(void);
+const EVP_CIPHER *EVP_camellia_128_cbc(void);
+const EVP_CIPHER *EVP_camellia_128_cfb1(void);
+const EVP_CIPHER *EVP_camellia_128_cfb8(void);
+const EVP_CIPHER *EVP_camellia_128_cfb128(void);
+# define EVP_camellia_128_cfb EVP_camellia_128_cfb128
+const EVP_CIPHER *EVP_camellia_128_ofb(void);
+const EVP_CIPHER *EVP_camellia_192_ecb(void);
+const EVP_CIPHER *EVP_camellia_192_cbc(void);
+const EVP_CIPHER *EVP_camellia_192_cfb1(void);
+const EVP_CIPHER *EVP_camellia_192_cfb8(void);
+const EVP_CIPHER *EVP_camellia_192_cfb128(void);
+# define EVP_camellia_192_cfb EVP_camellia_192_cfb128
+const EVP_CIPHER *EVP_camellia_192_ofb(void);
+const EVP_CIPHER *EVP_camellia_256_ecb(void);
+const EVP_CIPHER *EVP_camellia_256_cbc(void);
+const EVP_CIPHER *EVP_camellia_256_cfb1(void);
+const EVP_CIPHER *EVP_camellia_256_cfb8(void);
+const EVP_CIPHER *EVP_camellia_256_cfb128(void);
+# define EVP_camellia_256_cfb EVP_camellia_256_cfb128
+const EVP_CIPHER *EVP_camellia_256_ofb(void);
+# endif
+
+# ifndef OPENSSL_NO_SEED
+const EVP_CIPHER *EVP_seed_ecb(void);
+const EVP_CIPHER *EVP_seed_cbc(void);
+const EVP_CIPHER *EVP_seed_cfb128(void);
+# define EVP_seed_cfb EVP_seed_cfb128
+const EVP_CIPHER *EVP_seed_ofb(void);
+# endif
+
+void OPENSSL_add_all_algorithms_noconf(void);
+void OPENSSL_add_all_algorithms_conf(void);
+
+# ifdef OPENSSL_LOAD_CONF
+# define OpenSSL_add_all_algorithms() \
+ OPENSSL_add_all_algorithms_conf()
+# else
+# define OpenSSL_add_all_algorithms() \
+ OPENSSL_add_all_algorithms_noconf()
+# endif
+
+void OpenSSL_add_all_ciphers(void);
+void OpenSSL_add_all_digests(void);
+# define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms()
+# define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers()
+# define SSLeay_add_all_digests() OpenSSL_add_all_digests()
+
+int EVP_add_cipher(const EVP_CIPHER *cipher);
+int EVP_add_digest(const EVP_MD *digest);
+
+const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
+const EVP_MD *EVP_get_digestbyname(const char *name);
+void EVP_cleanup(void);
+
+void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph,
+ const char *from, const char *to, void *x),
+ void *arg);
+void EVP_CIPHER_do_all_sorted(void (*fn)
+ (const EVP_CIPHER *ciph, const char *from,
+ const char *to, void *x), void *arg);
+
+void EVP_MD_do_all(void (*fn) (const EVP_MD *ciph,
+ const char *from, const char *to, void *x),
+ void *arg);
+void EVP_MD_do_all_sorted(void (*fn)
+ (const EVP_MD *ciph, const char *from,
+ const char *to, void *x), void *arg);
+
+int EVP_PKEY_decrypt_old(unsigned char *dec_key,
+ const unsigned char *enc_key, int enc_key_len,
+ EVP_PKEY *private_key);
+int EVP_PKEY_encrypt_old(unsigned char *enc_key,
+ const unsigned char *key, int key_len,
+ EVP_PKEY *pub_key);
+int EVP_PKEY_type(int type);
+int EVP_PKEY_id(const EVP_PKEY *pkey);
+int EVP_PKEY_base_id(const EVP_PKEY *pkey);
+int EVP_PKEY_bits(EVP_PKEY *pkey);
+int EVP_PKEY_size(EVP_PKEY *pkey);
+int EVP_PKEY_set_type(EVP_PKEY *pkey, int type);
+int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
+int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key);
+void *EVP_PKEY_get0(EVP_PKEY *pkey);
+
+# ifndef OPENSSL_NO_RSA
+struct rsa_st;
+int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key);
+struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
+# endif
+# ifndef OPENSSL_NO_DSA
+struct dsa_st;
+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key);
+struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
+# endif
+# ifndef OPENSSL_NO_DH
+struct dh_st;
+int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key);
+struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
+# endif
+# ifndef OPENSSL_NO_EC
+struct ec_key_st;
+int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key);
+struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
+# endif
+
+EVP_PKEY *EVP_PKEY_new(void);
+void EVP_PKEY_free(EVP_PKEY *pkey);
+
+EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
+ long length);
+int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp);
+
+EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
+ long length);
+EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
+ long length);
+int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp);
+
+int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
+int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
+int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode);
+int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);
+
+int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
+
+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
+ int indent, ASN1_PCTX *pctx);
+int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
+ int indent, ASN1_PCTX *pctx);
+int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
+ int indent, ASN1_PCTX *pctx);
+
+int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
+
+int EVP_CIPHER_type(const EVP_CIPHER *ctx);
+
+/* calls methods */
+int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+
+/* These are used by EVP_CIPHER methods */
+int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+
+/* PKCS5 password based encryption */
+int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+ ASN1_TYPE *param, const EVP_CIPHER *cipher,
+ const EVP_MD *md, int en_de);
+int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+ const unsigned char *salt, int saltlen, int iter,
+ int keylen, unsigned char *out);
+int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
+ const unsigned char *salt, int saltlen, int iter,
+ const EVP_MD *digest, int keylen, unsigned char *out);
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+ ASN1_TYPE *param, const EVP_CIPHER *cipher,
+ const EVP_MD *md, int en_de);
+
+void PKCS5_PBE_add(void);
+
+int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
+ ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
+
+/* PBE type */
+
+/* Can appear as the outermost AlgorithmIdentifier */
+# define EVP_PBE_TYPE_OUTER 0x0
+/* Is an PRF type OID */
+# define EVP_PBE_TYPE_PRF 0x1
+
+int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid,
+ int md_nid, EVP_PBE_KEYGEN *keygen);
+int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+ EVP_PBE_KEYGEN *keygen);
+int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid,
+ EVP_PBE_KEYGEN **pkeygen);
+void EVP_PBE_cleanup(void);
+
+# define ASN1_PKEY_ALIAS 0x1
+# define ASN1_PKEY_DYNAMIC 0x2
+# define ASN1_PKEY_SIGPARAM_NULL 0x4
+
+# define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1
+# define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2
+# define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3
+# define ASN1_PKEY_CTRL_CMS_SIGN 0x5
+# define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7
+
+int EVP_PKEY_asn1_get_count(void);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
+ const char *str, int len);
+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth);
+int EVP_PKEY_asn1_add_alias(int to, int from);
+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id,
+ int *ppkey_flags, const char **pinfo,
+ const char **ppem_str,
+ const EVP_PKEY_ASN1_METHOD *ameth);
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey);
+EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
+ const char *pem_str,
+ const char *info);
+void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
+ const EVP_PKEY_ASN1_METHOD *src);
+void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth);
+void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*pub_decode) (EVP_PKEY *pk,
+ X509_PUBKEY *pub),
+ int (*pub_encode) (X509_PUBKEY *pub,
+ const EVP_PKEY *pk),
+ int (*pub_cmp) (const EVP_PKEY *a,
+ const EVP_PKEY *b),
+ int (*pub_print) (BIO *out,
+ const EVP_PKEY *pkey,
+ int indent, ASN1_PCTX *pctx),
+ int (*pkey_size) (const EVP_PKEY *pk),
+ int (*pkey_bits) (const EVP_PKEY *pk));
+void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*priv_decode) (EVP_PKEY *pk,
+ PKCS8_PRIV_KEY_INFO
+ *p8inf),
+ int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
+ const EVP_PKEY *pk),
+ int (*priv_print) (BIO *out,
+ const EVP_PKEY *pkey,
+ int indent,
+ ASN1_PCTX *pctx));
+void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*param_decode) (EVP_PKEY *pkey,
+ const unsigned char **pder,
+ int derlen),
+ int (*param_encode) (const EVP_PKEY *pkey,
+ unsigned char **pder),
+ int (*param_missing) (const EVP_PKEY *pk),
+ int (*param_copy) (EVP_PKEY *to,
+ const EVP_PKEY *from),
+ int (*param_cmp) (const EVP_PKEY *a,
+ const EVP_PKEY *b),
+ int (*param_print) (BIO *out,
+ const EVP_PKEY *pkey,
+ int indent,
+ ASN1_PCTX *pctx));
+
+void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
+ void (*pkey_free) (EVP_PKEY *pkey));
+void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
+ int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
+ long arg1, void *arg2));
+
+# define EVP_PKEY_OP_UNDEFINED 0
+# define EVP_PKEY_OP_PARAMGEN (1<<1)
+# define EVP_PKEY_OP_KEYGEN (1<<2)
+# define EVP_PKEY_OP_SIGN (1<<3)
+# define EVP_PKEY_OP_VERIFY (1<<4)
+# define EVP_PKEY_OP_VERIFYRECOVER (1<<5)
+# define EVP_PKEY_OP_SIGNCTX (1<<6)
+# define EVP_PKEY_OP_VERIFYCTX (1<<7)
+# define EVP_PKEY_OP_ENCRYPT (1<<8)
+# define EVP_PKEY_OP_DECRYPT (1<<9)
+# define EVP_PKEY_OP_DERIVE (1<<10)
+
+# define EVP_PKEY_OP_TYPE_SIG \
+ (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \
+ | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX)
+
+# define EVP_PKEY_OP_TYPE_CRYPT \
+ (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)
+
+# define EVP_PKEY_OP_TYPE_NOGEN \
+ (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE)
+
+# define EVP_PKEY_OP_TYPE_GEN \
+ (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
+
+# define EVP_PKEY_CTX_set_signature_md(ctx, md) \
+ EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \
+ EVP_PKEY_CTRL_MD, 0, (void *)md)
+
+# define EVP_PKEY_CTRL_MD 1
+# define EVP_PKEY_CTRL_PEER_KEY 2
+
+# define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3
+# define EVP_PKEY_CTRL_PKCS7_DECRYPT 4
+
+# define EVP_PKEY_CTRL_PKCS7_SIGN 5
+
+# define EVP_PKEY_CTRL_SET_MAC_KEY 6
+
+# define EVP_PKEY_CTRL_DIGESTINIT 7
+
+/* Used by GOST key encryption in TLS */
+# define EVP_PKEY_CTRL_SET_IV 8
+
+# define EVP_PKEY_CTRL_CMS_ENCRYPT 9
+# define EVP_PKEY_CTRL_CMS_DECRYPT 10
+# define EVP_PKEY_CTRL_CMS_SIGN 11
+
+# define EVP_PKEY_CTRL_CIPHER 12
+
+# define EVP_PKEY_ALG_CTRL 0x1000
+
+# define EVP_PKEY_FLAG_AUTOARGLEN 2
+/*
+ * Method handles all operations: don't assume any digest related defaults.
+ */
+# define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4
+
+const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
+EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags);
+void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
+ const EVP_PKEY_METHOD *meth);
+void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src);
+void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth);
+int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth);
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
+void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
+ int cmd, int p1, void *p2);
+int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
+ const char *value);
+
+int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx);
+void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);
+
+EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
+ const unsigned char *key, int keylen);
+
+void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
+void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
+EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
+
+EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx);
+
+void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
+void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
+ unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs, size_t tbslen);
+int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
+ const unsigned char *sig, size_t siglen,
+ const unsigned char *tbs, size_t tbslen);
+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
+ unsigned char *rout, size_t *routlen,
+ const unsigned char *sig, size_t siglen);
+int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
+ unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen);
+int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
+ unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen);
+
+int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
+int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+
+typedef int EVP_PKEY_gen_cb (EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+
+void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
+EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);
+
+void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
+ int (*init) (EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
+ int (*copy) (EVP_PKEY_CTX *dst,
+ EVP_PKEY_CTX *src));
+
+void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
+ void (*cleanup) (EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
+ int (*paramgen_init) (EVP_PKEY_CTX *ctx),
+ int (*paramgen) (EVP_PKEY_CTX *ctx,
+ EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
+ int (*keygen_init) (EVP_PKEY_CTX *ctx),
+ int (*keygen) (EVP_PKEY_CTX *ctx,
+ EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
+ int (*sign_init) (EVP_PKEY_CTX *ctx),
+ int (*sign) (EVP_PKEY_CTX *ctx,
+ unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs,
+ size_t tbslen));
+
+void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
+ int (*verify_init) (EVP_PKEY_CTX *ctx),
+ int (*verify) (EVP_PKEY_CTX *ctx,
+ const unsigned char *sig,
+ size_t siglen,
+ const unsigned char *tbs,
+ size_t tbslen));
+
+void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
+ int (*verify_recover_init) (EVP_PKEY_CTX
+ *ctx),
+ int (*verify_recover) (EVP_PKEY_CTX
+ *ctx,
+ unsigned char
+ *sig,
+ size_t *siglen,
+ const unsigned
+ char *tbs,
+ size_t tbslen));
+
+void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
+ int (*signctx_init) (EVP_PKEY_CTX *ctx,
+ EVP_MD_CTX *mctx),
+ int (*signctx) (EVP_PKEY_CTX *ctx,
+ unsigned char *sig,
+ size_t *siglen,
+ EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
+ int (*verifyctx_init) (EVP_PKEY_CTX *ctx,
+ EVP_MD_CTX *mctx),
+ int (*verifyctx) (EVP_PKEY_CTX *ctx,
+ const unsigned char *sig,
+ int siglen,
+ EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
+ int (*encrypt_init) (EVP_PKEY_CTX *ctx),
+ int (*encryptfn) (EVP_PKEY_CTX *ctx,
+ unsigned char *out,
+ size_t *outlen,
+ const unsigned char *in,
+ size_t inlen));
+
+void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
+ int (*decrypt_init) (EVP_PKEY_CTX *ctx),
+ int (*decrypt) (EVP_PKEY_CTX *ctx,
+ unsigned char *out,
+ size_t *outlen,
+ const unsigned char *in,
+ size_t inlen));
+
+void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
+ int (*derive_init) (EVP_PKEY_CTX *ctx),
+ int (*derive) (EVP_PKEY_CTX *ctx,
+ unsigned char *key,
+ size_t *keylen));
+
+void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
+ int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
+ void *p2),
+ int (*ctrl_str) (EVP_PKEY_CTX *ctx,
+ const char *type,
+ const char *value));
+
+void EVP_add_alg_module(void);
+
+/* 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.
+ */
+void ERR_load_EVP_strings(void);
+
+/* Error codes for the EVP functions. */
+
+/* Function codes. */
+# define EVP_F_AESNI_INIT_KEY 165
+# define EVP_F_AESNI_XTS_CIPHER 176
+# define EVP_F_AES_INIT_KEY 133
+# define EVP_F_AES_XTS 172
+# define EVP_F_AES_XTS_CIPHER 175
+# define EVP_F_ALG_MODULE_INIT 177
+# define EVP_F_CAMELLIA_INIT_KEY 159
+# define EVP_F_CMAC_INIT 173
+# define EVP_F_D2I_PKEY 100
+# define EVP_F_DO_SIGVER_INIT 161
+# define EVP_F_DSAPKEY2PKCS8 134
+# define EVP_F_DSA_PKEY2PKCS8 135
+# define EVP_F_ECDSA_PKEY2PKCS8 129
+# define EVP_F_ECKEY_PKEY2PKCS8 132
+# define EVP_F_EVP_CIPHERINIT_EX 123
+# define EVP_F_EVP_CIPHER_CTX_COPY 163
+# define EVP_F_EVP_CIPHER_CTX_CTRL 124
+# define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122
+# define EVP_F_EVP_DECRYPTFINAL_EX 101
+# define EVP_F_EVP_DIGESTINIT_EX 128
+# define EVP_F_EVP_ENCRYPTFINAL_EX 127
+# define EVP_F_EVP_MD_CTX_COPY_EX 110
+# define EVP_F_EVP_MD_SIZE 162
+# define EVP_F_EVP_OPENINIT 102
+# define EVP_F_EVP_PBE_ALG_ADD 115
+# define EVP_F_EVP_PBE_ALG_ADD_TYPE 160
+# define EVP_F_EVP_PBE_CIPHERINIT 116
+# define EVP_F_EVP_PKCS82PKEY 111
+# define EVP_F_EVP_PKCS82PKEY_BROKEN 136
+# define EVP_F_EVP_PKEY2PKCS8_BROKEN 113
+# define EVP_F_EVP_PKEY_COPY_PARAMETERS 103
+# define EVP_F_EVP_PKEY_CTX_CTRL 137
+# define EVP_F_EVP_PKEY_CTX_CTRL_STR 150
+# define EVP_F_EVP_PKEY_CTX_DUP 156
+# define EVP_F_EVP_PKEY_DECRYPT 104
+# define EVP_F_EVP_PKEY_DECRYPT_INIT 138
+# define EVP_F_EVP_PKEY_DECRYPT_OLD 151
+# define EVP_F_EVP_PKEY_DERIVE 153
+# define EVP_F_EVP_PKEY_DERIVE_INIT 154
+# define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155
+# define EVP_F_EVP_PKEY_ENCRYPT 105
+# define EVP_F_EVP_PKEY_ENCRYPT_INIT 139
+# define EVP_F_EVP_PKEY_ENCRYPT_OLD 152
+# define EVP_F_EVP_PKEY_GET1_DH 119
+# define EVP_F_EVP_PKEY_GET1_DSA 120
+# define EVP_F_EVP_PKEY_GET1_ECDSA 130
+# define EVP_F_EVP_PKEY_GET1_EC_KEY 131
+# define EVP_F_EVP_PKEY_GET1_RSA 121
+# define EVP_F_EVP_PKEY_KEYGEN 146
+# define EVP_F_EVP_PKEY_KEYGEN_INIT 147
+# define EVP_F_EVP_PKEY_NEW 106
+# define EVP_F_EVP_PKEY_PARAMGEN 148
+# define EVP_F_EVP_PKEY_PARAMGEN_INIT 149
+# define EVP_F_EVP_PKEY_SIGN 140
+# define EVP_F_EVP_PKEY_SIGN_INIT 141
+# define EVP_F_EVP_PKEY_VERIFY 142
+# define EVP_F_EVP_PKEY_VERIFY_INIT 143
+# define EVP_F_EVP_PKEY_VERIFY_RECOVER 144
+# define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT 145
+# define EVP_F_EVP_RIJNDAEL 126
+# define EVP_F_EVP_SIGNFINAL 107
+# define EVP_F_EVP_VERIFYFINAL 108
+# define EVP_F_FIPS_CIPHERINIT 166
+# define EVP_F_FIPS_CIPHER_CTX_COPY 170
+# define EVP_F_FIPS_CIPHER_CTX_CTRL 167
+# define EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH 171
+# define EVP_F_FIPS_DIGESTINIT 168
+# define EVP_F_FIPS_MD_CTX_COPY 169
+# define EVP_F_HMAC_INIT_EX 174
+# define EVP_F_INT_CTX_NEW 157
+# define EVP_F_PKCS5_PBE_KEYIVGEN 117
+# define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118
+# define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164
+# define EVP_F_PKCS8_SET_BROKEN 112
+# define EVP_F_PKEY_SET_TYPE 158
+# define EVP_F_RC2_MAGIC_TO_METH 109
+# define EVP_F_RC5_CTRL 125
+
+/* Reason codes. */
+# define EVP_R_AES_IV_SETUP_FAILED 162
+# define EVP_R_AES_KEY_SETUP_FAILED 143
+# define EVP_R_ASN1_LIB 140
+# define EVP_R_BAD_BLOCK_LENGTH 136
+# define EVP_R_BAD_DECRYPT 100
+# define EVP_R_BAD_KEY_LENGTH 137
+# define EVP_R_BN_DECODE_ERROR 112
+# define EVP_R_BN_PUBKEY_ERROR 113
+# define EVP_R_BUFFER_TOO_SMALL 155
+# define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157
+# define EVP_R_CIPHER_PARAMETER_ERROR 122
+# define EVP_R_COMMAND_NOT_SUPPORTED 147
+# define EVP_R_CTRL_NOT_IMPLEMENTED 132
+# define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133
+# define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138
+# define EVP_R_DECODE_ERROR 114
+# define EVP_R_DIFFERENT_KEY_TYPES 101
+# define EVP_R_DIFFERENT_PARAMETERS 153
+# define EVP_R_DISABLED_FOR_FIPS 163
+# define EVP_R_ENCODE_ERROR 115
+# define EVP_R_ERROR_LOADING_SECTION 165
+# define EVP_R_ERROR_SETTING_FIPS_MODE 166
+# define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119
+# define EVP_R_EXPECTING_AN_RSA_KEY 127
+# define EVP_R_EXPECTING_A_DH_KEY 128
+# define EVP_R_EXPECTING_A_DSA_KEY 129
+# define EVP_R_EXPECTING_A_ECDSA_KEY 141
+# define EVP_R_EXPECTING_A_EC_KEY 142
+# define EVP_R_FIPS_MODE_NOT_SUPPORTED 167
+# define EVP_R_INITIALIZATION_ERROR 134
+# define EVP_R_INPUT_NOT_INITIALIZED 111
+# define EVP_R_INVALID_DIGEST 152
+# define EVP_R_INVALID_FIPS_MODE 168
+# define EVP_R_INVALID_KEY_LENGTH 130
+# define EVP_R_INVALID_OPERATION 148
+# define EVP_R_IV_TOO_LARGE 102
+# define EVP_R_KEYGEN_FAILURE 120
+# define EVP_R_MESSAGE_DIGEST_IS_NULL 159
+# define EVP_R_METHOD_NOT_SUPPORTED 144
+# define EVP_R_MISSING_PARAMETERS 103
+# define EVP_R_NO_CIPHER_SET 131
+# define EVP_R_NO_DEFAULT_DIGEST 158
+# define EVP_R_NO_DIGEST_SET 139
+# define EVP_R_NO_DSA_PARAMETERS 116
+# define EVP_R_NO_KEY_SET 154
+# define EVP_R_NO_OPERATION_SET 149
+# define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104
+# define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105
+# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150
+# define EVP_R_OPERATON_NOT_INITIALIZED 151
+# define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117
+# define EVP_R_PRIVATE_KEY_DECODE_ERROR 145
+# define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146
+# define EVP_R_PUBLIC_KEY_NOT_RSA 106
+# define EVP_R_TOO_LARGE 164
+# define EVP_R_UNKNOWN_CIPHER 160
+# define EVP_R_UNKNOWN_DIGEST 161
+# define EVP_R_UNKNOWN_OPTION 169
+# define EVP_R_UNKNOWN_PBE_ALGORITHM 121
+# define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135
+# define EVP_R_UNSUPPORTED_ALGORITHM 156
+# define EVP_R_UNSUPPORTED_CIPHER 107
+# define EVP_R_UNSUPPORTED_KEYLENGTH 123
+# define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124
+# define EVP_R_UNSUPPORTED_KEY_SIZE 108
+# define EVP_R_UNSUPPORTED_PRF 125
+# define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118
+# define EVP_R_UNSUPPORTED_SALT_TYPE 126
+# define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109
+# define EVP_R_WRONG_PUBLIC_KEY_TYPE 110
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/evp/evp_locl.h b/openssl/evp/evp_locl.h
new file mode 100644
index 0000000..980dada
--- /dev/null
+++ b/openssl/evp/evp_locl.h
@@ -0,0 +1,370 @@
+/* evp_locl.h */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 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).
+ *
+ */
+
+/* Macros to code block cipher wrappers */
+
+/* Wrapper functions for each cipher mode */
+
+#define BLOCK_CIPHER_ecb_loop() \
+ size_t i, bl; \
+ bl = ctx->cipher->block_size;\
+ if(inl < bl) return 1;\
+ inl -= bl; \
+ for(i=0; i <= inl; i+=bl)
+
+#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
+static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+ BLOCK_CIPHER_ecb_loop() \
+ cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\
+ return 1;\
+}
+
+#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2))
+
+#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \
+static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+ while(inl>=EVP_MAXCHUNK)\
+ {\
+ cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
+ inl-=EVP_MAXCHUNK;\
+ in +=EVP_MAXCHUNK;\
+ out+=EVP_MAXCHUNK;\
+ }\
+ if (inl)\
+ cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\
+ return 1;\
+}
+
+#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
+static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+ while(inl>=EVP_MAXCHUNK) \
+ {\
+ cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
+ inl-=EVP_MAXCHUNK;\
+ in +=EVP_MAXCHUNK;\
+ out+=EVP_MAXCHUNK;\
+ }\
+ if (inl)\
+ cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\
+ return 1;\
+}
+
+#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
+static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+ size_t chunk=EVP_MAXCHUNK;\
+ if (cbits==1) chunk>>=3;\
+ if (inl<chunk) chunk=inl;\
+ while(inl && inl>=chunk)\
+ {\
+ cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
+ inl-=chunk;\
+ in +=chunk;\
+ out+=chunk;\
+ if(inl<chunk) chunk=inl;\
+ }\
+ return 1;\
+}
+
+#define BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
+ BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
+ BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
+ BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
+ BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched)
+
+#define BLOCK_CIPHER_def1(cname, nmode, mode, MODE, kstruct, nid, block_size, \
+ key_len, iv_len, flags, init_key, cleanup, \
+ set_asn1, get_asn1, ctrl) \
+static const EVP_CIPHER cname##_##mode = { \
+ nid##_##nmode, block_size, key_len, iv_len, \
+ flags | EVP_CIPH_##MODE##_MODE, \
+ init_key, \
+ cname##_##mode##_cipher, \
+ cleanup, \
+ sizeof(kstruct), \
+ set_asn1, get_asn1,\
+ ctrl, \
+ NULL \
+}; \
+const EVP_CIPHER *EVP_##cname##_##mode(void) { return &cname##_##mode; }
+
+#define BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, \
+ iv_len, flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, cbc, cbc, CBC, kstruct, nid, block_size, key_len, \
+ iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, \
+ iv_len, cbits, flags, init_key, cleanup, \
+ set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, cfb##cbits, cfb##cbits, CFB, kstruct, nid, 1, \
+ key_len, iv_len, flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, \
+ iv_len, cbits, flags, init_key, cleanup, \
+ set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, ofb##cbits, ofb, OFB, kstruct, nid, 1, \
+ key_len, iv_len, flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, \
+ flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \
+ 0, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+#define BLOCK_CIPHER_defs(cname, kstruct, \
+ nid, block_size, key_len, iv_len, cbits, flags, \
+ init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, iv_len, flags, \
+ init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, iv_len, cbits, \
+ flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, iv_len, cbits, \
+ flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, flags, \
+ init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+/*-
+#define BLOCK_CIPHER_defs(cname, kstruct, \
+ nid, block_size, key_len, iv_len, flags,\
+ init_key, cleanup, set_asn1, get_asn1, ctrl)\
+static const EVP_CIPHER cname##_cbc = {\
+ nid##_cbc, block_size, key_len, iv_len, \
+ flags | EVP_CIPH_CBC_MODE,\
+ init_key,\
+ cname##_cbc_cipher,\
+ cleanup,\
+ sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+ sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+ set_asn1, get_asn1,\
+ ctrl, \
+ NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\
+static const EVP_CIPHER cname##_cfb = {\
+ nid##_cfb64, 1, key_len, iv_len, \
+ flags | EVP_CIPH_CFB_MODE,\
+ init_key,\
+ cname##_cfb_cipher,\
+ cleanup,\
+ sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+ sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+ set_asn1, get_asn1,\
+ ctrl,\
+ NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\
+static const EVP_CIPHER cname##_ofb = {\
+ nid##_ofb64, 1, key_len, iv_len, \
+ flags | EVP_CIPH_OFB_MODE,\
+ init_key,\
+ cname##_ofb_cipher,\
+ cleanup,\
+ sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+ sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+ set_asn1, get_asn1,\
+ ctrl,\
+ NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\
+static const EVP_CIPHER cname##_ecb = {\
+ nid##_ecb, block_size, key_len, iv_len, \
+ flags | EVP_CIPH_ECB_MODE,\
+ init_key,\
+ cname##_ecb_cipher,\
+ cleanup,\
+ sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+ sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+ set_asn1, get_asn1,\
+ ctrl,\
+ NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
+*/
+
+#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \
+ block_size, key_len, iv_len, cbits, \
+ flags, init_key, \
+ cleanup, set_asn1, get_asn1, ctrl) \
+ BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
+ BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \
+ cbits, flags, init_key, cleanup, set_asn1, \
+ get_asn1, ctrl)
+
+#define EVP_C_DATA(kstruct, ctx) ((kstruct *)(ctx)->cipher_data)
+
+#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \
+ BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \
+ BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \
+ NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \
+ 0, cipher##_init_key, NULL, \
+ EVP_CIPHER_set_asn1_iv, \
+ EVP_CIPHER_get_asn1_iv, \
+ NULL)
+
+struct evp_pkey_ctx_st {
+ /* Method associated with this operation */
+ const EVP_PKEY_METHOD *pmeth;
+ /* Engine that implements this method or NULL if builtin */
+ ENGINE *engine;
+ /* Key: may be NULL */
+ EVP_PKEY *pkey;
+ /* Peer key for key agreement, may be NULL */
+ EVP_PKEY *peerkey;
+ /* Actual operation */
+ int operation;
+ /* Algorithm specific data */
+ void *data;
+ /* Application specific data */
+ void *app_data;
+ /* Keygen callback */
+ EVP_PKEY_gen_cb *pkey_gencb;
+ /* implementation specific keygen data */
+ int *keygen_info;
+ int keygen_info_count;
+} /* EVP_PKEY_CTX */ ;
+
+#define EVP_PKEY_FLAG_DYNAMIC 1
+
+struct evp_pkey_method_st {
+ int pkey_id;
+ int flags;
+ int (*init) (EVP_PKEY_CTX *ctx);
+ int (*copy) (EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
+ void (*cleanup) (EVP_PKEY_CTX *ctx);
+ int (*paramgen_init) (EVP_PKEY_CTX *ctx);
+ int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+ int (*keygen_init) (EVP_PKEY_CTX *ctx);
+ int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+ int (*sign_init) (EVP_PKEY_CTX *ctx);
+ int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs, size_t tbslen);
+ int (*verify_init) (EVP_PKEY_CTX *ctx);
+ int (*verify) (EVP_PKEY_CTX *ctx,
+ const unsigned char *sig, size_t siglen,
+ const unsigned char *tbs, size_t tbslen);
+ int (*verify_recover_init) (EVP_PKEY_CTX *ctx);
+ int (*verify_recover) (EVP_PKEY_CTX *ctx,
+ unsigned char *rout, size_t *routlen,
+ const unsigned char *sig, size_t siglen);
+ int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+ int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+ EVP_MD_CTX *mctx);
+ int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+ int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen,
+ EVP_MD_CTX *mctx);
+ int (*encrypt_init) (EVP_PKEY_CTX *ctx);
+ int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen);
+ int (*decrypt_init) (EVP_PKEY_CTX *ctx);
+ int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen);
+ int (*derive_init) (EVP_PKEY_CTX *ctx);
+ int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+ int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
+ int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value);
+} /* EVP_PKEY_METHOD */ ;
+
+void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
+
+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
+ int passlen, ASN1_TYPE *param,
+ const EVP_CIPHER *c, const EVP_MD *md,
+ int en_de);
+
+#ifdef OPENSSL_FIPS
+
+# ifdef OPENSSL_DOING_MAKEDEPEND
+# undef SHA1_Init
+# undef SHA1_Update
+# undef SHA224_Init
+# undef SHA256_Init
+# undef SHA384_Init
+# undef SHA512_Init
+# undef DES_set_key_unchecked
+# endif
+
+# define RIPEMD160_Init private_RIPEMD160_Init
+# define WHIRLPOOL_Init private_WHIRLPOOL_Init
+# define MD5_Init private_MD5_Init
+# define MD4_Init private_MD4_Init
+# define MD2_Init private_MD2_Init
+# define MDC2_Init private_MDC2_Init
+# define SHA_Init private_SHA_Init
+# define SHA1_Init private_SHA1_Init
+# define SHA224_Init private_SHA224_Init
+# define SHA256_Init private_SHA256_Init
+# define SHA384_Init private_SHA384_Init
+# define SHA512_Init private_SHA512_Init
+
+# define BF_set_key private_BF_set_key
+# define CAST_set_key private_CAST_set_key
+# define idea_set_encrypt_key private_idea_set_encrypt_key
+# define SEED_set_key private_SEED_set_key
+# define RC2_set_key private_RC2_set_key
+# define RC4_set_key private_RC4_set_key
+# define DES_set_key_unchecked private_DES_set_key_unchecked
+# define Camellia_set_key private_Camellia_set_key
+
+#endif
diff --git a/openssl/evp_locl.h b/openssl/evp_locl.h
new file mode 120000
index 0000000..b654fdc
--- /dev/null
+++ b/openssl/evp_locl.h
@@ -0,0 +1 @@
+evp/evp_locl.h
\ No newline at end of file
diff --git a/openssl/ex_data.c b/openssl/ex_data.c
new file mode 100644
index 0000000..f96a517
--- /dev/null
+++ b/openssl/ex_data.c
@@ -0,0 +1,646 @@
+/* crypto/ex_data.c */
+
+/*
+ * Overhaul notes;
+ *
+ * This code is now *mostly* thread-safe. It is now easier to understand in what
+ * ways it is safe and in what ways it is not, which is an improvement. Firstly,
+ * all per-class stacks and index-counters for ex_data are stored in the same
+ * global LHASH table (keyed by class). This hash table uses locking for all
+ * access with the exception of CRYPTO_cleanup_all_ex_data(), which must only be
+ * called when no other threads can possibly race against it (even if it was
+ * locked, the race would mean it's possible the hash table might have been
+ * recreated after the cleanup). As classes can only be added to the hash table,
+ * and within each class, the stack of methods can only be incremented, the
+ * locking mechanics are simpler than they would otherwise be. For example, the
+ * new/dup/free ex_data functions will lock the hash table, copy the method
+ * pointers it needs from the relevant class, then unlock the hash table before
+ * actually applying those method pointers to the task of the new/dup/free
+ * operations. As they can't be removed from the method-stack, only
+ * supplemented, there's no race conditions associated with using them outside
+ * the lock. The get/set_ex_data functions are not locked because they do not
+ * involve this global state at all - they operate directly with a previously
+ * obtained per-class method index and a particular "ex_data" variable. These
+ * variables are usually instantiated per-context (eg. each RSA structure has
+ * one) so locking on read/write access to that variable can be locked locally
+ * if required (eg. using the "RSA" lock to synchronise access to a
+ * per-RSA-structure ex_data variable if required).
+ * [Geoff]
+ */
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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 "cryptlib.h"
+#include <openssl/lhash.h>
+
+/* What an "implementation of ex_data functionality" looks like */
+struct st_CRYPTO_EX_DATA_IMPL {
+ /*********************/
+ /* GLOBAL OPERATIONS */
+ /* Return a new class index */
+ int (*cb_new_class) (void);
+ /* Cleanup all state used by the implementation */
+ void (*cb_cleanup) (void);
+ /************************/
+ /* PER-CLASS OPERATIONS */
+ /* Get a new method index within a class */
+ int (*cb_get_new_index) (int class_index, long argl, void *argp,
+ CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func);
+ /* Initialise a new CRYPTO_EX_DATA of a given class */
+ int (*cb_new_ex_data) (int class_index, void *obj, CRYPTO_EX_DATA *ad);
+ /* Duplicate a CRYPTO_EX_DATA of a given class onto a copy */
+ int (*cb_dup_ex_data) (int class_index, CRYPTO_EX_DATA *to,
+ CRYPTO_EX_DATA *from);
+ /* Cleanup a CRYPTO_EX_DATA of a given class */
+ void (*cb_free_ex_data) (int class_index, void *obj, CRYPTO_EX_DATA *ad);
+};
+
+/* The implementation we use at run-time */
+static const CRYPTO_EX_DATA_IMPL *impl = NULL;
+
+/*
+ * To call "impl" functions, use this macro rather than referring to 'impl'
+ * directly, eg. EX_IMPL(get_new_index)(...);
+ */
+#define EX_IMPL(a) impl->cb_##a
+
+/* Predeclare the "default" ex_data implementation */
+static int int_new_class(void);
+static void int_cleanup(void);
+static int int_get_new_index(int class_index, long argl, void *argp,
+ CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func);
+static int int_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+ CRYPTO_EX_DATA *from);
+static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+static CRYPTO_EX_DATA_IMPL impl_default = {
+ int_new_class,
+ int_cleanup,
+ int_get_new_index,
+ int_new_ex_data,
+ int_dup_ex_data,
+ int_free_ex_data
+};
+
+/*
+ * Internal function that checks whether "impl" is set and if not, sets it to
+ * the default.
+ */
+static void impl_check(void)
+{
+ CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+ if (!impl)
+ impl = &impl_default;
+ CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+}
+
+/*
+ * A macro wrapper for impl_check that first uses a non-locked test before
+ * invoking the function (which checks again inside a lock).
+ */
+#define IMPL_CHECK if(!impl) impl_check();
+
+/* API functions to get/set the "ex_data" implementation */
+const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void)
+{
+ IMPL_CHECK return impl;
+}
+
+int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i)
+{
+ int toret = 0;
+ CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+ if (!impl) {
+ impl = i;
+ toret = 1;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+ return toret;
+}
+
+/****************************************************************************/
+/*
+ * Interal (default) implementation of "ex_data" support. API functions are
+ * further down.
+ */
+
+/*
+ * The type that represents what each "class" used to implement locally. A
+ * STACK of CRYPTO_EX_DATA_FUNCS plus a index-counter. The 'class_index' is
+ * the global value representing the class that is used to distinguish these
+ * items.
+ */
+typedef struct st_ex_class_item {
+ int class_index;
+ STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth;
+ int meth_num;
+} EX_CLASS_ITEM;
+
+/* When assigning new class indexes, this is our counter */
+static int ex_class = CRYPTO_EX_INDEX_USER;
+
+/* The global hash table of EX_CLASS_ITEM items */
+DECLARE_LHASH_OF(EX_CLASS_ITEM);
+static LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL;
+
+/* The callbacks required in the "ex_data" hash table */
+static unsigned long ex_class_item_hash(const EX_CLASS_ITEM *a)
+{
+ return a->class_index;
+}
+
+static IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM)
+
+static int ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b)
+{
+ return a->class_index - b->class_index;
+}
+
+static IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM)
+
+/*
+ * Internal functions used by the "impl_default" implementation to access the
+ * state
+ */
+static int ex_data_check(void)
+{
+ int toret = 1;
+ CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+ if (!ex_data && (ex_data = lh_EX_CLASS_ITEM_new()) == NULL)
+ toret = 0;
+ CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+ return toret;
+}
+
+/*
+ * This macros helps reduce the locking from repeated checks because the
+ * ex_data_check() function checks ex_data again inside a lock.
+ */
+#define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail}
+
+/* This "inner" callback is used by the callback function that follows it */
+static void def_cleanup_util_cb(CRYPTO_EX_DATA_FUNCS *funcs)
+{
+ OPENSSL_free(funcs);
+}
+
+/*
+ * This callback is used in lh_doall to destroy all EX_CLASS_ITEM values from
+ * "ex_data" prior to the ex_data hash table being itself destroyed. Doesn't
+ * do any locking.
+ */
+static void def_cleanup_cb(void *a_void)
+{
+ EX_CLASS_ITEM *item = (EX_CLASS_ITEM *)a_void;
+ sk_CRYPTO_EX_DATA_FUNCS_pop_free(item->meth, def_cleanup_util_cb);
+ OPENSSL_free(item);
+}
+
+/*
+ * Return the EX_CLASS_ITEM from the "ex_data" hash table that corresponds to
+ * a given class. Handles locking.
+ */
+static EX_CLASS_ITEM *def_get_class(int class_index)
+{
+ EX_CLASS_ITEM d, *p, *gen;
+ EX_DATA_CHECK(return NULL;)
+ d.class_index = class_index;
+ CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+ p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d);
+ if (!p) {
+ gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM));
+ if (gen) {
+ gen->class_index = class_index;
+ gen->meth_num = 0;
+ gen->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null();
+ if (!gen->meth)
+ OPENSSL_free(gen);
+ else {
+ /*
+ * Because we're inside the ex_data lock, the return value
+ * from the insert will be NULL
+ */
+ (void)lh_EX_CLASS_ITEM_insert(ex_data, gen);
+ p = gen;
+ }
+ }
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+ if (!p)
+ CRYPTOerr(CRYPTO_F_DEF_GET_CLASS, ERR_R_MALLOC_FAILURE);
+ return p;
+}
+
+/*
+ * Add a new method to the given EX_CLASS_ITEM and return the corresponding
+ * index (or -1 for error). Handles locking.
+ */
+static int def_add_index(EX_CLASS_ITEM *item, long argl, void *argp,
+ CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func)
+{
+ int toret = -1;
+ CRYPTO_EX_DATA_FUNCS *a =
+ (CRYPTO_EX_DATA_FUNCS *)OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS));
+ if (!a) {
+ CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ a->argl = argl;
+ a->argp = argp;
+ a->new_func = new_func;
+ a->dup_func = dup_func;
+ a->free_func = free_func;
+ CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+ while (sk_CRYPTO_EX_DATA_FUNCS_num(item->meth) <= item->meth_num) {
+ if (!sk_CRYPTO_EX_DATA_FUNCS_push(item->meth, NULL)) {
+ CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(a);
+ goto err;
+ }
+ }
+ toret = item->meth_num++;
+ (void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a);
+ err:
+ CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+ return toret;
+}
+
+/**************************************************************/
+/* The functions in the default CRYPTO_EX_DATA_IMPL structure */
+
+static int int_new_class(void)
+{
+ int toret;
+ CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA);
+ toret = ex_class++;
+ CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA);
+ return toret;
+}
+
+static void int_cleanup(void)
+{
+ EX_DATA_CHECK(return;)
+ lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb);
+ lh_EX_CLASS_ITEM_free(ex_data);
+ ex_data = NULL;
+ impl = NULL;
+}
+
+static int int_get_new_index(int class_index, long argl, void *argp,
+ CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func)
+{
+ EX_CLASS_ITEM *item = def_get_class(class_index);
+ if (!item)
+ return -1;
+ return def_add_index(item, argl, argp, new_func, dup_func, free_func);
+}
+
+/*
+ * Thread-safe by copying a class's array of "CRYPTO_EX_DATA_FUNCS" entries
+ * in the lock, then using them outside the lock. NB: Thread-safety only
+ * applies to the global "ex_data" state (ie. class definitions), not
+ * thread-safe on 'ad' itself.
+ */
+static int int_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+ int mx, i;
+ void *ptr;
+ CRYPTO_EX_DATA_FUNCS **storage = NULL;
+ EX_CLASS_ITEM *item = def_get_class(class_index);
+ if (!item)
+ /* error is already set */
+ return 0;
+ ad->sk = NULL;
+ CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+ mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
+ if (mx > 0) {
+ storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *));
+ if (!storage)
+ goto skip;
+ for (i = 0; i < mx; i++)
+ storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i);
+ }
+ skip:
+ CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+ if ((mx > 0) && !storage) {
+ CRYPTOerr(CRYPTO_F_INT_NEW_EX_DATA, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ for (i = 0; i < mx; i++) {
+ if (storage[i] && storage[i]->new_func) {
+ ptr = CRYPTO_get_ex_data(ad, i);
+ storage[i]->new_func(obj, ptr, ad, i,
+ storage[i]->argl, storage[i]->argp);
+ }
+ }
+ if (storage)
+ OPENSSL_free(storage);
+ return 1;
+}
+
+/* Same thread-safety notes as for "int_new_ex_data" */
+static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+ CRYPTO_EX_DATA *from)
+{
+ int mx, j, i;
+ char *ptr;
+ CRYPTO_EX_DATA_FUNCS **storage = NULL;
+ EX_CLASS_ITEM *item;
+ if (!from->sk)
+ /* 'to' should be "blank" which *is* just like 'from' */
+ return 1;
+ if ((item = def_get_class(class_index)) == NULL)
+ return 0;
+ CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+ mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
+ j = sk_void_num(from->sk);
+ if (j < mx)
+ mx = j;
+ if (mx > 0) {
+ storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *));
+ if (!storage)
+ goto skip;
+ for (i = 0; i < mx; i++)
+ storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i);
+ }
+ skip:
+ CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+ if ((mx > 0) && !storage) {
+ CRYPTOerr(CRYPTO_F_INT_DUP_EX_DATA, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ for (i = 0; i < mx; i++) {
+ ptr = CRYPTO_get_ex_data(from, i);
+ if (storage[i] && storage[i]->dup_func)
+ storage[i]->dup_func(to, from, &ptr, i,
+ storage[i]->argl, storage[i]->argp);
+ CRYPTO_set_ex_data(to, i, ptr);
+ }
+ if (storage)
+ OPENSSL_free(storage);
+ return 1;
+}
+
+/* Same thread-safety notes as for "int_new_ex_data" */
+static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+ int mx, i;
+ EX_CLASS_ITEM *item;
+ void *ptr;
+ CRYPTO_EX_DATA_FUNCS **storage = NULL;
+ if (ex_data == NULL)
+ return;
+ if ((item = def_get_class(class_index)) == NULL)
+ return;
+ CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+ mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
+ if (mx > 0) {
+ storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *));
+ if (!storage)
+ goto skip;
+ for (i = 0; i < mx; i++)
+ storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i);
+ }
+ skip:
+ CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+ if ((mx > 0) && !storage) {
+ CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA, ERR_R_MALLOC_FAILURE);
+ return;
+ }
+ for (i = 0; i < mx; i++) {
+ if (storage[i] && storage[i]->free_func) {
+ ptr = CRYPTO_get_ex_data(ad, i);
+ storage[i]->free_func(obj, ptr, ad, i,
+ storage[i]->argl, storage[i]->argp);
+ }
+ }
+ if (storage)
+ OPENSSL_free(storage);
+ if (ad->sk) {
+ sk_void_free(ad->sk);
+ ad->sk = NULL;
+ }
+}
+
+/********************************************************************/
+/*
+ * API functions that defer all "state" operations to the "ex_data"
+ * implementation we have set.
+ */
+
+/*
+ * Obtain an index for a new class (not the same as getting a new index
+ * within an existing class - this is actually getting a new *class*)
+ */
+int CRYPTO_ex_data_new_class(void)
+{
+ IMPL_CHECK return EX_IMPL(new_class) ();
+}
+
+/*
+ * Release all "ex_data" state to prevent memory leaks. This can't be made
+ * thread-safe without overhauling a lot of stuff, and shouldn't really be
+ * called under potential race-conditions anyway (it's for program shutdown
+ * after all).
+ */
+void CRYPTO_cleanup_all_ex_data(void)
+{
+ IMPL_CHECK EX_IMPL(cleanup) ();
+}
+
+/* Inside an existing class, get/register a new index. */
+int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
+ CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func)
+{
+ int ret = -1;
+
+ IMPL_CHECK
+ ret = EX_IMPL(get_new_index) (class_index,
+ argl, argp, new_func, dup_func,
+ free_func);
+ return ret;
+}
+
+/*
+ * Initialise a new CRYPTO_EX_DATA for use in a particular class - including
+ * calling new() callbacks for each index in the class used by this variable
+ */
+int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+ IMPL_CHECK return EX_IMPL(new_ex_data) (class_index, obj, ad);
+}
+
+/*
+ * Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks
+ * for each index in the class used by this variable
+ */
+int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+ CRYPTO_EX_DATA *from)
+{
+ IMPL_CHECK return EX_IMPL(dup_ex_data) (class_index, to, from);
+}
+
+/*
+ * Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for
+ * each index in the class used by this variable
+ */
+void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+ IMPL_CHECK EX_IMPL(free_ex_data) (class_index, obj, ad);
+}
+
+/*
+ * For a given CRYPTO_EX_DATA variable, set the value corresponding to a
+ * particular index in the class used by this variable
+ */
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val)
+{
+ int i;
+
+ if (ad->sk == NULL) {
+ if ((ad->sk = sk_void_new_null()) == NULL) {
+ CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ }
+ i = sk_void_num(ad->sk);
+
+ while (i <= idx) {
+ if (!sk_void_push(ad->sk, NULL)) {
+ CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ i++;
+ }
+ sk_void_set(ad->sk, idx, val);
+ return (1);
+}
+
+/*
+ * For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a
+ * particular index in the class used by this variable
+ */
+void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
+{
+ if (ad->sk == NULL)
+ return (0);
+ else if (idx >= sk_void_num(ad->sk))
+ return (0);
+ else
+ return (sk_void_value(ad->sk, idx));
+}
+
+IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS)
diff --git a/openssl/jpake.h b/openssl/jpake.h
new file mode 120000
index 0000000..ee91426
--- /dev/null
+++ b/openssl/jpake.h
@@ -0,0 +1 @@
+jpake/jpake.h
\ No newline at end of file
diff --git a/openssl/jpake/Makefile b/openssl/jpake/Makefile
new file mode 100644
index 0000000..c2a8201
--- /dev/null
+++ b/openssl/jpake/Makefile
@@ -0,0 +1,48 @@
+# Copyright 2010 by Nest Labs, Inc. All rights reserved.
+#
+# This program is confidential and proprietary to Nest Labs, Inc.,
+# and may not be reproduced, published or disclosed to others without
+# company authorization.
+#
+
+DEPTH = ../../
+
+include $(DEPTH)Makefile.config
+
+CFLAGS += -Os -H
+
+OUTDIR = $(OBJ_DIR)
+SRCDIR = ./
+INCDIR = ./
+
+OBJECT_FILES = \
+ jpake \
+ jpake_err
+
+HEADER_FILES = \
+
+OBJECTS = $(OBJECT_FILES:%=$(OUTDIR)/%.o)
+HEADERS = $(HEADER_FILES:%=$(INCDIR)/%.h)
+
+all: $(OUTDIR) $(LIB_DIR)/libjpake.a
+
+$(OUTDIR):
+ $(MKDIR) $(OUTDIR)
+
+clean:
+ $(RM) $(OUTDIR)
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.c $(HEADERS)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.cpp $(HEADERS)
+ $(CC) $(CFLAGS) $< -o $@
+
+$(OUTDIR)/libjpake.a: $(OBJECTS)
+ $(ARCHIVE) $@ $(OBJECTS)
+ $(RANLIB) $@
+
+$(LIB_DIR)/libjpake.a: $(OUTDIR)/libjpake.a
+ $(MKDIR) $(dir $@)
+ $(CP) $< $@
+
diff --git a/openssl/jpake/jpake.c b/openssl/jpake/jpake.c
new file mode 100644
index 0000000..fb0d577
--- /dev/null
+++ b/openssl/jpake/jpake.c
@@ -0,0 +1,507 @@
+#include "jpake.h"
+
+#include <openssl/crypto.h>
+#include <openssl/sha.h>
+#include <openssl/err.h>
+#include <string.h>
+
+/*
+ * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or
+ * Bob's (x3, x4, x1, x2). If you see what I mean.
+ */
+
+typedef struct {
+ char *name; /* Must be unique */
+ char *peer_name;
+ BIGNUM *p;
+ BIGNUM *g;
+ BIGNUM *q;
+ BIGNUM *gxc; /* Alice's g^{x3} or Bob's g^{x1} */
+ BIGNUM *gxd; /* Alice's g^{x4} or Bob's g^{x2} */
+} JPAKE_CTX_PUBLIC;
+
+struct JPAKE_CTX {
+ JPAKE_CTX_PUBLIC p;
+ BIGNUM *secret; /* The shared secret */
+ BN_CTX *ctx;
+ BIGNUM *xa; /* Alice's x1 or Bob's x3 */
+ BIGNUM *xb; /* Alice's x2 or Bob's x4 */
+ BIGNUM *key; /* The calculated (shared) key */
+};
+
+static void JPAKE_ZKP_init(JPAKE_ZKP *zkp)
+{
+ zkp->gr = BN_new();
+ zkp->b = BN_new();
+}
+
+static void JPAKE_ZKP_release(JPAKE_ZKP *zkp)
+{
+ BN_free(zkp->b);
+ BN_free(zkp->gr);
+}
+
+/* Two birds with one stone - make the global name as expected */
+#define JPAKE_STEP_PART_init JPAKE_STEP2_init
+#define JPAKE_STEP_PART_release JPAKE_STEP2_release
+
+void JPAKE_STEP_PART_init(JPAKE_STEP_PART *p)
+{
+ p->gx = BN_new();
+ JPAKE_ZKP_init(&p->zkpx);
+}
+
+void JPAKE_STEP_PART_release(JPAKE_STEP_PART *p)
+{
+ JPAKE_ZKP_release(&p->zkpx);
+ BN_free(p->gx);
+}
+
+void JPAKE_STEP1_init(JPAKE_STEP1 *s1)
+{
+ JPAKE_STEP_PART_init(&s1->p1);
+ JPAKE_STEP_PART_init(&s1->p2);
+}
+
+void JPAKE_STEP1_release(JPAKE_STEP1 *s1)
+{
+ JPAKE_STEP_PART_release(&s1->p2);
+ JPAKE_STEP_PART_release(&s1->p1);
+}
+
+static void JPAKE_CTX_init(JPAKE_CTX *ctx, const char *name,
+ const char *peer_name, const BIGNUM *p,
+ const BIGNUM *g, const BIGNUM *q,
+ const BIGNUM *secret)
+{
+ ctx->p.name = OPENSSL_strdup(name);
+ ctx->p.peer_name = OPENSSL_strdup(peer_name);
+ ctx->p.p = BN_dup(p);
+ ctx->p.g = BN_dup(g);
+ ctx->p.q = BN_dup(q);
+ ctx->secret = BN_dup(secret);
+
+ ctx->p.gxc = BN_new();
+ ctx->p.gxd = BN_new();
+
+ ctx->xa = BN_new();
+ ctx->xb = BN_new();
+ ctx->key = BN_new();
+ ctx->ctx = BN_CTX_new();
+}
+
+static void JPAKE_CTX_release(JPAKE_CTX *ctx)
+{
+ BN_CTX_free(ctx->ctx);
+ BN_clear_free(ctx->key);
+ BN_clear_free(ctx->xb);
+ BN_clear_free(ctx->xa);
+
+ BN_free(ctx->p.gxd);
+ BN_free(ctx->p.gxc);
+
+ BN_clear_free(ctx->secret);
+ BN_free(ctx->p.q);
+ BN_free(ctx->p.g);
+ BN_free(ctx->p.p);
+ OPENSSL_free(ctx->p.peer_name);
+ OPENSSL_free(ctx->p.name);
+
+ memset(ctx, '\0', sizeof *ctx);
+}
+
+JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name,
+ const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
+ const BIGNUM *secret)
+{
+ JPAKE_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
+
+ JPAKE_CTX_init(ctx, name, peer_name, p, g, q, secret);
+
+ return ctx;
+}
+
+void JPAKE_CTX_free(JPAKE_CTX *ctx)
+{
+ JPAKE_CTX_release(ctx);
+ OPENSSL_free(ctx);
+}
+
+static void hashlength(SHA_CTX *sha, size_t l)
+{
+ unsigned char b[2];
+
+ OPENSSL_assert(l <= 0xffff);
+ b[0] = l >> 8;
+ b[1] = l & 0xff;
+ SHA1_Update(sha, b, 2);
+}
+
+static void hashstring(SHA_CTX *sha, const char *string)
+{
+ size_t l = strlen(string);
+
+ hashlength(sha, l);
+ SHA1_Update(sha, string, l);
+}
+
+static void hashbn(SHA_CTX *sha, const BIGNUM *bn)
+{
+ size_t l = BN_num_bytes(bn);
+ unsigned char *bin = OPENSSL_malloc(l);
+
+ hashlength(sha, l);
+ BN_bn2bin(bn, bin);
+ SHA1_Update(sha, bin, l);
+ OPENSSL_free(bin);
+}
+
+/* h=hash(g, g^r, g^x, name) */
+static void zkp_hash(BIGNUM *h, const BIGNUM *zkpg, const JPAKE_STEP_PART *p,
+ const char *proof_name)
+{
+ unsigned char md[SHA_DIGEST_LENGTH];
+ SHA_CTX sha;
+
+ /*
+ * XXX: hash should not allow moving of the boundaries - Java code
+ * is flawed in this respect. Length encoding seems simplest.
+ */
+ SHA1_Init(&sha);
+ hashbn(&sha, zkpg);
+ OPENSSL_assert(!BN_is_zero(p->zkpx.gr));
+ hashbn(&sha, p->zkpx.gr);
+ hashbn(&sha, p->gx);
+ hashstring(&sha, proof_name);
+ SHA1_Final(md, &sha);
+ BN_bin2bn(md, SHA_DIGEST_LENGTH, h);
+}
+
+/*
+ * Prove knowledge of x
+ * Note that p->gx has already been calculated
+ */
+static void generate_zkp(JPAKE_STEP_PART *p, const BIGNUM *x,
+ const BIGNUM *zkpg, JPAKE_CTX *ctx)
+{
+ BIGNUM *r = BN_new();
+ BIGNUM *h = BN_new();
+ BIGNUM *t = BN_new();
+
+ /*-
+ * r in [0,q)
+ * XXX: Java chooses r in [0, 2^160) - i.e. distribution not uniform
+ */
+ BN_rand_range(r, ctx->p.q);
+ /* g^r */
+ BN_mod_exp(p->zkpx.gr, zkpg, r, ctx->p.p, ctx->ctx);
+
+ /* h=hash... */
+ zkp_hash(h, zkpg, p, ctx->p.name);
+
+ /* b = r - x*h */
+ BN_mod_mul(t, x, h, ctx->p.q, ctx->ctx);
+ BN_mod_sub(p->zkpx.b, r, t, ctx->p.q, ctx->ctx);
+
+ /* cleanup */
+ BN_free(t);
+ BN_free(h);
+ BN_free(r);
+}
+
+static int verify_zkp(const JPAKE_STEP_PART *p, const BIGNUM *zkpg,
+ JPAKE_CTX *ctx)
+{
+ BIGNUM *h = BN_new();
+ BIGNUM *t1 = BN_new();
+ BIGNUM *t2 = BN_new();
+ BIGNUM *t3 = BN_new();
+ int ret = 0;
+
+ zkp_hash(h, zkpg, p, ctx->p.peer_name);
+
+ /* t1 = g^b */
+ BN_mod_exp(t1, zkpg, p->zkpx.b, ctx->p.p, ctx->ctx);
+ /* t2 = (g^x)^h = g^{hx} */
+ BN_mod_exp(t2, p->gx, h, ctx->p.p, ctx->ctx);
+ /* t3 = t1 * t2 = g^{hx} * g^b = g^{hx+b} = g^r (allegedly) */
+ BN_mod_mul(t3, t1, t2, ctx->p.p, ctx->ctx);
+
+ /* verify t3 == g^r */
+ if (BN_cmp(t3, p->zkpx.gr) == 0)
+ ret = 1;
+ else
+ JPAKEerr(JPAKE_F_VERIFY_ZKP, JPAKE_R_ZKP_VERIFY_FAILED);
+
+ /* cleanup */
+ BN_free(t3);
+ BN_free(t2);
+ BN_free(t1);
+ BN_free(h);
+
+ return ret;
+}
+
+static void generate_step_part(JPAKE_STEP_PART *p, const BIGNUM *x,
+ const BIGNUM *g, JPAKE_CTX *ctx)
+{
+ BN_mod_exp(p->gx, g, x, ctx->p.p, ctx->ctx);
+ generate_zkp(p, x, g, ctx);
+}
+
+/* Generate each party's random numbers. xa is in [0, q), xb is in [1, q). */
+static void genrand(JPAKE_CTX *ctx)
+{
+ BIGNUM *qm1;
+
+ /* xa in [0, q) */
+ BN_rand_range(ctx->xa, ctx->p.q);
+
+ /* q-1 */
+ qm1 = BN_new();
+ BN_copy(qm1, ctx->p.q);
+ BN_sub_word(qm1, 1);
+
+ /* ... and xb in [0, q-1) */
+ BN_rand_range(ctx->xb, qm1);
+ /* [1, q) */
+ BN_add_word(ctx->xb, 1);
+
+ /* cleanup */
+ BN_free(qm1);
+}
+
+int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx)
+{
+ genrand(ctx);
+ generate_step_part(&send->p1, ctx->xa, ctx->p.g, ctx);
+ generate_step_part(&send->p2, ctx->xb, ctx->p.g, ctx);
+
+ return 1;
+}
+
+/* g^x is a legal value */
+static int is_legal(const BIGNUM *gx, const JPAKE_CTX *ctx)
+{
+ BIGNUM *t;
+ int res;
+
+ if (BN_is_negative(gx) || BN_is_zero(gx) || BN_cmp(gx, ctx->p.p) >= 0)
+ return 0;
+
+ t = BN_new();
+ BN_mod_exp(t, gx, ctx->p.q, ctx->p.p, ctx->ctx);
+ res = BN_is_one(t);
+ BN_free(t);
+
+ return res;
+}
+
+int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received)
+{
+ if (!is_legal(received->p1.gx, ctx)) {
+ JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS,
+ JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL);
+ return 0;
+ }
+
+ if (!is_legal(received->p2.gx, ctx)) {
+ JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS,
+ JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL);
+ return 0;
+ }
+
+ /* verify their ZKP(xc) */
+ if (!verify_zkp(&received->p1, ctx->p.g, ctx)) {
+ JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X3_FAILED);
+ return 0;
+ }
+
+ /* verify their ZKP(xd) */
+ if (!verify_zkp(&received->p2, ctx->p.g, ctx)) {
+ JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X4_FAILED);
+ return 0;
+ }
+
+ /* g^xd != 1 */
+ if (BN_is_one(received->p2.gx)) {
+ JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_ONE);
+ return 0;
+ }
+
+ /* Save the bits we need for later */
+ BN_copy(ctx->p.gxc, received->p1.gx);
+ BN_copy(ctx->p.gxd, received->p2.gx);
+
+ return 1;
+}
+
+int JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx)
+{
+ BIGNUM *t1 = BN_new();
+ BIGNUM *t2 = BN_new();
+
+ /*-
+ * X = g^{(xa + xc + xd) * xb * s}
+ * t1 = g^xa
+ */
+ BN_mod_exp(t1, ctx->p.g, ctx->xa, ctx->p.p, ctx->ctx);
+ /* t2 = t1 * g^{xc} = g^{xa} * g^{xc} = g^{xa + xc} */
+ BN_mod_mul(t2, t1, ctx->p.gxc, ctx->p.p, ctx->ctx);
+ /* t1 = t2 * g^{xd} = g^{xa + xc + xd} */
+ BN_mod_mul(t1, t2, ctx->p.gxd, ctx->p.p, ctx->ctx);
+ /* t2 = xb * s */
+ BN_mod_mul(t2, ctx->xb, ctx->secret, ctx->p.q, ctx->ctx);
+
+ /*-
+ * ZKP(xb * s)
+ * XXX: this is kinda funky, because we're using
+ *
+ * g' = g^{xa + xc + xd}
+ *
+ * as the generator, which means X is g'^{xb * s}
+ * X = t1^{t2} = t1^{xb * s} = g^{(xa + xc + xd) * xb * s}
+ */
+ generate_step_part(send, t2, t1, ctx);
+
+ /* cleanup */
+ BN_free(t1);
+ BN_free(t2);
+
+ return 1;
+}
+
+/* gx = g^{xc + xa + xb} * xd * s */
+static int compute_key(JPAKE_CTX *ctx, const BIGNUM *gx)
+{
+ BIGNUM *t1 = BN_new();
+ BIGNUM *t2 = BN_new();
+ BIGNUM *t3 = BN_new();
+
+ /*-
+ * K = (gx/g^{xb * xd * s})^{xb}
+ * = (g^{(xc + xa + xb) * xd * s - xb * xd *s})^{xb}
+ * = (g^{(xa + xc) * xd * s})^{xb}
+ * = g^{(xa + xc) * xb * xd * s}
+ * [which is the same regardless of who calculates it]
+ */
+
+ /* t1 = (g^{xd})^{xb} = g^{xb * xd} */
+ BN_mod_exp(t1, ctx->p.gxd, ctx->xb, ctx->p.p, ctx->ctx);
+ /* t2 = -s = q-s */
+ BN_sub(t2, ctx->p.q, ctx->secret);
+ /* t3 = t1^t2 = g^{-xb * xd * s} */
+ BN_mod_exp(t3, t1, t2, ctx->p.p, ctx->ctx);
+ /* t1 = gx * t3 = X/g^{xb * xd * s} */
+ BN_mod_mul(t1, gx, t3, ctx->p.p, ctx->ctx);
+ /* K = t1^{xb} */
+ BN_mod_exp(ctx->key, t1, ctx->xb, ctx->p.p, ctx->ctx);
+
+ /* cleanup */
+ BN_free(t3);
+ BN_free(t2);
+ BN_free(t1);
+
+ return 1;
+}
+
+int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received)
+{
+ BIGNUM *t1 = BN_new();
+ BIGNUM *t2 = BN_new();
+ int ret = 0;
+
+ /*-
+ * g' = g^{xc + xa + xb} [from our POV]
+ * t1 = xa + xb
+ */
+ BN_mod_add(t1, ctx->xa, ctx->xb, ctx->p.q, ctx->ctx);
+ /* t2 = g^{t1} = g^{xa+xb} */
+ BN_mod_exp(t2, ctx->p.g, t1, ctx->p.p, ctx->ctx);
+ /* t1 = g^{xc} * t2 = g^{xc + xa + xb} */
+ BN_mod_mul(t1, ctx->p.gxc, t2, ctx->p.p, ctx->ctx);
+
+ if (verify_zkp(received, t1, ctx))
+ ret = 1;
+ else
+ JPAKEerr(JPAKE_F_JPAKE_STEP2_PROCESS, JPAKE_R_VERIFY_B_FAILED);
+
+ compute_key(ctx, received->gx);
+
+ /* cleanup */
+ BN_free(t2);
+ BN_free(t1);
+
+ return ret;
+}
+
+static void quickhashbn(unsigned char *md, const BIGNUM *bn)
+{
+ SHA_CTX sha;
+
+ SHA1_Init(&sha);
+ hashbn(&sha, bn);
+ SHA1_Final(md, &sha);
+}
+
+void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a)
+{
+}
+
+int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx)
+{
+ quickhashbn(send->hhk, ctx->key);
+ SHA1(send->hhk, sizeof send->hhk, send->hhk);
+
+ return 1;
+}
+
+int JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received)
+{
+ unsigned char hhk[SHA_DIGEST_LENGTH];
+
+ quickhashbn(hhk, ctx->key);
+ SHA1(hhk, sizeof hhk, hhk);
+ if (memcmp(hhk, received->hhk, sizeof hhk)) {
+ JPAKEerr(JPAKE_F_JPAKE_STEP3A_PROCESS,
+ JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH);
+ return 0;
+ }
+ return 1;
+}
+
+void JPAKE_STEP3A_release(JPAKE_STEP3A *s3a)
+{
+}
+
+void JPAKE_STEP3B_init(JPAKE_STEP3B *s3b)
+{
+}
+
+int JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx)
+{
+ quickhashbn(send->hk, ctx->key);
+
+ return 1;
+}
+
+int JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received)
+{
+ unsigned char hk[SHA_DIGEST_LENGTH];
+
+ quickhashbn(hk, ctx->key);
+ if (memcmp(hk, received->hk, sizeof hk)) {
+ JPAKEerr(JPAKE_F_JPAKE_STEP3B_PROCESS, JPAKE_R_HASH_OF_KEY_MISMATCH);
+ return 0;
+ }
+ return 1;
+}
+
+void JPAKE_STEP3B_release(JPAKE_STEP3B *s3b)
+{
+}
+
+const BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx)
+{
+ return ctx->key;
+}
diff --git a/openssl/jpake/jpake.h b/openssl/jpake/jpake.h
new file mode 100644
index 0000000..371eed6
--- /dev/null
+++ b/openssl/jpake/jpake.h
@@ -0,0 +1,128 @@
+/*
+ * Implement J-PAKE, as described in
+ * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf
+ *
+ * With hints from http://www.cl.cam.ac.uk/~fh240/software/JPAKE2.java.
+ */
+
+#ifndef HEADER_JPAKE_H
+# define HEADER_JPAKE_H
+
+# include <openssl/opensslconf.h>
+
+# ifdef OPENSSL_NO_JPAKE
+# error JPAKE is disabled.
+# endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# include <openssl/bn.h>
+# include <openssl/sha.h>
+
+typedef struct JPAKE_CTX JPAKE_CTX;
+
+/* Note that "g" in the ZKPs is not necessarily the J-PAKE g. */
+typedef struct {
+ BIGNUM *gr; /* g^r (r random) */
+ BIGNUM *b; /* b = r - x*h, h=hash(g, g^r, g^x, name) */
+} JPAKE_ZKP;
+
+typedef struct {
+ BIGNUM *gx; /* g^x in step 1, g^(xa + xc + xd) * xb * s
+ * in step 2 */
+ JPAKE_ZKP zkpx; /* ZKP(x) or ZKP(xb * s) */
+} JPAKE_STEP_PART;
+
+typedef struct {
+ JPAKE_STEP_PART p1; /* g^x3, ZKP(x3) or g^x1, ZKP(x1) */
+ JPAKE_STEP_PART p2; /* g^x4, ZKP(x4) or g^x2, ZKP(x2) */
+} JPAKE_STEP1;
+
+typedef JPAKE_STEP_PART JPAKE_STEP2;
+
+typedef struct {
+ unsigned char hhk[SHA_DIGEST_LENGTH];
+} JPAKE_STEP3A;
+
+typedef struct {
+ unsigned char hk[SHA_DIGEST_LENGTH];
+} JPAKE_STEP3B;
+
+/* Parameters are copied */
+JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name,
+ const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
+ const BIGNUM *secret);
+void JPAKE_CTX_free(JPAKE_CTX *ctx);
+
+/*
+ * Note that JPAKE_STEP1 can be used multiple times before release
+ * without another init.
+ */
+void JPAKE_STEP1_init(JPAKE_STEP1 *s1);
+int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx);
+int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received);
+void JPAKE_STEP1_release(JPAKE_STEP1 *s1);
+
+/*
+ * Note that JPAKE_STEP2 can be used multiple times before release
+ * without another init.
+ */
+void JPAKE_STEP2_init(JPAKE_STEP2 *s2);
+int JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx);
+int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received);
+void JPAKE_STEP2_release(JPAKE_STEP2 *s2);
+
+/*
+ * Optionally verify the shared key. If the shared secrets do not
+ * match, the two ends will disagree about the shared key, but
+ * otherwise the protocol will succeed.
+ */
+void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a);
+int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx);
+int JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received);
+void JPAKE_STEP3A_release(JPAKE_STEP3A *s3a);
+
+void JPAKE_STEP3B_init(JPAKE_STEP3B *s3b);
+int JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx);
+int JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received);
+void JPAKE_STEP3B_release(JPAKE_STEP3B *s3b);
+
+/*
+ * the return value belongs to the library and will be released when
+ * ctx is released, and will change when a new handshake is performed.
+ */
+const BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx);
+
+/* 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.
+ */
+void ERR_load_JPAKE_strings(void);
+
+/* Error codes for the JPAKE functions. */
+
+/* Function codes. */
+# define JPAKE_F_JPAKE_STEP1_PROCESS 101
+# define JPAKE_F_JPAKE_STEP2_PROCESS 102
+# define JPAKE_F_JPAKE_STEP3A_PROCESS 103
+# define JPAKE_F_JPAKE_STEP3B_PROCESS 104
+# define JPAKE_F_VERIFY_ZKP 100
+
+/* Reason codes. */
+# define JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL 108
+# define JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL 109
+# define JPAKE_R_G_TO_THE_X4_IS_ONE 105
+# define JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH 106
+# define JPAKE_R_HASH_OF_KEY_MISMATCH 107
+# define JPAKE_R_VERIFY_B_FAILED 102
+# define JPAKE_R_VERIFY_X3_FAILED 103
+# define JPAKE_R_VERIFY_X4_FAILED 104
+# define JPAKE_R_ZKP_VERIFY_FAILED 100
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/jpake/jpake_err.c b/openssl/jpake/jpake_err.c
new file mode 100644
index 0000000..be236d9
--- /dev/null
+++ b/openssl/jpake/jpake_err.c
@@ -0,0 +1,108 @@
+/* crypto/jpake/jpake_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2010 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).
+ *
+ */
+
+/*
+ * NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/jpake.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_JPAKE,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_JPAKE,0,reason)
+
+static ERR_STRING_DATA JPAKE_str_functs[] = {
+ {ERR_FUNC(JPAKE_F_JPAKE_STEP1_PROCESS), "JPAKE_STEP1_process"},
+ {ERR_FUNC(JPAKE_F_JPAKE_STEP2_PROCESS), "JPAKE_STEP2_process"},
+ {ERR_FUNC(JPAKE_F_JPAKE_STEP3A_PROCESS), "JPAKE_STEP3A_process"},
+ {ERR_FUNC(JPAKE_F_JPAKE_STEP3B_PROCESS), "JPAKE_STEP3B_process"},
+ {ERR_FUNC(JPAKE_F_VERIFY_ZKP), "VERIFY_ZKP"},
+ {0, NULL}
+};
+
+static ERR_STRING_DATA JPAKE_str_reasons[] = {
+ {ERR_REASON(JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL),
+ "g to the x3 is not legal"},
+ {ERR_REASON(JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL),
+ "g to the x4 is not legal"},
+ {ERR_REASON(JPAKE_R_G_TO_THE_X4_IS_ONE), "g to the x4 is one"},
+ {ERR_REASON(JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH),
+ "hash of hash of key mismatch"},
+ {ERR_REASON(JPAKE_R_HASH_OF_KEY_MISMATCH), "hash of key mismatch"},
+ {ERR_REASON(JPAKE_R_VERIFY_B_FAILED), "verify b failed"},
+ {ERR_REASON(JPAKE_R_VERIFY_X3_FAILED), "verify x3 failed"},
+ {ERR_REASON(JPAKE_R_VERIFY_X4_FAILED), "verify x4 failed"},
+ {ERR_REASON(JPAKE_R_ZKP_VERIFY_FAILED), "zkp verify failed"},
+ {0, NULL}
+};
+
+#endif
+
+void ERR_load_JPAKE_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+ if (ERR_func_error_string(JPAKE_str_functs[0].error) == NULL) {
+ ERR_load_strings(0, JPAKE_str_functs);
+ ERR_load_strings(0, JPAKE_str_reasons);
+ }
+#endif
+}
diff --git a/openssl/jpake/jpaketest.c b/openssl/jpake/jpaketest.c
new file mode 100644
index 0000000..ef9e54b
--- /dev/null
+++ b/openssl/jpake/jpaketest.c
@@ -0,0 +1,185 @@
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_JPAKE
+
+# include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ printf("No J-PAKE support\n");
+ return (0);
+}
+
+#else
+
+# include <openssl/jpake.h>
+# include <openssl/err.h>
+
+static void showbn(const char *name, const BIGNUM *bn)
+{
+ fputs(name, stdout);
+ fputs(" = ", stdout);
+ BN_print_fp(stdout, bn);
+ putc('\n', stdout);
+}
+
+static int run_jpake(JPAKE_CTX *alice, JPAKE_CTX *bob)
+{
+ JPAKE_STEP1 alice_s1;
+ JPAKE_STEP1 bob_s1;
+ JPAKE_STEP2 alice_s2;
+ JPAKE_STEP2 bob_s2;
+ JPAKE_STEP3A alice_s3a;
+ JPAKE_STEP3B bob_s3b;
+
+ /* Alice -> Bob: step 1 */
+ puts("A->B s1");
+ JPAKE_STEP1_init(&alice_s1);
+ JPAKE_STEP1_generate(&alice_s1, alice);
+ if (!JPAKE_STEP1_process(bob, &alice_s1)) {
+ printf("Bob fails to process Alice's step 1\n");
+ ERR_print_errors_fp(stdout);
+ return 1;
+ }
+ JPAKE_STEP1_release(&alice_s1);
+
+ /* Bob -> Alice: step 1 */
+ puts("B->A s1");
+ JPAKE_STEP1_init(&bob_s1);
+ JPAKE_STEP1_generate(&bob_s1, bob);
+ if (!JPAKE_STEP1_process(alice, &bob_s1)) {
+ printf("Alice fails to process Bob's step 1\n");
+ ERR_print_errors_fp(stdout);
+ return 2;
+ }
+ JPAKE_STEP1_release(&bob_s1);
+
+ /* Alice -> Bob: step 2 */
+ puts("A->B s2");
+ JPAKE_STEP2_init(&alice_s2);
+ JPAKE_STEP2_generate(&alice_s2, alice);
+ if (!JPAKE_STEP2_process(bob, &alice_s2)) {
+ printf("Bob fails to process Alice's step 2\n");
+ ERR_print_errors_fp(stdout);
+ return 3;
+ }
+ JPAKE_STEP2_release(&alice_s2);
+
+ /* Bob -> Alice: step 2 */
+ puts("B->A s2");
+ JPAKE_STEP2_init(&bob_s2);
+ JPAKE_STEP2_generate(&bob_s2, bob);
+ if (!JPAKE_STEP2_process(alice, &bob_s2)) {
+ printf("Alice fails to process Bob's step 2\n");
+ ERR_print_errors_fp(stdout);
+ return 4;
+ }
+ JPAKE_STEP2_release(&bob_s2);
+
+ showbn("Alice's key", JPAKE_get_shared_key(alice));
+ showbn("Bob's key ", JPAKE_get_shared_key(bob));
+
+ /* Alice -> Bob: step 3a */
+ puts("A->B s3a");
+ JPAKE_STEP3A_init(&alice_s3a);
+ JPAKE_STEP3A_generate(&alice_s3a, alice);
+ if (!JPAKE_STEP3A_process(bob, &alice_s3a)) {
+ printf("Bob fails to process Alice's step 3a\n");
+ ERR_print_errors_fp(stdout);
+ return 5;
+ }
+ JPAKE_STEP3A_release(&alice_s3a);
+
+ /* Bob -> Alice: step 3b */
+ puts("B->A s3b");
+ JPAKE_STEP3B_init(&bob_s3b);
+ JPAKE_STEP3B_generate(&bob_s3b, bob);
+ if (!JPAKE_STEP3B_process(alice, &bob_s3b)) {
+ printf("Alice fails to process Bob's step 3b\n");
+ ERR_print_errors_fp(stdout);
+ return 6;
+ }
+ JPAKE_STEP3B_release(&bob_s3b);
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ JPAKE_CTX *alice;
+ JPAKE_CTX *bob;
+ BIGNUM *p = NULL;
+ BIGNUM *g = NULL;
+ BIGNUM *q = NULL;
+ BIGNUM *secret = BN_new();
+ BIO *bio_err;
+
+ bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+ CRYPTO_malloc_debug_init();
+ CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+ ERR_load_crypto_strings();
+
+ /*-
+ BN_hex2bn(&p, "fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7");
+ BN_hex2bn(&g, "f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a");
+ BN_hex2bn(&q, "9760508f15230bccb292b982a2eb840bf0581cf5");
+ */
+ /*-
+ p = BN_new();
+ BN_generate_prime(p, 1024, 1, NULL, NULL, NULL, NULL);
+ */
+ /* Use a safe prime for p (that we found earlier) */
+ BN_hex2bn(&p,
+ "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F");
+ showbn("p", p);
+ g = BN_new();
+ BN_set_word(g, 2);
+ showbn("g", g);
+ q = BN_new();
+ BN_rshift1(q, p);
+ showbn("q", q);
+
+ BN_rand(secret, 32, -1, 0);
+
+ /* A normal run, expect this to work... */
+ alice = JPAKE_CTX_new("Alice", "Bob", p, g, q, secret);
+ bob = JPAKE_CTX_new("Bob", "Alice", p, g, q, secret);
+
+ if (run_jpake(alice, bob) != 0) {
+ fprintf(stderr, "Plain JPAKE run failed\n");
+ return 1;
+ }
+
+ JPAKE_CTX_free(bob);
+ JPAKE_CTX_free(alice);
+
+ /* Now give Alice and Bob different secrets */
+ alice = JPAKE_CTX_new("Alice", "Bob", p, g, q, secret);
+ BN_add_word(secret, 1);
+ bob = JPAKE_CTX_new("Bob", "Alice", p, g, q, secret);
+
+ if (run_jpake(alice, bob) != 5) {
+ fprintf(stderr, "Mismatched secret JPAKE run failed\n");
+ return 1;
+ }
+
+ JPAKE_CTX_free(bob);
+ JPAKE_CTX_free(alice);
+
+ BN_free(secret);
+ BN_free(q);
+ BN_free(g);
+ BN_free(p);
+
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_thread_state(NULL);
+ ERR_free_strings();
+ CRYPTO_mem_leaks(bio_err);
+
+ return 0;
+}
+
+#endif
diff --git a/openssl/lhash.h b/openssl/lhash.h
new file mode 120000
index 0000000..a58e65a
--- /dev/null
+++ b/openssl/lhash.h
@@ -0,0 +1 @@
+lhash/lhash.h
\ No newline at end of file
diff --git a/openssl/lhash/lhash.c b/openssl/lhash/lhash.c
new file mode 100644
index 0000000..53c5c13
--- /dev/null
+++ b/openssl/lhash/lhash.c
@@ -0,0 +1,458 @@
+/* crypto/lhash/lhash.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*-
+ * Code for dynamic hash table routines
+ * Author - Eric Young v 2.0
+ *
+ * 2.2 eay - added #include "crypto.h" so the memory leak checking code is
+ * present. eay 18-Jun-98
+ *
+ * 2.1 eay - Added an 'error in last operation' flag. eay 6-May-98
+ *
+ * 2.0 eay - Fixed a bug that occurred when using lh_delete
+ * from inside lh_doall(). As entries were deleted,
+ * the 'table' was 'contract()ed', making some entries
+ * jump from the end of the table to the start, there by
+ * skipping the lh_doall() processing. eay - 4/12/95
+ *
+ * 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs
+ * were not being free()ed. 21/11/95
+ *
+ * 1.8 eay - Put the stats routines into a separate file, lh_stats.c
+ * 19/09/95
+ *
+ * 1.7 eay - Removed the fputs() for realloc failures - the code
+ * should silently tolerate them. I have also fixed things
+ * lint complained about 04/05/95
+ *
+ * 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92
+ *
+ * 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992
+ *
+ * 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91
+ *
+ * 1.3 eay - Fixed a few lint problems 19/3/1991
+ *
+ * 1.2 eay - Fixed lh_doall problem 13/3/1991
+ *
+ * 1.1 eay - Added lh_doall
+ *
+ * 1.0 eay - First version
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+
+const char lh_version[] = "lhash" OPENSSL_VERSION_PTEXT;
+
+#undef MIN_NODES
+#define MIN_NODES 16
+#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */
+#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */
+
+static void expand(_LHASH *lh);
+static void contract(_LHASH *lh);
+static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash);
+
+_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c)
+{
+ _LHASH *ret;
+ int i;
+
+ if ((ret = OPENSSL_malloc(sizeof(_LHASH))) == NULL)
+ goto err0;
+ if ((ret->b = OPENSSL_malloc(sizeof(LHASH_NODE *) * MIN_NODES)) == NULL)
+ goto err1;
+ for (i = 0; i < MIN_NODES; i++)
+ ret->b[i] = NULL;
+ ret->comp = ((c == NULL) ? (LHASH_COMP_FN_TYPE)strcmp : c);
+ ret->hash = ((h == NULL) ? (LHASH_HASH_FN_TYPE)lh_strhash : h);
+ ret->num_nodes = MIN_NODES / 2;
+ ret->num_alloc_nodes = MIN_NODES;
+ ret->p = 0;
+ ret->pmax = MIN_NODES / 2;
+ ret->up_load = UP_LOAD;
+ ret->down_load = DOWN_LOAD;
+ ret->num_items = 0;
+
+ ret->num_expands = 0;
+ ret->num_expand_reallocs = 0;
+ ret->num_contracts = 0;
+ ret->num_contract_reallocs = 0;
+ ret->num_hash_calls = 0;
+ ret->num_comp_calls = 0;
+ ret->num_insert = 0;
+ ret->num_replace = 0;
+ ret->num_delete = 0;
+ ret->num_no_delete = 0;
+ ret->num_retrieve = 0;
+ ret->num_retrieve_miss = 0;
+ ret->num_hash_comps = 0;
+
+ ret->error = 0;
+ return (ret);
+ err1:
+ OPENSSL_free(ret);
+ err0:
+ return (NULL);
+}
+
+void lh_free(_LHASH *lh)
+{
+ unsigned int i;
+ LHASH_NODE *n, *nn;
+
+ if (lh == NULL)
+ return;
+
+ for (i = 0; i < lh->num_nodes; i++) {
+ n = lh->b[i];
+ while (n != NULL) {
+ nn = n->next;
+ OPENSSL_free(n);
+ n = nn;
+ }
+ }
+ OPENSSL_free(lh->b);
+ OPENSSL_free(lh);
+}
+
+void *lh_insert(_LHASH *lh, void *data)
+{
+ unsigned long hash;
+ LHASH_NODE *nn, **rn;
+ void *ret;
+
+ lh->error = 0;
+ if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes))
+ expand(lh);
+
+ rn = getrn(lh, data, &hash);
+
+ if (*rn == NULL) {
+ if ((nn = (LHASH_NODE *)OPENSSL_malloc(sizeof(LHASH_NODE))) == NULL) {
+ lh->error++;
+ return (NULL);
+ }
+ nn->data = data;
+ nn->next = NULL;
+#ifndef OPENSSL_NO_HASH_COMP
+ nn->hash = hash;
+#endif
+ *rn = nn;
+ ret = NULL;
+ lh->num_insert++;
+ lh->num_items++;
+ } else { /* replace same key */
+
+ ret = (*rn)->data;
+ (*rn)->data = data;
+ lh->num_replace++;
+ }
+ return (ret);
+}
+
+void *lh_delete(_LHASH *lh, const void *data)
+{
+ unsigned long hash;
+ LHASH_NODE *nn, **rn;
+ void *ret;
+
+ lh->error = 0;
+ rn = getrn(lh, data, &hash);
+
+ if (*rn == NULL) {
+ lh->num_no_delete++;
+ return (NULL);
+ } else {
+ nn = *rn;
+ *rn = nn->next;
+ ret = nn->data;
+ OPENSSL_free(nn);
+ lh->num_delete++;
+ }
+
+ lh->num_items--;
+ if ((lh->num_nodes > MIN_NODES) &&
+ (lh->down_load >= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)))
+ contract(lh);
+
+ return (ret);
+}
+
+void *lh_retrieve(_LHASH *lh, const void *data)
+{
+ unsigned long hash;
+ LHASH_NODE **rn;
+ void *ret;
+
+ lh->error = 0;
+ rn = getrn(lh, data, &hash);
+
+ if (*rn == NULL) {
+ lh->num_retrieve_miss++;
+ return (NULL);
+ } else {
+ ret = (*rn)->data;
+ lh->num_retrieve++;
+ }
+ return (ret);
+}
+
+static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func,
+ LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg)
+{
+ int i;
+ LHASH_NODE *a, *n;
+
+ if (lh == NULL)
+ return;
+
+ /*
+ * reverse the order so we search from 'top to bottom' We were having
+ * memory leaks otherwise
+ */
+ for (i = lh->num_nodes - 1; i >= 0; i--) {
+ a = lh->b[i];
+ while (a != NULL) {
+ /*
+ * 28/05/91 - eay - n added so items can be deleted via lh_doall
+ */
+ /*
+ * 22/05/08 - ben - eh? since a is not passed, this should not be
+ * needed
+ */
+ n = a->next;
+ if (use_arg)
+ func_arg(a->data, arg);
+ else
+ func(a->data);
+ a = n;
+ }
+ }
+}
+
+void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func)
+{
+ doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL);
+}
+
+void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg)
+{
+ doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg);
+}
+
+static void expand(_LHASH *lh)
+{
+ LHASH_NODE **n, **n1, **n2, *np;
+ unsigned int p, i, j;
+ unsigned long hash, nni;
+
+ lh->num_nodes++;
+ lh->num_expands++;
+ p = (int)lh->p++;
+ n1 = &(lh->b[p]);
+ n2 = &(lh->b[p + (int)lh->pmax]);
+ *n2 = NULL; /* 27/07/92 - eay - undefined pointer bug */
+ nni = lh->num_alloc_nodes;
+
+ for (np = *n1; np != NULL;) {
+#ifndef OPENSSL_NO_HASH_COMP
+ hash = np->hash;
+#else
+ hash = lh->hash(np->data);
+ lh->num_hash_calls++;
+#endif
+ if ((hash % nni) != p) { /* move it */
+ *n1 = (*n1)->next;
+ np->next = *n2;
+ *n2 = np;
+ } else
+ n1 = &((*n1)->next);
+ np = *n1;
+ }
+
+ if ((lh->p) >= lh->pmax) {
+ j = (int)lh->num_alloc_nodes * 2;
+ n = (LHASH_NODE **)OPENSSL_realloc(lh->b,
+ (int)(sizeof(LHASH_NODE *) * j));
+ if (n == NULL) {
+/* fputs("realloc error in lhash",stderr); */
+ lh->error++;
+ lh->p = 0;
+ return;
+ }
+ /* else */
+ for (i = (int)lh->num_alloc_nodes; i < j; i++) /* 26/02/92 eay */
+ n[i] = NULL; /* 02/03/92 eay */
+ lh->pmax = lh->num_alloc_nodes;
+ lh->num_alloc_nodes = j;
+ lh->num_expand_reallocs++;
+ lh->p = 0;
+ lh->b = n;
+ }
+}
+
+static void contract(_LHASH *lh)
+{
+ LHASH_NODE **n, *n1, *np;
+
+ np = lh->b[lh->p + lh->pmax - 1];
+ lh->b[lh->p + lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */
+ if (lh->p == 0) {
+ n = (LHASH_NODE **)OPENSSL_realloc(lh->b,
+ (unsigned int)(sizeof(LHASH_NODE *)
+ * lh->pmax));
+ if (n == NULL) {
+/* fputs("realloc error in lhash",stderr); */
+ lh->error++;
+ return;
+ }
+ lh->num_contract_reallocs++;
+ lh->num_alloc_nodes /= 2;
+ lh->pmax /= 2;
+ lh->p = lh->pmax - 1;
+ lh->b = n;
+ } else
+ lh->p--;
+
+ lh->num_nodes--;
+ lh->num_contracts++;
+
+ n1 = lh->b[(int)lh->p];
+ if (n1 == NULL)
+ lh->b[(int)lh->p] = np;
+ else {
+ while (n1->next != NULL)
+ n1 = n1->next;
+ n1->next = np;
+ }
+}
+
+static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash)
+{
+ LHASH_NODE **ret, *n1;
+ unsigned long hash, nn;
+ LHASH_COMP_FN_TYPE cf;
+
+ hash = (*(lh->hash)) (data);
+ lh->num_hash_calls++;
+ *rhash = hash;
+
+ nn = hash % lh->pmax;
+ if (nn < lh->p)
+ nn = hash % lh->num_alloc_nodes;
+
+ cf = lh->comp;
+ ret = &(lh->b[(int)nn]);
+ for (n1 = *ret; n1 != NULL; n1 = n1->next) {
+#ifndef OPENSSL_NO_HASH_COMP
+ lh->num_hash_comps++;
+ if (n1->hash != hash) {
+ ret = &(n1->next);
+ continue;
+ }
+#endif
+ lh->num_comp_calls++;
+ if (cf(n1->data, data) == 0)
+ break;
+ ret = &(n1->next);
+ }
+ return (ret);
+}
+
+/*
+ * The following hash seems to work very well on normal text strings no
+ * collisions on /usr/dict/words and it distributes on %2^n quite well, not
+ * as good as MD5, but still good.
+ */
+unsigned long lh_strhash(const char *c)
+{
+ unsigned long ret = 0;
+ long n;
+ unsigned long v;
+ int r;
+
+ if ((c == NULL) || (*c == '\0'))
+ return (ret);
+/*-
+ unsigned char b[16];
+ MD5(c,strlen(c),b);
+ return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24));
+*/
+
+ n = 0x100;
+ while (*c) {
+ v = n | (*c);
+ n += 0x100;
+ r = (int)((v >> 2) ^ v) & 0x0f;
+ ret = (ret << r) | (ret >> (32 - r));
+ ret &= 0xFFFFFFFFL;
+ ret ^= v * v;
+ c++;
+ }
+ return ((ret >> 16) ^ ret);
+}
+
+unsigned long lh_num_items(const _LHASH *lh)
+{
+ return lh ? lh->num_items : 0;
+}
diff --git a/openssl/lhash/lhash.h b/openssl/lhash/lhash.h
new file mode 100644
index 0000000..b6c328b
--- /dev/null
+++ b/openssl/lhash/lhash.h
@@ -0,0 +1,240 @@
+/* crypto/lhash/lhash.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * Header for dynamic hash table routines Author - Eric Young
+ */
+
+#ifndef HEADER_LHASH_H
+# define HEADER_LHASH_H
+
+# include <openssl/e_os2.h>
+# ifndef OPENSSL_NO_FP_API
+# include <stdio.h>
+# endif
+
+# ifndef OPENSSL_NO_BIO
+# include <openssl/bio.h>
+# endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct lhash_node_st {
+ void *data;
+ struct lhash_node_st *next;
+# ifndef OPENSSL_NO_HASH_COMP
+ unsigned long hash;
+# endif
+} LHASH_NODE;
+
+typedef int (*LHASH_COMP_FN_TYPE) (const void *, const void *);
+typedef unsigned long (*LHASH_HASH_FN_TYPE) (const void *);
+typedef void (*LHASH_DOALL_FN_TYPE) (void *);
+typedef void (*LHASH_DOALL_ARG_FN_TYPE) (void *, void *);
+
+/*
+ * Macros for declaring and implementing type-safe wrappers for LHASH
+ * callbacks. This way, callbacks can be provided to LHASH structures without
+ * function pointer casting and the macro-defined callbacks provide
+ * per-variable casting before deferring to the underlying type-specific
+ * callbacks. NB: It is possible to place a "static" in front of both the
+ * DECLARE and IMPLEMENT macros if the functions are strictly internal.
+ */
+
+/* First: "hash" functions */
+# define DECLARE_LHASH_HASH_FN(name, o_type) \
+ unsigned long name##_LHASH_HASH(const void *);
+# define IMPLEMENT_LHASH_HASH_FN(name, o_type) \
+ unsigned long name##_LHASH_HASH(const void *arg) { \
+ const o_type *a = arg; \
+ return name##_hash(a); }
+# define LHASH_HASH_FN(name) name##_LHASH_HASH
+
+/* Second: "compare" functions */
+# define DECLARE_LHASH_COMP_FN(name, o_type) \
+ int name##_LHASH_COMP(const void *, const void *);
+# define IMPLEMENT_LHASH_COMP_FN(name, o_type) \
+ int name##_LHASH_COMP(const void *arg1, const void *arg2) { \
+ const o_type *a = arg1; \
+ const o_type *b = arg2; \
+ return name##_cmp(a,b); }
+# define LHASH_COMP_FN(name) name##_LHASH_COMP
+
+/* Third: "doall" functions */
+# define DECLARE_LHASH_DOALL_FN(name, o_type) \
+ void name##_LHASH_DOALL(void *);
+# define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \
+ void name##_LHASH_DOALL(void *arg) { \
+ o_type *a = arg; \
+ name##_doall(a); }
+# define LHASH_DOALL_FN(name) name##_LHASH_DOALL
+
+/* Fourth: "doall_arg" functions */
+# define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+ void name##_LHASH_DOALL_ARG(void *, void *);
+# define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+ void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
+ o_type *a = arg1; \
+ a_type *b = arg2; \
+ name##_doall_arg(a, b); }
+# define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG
+
+typedef struct lhash_st {
+ LHASH_NODE **b;
+ LHASH_COMP_FN_TYPE comp;
+ LHASH_HASH_FN_TYPE hash;
+ unsigned int num_nodes;
+ unsigned int num_alloc_nodes;
+ unsigned int p;
+ unsigned int pmax;
+ unsigned long up_load; /* load times 256 */
+ unsigned long down_load; /* load times 256 */
+ unsigned long num_items;
+ unsigned long num_expands;
+ unsigned long num_expand_reallocs;
+ unsigned long num_contracts;
+ unsigned long num_contract_reallocs;
+ unsigned long num_hash_calls;
+ unsigned long num_comp_calls;
+ unsigned long num_insert;
+ unsigned long num_replace;
+ unsigned long num_delete;
+ unsigned long num_no_delete;
+ unsigned long num_retrieve;
+ unsigned long num_retrieve_miss;
+ unsigned long num_hash_comps;
+ int error;
+} _LHASH; /* Do not use _LHASH directly, use LHASH_OF
+ * and friends */
+
+# define LH_LOAD_MULT 256
+
+/*
+ * Indicates a malloc() error in the last call, this is only bad in
+ * lh_insert().
+ */
+# define lh_error(lh) ((lh)->error)
+
+_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c);
+void lh_free(_LHASH *lh);
+void *lh_insert(_LHASH *lh, void *data);
+void *lh_delete(_LHASH *lh, const void *data);
+void *lh_retrieve(_LHASH *lh, const void *data);
+void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func);
+void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
+unsigned long lh_strhash(const char *c);
+unsigned long lh_num_items(const _LHASH *lh);
+
+# ifndef OPENSSL_NO_FP_API
+void lh_stats(const _LHASH *lh, FILE *out);
+void lh_node_stats(const _LHASH *lh, FILE *out);
+void lh_node_usage_stats(const _LHASH *lh, FILE *out);
+# endif
+
+# ifndef OPENSSL_NO_BIO
+void lh_stats_bio(const _LHASH *lh, BIO *out);
+void lh_node_stats_bio(const _LHASH *lh, BIO *out);
+void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out);
+# endif
+
+/* Type checking... */
+
+# define LHASH_OF(type) struct lhash_st_##type
+
+# define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; }
+
+# define CHECKED_LHASH_OF(type,lh) \
+ ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh))
+
+/* Define wrapper functions. */
+# define LHM_lh_new(type, name) \
+ ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name)))
+# define LHM_lh_error(type, lh) \
+ lh_error(CHECKED_LHASH_OF(type,lh))
+# define LHM_lh_insert(type, lh, inst) \
+ ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \
+ CHECKED_PTR_OF(type, inst)))
+# define LHM_lh_retrieve(type, lh, inst) \
+ ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \
+ CHECKED_PTR_OF(type, inst)))
+# define LHM_lh_delete(type, lh, inst) \
+ ((type *)lh_delete(CHECKED_LHASH_OF(type, lh), \
+ CHECKED_PTR_OF(type, inst)))
+# define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn)
+# define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \
+ lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg))
+# define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh))
+# define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load)
+# define LHM_lh_node_stats_bio(type, lh, out) \
+ lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+# define LHM_lh_node_usage_stats_bio(type, lh, out) \
+ lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+# define LHM_lh_stats_bio(type, lh, out) \
+ lh_stats_bio(CHECKED_LHASH_OF(type, lh), out)
+# define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh))
+
+DECLARE_LHASH_OF(OPENSSL_STRING);
+DECLARE_LHASH_OF(OPENSSL_CSTRING);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/md32_common.h b/openssl/md32_common.h
new file mode 100644
index 0000000..c1efb45
--- /dev/null
+++ b/openssl/md32_common.h
@@ -0,0 +1,408 @@
+/* crypto/md32_common.h */
+/* ====================================================================
+ * Copyright (c) 1999-2007 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 is a generic 32 bit "collector" for message digest algorithms.
+ * Whenever needed it collects input character stream into chunks of
+ * 32 bit values and invokes a block function that performs actual hash
+ * calculations.
+ *
+ * Porting guide.
+ *
+ * Obligatory macros:
+ *
+ * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
+ * this macro defines byte order of input stream.
+ * HASH_CBLOCK
+ * size of a unit chunk HASH_BLOCK operates on.
+ * HASH_LONG
+ * has to be at lest 32 bit wide, if it's wider, then
+ * HASH_LONG_LOG2 *has to* be defined along
+ * HASH_CTX
+ * context structure that at least contains following
+ * members:
+ * typedef struct {
+ * ...
+ * HASH_LONG Nl,Nh;
+ * either {
+ * HASH_LONG data[HASH_LBLOCK];
+ * unsigned char data[HASH_CBLOCK];
+ * };
+ * unsigned int num;
+ * ...
+ * } HASH_CTX;
+ * data[] vector is expected to be zeroed upon first call to
+ * HASH_UPDATE.
+ * HASH_UPDATE
+ * name of "Update" function, implemented here.
+ * HASH_TRANSFORM
+ * name of "Transform" function, implemented here.
+ * HASH_FINAL
+ * name of "Final" function, implemented here.
+ * HASH_BLOCK_DATA_ORDER
+ * name of "block" function capable of treating *unaligned* input
+ * message in original (data) byte order, implemented externally.
+ * HASH_MAKE_STRING
+ * macro convering context variables to an ASCII hash string.
+ *
+ * MD5 example:
+ *
+ * #define DATA_ORDER_IS_LITTLE_ENDIAN
+ *
+ * #define HASH_LONG MD5_LONG
+ * #define HASH_LONG_LOG2 MD5_LONG_LOG2
+ * #define HASH_CTX MD5_CTX
+ * #define HASH_CBLOCK MD5_CBLOCK
+ * #define HASH_UPDATE MD5_Update
+ * #define HASH_TRANSFORM MD5_Transform
+ * #define HASH_FINAL MD5_Final
+ * #define HASH_BLOCK_DATA_ORDER md5_block_data_order
+ *
+ * <appro@fy.chalmers.se>
+ */
+
+#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+# error "DATA_ORDER must be defined!"
+#endif
+
+#ifndef HASH_CBLOCK
+# error "HASH_CBLOCK must be defined!"
+#endif
+#ifndef HASH_LONG
+# error "HASH_LONG must be defined!"
+#endif
+#ifndef HASH_CTX
+# error "HASH_CTX must be defined!"
+#endif
+
+#ifndef HASH_UPDATE
+# error "HASH_UPDATE must be defined!"
+#endif
+#ifndef HASH_TRANSFORM
+# error "HASH_TRANSFORM must be defined!"
+#endif
+#ifndef HASH_FINAL
+# error "HASH_FINAL must be defined!"
+#endif
+
+#ifndef HASH_BLOCK_DATA_ORDER
+# error "HASH_BLOCK_DATA_ORDER must be defined!"
+#endif
+
+/*
+ * Engage compiler specific rotate intrinsic function if available.
+ */
+#undef ROTATE
+#ifndef PEDANTIC
+# if defined(_MSC_VER) || defined(__ICC)
+# define ROTATE(a,n) _lrotl(a,n)
+# elif defined(__MWERKS__)
+# if defined(__POWERPC__)
+# define ROTATE(a,n) __rlwinm(a,n,0,31)
+# elif defined(__MC68K__)
+ /* Motorola specific tweak. <appro@fy.chalmers.se> */
+# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) )
+# else
+# define ROTATE(a,n) __rol(a,n)
+# endif
+# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+ /*
+ * Some GNU C inline assembler templates. Note that these are
+ * rotates by *constant* number of bits! But that's exactly
+ * what we need here...
+ * <appro@fy.chalmers.se>
+ */
+# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+# define ROTATE(a,n) ({ register unsigned int ret; \
+ asm ( \
+ "roll %1,%0" \
+ : "=r"(ret) \
+ : "I"(n), "0"((unsigned int)(a)) \
+ : "cc"); \
+ ret; \
+ })
+# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
+ defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
+# define ROTATE(a,n) ({ register unsigned int ret; \
+ asm ( \
+ "rlwinm %0,%1,%2,0,31" \
+ : "=r"(ret) \
+ : "r"(a), "I"(n)); \
+ ret; \
+ })
+# elif defined(__s390x__)
+# define ROTATE(a,n) ({ register unsigned int ret; \
+ asm ("rll %0,%1,%2" \
+ : "=r"(ret) \
+ : "r"(a), "I"(n)); \
+ ret; \
+ })
+# endif
+# endif
+#endif /* PEDANTIC */
+
+#ifndef ROTATE
+# define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
+#endif
+
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+
+# ifndef PEDANTIC
+# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+# if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \
+ (defined(__x86_64) || defined(__x86_64__))
+# if !defined(B_ENDIAN)
+ /*
+ * This gives ~30-40% performance improvement in SHA-256 compiled
+ * with gcc [on P4]. Well, first macro to be frank. We can pull
+ * this trick on x86* platforms only, because these CPUs can fetch
+ * unaligned data without raising an exception.
+ */
+# define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \
+ asm ("bswapl %0":"=r"(r):"0"(r)); \
+ (c)+=4; (l)=r; })
+# define HOST_l2c(l,c) ({ unsigned int r=(l); \
+ asm ("bswapl %0":"=r"(r):"0"(r)); \
+ *((unsigned int *)(c))=r; (c)+=4; r; })
+# endif
+# endif
+# endif
+# endif
+# if defined(__s390__) || defined(__s390x__)
+# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
+# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
+# endif
+
+# ifndef HOST_c2l
+# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++))) ) )
+# endif
+# ifndef HOST_l2c
+# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff), \
+ l)
+# endif
+
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+
+# ifndef PEDANTIC
+# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+# if defined(__s390x__)
+# define HOST_c2l(c,l) ({ asm ("lrv %0,%1" \
+ :"=d"(l) :"m"(*(const unsigned int *)(c)));\
+ (c)+=4; (l); })
+# define HOST_l2c(l,c) ({ asm ("strv %1,%0" \
+ :"=m"(*(unsigned int *)(c)) :"d"(l));\
+ (c)+=4; (l); })
+# endif
+# endif
+# endif
+# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+# ifndef B_ENDIAN
+ /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
+# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l)
+# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l)
+# endif
+# endif
+
+# ifndef HOST_c2l
+# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<<24) )
+# endif
+# ifndef HOST_l2c
+# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ l)
+# endif
+
+#endif
+
+/*
+ * Time for some action:-)
+ */
+
+int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
+{
+ const unsigned char *data = data_;
+ unsigned char *p;
+ HASH_LONG l;
+ size_t n;
+
+ if (len == 0)
+ return 1;
+
+ l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
+ /*
+ * 95-05-24 eay Fixed a bug with the overflow handling, thanks to Wei Dai
+ * <weidai@eskimo.com> for pointing it out.
+ */
+ if (l < c->Nl) /* overflow */
+ c->Nh++;
+ c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
+ * 16-bit */
+ c->Nl = l;
+
+ n = c->num;
+ if (n != 0) {
+ p = (unsigned char *)c->data;
+
+ if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
+ memcpy(p + n, data, HASH_CBLOCK - n);
+ HASH_BLOCK_DATA_ORDER(c, p, 1);
+ n = HASH_CBLOCK - n;
+ data += n;
+ len -= n;
+ c->num = 0;
+ memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
+ } else {
+ memcpy(p + n, data, len);
+ c->num += (unsigned int)len;
+ return 1;
+ }
+ }
+
+ n = len / HASH_CBLOCK;
+ if (n > 0) {
+ HASH_BLOCK_DATA_ORDER(c, data, n);
+ n *= HASH_CBLOCK;
+ data += n;
+ len -= n;
+ }
+
+ if (len != 0) {
+ p = (unsigned char *)c->data;
+ c->num = (unsigned int)len;
+ memcpy(p, data, len);
+ }
+ return 1;
+}
+
+void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data)
+{
+ HASH_BLOCK_DATA_ORDER(c, data, 1);
+}
+
+int HASH_FINAL(unsigned char *md, HASH_CTX *c)
+{
+ unsigned char *p = (unsigned char *)c->data;
+ size_t n = c->num;
+
+ p[n] = 0x80; /* there is always room for one */
+ n++;
+
+ if (n > (HASH_CBLOCK - 8)) {
+ memset(p + n, 0, HASH_CBLOCK - n);
+ n = 0;
+ HASH_BLOCK_DATA_ORDER(c, p, 1);
+ }
+ memset(p + n, 0, HASH_CBLOCK - 8 - n);
+
+ p += HASH_CBLOCK - 8;
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+ (void)HOST_l2c(c->Nh, p);
+ (void)HOST_l2c(c->Nl, p);
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+ (void)HOST_l2c(c->Nl, p);
+ (void)HOST_l2c(c->Nh, p);
+#endif
+ p -= HASH_CBLOCK;
+ HASH_BLOCK_DATA_ORDER(c, p, 1);
+ c->num = 0;
+ memset(p, 0, HASH_CBLOCK);
+
+#ifndef HASH_MAKE_STRING
+# error "HASH_MAKE_STRING must be defined!"
+#else
+ HASH_MAKE_STRING(c, md);
+#endif
+
+ return 1;
+}
+
+#ifndef MD32_REG_T
+# if defined(__alpha) || defined(__sparcv9) || defined(__mips)
+# define MD32_REG_T long
+/*
+ * This comment was originaly written for MD5, which is why it
+ * discusses A-D. But it basically applies to all 32-bit digests,
+ * which is why it was moved to common header file.
+ *
+ * In case you wonder why A-D are declared as long and not
+ * as MD5_LONG. Doing so results in slight performance
+ * boost on LP64 architectures. The catch is we don't
+ * really care if 32 MSBs of a 64-bit register get polluted
+ * with eventual overflows as we *save* only 32 LSBs in
+ * *either* case. Now declaring 'em long excuses the compiler
+ * from keeping 32 MSBs zeroed resulting in 13% performance
+ * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
+ * Well, to be honest it should say that this *prevents*
+ * performance degradation.
+ * <appro@fy.chalmers.se>
+ */
+# else
+/*
+ * Above is not absolute and there are LP64 compilers that
+ * generate better code if MD32_REG_T is defined int. The above
+ * pre-processor condition reflects the circumstances under which
+ * the conclusion was made and is subject to further extension.
+ * <appro@fy.chalmers.se>
+ */
+# define MD32_REG_T int
+# endif
+#endif
diff --git a/openssl/modes.h b/openssl/modes.h
new file mode 120000
index 0000000..dad46b6
--- /dev/null
+++ b/openssl/modes.h
@@ -0,0 +1 @@
+modes/modes.h
\ No newline at end of file
diff --git a/openssl/modes/modes.h b/openssl/modes/modes.h
new file mode 100644
index 0000000..880f020
--- /dev/null
+++ b/openssl/modes/modes.h
@@ -0,0 +1,153 @@
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
+ *
+ * Rights for redistribution and usage in source and binary
+ * forms are granted according to the OpenSSL license.
+ */
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef void (*block128_f) (const unsigned char in[16],
+ unsigned char out[16], const void *key);
+
+typedef void (*cbc128_f) (const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], int enc);
+
+typedef void (*ctr128_f) (const unsigned char *in, unsigned char *out,
+ size_t blocks, const void *key,
+ const unsigned char ivec[16]);
+
+typedef void (*ccm128_f) (const unsigned char *in, unsigned char *out,
+ size_t blocks, const void *key,
+ const unsigned char ivec[16],
+ unsigned char cmac[16]);
+
+void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], block128_f block);
+void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], block128_f block);
+
+void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16],
+ unsigned char ecount_buf[16], unsigned int *num,
+ block128_f block);
+
+void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16],
+ unsigned char ecount_buf[16],
+ unsigned int *num, ctr128_f ctr);
+
+void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], int *num,
+ block128_f block);
+
+void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], int *num,
+ int enc, block128_f block);
+void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
+ size_t length, const void *key,
+ unsigned char ivec[16], int *num,
+ int enc, block128_f block);
+void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
+ size_t bits, const void *key,
+ unsigned char ivec[16], int *num,
+ int enc, block128_f block);
+
+size_t CRYPTO_cts128_encrypt_block(const unsigned char *in,
+ unsigned char *out, size_t len,
+ const void *key, unsigned char ivec[16],
+ block128_f block);
+size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], cbc128_f cbc);
+size_t CRYPTO_cts128_decrypt_block(const unsigned char *in,
+ unsigned char *out, size_t len,
+ const void *key, unsigned char ivec[16],
+ block128_f block);
+size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], cbc128_f cbc);
+
+size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in,
+ unsigned char *out, size_t len,
+ const void *key,
+ unsigned char ivec[16],
+ block128_f block);
+size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], cbc128_f cbc);
+size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in,
+ unsigned char *out, size_t len,
+ const void *key,
+ unsigned char ivec[16],
+ block128_f block);
+size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
+ size_t len, const void *key,
+ unsigned char ivec[16], cbc128_f cbc);
+
+typedef struct gcm128_context GCM128_CONTEXT;
+
+GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block);
+void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block);
+void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv,
+ size_t len);
+int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad,
+ size_t len);
+int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len);
+int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len);
+int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len, ctr128_f stream);
+int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
+ const unsigned char *in, unsigned char *out,
+ size_t len, ctr128_f stream);
+int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag,
+ size_t len);
+void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len);
+void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
+
+typedef struct ccm128_context CCM128_CONTEXT;
+
+void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
+ unsigned int M, unsigned int L, void *key,
+ block128_f block);
+int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, const unsigned char *nonce,
+ size_t nlen, size_t mlen);
+void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, const unsigned char *aad,
+ size_t alen);
+int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, const unsigned char *inp,
+ unsigned char *out, size_t len);
+int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, const unsigned char *inp,
+ unsigned char *out, size_t len);
+int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp,
+ unsigned char *out, size_t len,
+ ccm128_f stream);
+int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp,
+ unsigned char *out, size_t len,
+ ccm128_f stream);
+size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len);
+
+typedef struct xts128_context XTS128_CONTEXT;
+
+int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
+ const unsigned char iv[16],
+ const unsigned char *inp, unsigned char *out,
+ size_t len, int enc);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/openssl/obj_mac.h b/openssl/obj_mac.h
new file mode 120000
index 0000000..234cbc9
--- /dev/null
+++ b/openssl/obj_mac.h
@@ -0,0 +1 @@
+objects/obj_mac.h
\ No newline at end of file
diff --git a/openssl/objects.h b/openssl/objects.h
new file mode 120000
index 0000000..197bb01
--- /dev/null
+++ b/openssl/objects.h
@@ -0,0 +1 @@
+objects/objects.h
\ No newline at end of file
diff --git a/openssl/objects/obj_mac.h b/openssl/objects/obj_mac.h
new file mode 100644
index 0000000..f752aef
--- /dev/null
+++ b/openssl/objects/obj_mac.h
@@ -0,0 +1,4031 @@
+/* crypto/objects/obj_mac.h */
+
+/*
+ * THIS FILE IS GENERATED FROM objects.txt by objects.pl via the following
+ * command: perl objects.pl objects.txt obj_mac.num obj_mac.h
+ */
+
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#define SN_undef "UNDEF"
+#define LN_undef "undefined"
+#define NID_undef 0
+#define OBJ_undef 0L
+
+#define SN_itu_t "ITU-T"
+#define LN_itu_t "itu-t"
+#define NID_itu_t 645
+#define OBJ_itu_t 0L
+
+#define NID_ccitt 404
+#define OBJ_ccitt OBJ_itu_t
+
+#define SN_iso "ISO"
+#define LN_iso "iso"
+#define NID_iso 181
+#define OBJ_iso 1L
+
+#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T"
+#define LN_joint_iso_itu_t "joint-iso-itu-t"
+#define NID_joint_iso_itu_t 646
+#define OBJ_joint_iso_itu_t 2L
+
+#define NID_joint_iso_ccitt 393
+#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t
+
+#define SN_member_body "member-body"
+#define LN_member_body "ISO Member Body"
+#define NID_member_body 182
+#define OBJ_member_body OBJ_iso,2L
+
+#define SN_identified_organization "identified-organization"
+#define NID_identified_organization 676
+#define OBJ_identified_organization OBJ_iso,3L
+
+#define SN_hmac_md5 "HMAC-MD5"
+#define LN_hmac_md5 "hmac-md5"
+#define NID_hmac_md5 780
+#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L
+
+#define SN_hmac_sha1 "HMAC-SHA1"
+#define LN_hmac_sha1 "hmac-sha1"
+#define NID_hmac_sha1 781
+#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L
+
+#define SN_certicom_arc "certicom-arc"
+#define NID_certicom_arc 677
+#define OBJ_certicom_arc OBJ_identified_organization,132L
+
+#define SN_international_organizations "international-organizations"
+#define LN_international_organizations "International Organizations"
+#define NID_international_organizations 647
+#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L
+
+#define SN_wap "wap"
+#define NID_wap 678
+#define OBJ_wap OBJ_international_organizations,43L
+
+#define SN_wap_wsg "wap-wsg"
+#define NID_wap_wsg 679
+#define OBJ_wap_wsg OBJ_wap,1L
+
+#define SN_selected_attribute_types "selected-attribute-types"
+#define LN_selected_attribute_types "Selected Attribute Types"
+#define NID_selected_attribute_types 394
+#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L
+
+#define SN_clearance "clearance"
+#define NID_clearance 395
+#define OBJ_clearance OBJ_selected_attribute_types,55L
+
+#define SN_ISO_US "ISO-US"
+#define LN_ISO_US "ISO US Member Body"
+#define NID_ISO_US 183
+#define OBJ_ISO_US OBJ_member_body,840L
+
+#define SN_X9_57 "X9-57"
+#define LN_X9_57 "X9.57"
+#define NID_X9_57 184
+#define OBJ_X9_57 OBJ_ISO_US,10040L
+
+#define SN_X9cm "X9cm"
+#define LN_X9cm "X9.57 CM ?"
+#define NID_X9cm 185
+#define OBJ_X9cm OBJ_X9_57,4L
+
+#define SN_dsa "DSA"
+#define LN_dsa "dsaEncryption"
+#define NID_dsa 116
+#define OBJ_dsa OBJ_X9cm,1L
+
+#define SN_dsaWithSHA1 "DSA-SHA1"
+#define LN_dsaWithSHA1 "dsaWithSHA1"
+#define NID_dsaWithSHA1 113
+#define OBJ_dsaWithSHA1 OBJ_X9cm,3L
+
+#define SN_ansi_X9_62 "ansi-X9-62"
+#define LN_ansi_X9_62 "ANSI X9.62"
+#define NID_ansi_X9_62 405
+#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L
+
+#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L
+
+#define SN_X9_62_prime_field "prime-field"
+#define NID_X9_62_prime_field 406
+#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L
+
+#define SN_X9_62_characteristic_two_field "characteristic-two-field"
+#define NID_X9_62_characteristic_two_field 407
+#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L
+
+#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis"
+#define NID_X9_62_id_characteristic_two_basis 680
+#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L
+
+#define SN_X9_62_onBasis "onBasis"
+#define NID_X9_62_onBasis 681
+#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L
+
+#define SN_X9_62_tpBasis "tpBasis"
+#define NID_X9_62_tpBasis 682
+#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L
+
+#define SN_X9_62_ppBasis "ppBasis"
+#define NID_X9_62_ppBasis 683
+#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L
+
+#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L
+
+#define SN_X9_62_id_ecPublicKey "id-ecPublicKey"
+#define NID_X9_62_id_ecPublicKey 408
+#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L
+
+#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L
+
+#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L
+
+#define SN_X9_62_c2pnb163v1 "c2pnb163v1"
+#define NID_X9_62_c2pnb163v1 684
+#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L
+
+#define SN_X9_62_c2pnb163v2 "c2pnb163v2"
+#define NID_X9_62_c2pnb163v2 685
+#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L
+
+#define SN_X9_62_c2pnb163v3 "c2pnb163v3"
+#define NID_X9_62_c2pnb163v3 686
+#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L
+
+#define SN_X9_62_c2pnb176v1 "c2pnb176v1"
+#define NID_X9_62_c2pnb176v1 687
+#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L
+
+#define SN_X9_62_c2tnb191v1 "c2tnb191v1"
+#define NID_X9_62_c2tnb191v1 688
+#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L
+
+#define SN_X9_62_c2tnb191v2 "c2tnb191v2"
+#define NID_X9_62_c2tnb191v2 689
+#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L
+
+#define SN_X9_62_c2tnb191v3 "c2tnb191v3"
+#define NID_X9_62_c2tnb191v3 690
+#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L
+
+#define SN_X9_62_c2onb191v4 "c2onb191v4"
+#define NID_X9_62_c2onb191v4 691
+#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L
+
+#define SN_X9_62_c2onb191v5 "c2onb191v5"
+#define NID_X9_62_c2onb191v5 692
+#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L
+
+#define SN_X9_62_c2pnb208w1 "c2pnb208w1"
+#define NID_X9_62_c2pnb208w1 693
+#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L
+
+#define SN_X9_62_c2tnb239v1 "c2tnb239v1"
+#define NID_X9_62_c2tnb239v1 694
+#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L
+
+#define SN_X9_62_c2tnb239v2 "c2tnb239v2"
+#define NID_X9_62_c2tnb239v2 695
+#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L
+
+#define SN_X9_62_c2tnb239v3 "c2tnb239v3"
+#define NID_X9_62_c2tnb239v3 696
+#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L
+
+#define SN_X9_62_c2onb239v4 "c2onb239v4"
+#define NID_X9_62_c2onb239v4 697
+#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L
+
+#define SN_X9_62_c2onb239v5 "c2onb239v5"
+#define NID_X9_62_c2onb239v5 698
+#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L
+
+#define SN_X9_62_c2pnb272w1 "c2pnb272w1"
+#define NID_X9_62_c2pnb272w1 699
+#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L
+
+#define SN_X9_62_c2pnb304w1 "c2pnb304w1"
+#define NID_X9_62_c2pnb304w1 700
+#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L
+
+#define SN_X9_62_c2tnb359v1 "c2tnb359v1"
+#define NID_X9_62_c2tnb359v1 701
+#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L
+
+#define SN_X9_62_c2pnb368w1 "c2pnb368w1"
+#define NID_X9_62_c2pnb368w1 702
+#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L
+
+#define SN_X9_62_c2tnb431r1 "c2tnb431r1"
+#define NID_X9_62_c2tnb431r1 703
+#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L
+
+#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L
+
+#define SN_X9_62_prime192v1 "prime192v1"
+#define NID_X9_62_prime192v1 409
+#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L
+
+#define SN_X9_62_prime192v2 "prime192v2"
+#define NID_X9_62_prime192v2 410
+#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L
+
+#define SN_X9_62_prime192v3 "prime192v3"
+#define NID_X9_62_prime192v3 411
+#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L
+
+#define SN_X9_62_prime239v1 "prime239v1"
+#define NID_X9_62_prime239v1 412
+#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L
+
+#define SN_X9_62_prime239v2 "prime239v2"
+#define NID_X9_62_prime239v2 413
+#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L
+
+#define SN_X9_62_prime239v3 "prime239v3"
+#define NID_X9_62_prime239v3 414
+#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L
+
+#define SN_X9_62_prime256v1 "prime256v1"
+#define NID_X9_62_prime256v1 415
+#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L
+
+#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L
+
+#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1"
+#define NID_ecdsa_with_SHA1 416
+#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L
+
+#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended"
+#define NID_ecdsa_with_Recommended 791
+#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L
+
+#define SN_ecdsa_with_Specified "ecdsa-with-Specified"
+#define NID_ecdsa_with_Specified 792
+#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L
+
+#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224"
+#define NID_ecdsa_with_SHA224 793
+#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L
+
+#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256"
+#define NID_ecdsa_with_SHA256 794
+#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L
+
+#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384"
+#define NID_ecdsa_with_SHA384 795
+#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L
+
+#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512"
+#define NID_ecdsa_with_SHA512 796
+#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L
+
+#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L
+
+#define SN_secp112r1 "secp112r1"
+#define NID_secp112r1 704
+#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L
+
+#define SN_secp112r2 "secp112r2"
+#define NID_secp112r2 705
+#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L
+
+#define SN_secp128r1 "secp128r1"
+#define NID_secp128r1 706
+#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L
+
+#define SN_secp128r2 "secp128r2"
+#define NID_secp128r2 707
+#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L
+
+#define SN_secp160k1 "secp160k1"
+#define NID_secp160k1 708
+#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L
+
+#define SN_secp160r1 "secp160r1"
+#define NID_secp160r1 709
+#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L
+
+#define SN_secp160r2 "secp160r2"
+#define NID_secp160r2 710
+#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L
+
+#define SN_secp192k1 "secp192k1"
+#define NID_secp192k1 711
+#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L
+
+#define SN_secp224k1 "secp224k1"
+#define NID_secp224k1 712
+#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L
+
+#define SN_secp224r1 "secp224r1"
+#define NID_secp224r1 713
+#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L
+
+#define SN_secp256k1 "secp256k1"
+#define NID_secp256k1 714
+#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L
+
+#define SN_secp384r1 "secp384r1"
+#define NID_secp384r1 715
+#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L
+
+#define SN_secp521r1 "secp521r1"
+#define NID_secp521r1 716
+#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L
+
+#define SN_sect113r1 "sect113r1"
+#define NID_sect113r1 717
+#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L
+
+#define SN_sect113r2 "sect113r2"
+#define NID_sect113r2 718
+#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L
+
+#define SN_sect131r1 "sect131r1"
+#define NID_sect131r1 719
+#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L
+
+#define SN_sect131r2 "sect131r2"
+#define NID_sect131r2 720
+#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L
+
+#define SN_sect163k1 "sect163k1"
+#define NID_sect163k1 721
+#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L
+
+#define SN_sect163r1 "sect163r1"
+#define NID_sect163r1 722
+#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L
+
+#define SN_sect163r2 "sect163r2"
+#define NID_sect163r2 723
+#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L
+
+#define SN_sect193r1 "sect193r1"
+#define NID_sect193r1 724
+#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L
+
+#define SN_sect193r2 "sect193r2"
+#define NID_sect193r2 725
+#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L
+
+#define SN_sect233k1 "sect233k1"
+#define NID_sect233k1 726
+#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L
+
+#define SN_sect233r1 "sect233r1"
+#define NID_sect233r1 727
+#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L
+
+#define SN_sect239k1 "sect239k1"
+#define NID_sect239k1 728
+#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L
+
+#define SN_sect283k1 "sect283k1"
+#define NID_sect283k1 729
+#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L
+
+#define SN_sect283r1 "sect283r1"
+#define NID_sect283r1 730
+#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L
+
+#define SN_sect409k1 "sect409k1"
+#define NID_sect409k1 731
+#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L
+
+#define SN_sect409r1 "sect409r1"
+#define NID_sect409r1 732
+#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L
+
+#define SN_sect571k1 "sect571k1"
+#define NID_sect571k1 733
+#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L
+
+#define SN_sect571r1 "sect571r1"
+#define NID_sect571r1 734
+#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L
+
+#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L
+
+#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1"
+#define NID_wap_wsg_idm_ecid_wtls1 735
+#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L
+
+#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3"
+#define NID_wap_wsg_idm_ecid_wtls3 736
+#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L
+
+#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4"
+#define NID_wap_wsg_idm_ecid_wtls4 737
+#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L
+
+#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5"
+#define NID_wap_wsg_idm_ecid_wtls5 738
+#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L
+
+#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6"
+#define NID_wap_wsg_idm_ecid_wtls6 739
+#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L
+
+#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7"
+#define NID_wap_wsg_idm_ecid_wtls7 740
+#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L
+
+#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8"
+#define NID_wap_wsg_idm_ecid_wtls8 741
+#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L
+
+#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9"
+#define NID_wap_wsg_idm_ecid_wtls9 742
+#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L
+
+#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10"
+#define NID_wap_wsg_idm_ecid_wtls10 743
+#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L
+
+#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11"
+#define NID_wap_wsg_idm_ecid_wtls11 744
+#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L
+
+#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12"
+#define NID_wap_wsg_idm_ecid_wtls12 745
+#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L
+
+#define SN_cast5_cbc "CAST5-CBC"
+#define LN_cast5_cbc "cast5-cbc"
+#define NID_cast5_cbc 108
+#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L
+
+#define SN_cast5_ecb "CAST5-ECB"
+#define LN_cast5_ecb "cast5-ecb"
+#define NID_cast5_ecb 109
+
+#define SN_cast5_cfb64 "CAST5-CFB"
+#define LN_cast5_cfb64 "cast5-cfb"
+#define NID_cast5_cfb64 110
+
+#define SN_cast5_ofb64 "CAST5-OFB"
+#define LN_cast5_ofb64 "cast5-ofb"
+#define NID_cast5_ofb64 111
+
+#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC 112
+#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L
+
+#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC"
+#define LN_id_PasswordBasedMAC "password based MAC"
+#define NID_id_PasswordBasedMAC 782
+#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L
+
+#define SN_id_DHBasedMac "id-DHBasedMac"
+#define LN_id_DHBasedMac "Diffie-Hellman based MAC"
+#define NID_id_DHBasedMac 783
+#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L
+
+#define SN_rsadsi "rsadsi"
+#define LN_rsadsi "RSA Data Security, Inc."
+#define NID_rsadsi 1
+#define OBJ_rsadsi OBJ_ISO_US,113549L
+
+#define SN_pkcs "pkcs"
+#define LN_pkcs "RSA Data Security, Inc. PKCS"
+#define NID_pkcs 2
+#define OBJ_pkcs OBJ_rsadsi,1L
+
+#define SN_pkcs1 "pkcs1"
+#define NID_pkcs1 186
+#define OBJ_pkcs1 OBJ_pkcs,1L
+
+#define LN_rsaEncryption "rsaEncryption"
+#define NID_rsaEncryption 6
+#define OBJ_rsaEncryption OBJ_pkcs1,1L
+
+#define SN_md2WithRSAEncryption "RSA-MD2"
+#define LN_md2WithRSAEncryption "md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption 7
+#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L
+
+#define SN_md4WithRSAEncryption "RSA-MD4"
+#define LN_md4WithRSAEncryption "md4WithRSAEncryption"
+#define NID_md4WithRSAEncryption 396
+#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L
+
+#define SN_md5WithRSAEncryption "RSA-MD5"
+#define LN_md5WithRSAEncryption "md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption 8
+#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L
+
+#define SN_sha1WithRSAEncryption "RSA-SHA1"
+#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption 65
+#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L
+
+#define SN_rsaesOaep "RSAES-OAEP"
+#define LN_rsaesOaep "rsaesOaep"
+#define NID_rsaesOaep 919
+#define OBJ_rsaesOaep OBJ_pkcs1,7L
+
+#define SN_mgf1 "MGF1"
+#define LN_mgf1 "mgf1"
+#define NID_mgf1 911
+#define OBJ_mgf1 OBJ_pkcs1,8L
+
+#define SN_rsassaPss "RSASSA-PSS"
+#define LN_rsassaPss "rsassaPss"
+#define NID_rsassaPss 912
+#define OBJ_rsassaPss OBJ_pkcs1,10L
+
+#define SN_sha256WithRSAEncryption "RSA-SHA256"
+#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption"
+#define NID_sha256WithRSAEncryption 668
+#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L
+
+#define SN_sha384WithRSAEncryption "RSA-SHA384"
+#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption"
+#define NID_sha384WithRSAEncryption 669
+#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L
+
+#define SN_sha512WithRSAEncryption "RSA-SHA512"
+#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption"
+#define NID_sha512WithRSAEncryption 670
+#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L
+
+#define SN_sha224WithRSAEncryption "RSA-SHA224"
+#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption"
+#define NID_sha224WithRSAEncryption 671
+#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L
+
+#define SN_pkcs3 "pkcs3"
+#define NID_pkcs3 27
+#define OBJ_pkcs3 OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement "dhKeyAgreement"
+#define NID_dhKeyAgreement 28
+#define OBJ_dhKeyAgreement OBJ_pkcs3,1L
+
+#define SN_pkcs5 "pkcs5"
+#define NID_pkcs5 187
+#define OBJ_pkcs5 OBJ_pkcs,5L
+
+#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC 9
+#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L
+
+#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC 10
+#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L
+
+#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC 168
+#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L
+
+#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC 169
+#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L
+
+#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC 170
+#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L
+
+#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC 68
+#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L
+
+#define LN_id_pbkdf2 "PBKDF2"
+#define NID_id_pbkdf2 69
+#define OBJ_id_pbkdf2 OBJ_pkcs5,12L
+
+#define LN_pbes2 "PBES2"
+#define NID_pbes2 161
+#define OBJ_pbes2 OBJ_pkcs5,13L
+
+#define LN_pbmac1 "PBMAC1"
+#define NID_pbmac1 162
+#define OBJ_pbmac1 OBJ_pkcs5,14L
+
+#define SN_pkcs7 "pkcs7"
+#define NID_pkcs7 20
+#define OBJ_pkcs7 OBJ_pkcs,7L
+
+#define LN_pkcs7_data "pkcs7-data"
+#define NID_pkcs7_data 21
+#define OBJ_pkcs7_data OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed "pkcs7-signedData"
+#define NID_pkcs7_signed 22
+#define OBJ_pkcs7_signed OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped "pkcs7-envelopedData"
+#define NID_pkcs7_enveloped 23
+#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped 24
+#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest "pkcs7-digestData"
+#define NID_pkcs7_digest 25
+#define OBJ_pkcs7_digest OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted "pkcs7-encryptedData"
+#define NID_pkcs7_encrypted 26
+#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L
+
+#define SN_pkcs9 "pkcs9"
+#define NID_pkcs9 47
+#define OBJ_pkcs9 OBJ_pkcs,9L
+
+#define LN_pkcs9_emailAddress "emailAddress"
+#define NID_pkcs9_emailAddress 48
+#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName "unstructuredName"
+#define NID_pkcs9_unstructuredName 49
+#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType "contentType"
+#define NID_pkcs9_contentType 50
+#define OBJ_pkcs9_contentType OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest "messageDigest"
+#define NID_pkcs9_messageDigest 51
+#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime "signingTime"
+#define NID_pkcs9_signingTime 52
+#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature "countersignature"
+#define NID_pkcs9_countersignature 53
+#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword "challengePassword"
+#define NID_pkcs9_challengePassword 54
+#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress "unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress 55
+#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes 56
+#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L
+
+#define SN_ext_req "extReq"
+#define LN_ext_req "Extension Request"
+#define NID_ext_req 172
+#define OBJ_ext_req OBJ_pkcs9,14L
+
+#define SN_SMIMECapabilities "SMIME-CAPS"
+#define LN_SMIMECapabilities "S/MIME Capabilities"
+#define NID_SMIMECapabilities 167
+#define OBJ_SMIMECapabilities OBJ_pkcs9,15L
+
+#define SN_SMIME "SMIME"
+#define LN_SMIME "S/MIME"
+#define NID_SMIME 188
+#define OBJ_SMIME OBJ_pkcs9,16L
+
+#define SN_id_smime_mod "id-smime-mod"
+#define NID_id_smime_mod 189
+#define OBJ_id_smime_mod OBJ_SMIME,0L
+
+#define SN_id_smime_ct "id-smime-ct"
+#define NID_id_smime_ct 190
+#define OBJ_id_smime_ct OBJ_SMIME,1L
+
+#define SN_id_smime_aa "id-smime-aa"
+#define NID_id_smime_aa 191
+#define OBJ_id_smime_aa OBJ_SMIME,2L
+
+#define SN_id_smime_alg "id-smime-alg"
+#define NID_id_smime_alg 192
+#define OBJ_id_smime_alg OBJ_SMIME,3L
+
+#define SN_id_smime_cd "id-smime-cd"
+#define NID_id_smime_cd 193
+#define OBJ_id_smime_cd OBJ_SMIME,4L
+
+#define SN_id_smime_spq "id-smime-spq"
+#define NID_id_smime_spq 194
+#define OBJ_id_smime_spq OBJ_SMIME,5L
+
+#define SN_id_smime_cti "id-smime-cti"
+#define NID_id_smime_cti 195
+#define OBJ_id_smime_cti OBJ_SMIME,6L
+
+#define SN_id_smime_mod_cms "id-smime-mod-cms"
+#define NID_id_smime_mod_cms 196
+#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L
+
+#define SN_id_smime_mod_ess "id-smime-mod-ess"
+#define NID_id_smime_mod_ess 197
+#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L
+
+#define SN_id_smime_mod_oid "id-smime-mod-oid"
+#define NID_id_smime_mod_oid 198
+#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L
+
+#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3"
+#define NID_id_smime_mod_msg_v3 199
+#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L
+
+#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88"
+#define NID_id_smime_mod_ets_eSignature_88 200
+#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L
+
+#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97"
+#define NID_id_smime_mod_ets_eSignature_97 201
+#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L
+
+#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88"
+#define NID_id_smime_mod_ets_eSigPolicy_88 202
+#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L
+
+#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97"
+#define NID_id_smime_mod_ets_eSigPolicy_97 203
+#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L
+
+#define SN_id_smime_ct_receipt "id-smime-ct-receipt"
+#define NID_id_smime_ct_receipt 204
+#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L
+
+#define SN_id_smime_ct_authData "id-smime-ct-authData"
+#define NID_id_smime_ct_authData 205
+#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L
+
+#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert"
+#define NID_id_smime_ct_publishCert 206
+#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L
+
+#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo"
+#define NID_id_smime_ct_TSTInfo 207
+#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L
+
+#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo"
+#define NID_id_smime_ct_TDTInfo 208
+#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L
+
+#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo"
+#define NID_id_smime_ct_contentInfo 209
+#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L
+
+#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData"
+#define NID_id_smime_ct_DVCSRequestData 210
+#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L
+
+#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData"
+#define NID_id_smime_ct_DVCSResponseData 211
+#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L
+
+#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData"
+#define NID_id_smime_ct_compressedData 786
+#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L
+
+#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF"
+#define NID_id_ct_asciiTextWithCRLF 787
+#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L
+
+#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest"
+#define NID_id_smime_aa_receiptRequest 212
+#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L
+
+#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel"
+#define NID_id_smime_aa_securityLabel 213
+#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L
+
+#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory"
+#define NID_id_smime_aa_mlExpandHistory 214
+#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L
+
+#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint"
+#define NID_id_smime_aa_contentHint 215
+#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L
+
+#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest"
+#define NID_id_smime_aa_msgSigDigest 216
+#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L
+
+#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType"
+#define NID_id_smime_aa_encapContentType 217
+#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L
+
+#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier"
+#define NID_id_smime_aa_contentIdentifier 218
+#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L
+
+#define SN_id_smime_aa_macValue "id-smime-aa-macValue"
+#define NID_id_smime_aa_macValue 219
+#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L
+
+#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels"
+#define NID_id_smime_aa_equivalentLabels 220
+#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L
+
+#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference"
+#define NID_id_smime_aa_contentReference 221
+#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L
+
+#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref"
+#define NID_id_smime_aa_encrypKeyPref 222
+#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L
+
+#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate"
+#define NID_id_smime_aa_signingCertificate 223
+#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L
+
+#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts"
+#define NID_id_smime_aa_smimeEncryptCerts 224
+#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L
+
+#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken"
+#define NID_id_smime_aa_timeStampToken 225
+#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L
+
+#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId"
+#define NID_id_smime_aa_ets_sigPolicyId 226
+#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L
+
+#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType"
+#define NID_id_smime_aa_ets_commitmentType 227
+#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L
+
+#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation"
+#define NID_id_smime_aa_ets_signerLocation 228
+#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L
+
+#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr"
+#define NID_id_smime_aa_ets_signerAttr 229
+#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L
+
+#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert"
+#define NID_id_smime_aa_ets_otherSigCert 230
+#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L
+
+#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp"
+#define NID_id_smime_aa_ets_contentTimestamp 231
+#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L
+
+#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs"
+#define NID_id_smime_aa_ets_CertificateRefs 232
+#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L
+
+#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs"
+#define NID_id_smime_aa_ets_RevocationRefs 233
+#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L
+
+#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues"
+#define NID_id_smime_aa_ets_certValues 234
+#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L
+
+#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues"
+#define NID_id_smime_aa_ets_revocationValues 235
+#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L
+
+#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp"
+#define NID_id_smime_aa_ets_escTimeStamp 236
+#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L
+
+#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp"
+#define NID_id_smime_aa_ets_certCRLTimestamp 237
+#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L
+
+#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp"
+#define NID_id_smime_aa_ets_archiveTimeStamp 238
+#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L
+
+#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType"
+#define NID_id_smime_aa_signatureType 239
+#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L
+
+#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc"
+#define NID_id_smime_aa_dvcs_dvc 240
+#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L
+
+#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES"
+#define NID_id_smime_alg_ESDHwith3DES 241
+#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L
+
+#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2"
+#define NID_id_smime_alg_ESDHwithRC2 242
+#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L
+
+#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap"
+#define NID_id_smime_alg_3DESwrap 243
+#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L
+
+#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap"
+#define NID_id_smime_alg_RC2wrap 244
+#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L
+
+#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH"
+#define NID_id_smime_alg_ESDH 245
+#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L
+
+#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap"
+#define NID_id_smime_alg_CMS3DESwrap 246
+#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L
+
+#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap"
+#define NID_id_smime_alg_CMSRC2wrap 247
+#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L
+
+#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK"
+#define NID_id_alg_PWRI_KEK 893
+#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L
+
+#define SN_id_smime_cd_ldap "id-smime-cd-ldap"
+#define NID_id_smime_cd_ldap 248
+#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L
+
+#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri"
+#define NID_id_smime_spq_ets_sqt_uri 249
+#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L
+
+#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice"
+#define NID_id_smime_spq_ets_sqt_unotice 250
+#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L
+
+#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin"
+#define NID_id_smime_cti_ets_proofOfOrigin 251
+#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L
+
+#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt"
+#define NID_id_smime_cti_ets_proofOfReceipt 252
+#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L
+
+#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery"
+#define NID_id_smime_cti_ets_proofOfDelivery 253
+#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L
+
+#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender"
+#define NID_id_smime_cti_ets_proofOfSender 254
+#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L
+
+#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval"
+#define NID_id_smime_cti_ets_proofOfApproval 255
+#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L
+
+#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation"
+#define NID_id_smime_cti_ets_proofOfCreation 256
+#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L
+
+#define LN_friendlyName "friendlyName"
+#define NID_friendlyName 156
+#define OBJ_friendlyName OBJ_pkcs9,20L
+
+#define LN_localKeyID "localKeyID"
+#define NID_localKeyID 157
+#define OBJ_localKeyID OBJ_pkcs9,21L
+
+#define SN_ms_csp_name "CSPName"
+#define LN_ms_csp_name "Microsoft CSP Name"
+#define NID_ms_csp_name 417
+#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L
+
+#define SN_LocalKeySet "LocalKeySet"
+#define LN_LocalKeySet "Microsoft Local Key set"
+#define NID_LocalKeySet 856
+#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L
+
+#define OBJ_certTypes OBJ_pkcs9,22L
+
+#define LN_x509Certificate "x509Certificate"
+#define NID_x509Certificate 158
+#define OBJ_x509Certificate OBJ_certTypes,1L
+
+#define LN_sdsiCertificate "sdsiCertificate"
+#define NID_sdsiCertificate 159
+#define OBJ_sdsiCertificate OBJ_certTypes,2L
+
+#define OBJ_crlTypes OBJ_pkcs9,23L
+
+#define LN_x509Crl "x509Crl"
+#define NID_x509Crl 160
+#define OBJ_x509Crl OBJ_crlTypes,1L
+
+#define OBJ_pkcs12 OBJ_pkcs,12L
+
+#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L
+
+#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4 144
+#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L
+
+#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4 145
+#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC 148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC 149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L
+
+#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L
+
+#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L
+
+#define LN_keyBag "keyBag"
+#define NID_keyBag 150
+#define OBJ_keyBag OBJ_pkcs12_BagIds,1L
+
+#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag 151
+#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L
+
+#define LN_certBag "certBag"
+#define NID_certBag 152
+#define OBJ_certBag OBJ_pkcs12_BagIds,3L
+
+#define LN_crlBag "crlBag"
+#define NID_crlBag 153
+#define OBJ_crlBag OBJ_pkcs12_BagIds,4L
+
+#define LN_secretBag "secretBag"
+#define NID_secretBag 154
+#define OBJ_secretBag OBJ_pkcs12_BagIds,5L
+
+#define LN_safeContentsBag "safeContentsBag"
+#define NID_safeContentsBag 155
+#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L
+
+#define SN_md2 "MD2"
+#define LN_md2 "md2"
+#define NID_md2 3
+#define OBJ_md2 OBJ_rsadsi,2L,2L
+
+#define SN_md4 "MD4"
+#define LN_md4 "md4"
+#define NID_md4 257
+#define OBJ_md4 OBJ_rsadsi,2L,4L
+
+#define SN_md5 "MD5"
+#define LN_md5 "md5"
+#define NID_md5 4
+#define OBJ_md5 OBJ_rsadsi,2L,5L
+
+#define SN_md5_sha1 "MD5-SHA1"
+#define LN_md5_sha1 "md5-sha1"
+#define NID_md5_sha1 114
+
+#define LN_hmacWithMD5 "hmacWithMD5"
+#define NID_hmacWithMD5 797
+#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L
+
+#define LN_hmacWithSHA1 "hmacWithSHA1"
+#define NID_hmacWithSHA1 163
+#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L
+
+#define LN_hmacWithSHA224 "hmacWithSHA224"
+#define NID_hmacWithSHA224 798
+#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L
+
+#define LN_hmacWithSHA256 "hmacWithSHA256"
+#define NID_hmacWithSHA256 799
+#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L
+
+#define LN_hmacWithSHA384 "hmacWithSHA384"
+#define NID_hmacWithSHA384 800
+#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L
+
+#define LN_hmacWithSHA512 "hmacWithSHA512"
+#define NID_hmacWithSHA512 801
+#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L
+
+#define SN_rc2_cbc "RC2-CBC"
+#define LN_rc2_cbc "rc2-cbc"
+#define NID_rc2_cbc 37
+#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb "RC2-ECB"
+#define LN_rc2_ecb "rc2-ecb"
+#define NID_rc2_ecb 38
+
+#define SN_rc2_cfb64 "RC2-CFB"
+#define LN_rc2_cfb64 "rc2-cfb"
+#define NID_rc2_cfb64 39
+
+#define SN_rc2_ofb64 "RC2-OFB"
+#define LN_rc2_ofb64 "rc2-ofb"
+#define NID_rc2_ofb64 40
+
+#define SN_rc2_40_cbc "RC2-40-CBC"
+#define LN_rc2_40_cbc "rc2-40-cbc"
+#define NID_rc2_40_cbc 98
+
+#define SN_rc2_64_cbc "RC2-64-CBC"
+#define LN_rc2_64_cbc "rc2-64-cbc"
+#define NID_rc2_64_cbc 166
+
+#define SN_rc4 "RC4"
+#define LN_rc4 "rc4"
+#define NID_rc4 5
+#define OBJ_rc4 OBJ_rsadsi,3L,4L
+
+#define SN_rc4_40 "RC4-40"
+#define LN_rc4_40 "rc4-40"
+#define NID_rc4_40 97
+
+#define SN_des_ede3_cbc "DES-EDE3-CBC"
+#define LN_des_ede3_cbc "des-ede3-cbc"
+#define NID_des_ede3_cbc 44
+#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L
+
+#define SN_rc5_cbc "RC5-CBC"
+#define LN_rc5_cbc "rc5-cbc"
+#define NID_rc5_cbc 120
+#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb "RC5-ECB"
+#define LN_rc5_ecb "rc5-ecb"
+#define NID_rc5_ecb 121
+
+#define SN_rc5_cfb64 "RC5-CFB"
+#define LN_rc5_cfb64 "rc5-cfb"
+#define NID_rc5_cfb64 122
+
+#define SN_rc5_ofb64 "RC5-OFB"
+#define LN_rc5_ofb64 "rc5-ofb"
+#define NID_rc5_ofb64 123
+
+#define SN_ms_ext_req "msExtReq"
+#define LN_ms_ext_req "Microsoft Extension Request"
+#define NID_ms_ext_req 171
+#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define SN_ms_code_ind "msCodeInd"
+#define LN_ms_code_ind "Microsoft Individual Code Signing"
+#define NID_ms_code_ind 134
+#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com "msCodeCom"
+#define LN_ms_code_com "Microsoft Commercial Code Signing"
+#define NID_ms_code_com 135
+#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign "msCTLSign"
+#define LN_ms_ctl_sign "Microsoft Trust List Signing"
+#define NID_ms_ctl_sign 136
+#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc "msSGC"
+#define LN_ms_sgc "Microsoft Server Gated Crypto"
+#define NID_ms_sgc 137
+#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs "msEFS"
+#define LN_ms_efs "Microsoft Encrypted File System"
+#define NID_ms_efs 138
+#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+#define SN_ms_smartcard_login "msSmartcardLogin"
+#define LN_ms_smartcard_login "Microsoft Smartcardlogin"
+#define NID_ms_smartcard_login 648
+#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L
+
+#define SN_ms_upn "msUPN"
+#define LN_ms_upn "Microsoft Universal Principal Name"
+#define NID_ms_upn 649
+#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L
+
+#define SN_idea_cbc "IDEA-CBC"
+#define LN_idea_cbc "idea-cbc"
+#define NID_idea_cbc 34
+#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_ecb "IDEA-ECB"
+#define LN_idea_ecb "idea-ecb"
+#define NID_idea_ecb 36
+
+#define SN_idea_cfb64 "IDEA-CFB"
+#define LN_idea_cfb64 "idea-cfb"
+#define NID_idea_cfb64 35
+
+#define SN_idea_ofb64 "IDEA-OFB"
+#define LN_idea_ofb64 "idea-ofb"
+#define NID_idea_ofb64 46
+
+#define SN_bf_cbc "BF-CBC"
+#define LN_bf_cbc "bf-cbc"
+#define NID_bf_cbc 91
+#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb "BF-ECB"
+#define LN_bf_ecb "bf-ecb"
+#define NID_bf_ecb 92
+
+#define SN_bf_cfb64 "BF-CFB"
+#define LN_bf_cfb64 "bf-cfb"
+#define NID_bf_cfb64 93
+
+#define SN_bf_ofb64 "BF-OFB"
+#define LN_bf_ofb64 "bf-ofb"
+#define NID_bf_ofb64 94
+
+#define SN_id_pkix "PKIX"
+#define NID_id_pkix 127
+#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_pkix_mod "id-pkix-mod"
+#define NID_id_pkix_mod 258
+#define OBJ_id_pkix_mod OBJ_id_pkix,0L
+
+#define SN_id_pe "id-pe"
+#define NID_id_pe 175
+#define OBJ_id_pe OBJ_id_pkix,1L
+
+#define SN_id_qt "id-qt"
+#define NID_id_qt 259
+#define OBJ_id_qt OBJ_id_pkix,2L
+
+#define SN_id_kp "id-kp"
+#define NID_id_kp 128
+#define OBJ_id_kp OBJ_id_pkix,3L
+
+#define SN_id_it "id-it"
+#define NID_id_it 260
+#define OBJ_id_it OBJ_id_pkix,4L
+
+#define SN_id_pkip "id-pkip"
+#define NID_id_pkip 261
+#define OBJ_id_pkip OBJ_id_pkix,5L
+
+#define SN_id_alg "id-alg"
+#define NID_id_alg 262
+#define OBJ_id_alg OBJ_id_pkix,6L
+
+#define SN_id_cmc "id-cmc"
+#define NID_id_cmc 263
+#define OBJ_id_cmc OBJ_id_pkix,7L
+
+#define SN_id_on "id-on"
+#define NID_id_on 264
+#define OBJ_id_on OBJ_id_pkix,8L
+
+#define SN_id_pda "id-pda"
+#define NID_id_pda 265
+#define OBJ_id_pda OBJ_id_pkix,9L
+
+#define SN_id_aca "id-aca"
+#define NID_id_aca 266
+#define OBJ_id_aca OBJ_id_pkix,10L
+
+#define SN_id_qcs "id-qcs"
+#define NID_id_qcs 267
+#define OBJ_id_qcs OBJ_id_pkix,11L
+
+#define SN_id_cct "id-cct"
+#define NID_id_cct 268
+#define OBJ_id_cct OBJ_id_pkix,12L
+
+#define SN_id_ppl "id-ppl"
+#define NID_id_ppl 662
+#define OBJ_id_ppl OBJ_id_pkix,21L
+
+#define SN_id_ad "id-ad"
+#define NID_id_ad 176
+#define OBJ_id_ad OBJ_id_pkix,48L
+
+#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88"
+#define NID_id_pkix1_explicit_88 269
+#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L
+
+#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88"
+#define NID_id_pkix1_implicit_88 270
+#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L
+
+#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93"
+#define NID_id_pkix1_explicit_93 271
+#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L
+
+#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93"
+#define NID_id_pkix1_implicit_93 272
+#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L
+
+#define SN_id_mod_crmf "id-mod-crmf"
+#define NID_id_mod_crmf 273
+#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L
+
+#define SN_id_mod_cmc "id-mod-cmc"
+#define NID_id_mod_cmc 274
+#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L
+
+#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88"
+#define NID_id_mod_kea_profile_88 275
+#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L
+
+#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93"
+#define NID_id_mod_kea_profile_93 276
+#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L
+
+#define SN_id_mod_cmp "id-mod-cmp"
+#define NID_id_mod_cmp 277
+#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L
+
+#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88"
+#define NID_id_mod_qualified_cert_88 278
+#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L
+
+#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93"
+#define NID_id_mod_qualified_cert_93 279
+#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L
+
+#define SN_id_mod_attribute_cert "id-mod-attribute-cert"
+#define NID_id_mod_attribute_cert 280
+#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L
+
+#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol"
+#define NID_id_mod_timestamp_protocol 281
+#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L
+
+#define SN_id_mod_ocsp "id-mod-ocsp"
+#define NID_id_mod_ocsp 282
+#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L
+
+#define SN_id_mod_dvcs "id-mod-dvcs"
+#define NID_id_mod_dvcs 283
+#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L
+
+#define SN_id_mod_cmp2000 "id-mod-cmp2000"
+#define NID_id_mod_cmp2000 284
+#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L
+
+#define SN_info_access "authorityInfoAccess"
+#define LN_info_access "Authority Information Access"
+#define NID_info_access 177
+#define OBJ_info_access OBJ_id_pe,1L
+
+#define SN_biometricInfo "biometricInfo"
+#define LN_biometricInfo "Biometric Info"
+#define NID_biometricInfo 285
+#define OBJ_biometricInfo OBJ_id_pe,2L
+
+#define SN_qcStatements "qcStatements"
+#define NID_qcStatements 286
+#define OBJ_qcStatements OBJ_id_pe,3L
+
+#define SN_ac_auditEntity "ac-auditEntity"
+#define NID_ac_auditEntity 287
+#define OBJ_ac_auditEntity OBJ_id_pe,4L
+
+#define SN_ac_targeting "ac-targeting"
+#define NID_ac_targeting 288
+#define OBJ_ac_targeting OBJ_id_pe,5L
+
+#define SN_aaControls "aaControls"
+#define NID_aaControls 289
+#define OBJ_aaControls OBJ_id_pe,6L
+
+#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock"
+#define NID_sbgp_ipAddrBlock 290
+#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L
+
+#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum"
+#define NID_sbgp_autonomousSysNum 291
+#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L
+
+#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier"
+#define NID_sbgp_routerIdentifier 292
+#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L
+
+#define SN_ac_proxying "ac-proxying"
+#define NID_ac_proxying 397
+#define OBJ_ac_proxying OBJ_id_pe,10L
+
+#define SN_sinfo_access "subjectInfoAccess"
+#define LN_sinfo_access "Subject Information Access"
+#define NID_sinfo_access 398
+#define OBJ_sinfo_access OBJ_id_pe,11L
+
+#define SN_proxyCertInfo "proxyCertInfo"
+#define LN_proxyCertInfo "Proxy Certificate Information"
+#define NID_proxyCertInfo 663
+#define OBJ_proxyCertInfo OBJ_id_pe,14L
+
+#define SN_id_qt_cps "id-qt-cps"
+#define LN_id_qt_cps "Policy Qualifier CPS"
+#define NID_id_qt_cps 164
+#define OBJ_id_qt_cps OBJ_id_qt,1L
+
+#define SN_id_qt_unotice "id-qt-unotice"
+#define LN_id_qt_unotice "Policy Qualifier User Notice"
+#define NID_id_qt_unotice 165
+#define OBJ_id_qt_unotice OBJ_id_qt,2L
+
+#define SN_textNotice "textNotice"
+#define NID_textNotice 293
+#define OBJ_textNotice OBJ_id_qt,3L
+
+#define SN_server_auth "serverAuth"
+#define LN_server_auth "TLS Web Server Authentication"
+#define NID_server_auth 129
+#define OBJ_server_auth OBJ_id_kp,1L
+
+#define SN_client_auth "clientAuth"
+#define LN_client_auth "TLS Web Client Authentication"
+#define NID_client_auth 130
+#define OBJ_client_auth OBJ_id_kp,2L
+
+#define SN_code_sign "codeSigning"
+#define LN_code_sign "Code Signing"
+#define NID_code_sign 131
+#define OBJ_code_sign OBJ_id_kp,3L
+
+#define SN_email_protect "emailProtection"
+#define LN_email_protect "E-mail Protection"
+#define NID_email_protect 132
+#define OBJ_email_protect OBJ_id_kp,4L
+
+#define SN_ipsecEndSystem "ipsecEndSystem"
+#define LN_ipsecEndSystem "IPSec End System"
+#define NID_ipsecEndSystem 294
+#define OBJ_ipsecEndSystem OBJ_id_kp,5L
+
+#define SN_ipsecTunnel "ipsecTunnel"
+#define LN_ipsecTunnel "IPSec Tunnel"
+#define NID_ipsecTunnel 295
+#define OBJ_ipsecTunnel OBJ_id_kp,6L
+
+#define SN_ipsecUser "ipsecUser"
+#define LN_ipsecUser "IPSec User"
+#define NID_ipsecUser 296
+#define OBJ_ipsecUser OBJ_id_kp,7L
+
+#define SN_time_stamp "timeStamping"
+#define LN_time_stamp "Time Stamping"
+#define NID_time_stamp 133
+#define OBJ_time_stamp OBJ_id_kp,8L
+
+#define SN_OCSP_sign "OCSPSigning"
+#define LN_OCSP_sign "OCSP Signing"
+#define NID_OCSP_sign 180
+#define OBJ_OCSP_sign OBJ_id_kp,9L
+
+#define SN_dvcs "DVCS"
+#define LN_dvcs "dvcs"
+#define NID_dvcs 297
+#define OBJ_dvcs OBJ_id_kp,10L
+
+#define SN_id_it_caProtEncCert "id-it-caProtEncCert"
+#define NID_id_it_caProtEncCert 298
+#define OBJ_id_it_caProtEncCert OBJ_id_it,1L
+
+#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes"
+#define NID_id_it_signKeyPairTypes 299
+#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L
+
+#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes"
+#define NID_id_it_encKeyPairTypes 300
+#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L
+
+#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg"
+#define NID_id_it_preferredSymmAlg 301
+#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L
+
+#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo"
+#define NID_id_it_caKeyUpdateInfo 302
+#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L
+
+#define SN_id_it_currentCRL "id-it-currentCRL"
+#define NID_id_it_currentCRL 303
+#define OBJ_id_it_currentCRL OBJ_id_it,6L
+
+#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs"
+#define NID_id_it_unsupportedOIDs 304
+#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L
+
+#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest"
+#define NID_id_it_subscriptionRequest 305
+#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L
+
+#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse"
+#define NID_id_it_subscriptionResponse 306
+#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L
+
+#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq"
+#define NID_id_it_keyPairParamReq 307
+#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L
+
+#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep"
+#define NID_id_it_keyPairParamRep 308
+#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L
+
+#define SN_id_it_revPassphrase "id-it-revPassphrase"
+#define NID_id_it_revPassphrase 309
+#define OBJ_id_it_revPassphrase OBJ_id_it,12L
+
+#define SN_id_it_implicitConfirm "id-it-implicitConfirm"
+#define NID_id_it_implicitConfirm 310
+#define OBJ_id_it_implicitConfirm OBJ_id_it,13L
+
+#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime"
+#define NID_id_it_confirmWaitTime 311
+#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L
+
+#define SN_id_it_origPKIMessage "id-it-origPKIMessage"
+#define NID_id_it_origPKIMessage 312
+#define OBJ_id_it_origPKIMessage OBJ_id_it,15L
+
+#define SN_id_it_suppLangTags "id-it-suppLangTags"
+#define NID_id_it_suppLangTags 784
+#define OBJ_id_it_suppLangTags OBJ_id_it,16L
+
+#define SN_id_regCtrl "id-regCtrl"
+#define NID_id_regCtrl 313
+#define OBJ_id_regCtrl OBJ_id_pkip,1L
+
+#define SN_id_regInfo "id-regInfo"
+#define NID_id_regInfo 314
+#define OBJ_id_regInfo OBJ_id_pkip,2L
+
+#define SN_id_regCtrl_regToken "id-regCtrl-regToken"
+#define NID_id_regCtrl_regToken 315
+#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L
+
+#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator"
+#define NID_id_regCtrl_authenticator 316
+#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L
+
+#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo"
+#define NID_id_regCtrl_pkiPublicationInfo 317
+#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L
+
+#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions"
+#define NID_id_regCtrl_pkiArchiveOptions 318
+#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L
+
+#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID"
+#define NID_id_regCtrl_oldCertID 319
+#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L
+
+#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey"
+#define NID_id_regCtrl_protocolEncrKey 320
+#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L
+
+#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs"
+#define NID_id_regInfo_utf8Pairs 321
+#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L
+
+#define SN_id_regInfo_certReq "id-regInfo-certReq"
+#define NID_id_regInfo_certReq 322
+#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L
+
+#define SN_id_alg_des40 "id-alg-des40"
+#define NID_id_alg_des40 323
+#define OBJ_id_alg_des40 OBJ_id_alg,1L
+
+#define SN_id_alg_noSignature "id-alg-noSignature"
+#define NID_id_alg_noSignature 324
+#define OBJ_id_alg_noSignature OBJ_id_alg,2L
+
+#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1"
+#define NID_id_alg_dh_sig_hmac_sha1 325
+#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L
+
+#define SN_id_alg_dh_pop "id-alg-dh-pop"
+#define NID_id_alg_dh_pop 326
+#define OBJ_id_alg_dh_pop OBJ_id_alg,4L
+
+#define SN_id_cmc_statusInfo "id-cmc-statusInfo"
+#define NID_id_cmc_statusInfo 327
+#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L
+
+#define SN_id_cmc_identification "id-cmc-identification"
+#define NID_id_cmc_identification 328
+#define OBJ_id_cmc_identification OBJ_id_cmc,2L
+
+#define SN_id_cmc_identityProof "id-cmc-identityProof"
+#define NID_id_cmc_identityProof 329
+#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L
+
+#define SN_id_cmc_dataReturn "id-cmc-dataReturn"
+#define NID_id_cmc_dataReturn 330
+#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L
+
+#define SN_id_cmc_transactionId "id-cmc-transactionId"
+#define NID_id_cmc_transactionId 331
+#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L
+
+#define SN_id_cmc_senderNonce "id-cmc-senderNonce"
+#define NID_id_cmc_senderNonce 332
+#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L
+
+#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce"
+#define NID_id_cmc_recipientNonce 333
+#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L
+
+#define SN_id_cmc_addExtensions "id-cmc-addExtensions"
+#define NID_id_cmc_addExtensions 334
+#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L
+
+#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP"
+#define NID_id_cmc_encryptedPOP 335
+#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L
+
+#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP"
+#define NID_id_cmc_decryptedPOP 336
+#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L
+
+#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness"
+#define NID_id_cmc_lraPOPWitness 337
+#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L
+
+#define SN_id_cmc_getCert "id-cmc-getCert"
+#define NID_id_cmc_getCert 338
+#define OBJ_id_cmc_getCert OBJ_id_cmc,15L
+
+#define SN_id_cmc_getCRL "id-cmc-getCRL"
+#define NID_id_cmc_getCRL 339
+#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L
+
+#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest"
+#define NID_id_cmc_revokeRequest 340
+#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L
+
+#define SN_id_cmc_regInfo "id-cmc-regInfo"
+#define NID_id_cmc_regInfo 341
+#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L
+
+#define SN_id_cmc_responseInfo "id-cmc-responseInfo"
+#define NID_id_cmc_responseInfo 342
+#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L
+
+#define SN_id_cmc_queryPending "id-cmc-queryPending"
+#define NID_id_cmc_queryPending 343
+#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L
+
+#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom"
+#define NID_id_cmc_popLinkRandom 344
+#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L
+
+#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness"
+#define NID_id_cmc_popLinkWitness 345
+#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L
+
+#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance"
+#define NID_id_cmc_confirmCertAcceptance 346
+#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L
+
+#define SN_id_on_personalData "id-on-personalData"
+#define NID_id_on_personalData 347
+#define OBJ_id_on_personalData OBJ_id_on,1L
+
+#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier"
+#define LN_id_on_permanentIdentifier "Permanent Identifier"
+#define NID_id_on_permanentIdentifier 858
+#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L
+
+#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth"
+#define NID_id_pda_dateOfBirth 348
+#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L
+
+#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth"
+#define NID_id_pda_placeOfBirth 349
+#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L
+
+#define SN_id_pda_gender "id-pda-gender"
+#define NID_id_pda_gender 351
+#define OBJ_id_pda_gender OBJ_id_pda,3L
+
+#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship"
+#define NID_id_pda_countryOfCitizenship 352
+#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L
+
+#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence"
+#define NID_id_pda_countryOfResidence 353
+#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L
+
+#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo"
+#define NID_id_aca_authenticationInfo 354
+#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L
+
+#define SN_id_aca_accessIdentity "id-aca-accessIdentity"
+#define NID_id_aca_accessIdentity 355
+#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L
+
+#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity"
+#define NID_id_aca_chargingIdentity 356
+#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L
+
+#define SN_id_aca_group "id-aca-group"
+#define NID_id_aca_group 357
+#define OBJ_id_aca_group OBJ_id_aca,4L
+
+#define SN_id_aca_role "id-aca-role"
+#define NID_id_aca_role 358
+#define OBJ_id_aca_role OBJ_id_aca,5L
+
+#define SN_id_aca_encAttrs "id-aca-encAttrs"
+#define NID_id_aca_encAttrs 399
+#define OBJ_id_aca_encAttrs OBJ_id_aca,6L
+
+#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1"
+#define NID_id_qcs_pkixQCSyntax_v1 359
+#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L
+
+#define SN_id_cct_crs "id-cct-crs"
+#define NID_id_cct_crs 360
+#define OBJ_id_cct_crs OBJ_id_cct,1L
+
+#define SN_id_cct_PKIData "id-cct-PKIData"
+#define NID_id_cct_PKIData 361
+#define OBJ_id_cct_PKIData OBJ_id_cct,2L
+
+#define SN_id_cct_PKIResponse "id-cct-PKIResponse"
+#define NID_id_cct_PKIResponse 362
+#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L
+
+#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage"
+#define LN_id_ppl_anyLanguage "Any language"
+#define NID_id_ppl_anyLanguage 664
+#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L
+
+#define SN_id_ppl_inheritAll "id-ppl-inheritAll"
+#define LN_id_ppl_inheritAll "Inherit all"
+#define NID_id_ppl_inheritAll 665
+#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L
+
+#define SN_Independent "id-ppl-independent"
+#define LN_Independent "Independent"
+#define NID_Independent 667
+#define OBJ_Independent OBJ_id_ppl,2L
+
+#define SN_ad_OCSP "OCSP"
+#define LN_ad_OCSP "OCSP"
+#define NID_ad_OCSP 178
+#define OBJ_ad_OCSP OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers "caIssuers"
+#define LN_ad_ca_issuers "CA Issuers"
+#define NID_ad_ca_issuers 179
+#define OBJ_ad_ca_issuers OBJ_id_ad,2L
+
+#define SN_ad_timeStamping "ad_timestamping"
+#define LN_ad_timeStamping "AD Time Stamping"
+#define NID_ad_timeStamping 363
+#define OBJ_ad_timeStamping OBJ_id_ad,3L
+
+#define SN_ad_dvcs "AD_DVCS"
+#define LN_ad_dvcs "ad dvcs"
+#define NID_ad_dvcs 364
+#define OBJ_ad_dvcs OBJ_id_ad,4L
+
+#define SN_caRepository "caRepository"
+#define LN_caRepository "CA Repository"
+#define NID_caRepository 785
+#define OBJ_caRepository OBJ_id_ad,5L
+
+#define OBJ_id_pkix_OCSP OBJ_ad_OCSP
+
+#define SN_id_pkix_OCSP_basic "basicOCSPResponse"
+#define LN_id_pkix_OCSP_basic "Basic OCSP Response"
+#define NID_id_pkix_OCSP_basic 365
+#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L
+
+#define SN_id_pkix_OCSP_Nonce "Nonce"
+#define LN_id_pkix_OCSP_Nonce "OCSP Nonce"
+#define NID_id_pkix_OCSP_Nonce 366
+#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L
+
+#define SN_id_pkix_OCSP_CrlID "CrlID"
+#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID"
+#define NID_id_pkix_OCSP_CrlID 367
+#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L
+
+#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses"
+#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses"
+#define NID_id_pkix_OCSP_acceptableResponses 368
+#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L
+
+#define SN_id_pkix_OCSP_noCheck "noCheck"
+#define LN_id_pkix_OCSP_noCheck "OCSP No Check"
+#define NID_id_pkix_OCSP_noCheck 369
+#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L
+
+#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff"
+#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff"
+#define NID_id_pkix_OCSP_archiveCutoff 370
+#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L
+
+#define SN_id_pkix_OCSP_serviceLocator "serviceLocator"
+#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator"
+#define NID_id_pkix_OCSP_serviceLocator 371
+#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L
+
+#define SN_id_pkix_OCSP_extendedStatus "extendedStatus"
+#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status"
+#define NID_id_pkix_OCSP_extendedStatus 372
+#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L
+
+#define SN_id_pkix_OCSP_valid "valid"
+#define NID_id_pkix_OCSP_valid 373
+#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L
+
+#define SN_id_pkix_OCSP_path "path"
+#define NID_id_pkix_OCSP_path 374
+#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L
+
+#define SN_id_pkix_OCSP_trustRoot "trustRoot"
+#define LN_id_pkix_OCSP_trustRoot "Trust Root"
+#define NID_id_pkix_OCSP_trustRoot 375
+#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L
+
+#define SN_algorithm "algorithm"
+#define LN_algorithm "algorithm"
+#define NID_algorithm 376
+#define OBJ_algorithm 1L,3L,14L,3L,2L
+
+#define SN_md5WithRSA "RSA-NP-MD5"
+#define LN_md5WithRSA "md5WithRSA"
+#define NID_md5WithRSA 104
+#define OBJ_md5WithRSA OBJ_algorithm,3L
+
+#define SN_des_ecb "DES-ECB"
+#define LN_des_ecb "des-ecb"
+#define NID_des_ecb 29
+#define OBJ_des_ecb OBJ_algorithm,6L
+
+#define SN_des_cbc "DES-CBC"
+#define LN_des_cbc "des-cbc"
+#define NID_des_cbc 31
+#define OBJ_des_cbc OBJ_algorithm,7L
+
+#define SN_des_ofb64 "DES-OFB"
+#define LN_des_ofb64 "des-ofb"
+#define NID_des_ofb64 45
+#define OBJ_des_ofb64 OBJ_algorithm,8L
+
+#define SN_des_cfb64 "DES-CFB"
+#define LN_des_cfb64 "des-cfb"
+#define NID_des_cfb64 30
+#define OBJ_des_cfb64 OBJ_algorithm,9L
+
+#define SN_rsaSignature "rsaSignature"
+#define NID_rsaSignature 377
+#define OBJ_rsaSignature OBJ_algorithm,11L
+
+#define SN_dsa_2 "DSA-old"
+#define LN_dsa_2 "dsaEncryption-old"
+#define NID_dsa_2 67
+#define OBJ_dsa_2 OBJ_algorithm,12L
+
+#define SN_dsaWithSHA "DSA-SHA"
+#define LN_dsaWithSHA "dsaWithSHA"
+#define NID_dsaWithSHA 66
+#define OBJ_dsaWithSHA OBJ_algorithm,13L
+
+#define SN_shaWithRSAEncryption "RSA-SHA"
+#define LN_shaWithRSAEncryption "shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption 42
+#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L
+
+#define SN_des_ede_ecb "DES-EDE"
+#define LN_des_ede_ecb "des-ede"
+#define NID_des_ede_ecb 32
+#define OBJ_des_ede_ecb OBJ_algorithm,17L
+
+#define SN_des_ede3_ecb "DES-EDE3"
+#define LN_des_ede3_ecb "des-ede3"
+#define NID_des_ede3_ecb 33
+
+#define SN_des_ede_cbc "DES-EDE-CBC"
+#define LN_des_ede_cbc "des-ede-cbc"
+#define NID_des_ede_cbc 43
+
+#define SN_des_ede_cfb64 "DES-EDE-CFB"
+#define LN_des_ede_cfb64 "des-ede-cfb"
+#define NID_des_ede_cfb64 60
+
+#define SN_des_ede3_cfb64 "DES-EDE3-CFB"
+#define LN_des_ede3_cfb64 "des-ede3-cfb"
+#define NID_des_ede3_cfb64 61
+
+#define SN_des_ede_ofb64 "DES-EDE-OFB"
+#define LN_des_ede_ofb64 "des-ede-ofb"
+#define NID_des_ede_ofb64 62
+
+#define SN_des_ede3_ofb64 "DES-EDE3-OFB"
+#define LN_des_ede3_ofb64 "des-ede3-ofb"
+#define NID_des_ede3_ofb64 63
+
+#define SN_desx_cbc "DESX-CBC"
+#define LN_desx_cbc "desx-cbc"
+#define NID_desx_cbc 80
+
+#define SN_sha "SHA"
+#define LN_sha "sha"
+#define NID_sha 41
+#define OBJ_sha OBJ_algorithm,18L
+
+#define SN_sha1 "SHA1"
+#define LN_sha1 "sha1"
+#define NID_sha1 64
+#define OBJ_sha1 OBJ_algorithm,26L
+
+#define SN_dsaWithSHA1_2 "DSA-SHA1-old"
+#define LN_dsaWithSHA1_2 "dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2 70
+#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L
+
+#define SN_sha1WithRSA "RSA-SHA1-2"
+#define LN_sha1WithRSA "sha1WithRSA"
+#define NID_sha1WithRSA 115
+#define OBJ_sha1WithRSA OBJ_algorithm,29L
+
+#define SN_ripemd160 "RIPEMD160"
+#define LN_ripemd160 "ripemd160"
+#define NID_ripemd160 117
+#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L
+
+#define SN_ripemd160WithRSA "RSA-RIPEMD160"
+#define LN_ripemd160WithRSA "ripemd160WithRSA"
+#define NID_ripemd160WithRSA 119
+#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L
+
+#define SN_sxnet "SXNetID"
+#define LN_sxnet "Strong Extranet ID"
+#define NID_sxnet 143
+#define OBJ_sxnet 1L,3L,101L,1L,4L,1L
+
+#define SN_X500 "X500"
+#define LN_X500 "directory services (X.500)"
+#define NID_X500 11
+#define OBJ_X500 2L,5L
+
+#define SN_X509 "X509"
+#define NID_X509 12
+#define OBJ_X509 OBJ_X500,4L
+
+#define SN_commonName "CN"
+#define LN_commonName "commonName"
+#define NID_commonName 13
+#define OBJ_commonName OBJ_X509,3L
+
+#define SN_surname "SN"
+#define LN_surname "surname"
+#define NID_surname 100
+#define OBJ_surname OBJ_X509,4L
+
+#define LN_serialNumber "serialNumber"
+#define NID_serialNumber 105
+#define OBJ_serialNumber OBJ_X509,5L
+
+#define SN_countryName "C"
+#define LN_countryName "countryName"
+#define NID_countryName 14
+#define OBJ_countryName OBJ_X509,6L
+
+#define SN_localityName "L"
+#define LN_localityName "localityName"
+#define NID_localityName 15
+#define OBJ_localityName OBJ_X509,7L
+
+#define SN_stateOrProvinceName "ST"
+#define LN_stateOrProvinceName "stateOrProvinceName"
+#define NID_stateOrProvinceName 16
+#define OBJ_stateOrProvinceName OBJ_X509,8L
+
+#define SN_streetAddress "street"
+#define LN_streetAddress "streetAddress"
+#define NID_streetAddress 660
+#define OBJ_streetAddress OBJ_X509,9L
+
+#define SN_organizationName "O"
+#define LN_organizationName "organizationName"
+#define NID_organizationName 17
+#define OBJ_organizationName OBJ_X509,10L
+
+#define SN_organizationalUnitName "OU"
+#define LN_organizationalUnitName "organizationalUnitName"
+#define NID_organizationalUnitName 18
+#define OBJ_organizationalUnitName OBJ_X509,11L
+
+#define SN_title "title"
+#define LN_title "title"
+#define NID_title 106
+#define OBJ_title OBJ_X509,12L
+
+#define LN_description "description"
+#define NID_description 107
+#define OBJ_description OBJ_X509,13L
+
+#define LN_searchGuide "searchGuide"
+#define NID_searchGuide 859
+#define OBJ_searchGuide OBJ_X509,14L
+
+#define LN_businessCategory "businessCategory"
+#define NID_businessCategory 860
+#define OBJ_businessCategory OBJ_X509,15L
+
+#define LN_postalAddress "postalAddress"
+#define NID_postalAddress 861
+#define OBJ_postalAddress OBJ_X509,16L
+
+#define LN_postalCode "postalCode"
+#define NID_postalCode 661
+#define OBJ_postalCode OBJ_X509,17L
+
+#define LN_postOfficeBox "postOfficeBox"
+#define NID_postOfficeBox 862
+#define OBJ_postOfficeBox OBJ_X509,18L
+
+#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName"
+#define NID_physicalDeliveryOfficeName 863
+#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L
+
+#define LN_telephoneNumber "telephoneNumber"
+#define NID_telephoneNumber 864
+#define OBJ_telephoneNumber OBJ_X509,20L
+
+#define LN_telexNumber "telexNumber"
+#define NID_telexNumber 865
+#define OBJ_telexNumber OBJ_X509,21L
+
+#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier"
+#define NID_teletexTerminalIdentifier 866
+#define OBJ_teletexTerminalIdentifier OBJ_X509,22L
+
+#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber"
+#define NID_facsimileTelephoneNumber 867
+#define OBJ_facsimileTelephoneNumber OBJ_X509,23L
+
+#define LN_x121Address "x121Address"
+#define NID_x121Address 868
+#define OBJ_x121Address OBJ_X509,24L
+
+#define LN_internationaliSDNNumber "internationaliSDNNumber"
+#define NID_internationaliSDNNumber 869
+#define OBJ_internationaliSDNNumber OBJ_X509,25L
+
+#define LN_registeredAddress "registeredAddress"
+#define NID_registeredAddress 870
+#define OBJ_registeredAddress OBJ_X509,26L
+
+#define LN_destinationIndicator "destinationIndicator"
+#define NID_destinationIndicator 871
+#define OBJ_destinationIndicator OBJ_X509,27L
+
+#define LN_preferredDeliveryMethod "preferredDeliveryMethod"
+#define NID_preferredDeliveryMethod 872
+#define OBJ_preferredDeliveryMethod OBJ_X509,28L
+
+#define LN_presentationAddress "presentationAddress"
+#define NID_presentationAddress 873
+#define OBJ_presentationAddress OBJ_X509,29L
+
+#define LN_supportedApplicationContext "supportedApplicationContext"
+#define NID_supportedApplicationContext 874
+#define OBJ_supportedApplicationContext OBJ_X509,30L
+
+#define SN_member "member"
+#define NID_member 875
+#define OBJ_member OBJ_X509,31L
+
+#define SN_owner "owner"
+#define NID_owner 876
+#define OBJ_owner OBJ_X509,32L
+
+#define LN_roleOccupant "roleOccupant"
+#define NID_roleOccupant 877
+#define OBJ_roleOccupant OBJ_X509,33L
+
+#define SN_seeAlso "seeAlso"
+#define NID_seeAlso 878
+#define OBJ_seeAlso OBJ_X509,34L
+
+#define LN_userPassword "userPassword"
+#define NID_userPassword 879
+#define OBJ_userPassword OBJ_X509,35L
+
+#define LN_userCertificate "userCertificate"
+#define NID_userCertificate 880
+#define OBJ_userCertificate OBJ_X509,36L
+
+#define LN_cACertificate "cACertificate"
+#define NID_cACertificate 881
+#define OBJ_cACertificate OBJ_X509,37L
+
+#define LN_authorityRevocationList "authorityRevocationList"
+#define NID_authorityRevocationList 882
+#define OBJ_authorityRevocationList OBJ_X509,38L
+
+#define LN_certificateRevocationList "certificateRevocationList"
+#define NID_certificateRevocationList 883
+#define OBJ_certificateRevocationList OBJ_X509,39L
+
+#define LN_crossCertificatePair "crossCertificatePair"
+#define NID_crossCertificatePair 884
+#define OBJ_crossCertificatePair OBJ_X509,40L
+
+#define SN_name "name"
+#define LN_name "name"
+#define NID_name 173
+#define OBJ_name OBJ_X509,41L
+
+#define SN_givenName "GN"
+#define LN_givenName "givenName"
+#define NID_givenName 99
+#define OBJ_givenName OBJ_X509,42L
+
+#define SN_initials "initials"
+#define LN_initials "initials"
+#define NID_initials 101
+#define OBJ_initials OBJ_X509,43L
+
+#define LN_generationQualifier "generationQualifier"
+#define NID_generationQualifier 509
+#define OBJ_generationQualifier OBJ_X509,44L
+
+#define LN_x500UniqueIdentifier "x500UniqueIdentifier"
+#define NID_x500UniqueIdentifier 503
+#define OBJ_x500UniqueIdentifier OBJ_X509,45L
+
+#define SN_dnQualifier "dnQualifier"
+#define LN_dnQualifier "dnQualifier"
+#define NID_dnQualifier 174
+#define OBJ_dnQualifier OBJ_X509,46L
+
+#define LN_enhancedSearchGuide "enhancedSearchGuide"
+#define NID_enhancedSearchGuide 885
+#define OBJ_enhancedSearchGuide OBJ_X509,47L
+
+#define LN_protocolInformation "protocolInformation"
+#define NID_protocolInformation 886
+#define OBJ_protocolInformation OBJ_X509,48L
+
+#define LN_distinguishedName "distinguishedName"
+#define NID_distinguishedName 887
+#define OBJ_distinguishedName OBJ_X509,49L
+
+#define LN_uniqueMember "uniqueMember"
+#define NID_uniqueMember 888
+#define OBJ_uniqueMember OBJ_X509,50L
+
+#define LN_houseIdentifier "houseIdentifier"
+#define NID_houseIdentifier 889
+#define OBJ_houseIdentifier OBJ_X509,51L
+
+#define LN_supportedAlgorithms "supportedAlgorithms"
+#define NID_supportedAlgorithms 890
+#define OBJ_supportedAlgorithms OBJ_X509,52L
+
+#define LN_deltaRevocationList "deltaRevocationList"
+#define NID_deltaRevocationList 891
+#define OBJ_deltaRevocationList OBJ_X509,53L
+
+#define SN_dmdName "dmdName"
+#define NID_dmdName 892
+#define OBJ_dmdName OBJ_X509,54L
+
+#define LN_pseudonym "pseudonym"
+#define NID_pseudonym 510
+#define OBJ_pseudonym OBJ_X509,65L
+
+#define SN_role "role"
+#define LN_role "role"
+#define NID_role 400
+#define OBJ_role OBJ_X509,72L
+
+#define SN_X500algorithms "X500algorithms"
+#define LN_X500algorithms "directory services - algorithms"
+#define NID_X500algorithms 378
+#define OBJ_X500algorithms OBJ_X500,8L
+
+#define SN_rsa "RSA"
+#define LN_rsa "rsa"
+#define NID_rsa 19
+#define OBJ_rsa OBJ_X500algorithms,1L,1L
+
+#define SN_mdc2WithRSA "RSA-MDC2"
+#define LN_mdc2WithRSA "mdc2WithRSA"
+#define NID_mdc2WithRSA 96
+#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L
+
+#define SN_mdc2 "MDC2"
+#define LN_mdc2 "mdc2"
+#define NID_mdc2 95
+#define OBJ_mdc2 OBJ_X500algorithms,3L,101L
+
+#define SN_id_ce "id-ce"
+#define NID_id_ce 81
+#define OBJ_id_ce OBJ_X500,29L
+
+#define SN_subject_directory_attributes "subjectDirectoryAttributes"
+#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes"
+#define NID_subject_directory_attributes 769
+#define OBJ_subject_directory_attributes OBJ_id_ce,9L
+
+#define SN_subject_key_identifier "subjectKeyIdentifier"
+#define LN_subject_key_identifier "X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier 82
+#define OBJ_subject_key_identifier OBJ_id_ce,14L
+
+#define SN_key_usage "keyUsage"
+#define LN_key_usage "X509v3 Key Usage"
+#define NID_key_usage 83
+#define OBJ_key_usage OBJ_id_ce,15L
+
+#define SN_private_key_usage_period "privateKeyUsagePeriod"
+#define LN_private_key_usage_period "X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period 84
+#define OBJ_private_key_usage_period OBJ_id_ce,16L
+
+#define SN_subject_alt_name "subjectAltName"
+#define LN_subject_alt_name "X509v3 Subject Alternative Name"
+#define NID_subject_alt_name 85
+#define OBJ_subject_alt_name OBJ_id_ce,17L
+
+#define SN_issuer_alt_name "issuerAltName"
+#define LN_issuer_alt_name "X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name 86
+#define OBJ_issuer_alt_name OBJ_id_ce,18L
+
+#define SN_basic_constraints "basicConstraints"
+#define LN_basic_constraints "X509v3 Basic Constraints"
+#define NID_basic_constraints 87
+#define OBJ_basic_constraints OBJ_id_ce,19L
+
+#define SN_crl_number "crlNumber"
+#define LN_crl_number "X509v3 CRL Number"
+#define NID_crl_number 88
+#define OBJ_crl_number OBJ_id_ce,20L
+
+#define SN_crl_reason "CRLReason"
+#define LN_crl_reason "X509v3 CRL Reason Code"
+#define NID_crl_reason 141
+#define OBJ_crl_reason OBJ_id_ce,21L
+
+#define SN_invalidity_date "invalidityDate"
+#define LN_invalidity_date "Invalidity Date"
+#define NID_invalidity_date 142
+#define OBJ_invalidity_date OBJ_id_ce,24L
+
+#define SN_delta_crl "deltaCRL"
+#define LN_delta_crl "X509v3 Delta CRL Indicator"
+#define NID_delta_crl 140
+#define OBJ_delta_crl OBJ_id_ce,27L
+
+#define SN_issuing_distribution_point "issuingDistributionPoint"
+#define LN_issuing_distribution_point "X509v3 Issuing Distrubution Point"
+#define NID_issuing_distribution_point 770
+#define OBJ_issuing_distribution_point OBJ_id_ce,28L
+
+#define SN_certificate_issuer "certificateIssuer"
+#define LN_certificate_issuer "X509v3 Certificate Issuer"
+#define NID_certificate_issuer 771
+#define OBJ_certificate_issuer OBJ_id_ce,29L
+
+#define SN_name_constraints "nameConstraints"
+#define LN_name_constraints "X509v3 Name Constraints"
+#define NID_name_constraints 666
+#define OBJ_name_constraints OBJ_id_ce,30L
+
+#define SN_crl_distribution_points "crlDistributionPoints"
+#define LN_crl_distribution_points "X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points 103
+#define OBJ_crl_distribution_points OBJ_id_ce,31L
+
+#define SN_certificate_policies "certificatePolicies"
+#define LN_certificate_policies "X509v3 Certificate Policies"
+#define NID_certificate_policies 89
+#define OBJ_certificate_policies OBJ_id_ce,32L
+
+#define SN_any_policy "anyPolicy"
+#define LN_any_policy "X509v3 Any Policy"
+#define NID_any_policy 746
+#define OBJ_any_policy OBJ_certificate_policies,0L
+
+#define SN_policy_mappings "policyMappings"
+#define LN_policy_mappings "X509v3 Policy Mappings"
+#define NID_policy_mappings 747
+#define OBJ_policy_mappings OBJ_id_ce,33L
+
+#define SN_authority_key_identifier "authorityKeyIdentifier"
+#define LN_authority_key_identifier "X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier 90
+#define OBJ_authority_key_identifier OBJ_id_ce,35L
+
+#define SN_policy_constraints "policyConstraints"
+#define LN_policy_constraints "X509v3 Policy Constraints"
+#define NID_policy_constraints 401
+#define OBJ_policy_constraints OBJ_id_ce,36L
+
+#define SN_ext_key_usage "extendedKeyUsage"
+#define LN_ext_key_usage "X509v3 Extended Key Usage"
+#define NID_ext_key_usage 126
+#define OBJ_ext_key_usage OBJ_id_ce,37L
+
+#define SN_freshest_crl "freshestCRL"
+#define LN_freshest_crl "X509v3 Freshest CRL"
+#define NID_freshest_crl 857
+#define OBJ_freshest_crl OBJ_id_ce,46L
+
+#define SN_inhibit_any_policy "inhibitAnyPolicy"
+#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy"
+#define NID_inhibit_any_policy 748
+#define OBJ_inhibit_any_policy OBJ_id_ce,54L
+
+#define SN_target_information "targetInformation"
+#define LN_target_information "X509v3 AC Targeting"
+#define NID_target_information 402
+#define OBJ_target_information OBJ_id_ce,55L
+
+#define SN_no_rev_avail "noRevAvail"
+#define LN_no_rev_avail "X509v3 No Revocation Available"
+#define NID_no_rev_avail 403
+#define OBJ_no_rev_avail OBJ_id_ce,56L
+
+#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage"
+#define LN_anyExtendedKeyUsage "Any Extended Key Usage"
+#define NID_anyExtendedKeyUsage 910
+#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L
+
+#define SN_netscape "Netscape"
+#define LN_netscape "Netscape Communications Corp."
+#define NID_netscape 57
+#define OBJ_netscape 2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension "nsCertExt"
+#define LN_netscape_cert_extension "Netscape Certificate Extension"
+#define NID_netscape_cert_extension 58
+#define OBJ_netscape_cert_extension OBJ_netscape,1L
+
+#define SN_netscape_data_type "nsDataType"
+#define LN_netscape_data_type "Netscape Data Type"
+#define NID_netscape_data_type 59
+#define OBJ_netscape_data_type OBJ_netscape,2L
+
+#define SN_netscape_cert_type "nsCertType"
+#define LN_netscape_cert_type "Netscape Cert Type"
+#define NID_netscape_cert_type 71
+#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url "nsBaseUrl"
+#define LN_netscape_base_url "Netscape Base Url"
+#define NID_netscape_base_url 72
+#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url "nsRevocationUrl"
+#define LN_netscape_revocation_url "Netscape Revocation Url"
+#define NID_netscape_revocation_url 73
+#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url "nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url 74
+#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url "nsRenewalUrl"
+#define LN_netscape_renewal_url "Netscape Renewal Url"
+#define NID_netscape_renewal_url 75
+#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url "nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url "Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url 76
+#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name "nsSslServerName"
+#define LN_netscape_ssl_server_name "Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name 77
+#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment "nsComment"
+#define LN_netscape_comment "Netscape Comment"
+#define NID_netscape_comment 78
+#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence "nsCertSequence"
+#define LN_netscape_cert_sequence "Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence 79
+#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L
+
+#define SN_ns_sgc "nsSGC"
+#define LN_ns_sgc "Netscape Server Gated Crypto"
+#define NID_ns_sgc 139
+#define OBJ_ns_sgc OBJ_netscape,4L,1L
+
+#define SN_org "ORG"
+#define LN_org "org"
+#define NID_org 379
+#define OBJ_org OBJ_iso,3L
+
+#define SN_dod "DOD"
+#define LN_dod "dod"
+#define NID_dod 380
+#define OBJ_dod OBJ_org,6L
+
+#define SN_iana "IANA"
+#define LN_iana "iana"
+#define NID_iana 381
+#define OBJ_iana OBJ_dod,1L
+
+#define OBJ_internet OBJ_iana
+
+#define SN_Directory "directory"
+#define LN_Directory "Directory"
+#define NID_Directory 382
+#define OBJ_Directory OBJ_internet,1L
+
+#define SN_Management "mgmt"
+#define LN_Management "Management"
+#define NID_Management 383
+#define OBJ_Management OBJ_internet,2L
+
+#define SN_Experimental "experimental"
+#define LN_Experimental "Experimental"
+#define NID_Experimental 384
+#define OBJ_Experimental OBJ_internet,3L
+
+#define SN_Private "private"
+#define LN_Private "Private"
+#define NID_Private 385
+#define OBJ_Private OBJ_internet,4L
+
+#define SN_Security "security"
+#define LN_Security "Security"
+#define NID_Security 386
+#define OBJ_Security OBJ_internet,5L
+
+#define SN_SNMPv2 "snmpv2"
+#define LN_SNMPv2 "SNMPv2"
+#define NID_SNMPv2 387
+#define OBJ_SNMPv2 OBJ_internet,6L
+
+#define LN_Mail "Mail"
+#define NID_Mail 388
+#define OBJ_Mail OBJ_internet,7L
+
+#define SN_Enterprises "enterprises"
+#define LN_Enterprises "Enterprises"
+#define NID_Enterprises 389
+#define OBJ_Enterprises OBJ_Private,1L
+
+#define SN_dcObject "dcobject"
+#define LN_dcObject "dcObject"
+#define NID_dcObject 390
+#define OBJ_dcObject OBJ_Enterprises,1466L,344L
+
+#define SN_mime_mhs "mime-mhs"
+#define LN_mime_mhs "MIME MHS"
+#define NID_mime_mhs 504
+#define OBJ_mime_mhs OBJ_Mail,1L
+
+#define SN_mime_mhs_headings "mime-mhs-headings"
+#define LN_mime_mhs_headings "mime-mhs-headings"
+#define NID_mime_mhs_headings 505
+#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L
+
+#define SN_mime_mhs_bodies "mime-mhs-bodies"
+#define LN_mime_mhs_bodies "mime-mhs-bodies"
+#define NID_mime_mhs_bodies 506
+#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L
+
+#define SN_id_hex_partial_message "id-hex-partial-message"
+#define LN_id_hex_partial_message "id-hex-partial-message"
+#define NID_id_hex_partial_message 507
+#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L
+
+#define SN_id_hex_multipart_message "id-hex-multipart-message"
+#define LN_id_hex_multipart_message "id-hex-multipart-message"
+#define NID_id_hex_multipart_message 508
+#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L
+
+#define SN_rle_compression "RLE"
+#define LN_rle_compression "run length compression"
+#define NID_rle_compression 124
+#define OBJ_rle_compression 1L,1L,1L,1L,666L,1L
+
+#define SN_zlib_compression "ZLIB"
+#define LN_zlib_compression "zlib compression"
+#define NID_zlib_compression 125
+#define OBJ_zlib_compression OBJ_id_smime_alg,8L
+
+#define OBJ_csor 2L,16L,840L,1L,101L,3L
+
+#define OBJ_nistAlgorithms OBJ_csor,4L
+
+#define OBJ_aes OBJ_nistAlgorithms,1L
+
+#define SN_aes_128_ecb "AES-128-ECB"
+#define LN_aes_128_ecb "aes-128-ecb"
+#define NID_aes_128_ecb 418
+#define OBJ_aes_128_ecb OBJ_aes,1L
+
+#define SN_aes_128_cbc "AES-128-CBC"
+#define LN_aes_128_cbc "aes-128-cbc"
+#define NID_aes_128_cbc 419
+#define OBJ_aes_128_cbc OBJ_aes,2L
+
+#define SN_aes_128_ofb128 "AES-128-OFB"
+#define LN_aes_128_ofb128 "aes-128-ofb"
+#define NID_aes_128_ofb128 420
+#define OBJ_aes_128_ofb128 OBJ_aes,3L
+
+#define SN_aes_128_cfb128 "AES-128-CFB"
+#define LN_aes_128_cfb128 "aes-128-cfb"
+#define NID_aes_128_cfb128 421
+#define OBJ_aes_128_cfb128 OBJ_aes,4L
+
+#define SN_id_aes128_wrap "id-aes128-wrap"
+#define NID_id_aes128_wrap 788
+#define OBJ_id_aes128_wrap OBJ_aes,5L
+
+#define SN_aes_128_gcm "id-aes128-GCM"
+#define LN_aes_128_gcm "aes-128-gcm"
+#define NID_aes_128_gcm 895
+#define OBJ_aes_128_gcm OBJ_aes,6L
+
+#define SN_aes_128_ccm "id-aes128-CCM"
+#define LN_aes_128_ccm "aes-128-ccm"
+#define NID_aes_128_ccm 896
+#define OBJ_aes_128_ccm OBJ_aes,7L
+
+#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad"
+#define NID_id_aes128_wrap_pad 897
+#define OBJ_id_aes128_wrap_pad OBJ_aes,8L
+
+#define SN_aes_192_ecb "AES-192-ECB"
+#define LN_aes_192_ecb "aes-192-ecb"
+#define NID_aes_192_ecb 422
+#define OBJ_aes_192_ecb OBJ_aes,21L
+
+#define SN_aes_192_cbc "AES-192-CBC"
+#define LN_aes_192_cbc "aes-192-cbc"
+#define NID_aes_192_cbc 423
+#define OBJ_aes_192_cbc OBJ_aes,22L
+
+#define SN_aes_192_ofb128 "AES-192-OFB"
+#define LN_aes_192_ofb128 "aes-192-ofb"
+#define NID_aes_192_ofb128 424
+#define OBJ_aes_192_ofb128 OBJ_aes,23L
+
+#define SN_aes_192_cfb128 "AES-192-CFB"
+#define LN_aes_192_cfb128 "aes-192-cfb"
+#define NID_aes_192_cfb128 425
+#define OBJ_aes_192_cfb128 OBJ_aes,24L
+
+#define SN_id_aes192_wrap "id-aes192-wrap"
+#define NID_id_aes192_wrap 789
+#define OBJ_id_aes192_wrap OBJ_aes,25L
+
+#define SN_aes_192_gcm "id-aes192-GCM"
+#define LN_aes_192_gcm "aes-192-gcm"
+#define NID_aes_192_gcm 898
+#define OBJ_aes_192_gcm OBJ_aes,26L
+
+#define SN_aes_192_ccm "id-aes192-CCM"
+#define LN_aes_192_ccm "aes-192-ccm"
+#define NID_aes_192_ccm 899
+#define OBJ_aes_192_ccm OBJ_aes,27L
+
+#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad"
+#define NID_id_aes192_wrap_pad 900
+#define OBJ_id_aes192_wrap_pad OBJ_aes,28L
+
+#define SN_aes_256_ecb "AES-256-ECB"
+#define LN_aes_256_ecb "aes-256-ecb"
+#define NID_aes_256_ecb 426
+#define OBJ_aes_256_ecb OBJ_aes,41L
+
+#define SN_aes_256_cbc "AES-256-CBC"
+#define LN_aes_256_cbc "aes-256-cbc"
+#define NID_aes_256_cbc 427
+#define OBJ_aes_256_cbc OBJ_aes,42L
+
+#define SN_aes_256_ofb128 "AES-256-OFB"
+#define LN_aes_256_ofb128 "aes-256-ofb"
+#define NID_aes_256_ofb128 428
+#define OBJ_aes_256_ofb128 OBJ_aes,43L
+
+#define SN_aes_256_cfb128 "AES-256-CFB"
+#define LN_aes_256_cfb128 "aes-256-cfb"
+#define NID_aes_256_cfb128 429
+#define OBJ_aes_256_cfb128 OBJ_aes,44L
+
+#define SN_id_aes256_wrap "id-aes256-wrap"
+#define NID_id_aes256_wrap 790
+#define OBJ_id_aes256_wrap OBJ_aes,45L
+
+#define SN_aes_256_gcm "id-aes256-GCM"
+#define LN_aes_256_gcm "aes-256-gcm"
+#define NID_aes_256_gcm 901
+#define OBJ_aes_256_gcm OBJ_aes,46L
+
+#define SN_aes_256_ccm "id-aes256-CCM"
+#define LN_aes_256_ccm "aes-256-ccm"
+#define NID_aes_256_ccm 902
+#define OBJ_aes_256_ccm OBJ_aes,47L
+
+#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad"
+#define NID_id_aes256_wrap_pad 903
+#define OBJ_id_aes256_wrap_pad OBJ_aes,48L
+
+#define SN_aes_128_cfb1 "AES-128-CFB1"
+#define LN_aes_128_cfb1 "aes-128-cfb1"
+#define NID_aes_128_cfb1 650
+
+#define SN_aes_192_cfb1 "AES-192-CFB1"
+#define LN_aes_192_cfb1 "aes-192-cfb1"
+#define NID_aes_192_cfb1 651
+
+#define SN_aes_256_cfb1 "AES-256-CFB1"
+#define LN_aes_256_cfb1 "aes-256-cfb1"
+#define NID_aes_256_cfb1 652
+
+#define SN_aes_128_cfb8 "AES-128-CFB8"
+#define LN_aes_128_cfb8 "aes-128-cfb8"
+#define NID_aes_128_cfb8 653
+
+#define SN_aes_192_cfb8 "AES-192-CFB8"
+#define LN_aes_192_cfb8 "aes-192-cfb8"
+#define NID_aes_192_cfb8 654
+
+#define SN_aes_256_cfb8 "AES-256-CFB8"
+#define LN_aes_256_cfb8 "aes-256-cfb8"
+#define NID_aes_256_cfb8 655
+
+#define SN_aes_128_ctr "AES-128-CTR"
+#define LN_aes_128_ctr "aes-128-ctr"
+#define NID_aes_128_ctr 904
+
+#define SN_aes_192_ctr "AES-192-CTR"
+#define LN_aes_192_ctr "aes-192-ctr"
+#define NID_aes_192_ctr 905
+
+#define SN_aes_256_ctr "AES-256-CTR"
+#define LN_aes_256_ctr "aes-256-ctr"
+#define NID_aes_256_ctr 906
+
+#define SN_aes_128_xts "AES-128-XTS"
+#define LN_aes_128_xts "aes-128-xts"
+#define NID_aes_128_xts 913
+
+#define SN_aes_256_xts "AES-256-XTS"
+#define LN_aes_256_xts "aes-256-xts"
+#define NID_aes_256_xts 914
+
+#define SN_des_cfb1 "DES-CFB1"
+#define LN_des_cfb1 "des-cfb1"
+#define NID_des_cfb1 656
+
+#define SN_des_cfb8 "DES-CFB8"
+#define LN_des_cfb8 "des-cfb8"
+#define NID_des_cfb8 657
+
+#define SN_des_ede3_cfb1 "DES-EDE3-CFB1"
+#define LN_des_ede3_cfb1 "des-ede3-cfb1"
+#define NID_des_ede3_cfb1 658
+
+#define SN_des_ede3_cfb8 "DES-EDE3-CFB8"
+#define LN_des_ede3_cfb8 "des-ede3-cfb8"
+#define NID_des_ede3_cfb8 659
+
+#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L
+
+#define SN_sha256 "SHA256"
+#define LN_sha256 "sha256"
+#define NID_sha256 672
+#define OBJ_sha256 OBJ_nist_hashalgs,1L
+
+#define SN_sha384 "SHA384"
+#define LN_sha384 "sha384"
+#define NID_sha384 673
+#define OBJ_sha384 OBJ_nist_hashalgs,2L
+
+#define SN_sha512 "SHA512"
+#define LN_sha512 "sha512"
+#define NID_sha512 674
+#define OBJ_sha512 OBJ_nist_hashalgs,3L
+
+#define SN_sha224 "SHA224"
+#define LN_sha224 "sha224"
+#define NID_sha224 675
+#define OBJ_sha224 OBJ_nist_hashalgs,4L
+
+#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L
+
+#define SN_dsa_with_SHA224 "dsa_with_SHA224"
+#define NID_dsa_with_SHA224 802
+#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L
+
+#define SN_dsa_with_SHA256 "dsa_with_SHA256"
+#define NID_dsa_with_SHA256 803
+#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L
+
+#define SN_hold_instruction_code "holdInstructionCode"
+#define LN_hold_instruction_code "Hold Instruction Code"
+#define NID_hold_instruction_code 430
+#define OBJ_hold_instruction_code OBJ_id_ce,23L
+
+#define OBJ_holdInstruction OBJ_X9_57,2L
+
+#define SN_hold_instruction_none "holdInstructionNone"
+#define LN_hold_instruction_none "Hold Instruction None"
+#define NID_hold_instruction_none 431
+#define OBJ_hold_instruction_none OBJ_holdInstruction,1L
+
+#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer"
+#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer"
+#define NID_hold_instruction_call_issuer 432
+#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L
+
+#define SN_hold_instruction_reject "holdInstructionReject"
+#define LN_hold_instruction_reject "Hold Instruction Reject"
+#define NID_hold_instruction_reject 433
+#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L
+
+#define SN_data "data"
+#define NID_data 434
+#define OBJ_data OBJ_itu_t,9L
+
+#define SN_pss "pss"
+#define NID_pss 435
+#define OBJ_pss OBJ_data,2342L
+
+#define SN_ucl "ucl"
+#define NID_ucl 436
+#define OBJ_ucl OBJ_pss,19200300L
+
+#define SN_pilot "pilot"
+#define NID_pilot 437
+#define OBJ_pilot OBJ_ucl,100L
+
+#define LN_pilotAttributeType "pilotAttributeType"
+#define NID_pilotAttributeType 438
+#define OBJ_pilotAttributeType OBJ_pilot,1L
+
+#define LN_pilotAttributeSyntax "pilotAttributeSyntax"
+#define NID_pilotAttributeSyntax 439
+#define OBJ_pilotAttributeSyntax OBJ_pilot,3L
+
+#define LN_pilotObjectClass "pilotObjectClass"
+#define NID_pilotObjectClass 440
+#define OBJ_pilotObjectClass OBJ_pilot,4L
+
+#define LN_pilotGroups "pilotGroups"
+#define NID_pilotGroups 441
+#define OBJ_pilotGroups OBJ_pilot,10L
+
+#define LN_iA5StringSyntax "iA5StringSyntax"
+#define NID_iA5StringSyntax 442
+#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L
+
+#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax"
+#define NID_caseIgnoreIA5StringSyntax 443
+#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L
+
+#define LN_pilotObject "pilotObject"
+#define NID_pilotObject 444
+#define OBJ_pilotObject OBJ_pilotObjectClass,3L
+
+#define LN_pilotPerson "pilotPerson"
+#define NID_pilotPerson 445
+#define OBJ_pilotPerson OBJ_pilotObjectClass,4L
+
+#define SN_account "account"
+#define NID_account 446
+#define OBJ_account OBJ_pilotObjectClass,5L
+
+#define SN_document "document"
+#define NID_document 447
+#define OBJ_document OBJ_pilotObjectClass,6L
+
+#define SN_room "room"
+#define NID_room 448
+#define OBJ_room OBJ_pilotObjectClass,7L
+
+#define LN_documentSeries "documentSeries"
+#define NID_documentSeries 449
+#define OBJ_documentSeries OBJ_pilotObjectClass,9L
+
+#define SN_Domain "domain"
+#define LN_Domain "Domain"
+#define NID_Domain 392
+#define OBJ_Domain OBJ_pilotObjectClass,13L
+
+#define LN_rFC822localPart "rFC822localPart"
+#define NID_rFC822localPart 450
+#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L
+
+#define LN_dNSDomain "dNSDomain"
+#define NID_dNSDomain 451
+#define OBJ_dNSDomain OBJ_pilotObjectClass,15L
+
+#define LN_domainRelatedObject "domainRelatedObject"
+#define NID_domainRelatedObject 452
+#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L
+
+#define LN_friendlyCountry "friendlyCountry"
+#define NID_friendlyCountry 453
+#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L
+
+#define LN_simpleSecurityObject "simpleSecurityObject"
+#define NID_simpleSecurityObject 454
+#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L
+
+#define LN_pilotOrganization "pilotOrganization"
+#define NID_pilotOrganization 455
+#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L
+
+#define LN_pilotDSA "pilotDSA"
+#define NID_pilotDSA 456
+#define OBJ_pilotDSA OBJ_pilotObjectClass,21L
+
+#define LN_qualityLabelledData "qualityLabelledData"
+#define NID_qualityLabelledData 457
+#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L
+
+#define SN_userId "UID"
+#define LN_userId "userId"
+#define NID_userId 458
+#define OBJ_userId OBJ_pilotAttributeType,1L
+
+#define LN_textEncodedORAddress "textEncodedORAddress"
+#define NID_textEncodedORAddress 459
+#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L
+
+#define SN_rfc822Mailbox "mail"
+#define LN_rfc822Mailbox "rfc822Mailbox"
+#define NID_rfc822Mailbox 460
+#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L
+
+#define SN_info "info"
+#define NID_info 461
+#define OBJ_info OBJ_pilotAttributeType,4L
+
+#define LN_favouriteDrink "favouriteDrink"
+#define NID_favouriteDrink 462
+#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L
+
+#define LN_roomNumber "roomNumber"
+#define NID_roomNumber 463
+#define OBJ_roomNumber OBJ_pilotAttributeType,6L
+
+#define SN_photo "photo"
+#define NID_photo 464
+#define OBJ_photo OBJ_pilotAttributeType,7L
+
+#define LN_userClass "userClass"
+#define NID_userClass 465
+#define OBJ_userClass OBJ_pilotAttributeType,8L
+
+#define SN_host "host"
+#define NID_host 466
+#define OBJ_host OBJ_pilotAttributeType,9L
+
+#define SN_manager "manager"
+#define NID_manager 467
+#define OBJ_manager OBJ_pilotAttributeType,10L
+
+#define LN_documentIdentifier "documentIdentifier"
+#define NID_documentIdentifier 468
+#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L
+
+#define LN_documentTitle "documentTitle"
+#define NID_documentTitle 469
+#define OBJ_documentTitle OBJ_pilotAttributeType,12L
+
+#define LN_documentVersion "documentVersion"
+#define NID_documentVersion 470
+#define OBJ_documentVersion OBJ_pilotAttributeType,13L
+
+#define LN_documentAuthor "documentAuthor"
+#define NID_documentAuthor 471
+#define OBJ_documentAuthor OBJ_pilotAttributeType,14L
+
+#define LN_documentLocation "documentLocation"
+#define NID_documentLocation 472
+#define OBJ_documentLocation OBJ_pilotAttributeType,15L
+
+#define LN_homeTelephoneNumber "homeTelephoneNumber"
+#define NID_homeTelephoneNumber 473
+#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L
+
+#define SN_secretary "secretary"
+#define NID_secretary 474
+#define OBJ_secretary OBJ_pilotAttributeType,21L
+
+#define LN_otherMailbox "otherMailbox"
+#define NID_otherMailbox 475
+#define OBJ_otherMailbox OBJ_pilotAttributeType,22L
+
+#define LN_lastModifiedTime "lastModifiedTime"
+#define NID_lastModifiedTime 476
+#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L
+
+#define LN_lastModifiedBy "lastModifiedBy"
+#define NID_lastModifiedBy 477
+#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L
+
+#define SN_domainComponent "DC"
+#define LN_domainComponent "domainComponent"
+#define NID_domainComponent 391
+#define OBJ_domainComponent OBJ_pilotAttributeType,25L
+
+#define LN_aRecord "aRecord"
+#define NID_aRecord 478
+#define OBJ_aRecord OBJ_pilotAttributeType,26L
+
+#define LN_pilotAttributeType27 "pilotAttributeType27"
+#define NID_pilotAttributeType27 479
+#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L
+
+#define LN_mXRecord "mXRecord"
+#define NID_mXRecord 480
+#define OBJ_mXRecord OBJ_pilotAttributeType,28L
+
+#define LN_nSRecord "nSRecord"
+#define NID_nSRecord 481
+#define OBJ_nSRecord OBJ_pilotAttributeType,29L
+
+#define LN_sOARecord "sOARecord"
+#define NID_sOARecord 482
+#define OBJ_sOARecord OBJ_pilotAttributeType,30L
+
+#define LN_cNAMERecord "cNAMERecord"
+#define NID_cNAMERecord 483
+#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L
+
+#define LN_associatedDomain "associatedDomain"
+#define NID_associatedDomain 484
+#define OBJ_associatedDomain OBJ_pilotAttributeType,37L
+
+#define LN_associatedName "associatedName"
+#define NID_associatedName 485
+#define OBJ_associatedName OBJ_pilotAttributeType,38L
+
+#define LN_homePostalAddress "homePostalAddress"
+#define NID_homePostalAddress 486
+#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L
+
+#define LN_personalTitle "personalTitle"
+#define NID_personalTitle 487
+#define OBJ_personalTitle OBJ_pilotAttributeType,40L
+
+#define LN_mobileTelephoneNumber "mobileTelephoneNumber"
+#define NID_mobileTelephoneNumber 488
+#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L
+
+#define LN_pagerTelephoneNumber "pagerTelephoneNumber"
+#define NID_pagerTelephoneNumber 489
+#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L
+
+#define LN_friendlyCountryName "friendlyCountryName"
+#define NID_friendlyCountryName 490
+#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L
+
+#define LN_organizationalStatus "organizationalStatus"
+#define NID_organizationalStatus 491
+#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L
+
+#define LN_janetMailbox "janetMailbox"
+#define NID_janetMailbox 492
+#define OBJ_janetMailbox OBJ_pilotAttributeType,46L
+
+#define LN_mailPreferenceOption "mailPreferenceOption"
+#define NID_mailPreferenceOption 493
+#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L
+
+#define LN_buildingName "buildingName"
+#define NID_buildingName 494
+#define OBJ_buildingName OBJ_pilotAttributeType,48L
+
+#define LN_dSAQuality "dSAQuality"
+#define NID_dSAQuality 495
+#define OBJ_dSAQuality OBJ_pilotAttributeType,49L
+
+#define LN_singleLevelQuality "singleLevelQuality"
+#define NID_singleLevelQuality 496
+#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L
+
+#define LN_subtreeMinimumQuality "subtreeMinimumQuality"
+#define NID_subtreeMinimumQuality 497
+#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L
+
+#define LN_subtreeMaximumQuality "subtreeMaximumQuality"
+#define NID_subtreeMaximumQuality 498
+#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L
+
+#define LN_personalSignature "personalSignature"
+#define NID_personalSignature 499
+#define OBJ_personalSignature OBJ_pilotAttributeType,53L
+
+#define LN_dITRedirect "dITRedirect"
+#define NID_dITRedirect 500
+#define OBJ_dITRedirect OBJ_pilotAttributeType,54L
+
+#define SN_audio "audio"
+#define NID_audio 501
+#define OBJ_audio OBJ_pilotAttributeType,55L
+
+#define LN_documentPublisher "documentPublisher"
+#define NID_documentPublisher 502
+#define OBJ_documentPublisher OBJ_pilotAttributeType,56L
+
+#define SN_id_set "id-set"
+#define LN_id_set "Secure Electronic Transactions"
+#define NID_id_set 512
+#define OBJ_id_set OBJ_international_organizations,42L
+
+#define SN_set_ctype "set-ctype"
+#define LN_set_ctype "content types"
+#define NID_set_ctype 513
+#define OBJ_set_ctype OBJ_id_set,0L
+
+#define SN_set_msgExt "set-msgExt"
+#define LN_set_msgExt "message extensions"
+#define NID_set_msgExt 514
+#define OBJ_set_msgExt OBJ_id_set,1L
+
+#define SN_set_attr "set-attr"
+#define NID_set_attr 515
+#define OBJ_set_attr OBJ_id_set,3L
+
+#define SN_set_policy "set-policy"
+#define NID_set_policy 516
+#define OBJ_set_policy OBJ_id_set,5L
+
+#define SN_set_certExt "set-certExt"
+#define LN_set_certExt "certificate extensions"
+#define NID_set_certExt 517
+#define OBJ_set_certExt OBJ_id_set,7L
+
+#define SN_set_brand "set-brand"
+#define NID_set_brand 518
+#define OBJ_set_brand OBJ_id_set,8L
+
+#define SN_setct_PANData "setct-PANData"
+#define NID_setct_PANData 519
+#define OBJ_setct_PANData OBJ_set_ctype,0L
+
+#define SN_setct_PANToken "setct-PANToken"
+#define NID_setct_PANToken 520
+#define OBJ_setct_PANToken OBJ_set_ctype,1L
+
+#define SN_setct_PANOnly "setct-PANOnly"
+#define NID_setct_PANOnly 521
+#define OBJ_setct_PANOnly OBJ_set_ctype,2L
+
+#define SN_setct_OIData "setct-OIData"
+#define NID_setct_OIData 522
+#define OBJ_setct_OIData OBJ_set_ctype,3L
+
+#define SN_setct_PI "setct-PI"
+#define NID_setct_PI 523
+#define OBJ_setct_PI OBJ_set_ctype,4L
+
+#define SN_setct_PIData "setct-PIData"
+#define NID_setct_PIData 524
+#define OBJ_setct_PIData OBJ_set_ctype,5L
+
+#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned"
+#define NID_setct_PIDataUnsigned 525
+#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L
+
+#define SN_setct_HODInput "setct-HODInput"
+#define NID_setct_HODInput 526
+#define OBJ_setct_HODInput OBJ_set_ctype,7L
+
+#define SN_setct_AuthResBaggage "setct-AuthResBaggage"
+#define NID_setct_AuthResBaggage 527
+#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L
+
+#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage"
+#define NID_setct_AuthRevReqBaggage 528
+#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L
+
+#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage"
+#define NID_setct_AuthRevResBaggage 529
+#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L
+
+#define SN_setct_CapTokenSeq "setct-CapTokenSeq"
+#define NID_setct_CapTokenSeq 530
+#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L
+
+#define SN_setct_PInitResData "setct-PInitResData"
+#define NID_setct_PInitResData 531
+#define OBJ_setct_PInitResData OBJ_set_ctype,12L
+
+#define SN_setct_PI_TBS "setct-PI-TBS"
+#define NID_setct_PI_TBS 532
+#define OBJ_setct_PI_TBS OBJ_set_ctype,13L
+
+#define SN_setct_PResData "setct-PResData"
+#define NID_setct_PResData 533
+#define OBJ_setct_PResData OBJ_set_ctype,14L
+
+#define SN_setct_AuthReqTBS "setct-AuthReqTBS"
+#define NID_setct_AuthReqTBS 534
+#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L
+
+#define SN_setct_AuthResTBS "setct-AuthResTBS"
+#define NID_setct_AuthResTBS 535
+#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L
+
+#define SN_setct_AuthResTBSX "setct-AuthResTBSX"
+#define NID_setct_AuthResTBSX 536
+#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L
+
+#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS"
+#define NID_setct_AuthTokenTBS 537
+#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L
+
+#define SN_setct_CapTokenData "setct-CapTokenData"
+#define NID_setct_CapTokenData 538
+#define OBJ_setct_CapTokenData OBJ_set_ctype,20L
+
+#define SN_setct_CapTokenTBS "setct-CapTokenTBS"
+#define NID_setct_CapTokenTBS 539
+#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L
+
+#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg"
+#define NID_setct_AcqCardCodeMsg 540
+#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L
+
+#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS"
+#define NID_setct_AuthRevReqTBS 541
+#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L
+
+#define SN_setct_AuthRevResData "setct-AuthRevResData"
+#define NID_setct_AuthRevResData 542
+#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L
+
+#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS"
+#define NID_setct_AuthRevResTBS 543
+#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L
+
+#define SN_setct_CapReqTBS "setct-CapReqTBS"
+#define NID_setct_CapReqTBS 544
+#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L
+
+#define SN_setct_CapReqTBSX "setct-CapReqTBSX"
+#define NID_setct_CapReqTBSX 545
+#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L
+
+#define SN_setct_CapResData "setct-CapResData"
+#define NID_setct_CapResData 546
+#define OBJ_setct_CapResData OBJ_set_ctype,28L
+
+#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS"
+#define NID_setct_CapRevReqTBS 547
+#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L
+
+#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX"
+#define NID_setct_CapRevReqTBSX 548
+#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L
+
+#define SN_setct_CapRevResData "setct-CapRevResData"
+#define NID_setct_CapRevResData 549
+#define OBJ_setct_CapRevResData OBJ_set_ctype,31L
+
+#define SN_setct_CredReqTBS "setct-CredReqTBS"
+#define NID_setct_CredReqTBS 550
+#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L
+
+#define SN_setct_CredReqTBSX "setct-CredReqTBSX"
+#define NID_setct_CredReqTBSX 551
+#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L
+
+#define SN_setct_CredResData "setct-CredResData"
+#define NID_setct_CredResData 552
+#define OBJ_setct_CredResData OBJ_set_ctype,34L
+
+#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS"
+#define NID_setct_CredRevReqTBS 553
+#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L
+
+#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX"
+#define NID_setct_CredRevReqTBSX 554
+#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L
+
+#define SN_setct_CredRevResData "setct-CredRevResData"
+#define NID_setct_CredRevResData 555
+#define OBJ_setct_CredRevResData OBJ_set_ctype,37L
+
+#define SN_setct_PCertReqData "setct-PCertReqData"
+#define NID_setct_PCertReqData 556
+#define OBJ_setct_PCertReqData OBJ_set_ctype,38L
+
+#define SN_setct_PCertResTBS "setct-PCertResTBS"
+#define NID_setct_PCertResTBS 557
+#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L
+
+#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData"
+#define NID_setct_BatchAdminReqData 558
+#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L
+
+#define SN_setct_BatchAdminResData "setct-BatchAdminResData"
+#define NID_setct_BatchAdminResData 559
+#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L
+
+#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS"
+#define NID_setct_CardCInitResTBS 560
+#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L
+
+#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS"
+#define NID_setct_MeAqCInitResTBS 561
+#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L
+
+#define SN_setct_RegFormResTBS "setct-RegFormResTBS"
+#define NID_setct_RegFormResTBS 562
+#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L
+
+#define SN_setct_CertReqData "setct-CertReqData"
+#define NID_setct_CertReqData 563
+#define OBJ_setct_CertReqData OBJ_set_ctype,45L
+
+#define SN_setct_CertReqTBS "setct-CertReqTBS"
+#define NID_setct_CertReqTBS 564
+#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L
+
+#define SN_setct_CertResData "setct-CertResData"
+#define NID_setct_CertResData 565
+#define OBJ_setct_CertResData OBJ_set_ctype,47L
+
+#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS"
+#define NID_setct_CertInqReqTBS 566
+#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L
+
+#define SN_setct_ErrorTBS "setct-ErrorTBS"
+#define NID_setct_ErrorTBS 567
+#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L
+
+#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE"
+#define NID_setct_PIDualSignedTBE 568
+#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L
+
+#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE"
+#define NID_setct_PIUnsignedTBE 569
+#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L
+
+#define SN_setct_AuthReqTBE "setct-AuthReqTBE"
+#define NID_setct_AuthReqTBE 570
+#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L
+
+#define SN_setct_AuthResTBE "setct-AuthResTBE"
+#define NID_setct_AuthResTBE 571
+#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L
+
+#define SN_setct_AuthResTBEX "setct-AuthResTBEX"
+#define NID_setct_AuthResTBEX 572
+#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L
+
+#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE"
+#define NID_setct_AuthTokenTBE 573
+#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L
+
+#define SN_setct_CapTokenTBE "setct-CapTokenTBE"
+#define NID_setct_CapTokenTBE 574
+#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L
+
+#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX"
+#define NID_setct_CapTokenTBEX 575
+#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L
+
+#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE"
+#define NID_setct_AcqCardCodeMsgTBE 576
+#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L
+
+#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE"
+#define NID_setct_AuthRevReqTBE 577
+#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L
+
+#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE"
+#define NID_setct_AuthRevResTBE 578
+#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L
+
+#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB"
+#define NID_setct_AuthRevResTBEB 579
+#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L
+
+#define SN_setct_CapReqTBE "setct-CapReqTBE"
+#define NID_setct_CapReqTBE 580
+#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L
+
+#define SN_setct_CapReqTBEX "setct-CapReqTBEX"
+#define NID_setct_CapReqTBEX 581
+#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L
+
+#define SN_setct_CapResTBE "setct-CapResTBE"
+#define NID_setct_CapResTBE 582
+#define OBJ_setct_CapResTBE OBJ_set_ctype,64L
+
+#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE"
+#define NID_setct_CapRevReqTBE 583
+#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L
+
+#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX"
+#define NID_setct_CapRevReqTBEX 584
+#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L
+
+#define SN_setct_CapRevResTBE "setct-CapRevResTBE"
+#define NID_setct_CapRevResTBE 585
+#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L
+
+#define SN_setct_CredReqTBE "setct-CredReqTBE"
+#define NID_setct_CredReqTBE 586
+#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L
+
+#define SN_setct_CredReqTBEX "setct-CredReqTBEX"
+#define NID_setct_CredReqTBEX 587
+#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L
+
+#define SN_setct_CredResTBE "setct-CredResTBE"
+#define NID_setct_CredResTBE 588
+#define OBJ_setct_CredResTBE OBJ_set_ctype,70L
+
+#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE"
+#define NID_setct_CredRevReqTBE 589
+#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L
+
+#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX"
+#define NID_setct_CredRevReqTBEX 590
+#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L
+
+#define SN_setct_CredRevResTBE "setct-CredRevResTBE"
+#define NID_setct_CredRevResTBE 591
+#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L
+
+#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE"
+#define NID_setct_BatchAdminReqTBE 592
+#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L
+
+#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE"
+#define NID_setct_BatchAdminResTBE 593
+#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L
+
+#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE"
+#define NID_setct_RegFormReqTBE 594
+#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L
+
+#define SN_setct_CertReqTBE "setct-CertReqTBE"
+#define NID_setct_CertReqTBE 595
+#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L
+
+#define SN_setct_CertReqTBEX "setct-CertReqTBEX"
+#define NID_setct_CertReqTBEX 596
+#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L
+
+#define SN_setct_CertResTBE "setct-CertResTBE"
+#define NID_setct_CertResTBE 597
+#define OBJ_setct_CertResTBE OBJ_set_ctype,79L
+
+#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS"
+#define NID_setct_CRLNotificationTBS 598
+#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L
+
+#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS"
+#define NID_setct_CRLNotificationResTBS 599
+#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L
+
+#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS"
+#define NID_setct_BCIDistributionTBS 600
+#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L
+
+#define SN_setext_genCrypt "setext-genCrypt"
+#define LN_setext_genCrypt "generic cryptogram"
+#define NID_setext_genCrypt 601
+#define OBJ_setext_genCrypt OBJ_set_msgExt,1L
+
+#define SN_setext_miAuth "setext-miAuth"
+#define LN_setext_miAuth "merchant initiated auth"
+#define NID_setext_miAuth 602
+#define OBJ_setext_miAuth OBJ_set_msgExt,3L
+
+#define SN_setext_pinSecure "setext-pinSecure"
+#define NID_setext_pinSecure 603
+#define OBJ_setext_pinSecure OBJ_set_msgExt,4L
+
+#define SN_setext_pinAny "setext-pinAny"
+#define NID_setext_pinAny 604
+#define OBJ_setext_pinAny OBJ_set_msgExt,5L
+
+#define SN_setext_track2 "setext-track2"
+#define NID_setext_track2 605
+#define OBJ_setext_track2 OBJ_set_msgExt,7L
+
+#define SN_setext_cv "setext-cv"
+#define LN_setext_cv "additional verification"
+#define NID_setext_cv 606
+#define OBJ_setext_cv OBJ_set_msgExt,8L
+
+#define SN_set_policy_root "set-policy-root"
+#define NID_set_policy_root 607
+#define OBJ_set_policy_root OBJ_set_policy,0L
+
+#define SN_setCext_hashedRoot "setCext-hashedRoot"
+#define NID_setCext_hashedRoot 608
+#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L
+
+#define SN_setCext_certType "setCext-certType"
+#define NID_setCext_certType 609
+#define OBJ_setCext_certType OBJ_set_certExt,1L
+
+#define SN_setCext_merchData "setCext-merchData"
+#define NID_setCext_merchData 610
+#define OBJ_setCext_merchData OBJ_set_certExt,2L
+
+#define SN_setCext_cCertRequired "setCext-cCertRequired"
+#define NID_setCext_cCertRequired 611
+#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L
+
+#define SN_setCext_tunneling "setCext-tunneling"
+#define NID_setCext_tunneling 612
+#define OBJ_setCext_tunneling OBJ_set_certExt,4L
+
+#define SN_setCext_setExt "setCext-setExt"
+#define NID_setCext_setExt 613
+#define OBJ_setCext_setExt OBJ_set_certExt,5L
+
+#define SN_setCext_setQualf "setCext-setQualf"
+#define NID_setCext_setQualf 614
+#define OBJ_setCext_setQualf OBJ_set_certExt,6L
+
+#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities"
+#define NID_setCext_PGWYcapabilities 615
+#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L
+
+#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier"
+#define NID_setCext_TokenIdentifier 616
+#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L
+
+#define SN_setCext_Track2Data "setCext-Track2Data"
+#define NID_setCext_Track2Data 617
+#define OBJ_setCext_Track2Data OBJ_set_certExt,9L
+
+#define SN_setCext_TokenType "setCext-TokenType"
+#define NID_setCext_TokenType 618
+#define OBJ_setCext_TokenType OBJ_set_certExt,10L
+
+#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities"
+#define NID_setCext_IssuerCapabilities 619
+#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L
+
+#define SN_setAttr_Cert "setAttr-Cert"
+#define NID_setAttr_Cert 620
+#define OBJ_setAttr_Cert OBJ_set_attr,0L
+
+#define SN_setAttr_PGWYcap "setAttr-PGWYcap"
+#define LN_setAttr_PGWYcap "payment gateway capabilities"
+#define NID_setAttr_PGWYcap 621
+#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L
+
+#define SN_setAttr_TokenType "setAttr-TokenType"
+#define NID_setAttr_TokenType 622
+#define OBJ_setAttr_TokenType OBJ_set_attr,2L
+
+#define SN_setAttr_IssCap "setAttr-IssCap"
+#define LN_setAttr_IssCap "issuer capabilities"
+#define NID_setAttr_IssCap 623
+#define OBJ_setAttr_IssCap OBJ_set_attr,3L
+
+#define SN_set_rootKeyThumb "set-rootKeyThumb"
+#define NID_set_rootKeyThumb 624
+#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L
+
+#define SN_set_addPolicy "set-addPolicy"
+#define NID_set_addPolicy 625
+#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L
+
+#define SN_setAttr_Token_EMV "setAttr-Token-EMV"
+#define NID_setAttr_Token_EMV 626
+#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L
+
+#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime"
+#define NID_setAttr_Token_B0Prime 627
+#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L
+
+#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM"
+#define NID_setAttr_IssCap_CVM 628
+#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L
+
+#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2"
+#define NID_setAttr_IssCap_T2 629
+#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L
+
+#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig"
+#define NID_setAttr_IssCap_Sig 630
+#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L
+
+#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm"
+#define LN_setAttr_GenCryptgrm "generate cryptogram"
+#define NID_setAttr_GenCryptgrm 631
+#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L
+
+#define SN_setAttr_T2Enc "setAttr-T2Enc"
+#define LN_setAttr_T2Enc "encrypted track 2"
+#define NID_setAttr_T2Enc 632
+#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L
+
+#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt"
+#define LN_setAttr_T2cleartxt "cleartext track 2"
+#define NID_setAttr_T2cleartxt 633
+#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L
+
+#define SN_setAttr_TokICCsig "setAttr-TokICCsig"
+#define LN_setAttr_TokICCsig "ICC or token signature"
+#define NID_setAttr_TokICCsig 634
+#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L
+
+#define SN_setAttr_SecDevSig "setAttr-SecDevSig"
+#define LN_setAttr_SecDevSig "secure device signature"
+#define NID_setAttr_SecDevSig 635
+#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L
+
+#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA"
+#define NID_set_brand_IATA_ATA 636
+#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L
+
+#define SN_set_brand_Diners "set-brand-Diners"
+#define NID_set_brand_Diners 637
+#define OBJ_set_brand_Diners OBJ_set_brand,30L
+
+#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress"
+#define NID_set_brand_AmericanExpress 638
+#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L
+
+#define SN_set_brand_JCB "set-brand-JCB"
+#define NID_set_brand_JCB 639
+#define OBJ_set_brand_JCB OBJ_set_brand,35L
+
+#define SN_set_brand_Visa "set-brand-Visa"
+#define NID_set_brand_Visa 640
+#define OBJ_set_brand_Visa OBJ_set_brand,4L
+
+#define SN_set_brand_MasterCard "set-brand-MasterCard"
+#define NID_set_brand_MasterCard 641
+#define OBJ_set_brand_MasterCard OBJ_set_brand,5L
+
+#define SN_set_brand_Novus "set-brand-Novus"
+#define NID_set_brand_Novus 642
+#define OBJ_set_brand_Novus OBJ_set_brand,6011L
+
+#define SN_des_cdmf "DES-CDMF"
+#define LN_des_cdmf "des-cdmf"
+#define NID_des_cdmf 643
+#define OBJ_des_cdmf OBJ_rsadsi,3L,10L
+
+#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET"
+#define NID_rsaOAEPEncryptionSET 644
+#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L
+
+#define SN_ipsec3 "Oakley-EC2N-3"
+#define LN_ipsec3 "ipsec3"
+#define NID_ipsec3 749
+
+#define SN_ipsec4 "Oakley-EC2N-4"
+#define LN_ipsec4 "ipsec4"
+#define NID_ipsec4 750
+
+#define SN_whirlpool "whirlpool"
+#define NID_whirlpool 804
+#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L
+
+#define SN_cryptopro "cryptopro"
+#define NID_cryptopro 805
+#define OBJ_cryptopro OBJ_member_body,643L,2L,2L
+
+#define SN_cryptocom "cryptocom"
+#define NID_cryptocom 806
+#define OBJ_cryptocom OBJ_member_body,643L,2L,9L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001"
+#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001"
+#define NID_id_GostR3411_94_with_GostR3410_2001 807
+#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94"
+#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94"
+#define NID_id_GostR3411_94_with_GostR3410_94 808
+#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L
+
+#define SN_id_GostR3411_94 "md_gost94"
+#define LN_id_GostR3411_94 "GOST R 34.11-94"
+#define NID_id_GostR3411_94 809
+#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L
+
+#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94"
+#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94"
+#define NID_id_HMACGostR3411_94 810
+#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L
+
+#define SN_id_GostR3410_2001 "gost2001"
+#define LN_id_GostR3410_2001 "GOST R 34.10-2001"
+#define NID_id_GostR3410_2001 811
+#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L
+
+#define SN_id_GostR3410_94 "gost94"
+#define LN_id_GostR3410_94 "GOST R 34.10-94"
+#define NID_id_GostR3410_94 812
+#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L
+
+#define SN_id_Gost28147_89 "gost89"
+#define LN_id_Gost28147_89 "GOST 28147-89"
+#define NID_id_Gost28147_89 813
+#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L
+
+#define SN_gost89_cnt "gost89-cnt"
+#define NID_gost89_cnt 814
+
+#define SN_id_Gost28147_89_MAC "gost-mac"
+#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC"
+#define NID_id_Gost28147_89_MAC 815
+#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L
+
+#define SN_id_GostR3411_94_prf "prf-gostr3411-94"
+#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF"
+#define NID_id_GostR3411_94_prf 816
+#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L
+
+#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH"
+#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH"
+#define NID_id_GostR3410_2001DH 817
+#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L
+
+#define SN_id_GostR3410_94DH "id-GostR3410-94DH"
+#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH"
+#define NID_id_GostR3410_94DH 818
+#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L
+
+#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing"
+#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819
+#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L
+
+#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing"
+#define NID_id_Gost28147_89_None_KeyMeshing 820
+#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L
+
+#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet"
+#define NID_id_GostR3411_94_TestParamSet 821
+#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L
+
+#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet"
+#define NID_id_GostR3411_94_CryptoProParamSet 822
+#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L
+
+#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet"
+#define NID_id_Gost28147_89_TestParamSet 823
+#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L
+
+#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824
+#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L
+
+#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825
+#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L
+
+#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826
+#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L
+
+#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827
+#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L
+
+#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830
+#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L
+
+#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet"
+#define NID_id_GostR3410_94_TestParamSet 831
+#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L
+
+#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832
+#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833
+#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L
+
+#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834
+#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L
+
+#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835
+#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L
+
+#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836
+#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L
+
+#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837
+#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838
+#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L
+
+#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet"
+#define NID_id_GostR3410_2001_TestParamSet 839
+#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840
+#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L
+
+#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841
+#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L
+
+#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842
+#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843
+#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844
+#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L
+
+#define SN_id_GostR3410_94_a "id-GostR3410-94-a"
+#define NID_id_GostR3410_94_a 845
+#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L
+
+#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis"
+#define NID_id_GostR3410_94_aBis 846
+#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L
+
+#define SN_id_GostR3410_94_b "id-GostR3410-94-b"
+#define NID_id_GostR3410_94_b 847
+#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L
+
+#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis"
+#define NID_id_GostR3410_94_bBis 848
+#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L
+
+#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc"
+#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet"
+#define NID_id_Gost28147_89_cc 849
+#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L
+
+#define SN_id_GostR3410_94_cc "gost94cc"
+#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom"
+#define NID_id_GostR3410_94_cc 850
+#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L
+
+#define SN_id_GostR3410_2001_cc "gost2001cc"
+#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom"
+#define NID_id_GostR3410_2001_cc 851
+#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L
+
+#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc"
+#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_94_cc 852
+#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc"
+#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853
+#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L
+
+#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc"
+#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom"
+#define NID_id_GostR3410_2001_ParamSet_cc 854
+#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L
+
+#define SN_camellia_128_cbc "CAMELLIA-128-CBC"
+#define LN_camellia_128_cbc "camellia-128-cbc"
+#define NID_camellia_128_cbc 751
+#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L
+
+#define SN_camellia_192_cbc "CAMELLIA-192-CBC"
+#define LN_camellia_192_cbc "camellia-192-cbc"
+#define NID_camellia_192_cbc 752
+#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L
+
+#define SN_camellia_256_cbc "CAMELLIA-256-CBC"
+#define LN_camellia_256_cbc "camellia-256-cbc"
+#define NID_camellia_256_cbc 753
+#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L
+
+#define SN_id_camellia128_wrap "id-camellia128-wrap"
+#define NID_id_camellia128_wrap 907
+#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L
+
+#define SN_id_camellia192_wrap "id-camellia192-wrap"
+#define NID_id_camellia192_wrap 908
+#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L
+
+#define SN_id_camellia256_wrap "id-camellia256-wrap"
+#define NID_id_camellia256_wrap 909
+#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L
+
+#define OBJ_ntt_ds 0L,3L,4401L,5L
+
+#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L
+
+#define SN_camellia_128_ecb "CAMELLIA-128-ECB"
+#define LN_camellia_128_ecb "camellia-128-ecb"
+#define NID_camellia_128_ecb 754
+#define OBJ_camellia_128_ecb OBJ_camellia,1L
+
+#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB"
+#define LN_camellia_128_ofb128 "camellia-128-ofb"
+#define NID_camellia_128_ofb128 766
+#define OBJ_camellia_128_ofb128 OBJ_camellia,3L
+
+#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB"
+#define LN_camellia_128_cfb128 "camellia-128-cfb"
+#define NID_camellia_128_cfb128 757
+#define OBJ_camellia_128_cfb128 OBJ_camellia,4L
+
+#define SN_camellia_192_ecb "CAMELLIA-192-ECB"
+#define LN_camellia_192_ecb "camellia-192-ecb"
+#define NID_camellia_192_ecb 755
+#define OBJ_camellia_192_ecb OBJ_camellia,21L
+
+#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB"
+#define LN_camellia_192_ofb128 "camellia-192-ofb"
+#define NID_camellia_192_ofb128 767
+#define OBJ_camellia_192_ofb128 OBJ_camellia,23L
+
+#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB"
+#define LN_camellia_192_cfb128 "camellia-192-cfb"
+#define NID_camellia_192_cfb128 758
+#define OBJ_camellia_192_cfb128 OBJ_camellia,24L
+
+#define SN_camellia_256_ecb "CAMELLIA-256-ECB"
+#define LN_camellia_256_ecb "camellia-256-ecb"
+#define NID_camellia_256_ecb 756
+#define OBJ_camellia_256_ecb OBJ_camellia,41L
+
+#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB"
+#define LN_camellia_256_ofb128 "camellia-256-ofb"
+#define NID_camellia_256_ofb128 768
+#define OBJ_camellia_256_ofb128 OBJ_camellia,43L
+
+#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB"
+#define LN_camellia_256_cfb128 "camellia-256-cfb"
+#define NID_camellia_256_cfb128 759
+#define OBJ_camellia_256_cfb128 OBJ_camellia,44L
+
+#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1"
+#define LN_camellia_128_cfb1 "camellia-128-cfb1"
+#define NID_camellia_128_cfb1 760
+
+#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1"
+#define LN_camellia_192_cfb1 "camellia-192-cfb1"
+#define NID_camellia_192_cfb1 761
+
+#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1"
+#define LN_camellia_256_cfb1 "camellia-256-cfb1"
+#define NID_camellia_256_cfb1 762
+
+#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8"
+#define LN_camellia_128_cfb8 "camellia-128-cfb8"
+#define NID_camellia_128_cfb8 763
+
+#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8"
+#define LN_camellia_192_cfb8 "camellia-192-cfb8"
+#define NID_camellia_192_cfb8 764
+
+#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8"
+#define LN_camellia_256_cfb8 "camellia-256-cfb8"
+#define NID_camellia_256_cfb8 765
+
+#define SN_kisa "KISA"
+#define LN_kisa "kisa"
+#define NID_kisa 773
+#define OBJ_kisa OBJ_member_body,410L,200004L
+
+#define SN_seed_ecb "SEED-ECB"
+#define LN_seed_ecb "seed-ecb"
+#define NID_seed_ecb 776
+#define OBJ_seed_ecb OBJ_kisa,1L,3L
+
+#define SN_seed_cbc "SEED-CBC"
+#define LN_seed_cbc "seed-cbc"
+#define NID_seed_cbc 777
+#define OBJ_seed_cbc OBJ_kisa,1L,4L
+
+#define SN_seed_cfb128 "SEED-CFB"
+#define LN_seed_cfb128 "seed-cfb"
+#define NID_seed_cfb128 779
+#define OBJ_seed_cfb128 OBJ_kisa,1L,5L
+
+#define SN_seed_ofb128 "SEED-OFB"
+#define LN_seed_ofb128 "seed-ofb"
+#define NID_seed_ofb128 778
+#define OBJ_seed_ofb128 OBJ_kisa,1L,6L
+
+#define SN_hmac "HMAC"
+#define LN_hmac "hmac"
+#define NID_hmac 855
+
+#define SN_cmac "CMAC"
+#define LN_cmac "cmac"
+#define NID_cmac 894
+
+#define SN_rc4_hmac_md5 "RC4-HMAC-MD5"
+#define LN_rc4_hmac_md5 "rc4-hmac-md5"
+#define NID_rc4_hmac_md5 915
+
+#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1"
+#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1"
+#define NID_aes_128_cbc_hmac_sha1 916
+
+#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1"
+#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1"
+#define NID_aes_192_cbc_hmac_sha1 917
+
+#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1"
+#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1"
+#define NID_aes_256_cbc_hmac_sha1 918
diff --git a/openssl/objects/objects.h b/openssl/objects/objects.h
new file mode 100644
index 0000000..b8dafa8
--- /dev/null
+++ b/openssl/objects/objects.h
@@ -0,0 +1,1143 @@
+/* crypto/objects/objects.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_OBJECTS_H
+# define HEADER_OBJECTS_H
+
+# define USE_OBJ_MAC
+
+# ifdef USE_OBJ_MAC
+# include <openssl/obj_mac.h>
+# else
+# define SN_undef "UNDEF"
+# define LN_undef "undefined"
+# define NID_undef 0
+# define OBJ_undef 0L
+
+# define SN_Algorithm "Algorithm"
+# define LN_algorithm "algorithm"
+# define NID_algorithm 38
+# define OBJ_algorithm 1L,3L,14L,3L,2L
+
+# define LN_rsadsi "rsadsi"
+# define NID_rsadsi 1
+# define OBJ_rsadsi 1L,2L,840L,113549L
+
+# define LN_pkcs "pkcs"
+# define NID_pkcs 2
+# define OBJ_pkcs OBJ_rsadsi,1L
+
+# define SN_md2 "MD2"
+# define LN_md2 "md2"
+# define NID_md2 3
+# define OBJ_md2 OBJ_rsadsi,2L,2L
+
+# define SN_md5 "MD5"
+# define LN_md5 "md5"
+# define NID_md5 4
+# define OBJ_md5 OBJ_rsadsi,2L,5L
+
+# define SN_rc4 "RC4"
+# define LN_rc4 "rc4"
+# define NID_rc4 5
+# define OBJ_rc4 OBJ_rsadsi,3L,4L
+
+# define LN_rsaEncryption "rsaEncryption"
+# define NID_rsaEncryption 6
+# define OBJ_rsaEncryption OBJ_pkcs,1L,1L
+
+# define SN_md2WithRSAEncryption "RSA-MD2"
+# define LN_md2WithRSAEncryption "md2WithRSAEncryption"
+# define NID_md2WithRSAEncryption 7
+# define OBJ_md2WithRSAEncryption OBJ_pkcs,1L,2L
+
+# define SN_md5WithRSAEncryption "RSA-MD5"
+# define LN_md5WithRSAEncryption "md5WithRSAEncryption"
+# define NID_md5WithRSAEncryption 8
+# define OBJ_md5WithRSAEncryption OBJ_pkcs,1L,4L
+
+# define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES"
+# define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC"
+# define NID_pbeWithMD2AndDES_CBC 9
+# define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs,5L,1L
+
+# define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES"
+# define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC"
+# define NID_pbeWithMD5AndDES_CBC 10
+# define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs,5L,3L
+
+# define LN_X500 "X500"
+# define NID_X500 11
+# define OBJ_X500 2L,5L
+
+# define LN_X509 "X509"
+# define NID_X509 12
+# define OBJ_X509 OBJ_X500,4L
+
+# define SN_commonName "CN"
+# define LN_commonName "commonName"
+# define NID_commonName 13
+# define OBJ_commonName OBJ_X509,3L
+
+# define SN_countryName "C"
+# define LN_countryName "countryName"
+# define NID_countryName 14
+# define OBJ_countryName OBJ_X509,6L
+
+# define SN_localityName "L"
+# define LN_localityName "localityName"
+# define NID_localityName 15
+# define OBJ_localityName OBJ_X509,7L
+
+/* Postal Address? PA */
+
+/* should be "ST" (rfc1327) but MS uses 'S' */
+# define SN_stateOrProvinceName "ST"
+# define LN_stateOrProvinceName "stateOrProvinceName"
+# define NID_stateOrProvinceName 16
+# define OBJ_stateOrProvinceName OBJ_X509,8L
+
+# define SN_organizationName "O"
+# define LN_organizationName "organizationName"
+# define NID_organizationName 17
+# define OBJ_organizationName OBJ_X509,10L
+
+# define SN_organizationalUnitName "OU"
+# define LN_organizationalUnitName "organizationalUnitName"
+# define NID_organizationalUnitName 18
+# define OBJ_organizationalUnitName OBJ_X509,11L
+
+# define SN_rsa "RSA"
+# define LN_rsa "rsa"
+# define NID_rsa 19
+# define OBJ_rsa OBJ_X500,8L,1L,1L
+
+# define LN_pkcs7 "pkcs7"
+# define NID_pkcs7 20
+# define OBJ_pkcs7 OBJ_pkcs,7L
+
+# define LN_pkcs7_data "pkcs7-data"
+# define NID_pkcs7_data 21
+# define OBJ_pkcs7_data OBJ_pkcs7,1L
+
+# define LN_pkcs7_signed "pkcs7-signedData"
+# define NID_pkcs7_signed 22
+# define OBJ_pkcs7_signed OBJ_pkcs7,2L
+
+# define LN_pkcs7_enveloped "pkcs7-envelopedData"
+# define NID_pkcs7_enveloped 23
+# define OBJ_pkcs7_enveloped OBJ_pkcs7,3L
+
+# define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData"
+# define NID_pkcs7_signedAndEnveloped 24
+# define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L
+
+# define LN_pkcs7_digest "pkcs7-digestData"
+# define NID_pkcs7_digest 25
+# define OBJ_pkcs7_digest OBJ_pkcs7,5L
+
+# define LN_pkcs7_encrypted "pkcs7-encryptedData"
+# define NID_pkcs7_encrypted 26
+# define OBJ_pkcs7_encrypted OBJ_pkcs7,6L
+
+# define LN_pkcs3 "pkcs3"
+# define NID_pkcs3 27
+# define OBJ_pkcs3 OBJ_pkcs,3L
+
+# define LN_dhKeyAgreement "dhKeyAgreement"
+# define NID_dhKeyAgreement 28
+# define OBJ_dhKeyAgreement OBJ_pkcs3,1L
+
+# define SN_des_ecb "DES-ECB"
+# define LN_des_ecb "des-ecb"
+# define NID_des_ecb 29
+# define OBJ_des_ecb OBJ_algorithm,6L
+
+# define SN_des_cfb64 "DES-CFB"
+# define LN_des_cfb64 "des-cfb"
+# define NID_des_cfb64 30
+/* IV + num */
+# define OBJ_des_cfb64 OBJ_algorithm,9L
+
+# define SN_des_cbc "DES-CBC"
+# define LN_des_cbc "des-cbc"
+# define NID_des_cbc 31
+/* IV */
+# define OBJ_des_cbc OBJ_algorithm,7L
+
+# define SN_des_ede "DES-EDE"
+# define LN_des_ede "des-ede"
+# define NID_des_ede 32
+/* ?? */
+# define OBJ_des_ede OBJ_algorithm,17L
+
+# define SN_des_ede3 "DES-EDE3"
+# define LN_des_ede3 "des-ede3"
+# define NID_des_ede3 33
+
+# define SN_idea_cbc "IDEA-CBC"
+# define LN_idea_cbc "idea-cbc"
+# define NID_idea_cbc 34
+# define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+# define SN_idea_cfb64 "IDEA-CFB"
+# define LN_idea_cfb64 "idea-cfb"
+# define NID_idea_cfb64 35
+
+# define SN_idea_ecb "IDEA-ECB"
+# define LN_idea_ecb "idea-ecb"
+# define NID_idea_ecb 36
+
+# define SN_rc2_cbc "RC2-CBC"
+# define LN_rc2_cbc "rc2-cbc"
+# define NID_rc2_cbc 37
+# define OBJ_rc2_cbc OBJ_rsadsi,3L,2L
+
+# define SN_rc2_ecb "RC2-ECB"
+# define LN_rc2_ecb "rc2-ecb"
+# define NID_rc2_ecb 38
+
+# define SN_rc2_cfb64 "RC2-CFB"
+# define LN_rc2_cfb64 "rc2-cfb"
+# define NID_rc2_cfb64 39
+
+# define SN_rc2_ofb64 "RC2-OFB"
+# define LN_rc2_ofb64 "rc2-ofb"
+# define NID_rc2_ofb64 40
+
+# define SN_sha "SHA"
+# define LN_sha "sha"
+# define NID_sha 41
+# define OBJ_sha OBJ_algorithm,18L
+
+# define SN_shaWithRSAEncryption "RSA-SHA"
+# define LN_shaWithRSAEncryption "shaWithRSAEncryption"
+# define NID_shaWithRSAEncryption 42
+# define OBJ_shaWithRSAEncryption OBJ_algorithm,15L
+
+# define SN_des_ede_cbc "DES-EDE-CBC"
+# define LN_des_ede_cbc "des-ede-cbc"
+# define NID_des_ede_cbc 43
+
+# define SN_des_ede3_cbc "DES-EDE3-CBC"
+# define LN_des_ede3_cbc "des-ede3-cbc"
+# define NID_des_ede3_cbc 44
+# define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L
+
+# define SN_des_ofb64 "DES-OFB"
+# define LN_des_ofb64 "des-ofb"
+# define NID_des_ofb64 45
+# define OBJ_des_ofb64 OBJ_algorithm,8L
+
+# define SN_idea_ofb64 "IDEA-OFB"
+# define LN_idea_ofb64 "idea-ofb"
+# define NID_idea_ofb64 46
+
+# define LN_pkcs9 "pkcs9"
+# define NID_pkcs9 47
+# define OBJ_pkcs9 OBJ_pkcs,9L
+
+# define SN_pkcs9_emailAddress "Email"
+# define LN_pkcs9_emailAddress "emailAddress"
+# define NID_pkcs9_emailAddress 48
+# define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L
+
+# define LN_pkcs9_unstructuredName "unstructuredName"
+# define NID_pkcs9_unstructuredName 49
+# define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L
+
+# define LN_pkcs9_contentType "contentType"
+# define NID_pkcs9_contentType 50
+# define OBJ_pkcs9_contentType OBJ_pkcs9,3L
+
+# define LN_pkcs9_messageDigest "messageDigest"
+# define NID_pkcs9_messageDigest 51
+# define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L
+
+# define LN_pkcs9_signingTime "signingTime"
+# define NID_pkcs9_signingTime 52
+# define OBJ_pkcs9_signingTime OBJ_pkcs9,5L
+
+# define LN_pkcs9_countersignature "countersignature"
+# define NID_pkcs9_countersignature 53
+# define OBJ_pkcs9_countersignature OBJ_pkcs9,6L
+
+# define LN_pkcs9_challengePassword "challengePassword"
+# define NID_pkcs9_challengePassword 54
+# define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L
+
+# define LN_pkcs9_unstructuredAddress "unstructuredAddress"
+# define NID_pkcs9_unstructuredAddress 55
+# define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L
+
+# define LN_pkcs9_extCertAttributes "extendedCertificateAttributes"
+# define NID_pkcs9_extCertAttributes 56
+# define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L
+
+# define SN_netscape "Netscape"
+# define LN_netscape "Netscape Communications Corp."
+# define NID_netscape 57
+# define OBJ_netscape 2L,16L,840L,1L,113730L
+
+# define SN_netscape_cert_extension "nsCertExt"
+# define LN_netscape_cert_extension "Netscape Certificate Extension"
+# define NID_netscape_cert_extension 58
+# define OBJ_netscape_cert_extension OBJ_netscape,1L
+
+# define SN_netscape_data_type "nsDataType"
+# define LN_netscape_data_type "Netscape Data Type"
+# define NID_netscape_data_type 59
+# define OBJ_netscape_data_type OBJ_netscape,2L
+
+# define SN_des_ede_cfb64 "DES-EDE-CFB"
+# define LN_des_ede_cfb64 "des-ede-cfb"
+# define NID_des_ede_cfb64 60
+
+# define SN_des_ede3_cfb64 "DES-EDE3-CFB"
+# define LN_des_ede3_cfb64 "des-ede3-cfb"
+# define NID_des_ede3_cfb64 61
+
+# define SN_des_ede_ofb64 "DES-EDE-OFB"
+# define LN_des_ede_ofb64 "des-ede-ofb"
+# define NID_des_ede_ofb64 62
+
+# define SN_des_ede3_ofb64 "DES-EDE3-OFB"
+# define LN_des_ede3_ofb64 "des-ede3-ofb"
+# define NID_des_ede3_ofb64 63
+
+/* I'm not sure about the object ID */
+# define SN_sha1 "SHA1"
+# define LN_sha1 "sha1"
+# define NID_sha1 64
+# define OBJ_sha1 OBJ_algorithm,26L
+/* 28 Jun 1996 - eay */
+/* #define OBJ_sha1 1L,3L,14L,2L,26L,05L <- wrong */
+
+# define SN_sha1WithRSAEncryption "RSA-SHA1"
+# define LN_sha1WithRSAEncryption "sha1WithRSAEncryption"
+# define NID_sha1WithRSAEncryption 65
+# define OBJ_sha1WithRSAEncryption OBJ_pkcs,1L,5L
+
+# define SN_dsaWithSHA "DSA-SHA"
+# define LN_dsaWithSHA "dsaWithSHA"
+# define NID_dsaWithSHA 66
+# define OBJ_dsaWithSHA OBJ_algorithm,13L
+
+# define SN_dsa_2 "DSA-old"
+# define LN_dsa_2 "dsaEncryption-old"
+# define NID_dsa_2 67
+# define OBJ_dsa_2 OBJ_algorithm,12L
+
+/* proposed by microsoft to RSA */
+# define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64"
+# define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC"
+# define NID_pbeWithSHA1AndRC2_CBC 68
+# define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs,5L,11L
+
+/*
+ * proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now defined
+ * explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something completely
+ * different.
+ */
+# define LN_id_pbkdf2 "PBKDF2"
+# define NID_id_pbkdf2 69
+# define OBJ_id_pbkdf2 OBJ_pkcs,5L,12L
+
+# define SN_dsaWithSHA1_2 "DSA-SHA1-old"
+# define LN_dsaWithSHA1_2 "dsaWithSHA1-old"
+# define NID_dsaWithSHA1_2 70
+/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */
+# define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L
+
+# define SN_netscape_cert_type "nsCertType"
+# define LN_netscape_cert_type "Netscape Cert Type"
+# define NID_netscape_cert_type 71
+# define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L
+
+# define SN_netscape_base_url "nsBaseUrl"
+# define LN_netscape_base_url "Netscape Base Url"
+# define NID_netscape_base_url 72
+# define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L
+
+# define SN_netscape_revocation_url "nsRevocationUrl"
+# define LN_netscape_revocation_url "Netscape Revocation Url"
+# define NID_netscape_revocation_url 73
+# define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L
+
+# define SN_netscape_ca_revocation_url "nsCaRevocationUrl"
+# define LN_netscape_ca_revocation_url "Netscape CA Revocation Url"
+# define NID_netscape_ca_revocation_url 74
+# define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L
+
+# define SN_netscape_renewal_url "nsRenewalUrl"
+# define LN_netscape_renewal_url "Netscape Renewal Url"
+# define NID_netscape_renewal_url 75
+# define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L
+
+# define SN_netscape_ca_policy_url "nsCaPolicyUrl"
+# define LN_netscape_ca_policy_url "Netscape CA Policy Url"
+# define NID_netscape_ca_policy_url 76
+# define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L
+
+# define SN_netscape_ssl_server_name "nsSslServerName"
+# define LN_netscape_ssl_server_name "Netscape SSL Server Name"
+# define NID_netscape_ssl_server_name 77
+# define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L
+
+# define SN_netscape_comment "nsComment"
+# define LN_netscape_comment "Netscape Comment"
+# define NID_netscape_comment 78
+# define OBJ_netscape_comment OBJ_netscape_cert_extension,13L
+
+# define SN_netscape_cert_sequence "nsCertSequence"
+# define LN_netscape_cert_sequence "Netscape Certificate Sequence"
+# define NID_netscape_cert_sequence 79
+# define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L
+
+# define SN_desx_cbc "DESX-CBC"
+# define LN_desx_cbc "desx-cbc"
+# define NID_desx_cbc 80
+
+# define SN_id_ce "id-ce"
+# define NID_id_ce 81
+# define OBJ_id_ce 2L,5L,29L
+
+# define SN_subject_key_identifier "subjectKeyIdentifier"
+# define LN_subject_key_identifier "X509v3 Subject Key Identifier"
+# define NID_subject_key_identifier 82
+# define OBJ_subject_key_identifier OBJ_id_ce,14L
+
+# define SN_key_usage "keyUsage"
+# define LN_key_usage "X509v3 Key Usage"
+# define NID_key_usage 83
+# define OBJ_key_usage OBJ_id_ce,15L
+
+# define SN_private_key_usage_period "privateKeyUsagePeriod"
+# define LN_private_key_usage_period "X509v3 Private Key Usage Period"
+# define NID_private_key_usage_period 84
+# define OBJ_private_key_usage_period OBJ_id_ce,16L
+
+# define SN_subject_alt_name "subjectAltName"
+# define LN_subject_alt_name "X509v3 Subject Alternative Name"
+# define NID_subject_alt_name 85
+# define OBJ_subject_alt_name OBJ_id_ce,17L
+
+# define SN_issuer_alt_name "issuerAltName"
+# define LN_issuer_alt_name "X509v3 Issuer Alternative Name"
+# define NID_issuer_alt_name 86
+# define OBJ_issuer_alt_name OBJ_id_ce,18L
+
+# define SN_basic_constraints "basicConstraints"
+# define LN_basic_constraints "X509v3 Basic Constraints"
+# define NID_basic_constraints 87
+# define OBJ_basic_constraints OBJ_id_ce,19L
+
+# define SN_crl_number "crlNumber"
+# define LN_crl_number "X509v3 CRL Number"
+# define NID_crl_number 88
+# define OBJ_crl_number OBJ_id_ce,20L
+
+# define SN_certificate_policies "certificatePolicies"
+# define LN_certificate_policies "X509v3 Certificate Policies"
+# define NID_certificate_policies 89
+# define OBJ_certificate_policies OBJ_id_ce,32L
+
+# define SN_authority_key_identifier "authorityKeyIdentifier"
+# define LN_authority_key_identifier "X509v3 Authority Key Identifier"
+# define NID_authority_key_identifier 90
+# define OBJ_authority_key_identifier OBJ_id_ce,35L
+
+# define SN_bf_cbc "BF-CBC"
+# define LN_bf_cbc "bf-cbc"
+# define NID_bf_cbc 91
+# define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+# define SN_bf_ecb "BF-ECB"
+# define LN_bf_ecb "bf-ecb"
+# define NID_bf_ecb 92
+
+# define SN_bf_cfb64 "BF-CFB"
+# define LN_bf_cfb64 "bf-cfb"
+# define NID_bf_cfb64 93
+
+# define SN_bf_ofb64 "BF-OFB"
+# define LN_bf_ofb64 "bf-ofb"
+# define NID_bf_ofb64 94
+
+# define SN_mdc2 "MDC2"
+# define LN_mdc2 "mdc2"
+# define NID_mdc2 95
+# define OBJ_mdc2 2L,5L,8L,3L,101L
+/* An alternative? 1L,3L,14L,3L,2L,19L */
+
+# define SN_mdc2WithRSA "RSA-MDC2"
+# define LN_mdc2WithRSA "mdc2withRSA"
+# define NID_mdc2WithRSA 96
+# define OBJ_mdc2WithRSA 2L,5L,8L,3L,100L
+
+# define SN_rc4_40 "RC4-40"
+# define LN_rc4_40 "rc4-40"
+# define NID_rc4_40 97
+
+# define SN_rc2_40_cbc "RC2-40-CBC"
+# define LN_rc2_40_cbc "rc2-40-cbc"
+# define NID_rc2_40_cbc 98
+
+# define SN_givenName "G"
+# define LN_givenName "givenName"
+# define NID_givenName 99
+# define OBJ_givenName OBJ_X509,42L
+
+# define SN_surname "S"
+# define LN_surname "surname"
+# define NID_surname 100
+# define OBJ_surname OBJ_X509,4L
+
+# define SN_initials "I"
+# define LN_initials "initials"
+# define NID_initials 101
+# define OBJ_initials OBJ_X509,43L
+
+# define SN_uniqueIdentifier "UID"
+# define LN_uniqueIdentifier "uniqueIdentifier"
+# define NID_uniqueIdentifier 102
+# define OBJ_uniqueIdentifier OBJ_X509,45L
+
+# define SN_crl_distribution_points "crlDistributionPoints"
+# define LN_crl_distribution_points "X509v3 CRL Distribution Points"
+# define NID_crl_distribution_points 103
+# define OBJ_crl_distribution_points OBJ_id_ce,31L
+
+# define SN_md5WithRSA "RSA-NP-MD5"
+# define LN_md5WithRSA "md5WithRSA"
+# define NID_md5WithRSA 104
+# define OBJ_md5WithRSA OBJ_algorithm,3L
+
+# define SN_serialNumber "SN"
+# define LN_serialNumber "serialNumber"
+# define NID_serialNumber 105
+# define OBJ_serialNumber OBJ_X509,5L
+
+# define SN_title "T"
+# define LN_title "title"
+# define NID_title 106
+# define OBJ_title OBJ_X509,12L
+
+# define SN_description "D"
+# define LN_description "description"
+# define NID_description 107
+# define OBJ_description OBJ_X509,13L
+
+/* CAST5 is CAST-128, I'm just sticking with the documentation */
+# define SN_cast5_cbc "CAST5-CBC"
+# define LN_cast5_cbc "cast5-cbc"
+# define NID_cast5_cbc 108
+# define OBJ_cast5_cbc 1L,2L,840L,113533L,7L,66L,10L
+
+# define SN_cast5_ecb "CAST5-ECB"
+# define LN_cast5_ecb "cast5-ecb"
+# define NID_cast5_ecb 109
+
+# define SN_cast5_cfb64 "CAST5-CFB"
+# define LN_cast5_cfb64 "cast5-cfb"
+# define NID_cast5_cfb64 110
+
+# define SN_cast5_ofb64 "CAST5-OFB"
+# define LN_cast5_ofb64 "cast5-ofb"
+# define NID_cast5_ofb64 111
+
+# define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC"
+# define NID_pbeWithMD5AndCast5_CBC 112
+# define OBJ_pbeWithMD5AndCast5_CBC 1L,2L,840L,113533L,7L,66L,12L
+
+/*-
+ * This is one sun will soon be using :-(
+ * id-dsa-with-sha1 ID ::= {
+ * iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 }
+ */
+# define SN_dsaWithSHA1 "DSA-SHA1"
+# define LN_dsaWithSHA1 "dsaWithSHA1"
+# define NID_dsaWithSHA1 113
+# define OBJ_dsaWithSHA1 1L,2L,840L,10040L,4L,3L
+
+# define NID_md5_sha1 114
+# define SN_md5_sha1 "MD5-SHA1"
+# define LN_md5_sha1 "md5-sha1"
+
+# define SN_sha1WithRSA "RSA-SHA1-2"
+# define LN_sha1WithRSA "sha1WithRSA"
+# define NID_sha1WithRSA 115
+# define OBJ_sha1WithRSA OBJ_algorithm,29L
+
+# define SN_dsa "DSA"
+# define LN_dsa "dsaEncryption"
+# define NID_dsa 116
+# define OBJ_dsa 1L,2L,840L,10040L,4L,1L
+
+# define SN_ripemd160 "RIPEMD160"
+# define LN_ripemd160 "ripemd160"
+# define NID_ripemd160 117
+# define OBJ_ripemd160 1L,3L,36L,3L,2L,1L
+
+/*
+ * The name should actually be rsaSignatureWithripemd160, but I'm going to
+ * continue using the convention I'm using with the other ciphers
+ */
+# define SN_ripemd160WithRSA "RSA-RIPEMD160"
+# define LN_ripemd160WithRSA "ripemd160WithRSA"
+# define NID_ripemd160WithRSA 119
+# define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L
+
+/*-
+ * Taken from rfc2040
+ * RC5_CBC_Parameters ::= SEQUENCE {
+ * version INTEGER (v1_0(16)),
+ * rounds INTEGER (8..127),
+ * blockSizeInBits INTEGER (64, 128),
+ * iv OCTET STRING OPTIONAL
+ * }
+ */
+# define SN_rc5_cbc "RC5-CBC"
+# define LN_rc5_cbc "rc5-cbc"
+# define NID_rc5_cbc 120
+# define OBJ_rc5_cbc OBJ_rsadsi,3L,8L
+
+# define SN_rc5_ecb "RC5-ECB"
+# define LN_rc5_ecb "rc5-ecb"
+# define NID_rc5_ecb 121
+
+# define SN_rc5_cfb64 "RC5-CFB"
+# define LN_rc5_cfb64 "rc5-cfb"
+# define NID_rc5_cfb64 122
+
+# define SN_rc5_ofb64 "RC5-OFB"
+# define LN_rc5_ofb64 "rc5-ofb"
+# define NID_rc5_ofb64 123
+
+# define SN_rle_compression "RLE"
+# define LN_rle_compression "run length compression"
+# define NID_rle_compression 124
+# define OBJ_rle_compression 1L,1L,1L,1L,666L,1L
+
+# define SN_zlib_compression "ZLIB"
+# define LN_zlib_compression "zlib compression"
+# define NID_zlib_compression 125
+# define OBJ_zlib_compression 1L,1L,1L,1L,666L,2L
+
+# define SN_ext_key_usage "extendedKeyUsage"
+# define LN_ext_key_usage "X509v3 Extended Key Usage"
+# define NID_ext_key_usage 126
+# define OBJ_ext_key_usage OBJ_id_ce,37
+
+# define SN_id_pkix "PKIX"
+# define NID_id_pkix 127
+# define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L
+
+# define SN_id_kp "id-kp"
+# define NID_id_kp 128
+# define OBJ_id_kp OBJ_id_pkix,3L
+
+/* PKIX extended key usage OIDs */
+
+# define SN_server_auth "serverAuth"
+# define LN_server_auth "TLS Web Server Authentication"
+# define NID_server_auth 129
+# define OBJ_server_auth OBJ_id_kp,1L
+
+# define SN_client_auth "clientAuth"
+# define LN_client_auth "TLS Web Client Authentication"
+# define NID_client_auth 130
+# define OBJ_client_auth OBJ_id_kp,2L
+
+# define SN_code_sign "codeSigning"
+# define LN_code_sign "Code Signing"
+# define NID_code_sign 131
+# define OBJ_code_sign OBJ_id_kp,3L
+
+# define SN_email_protect "emailProtection"
+# define LN_email_protect "E-mail Protection"
+# define NID_email_protect 132
+# define OBJ_email_protect OBJ_id_kp,4L
+
+# define SN_time_stamp "timeStamping"
+# define LN_time_stamp "Time Stamping"
+# define NID_time_stamp 133
+# define OBJ_time_stamp OBJ_id_kp,8L
+
+/* Additional extended key usage OIDs: Microsoft */
+
+# define SN_ms_code_ind "msCodeInd"
+# define LN_ms_code_ind "Microsoft Individual Code Signing"
+# define NID_ms_code_ind 134
+# define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+# define SN_ms_code_com "msCodeCom"
+# define LN_ms_code_com "Microsoft Commercial Code Signing"
+# define NID_ms_code_com 135
+# define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+# define SN_ms_ctl_sign "msCTLSign"
+# define LN_ms_ctl_sign "Microsoft Trust List Signing"
+# define NID_ms_ctl_sign 136
+# define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+# define SN_ms_sgc "msSGC"
+# define LN_ms_sgc "Microsoft Server Gated Crypto"
+# define NID_ms_sgc 137
+# define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+# define SN_ms_efs "msEFS"
+# define LN_ms_efs "Microsoft Encrypted File System"
+# define NID_ms_efs 138
+# define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+/* Additional usage: Netscape */
+
+# define SN_ns_sgc "nsSGC"
+# define LN_ns_sgc "Netscape Server Gated Crypto"
+# define NID_ns_sgc 139
+# define OBJ_ns_sgc OBJ_netscape,4L,1L
+
+# define SN_delta_crl "deltaCRL"
+# define LN_delta_crl "X509v3 Delta CRL Indicator"
+# define NID_delta_crl 140
+# define OBJ_delta_crl OBJ_id_ce,27L
+
+# define SN_crl_reason "CRLReason"
+# define LN_crl_reason "CRL Reason Code"
+# define NID_crl_reason 141
+# define OBJ_crl_reason OBJ_id_ce,21L
+
+# define SN_invalidity_date "invalidityDate"
+# define LN_invalidity_date "Invalidity Date"
+# define NID_invalidity_date 142
+# define OBJ_invalidity_date OBJ_id_ce,24L
+
+# define SN_sxnet "SXNetID"
+# define LN_sxnet "Strong Extranet ID"
+# define NID_sxnet 143
+# define OBJ_sxnet 1L,3L,101L,1L,4L,1L
+
+/* PKCS12 and related OBJECT IDENTIFIERS */
+
+# define OBJ_pkcs12 OBJ_pkcs,12L
+# define OBJ_pkcs12_pbeids OBJ_pkcs12, 1
+
+# define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128"
+# define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4"
+# define NID_pbe_WithSHA1And128BitRC4 144
+# define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids, 1L
+
+# define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40"
+# define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4"
+# define NID_pbe_WithSHA1And40BitRC4 145
+# define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids, 2L
+
+# define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES"
+# define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC"
+# define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146
+# define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 3L
+
+# define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES"
+# define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC"
+# define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147
+# define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 4L
+
+# define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128"
+# define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC"
+# define NID_pbe_WithSHA1And128BitRC2_CBC 148
+# define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids, 5L
+
+# define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40"
+# define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC"
+# define NID_pbe_WithSHA1And40BitRC2_CBC 149
+# define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids, 6L
+
+# define OBJ_pkcs12_Version1 OBJ_pkcs12, 10L
+
+# define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1, 1L
+
+# define LN_keyBag "keyBag"
+# define NID_keyBag 150
+# define OBJ_keyBag OBJ_pkcs12_BagIds, 1L
+
+# define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag"
+# define NID_pkcs8ShroudedKeyBag 151
+# define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds, 2L
+
+# define LN_certBag "certBag"
+# define NID_certBag 152
+# define OBJ_certBag OBJ_pkcs12_BagIds, 3L
+
+# define LN_crlBag "crlBag"
+# define NID_crlBag 153
+# define OBJ_crlBag OBJ_pkcs12_BagIds, 4L
+
+# define LN_secretBag "secretBag"
+# define NID_secretBag 154
+# define OBJ_secretBag OBJ_pkcs12_BagIds, 5L
+
+# define LN_safeContentsBag "safeContentsBag"
+# define NID_safeContentsBag 155
+# define OBJ_safeContentsBag OBJ_pkcs12_BagIds, 6L
+
+# define LN_friendlyName "friendlyName"
+# define NID_friendlyName 156
+# define OBJ_friendlyName OBJ_pkcs9, 20L
+
+# define LN_localKeyID "localKeyID"
+# define NID_localKeyID 157
+# define OBJ_localKeyID OBJ_pkcs9, 21L
+
+# define OBJ_certTypes OBJ_pkcs9, 22L
+
+# define LN_x509Certificate "x509Certificate"
+# define NID_x509Certificate 158
+# define OBJ_x509Certificate OBJ_certTypes, 1L
+
+# define LN_sdsiCertificate "sdsiCertificate"
+# define NID_sdsiCertificate 159
+# define OBJ_sdsiCertificate OBJ_certTypes, 2L
+
+# define OBJ_crlTypes OBJ_pkcs9, 23L
+
+# define LN_x509Crl "x509Crl"
+# define NID_x509Crl 160
+# define OBJ_x509Crl OBJ_crlTypes, 1L
+
+/* PKCS#5 v2 OIDs */
+
+# define LN_pbes2 "PBES2"
+# define NID_pbes2 161
+# define OBJ_pbes2 OBJ_pkcs,5L,13L
+
+# define LN_pbmac1 "PBMAC1"
+# define NID_pbmac1 162
+# define OBJ_pbmac1 OBJ_pkcs,5L,14L
+
+# define LN_hmacWithSHA1 "hmacWithSHA1"
+# define NID_hmacWithSHA1 163
+# define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L
+
+/* Policy Qualifier Ids */
+
+# define LN_id_qt_cps "Policy Qualifier CPS"
+# define SN_id_qt_cps "id-qt-cps"
+# define NID_id_qt_cps 164
+# define OBJ_id_qt_cps OBJ_id_pkix,2L,1L
+
+# define LN_id_qt_unotice "Policy Qualifier User Notice"
+# define SN_id_qt_unotice "id-qt-unotice"
+# define NID_id_qt_unotice 165
+# define OBJ_id_qt_unotice OBJ_id_pkix,2L,2L
+
+# define SN_rc2_64_cbc "RC2-64-CBC"
+# define LN_rc2_64_cbc "rc2-64-cbc"
+# define NID_rc2_64_cbc 166
+
+# define SN_SMIMECapabilities "SMIME-CAPS"
+# define LN_SMIMECapabilities "S/MIME Capabilities"
+# define NID_SMIMECapabilities 167
+# define OBJ_SMIMECapabilities OBJ_pkcs9,15L
+
+# define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64"
+# define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC"
+# define NID_pbeWithMD2AndRC2_CBC 168
+# define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs,5L,4L
+
+# define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64"
+# define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC"
+# define NID_pbeWithMD5AndRC2_CBC 169
+# define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs,5L,6L
+
+# define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES"
+# define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC"
+# define NID_pbeWithSHA1AndDES_CBC 170
+# define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs,5L,10L
+
+/* Extension request OIDs */
+
+# define LN_ms_ext_req "Microsoft Extension Request"
+# define SN_ms_ext_req "msExtReq"
+# define NID_ms_ext_req 171
+# define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+# define LN_ext_req "Extension Request"
+# define SN_ext_req "extReq"
+# define NID_ext_req 172
+# define OBJ_ext_req OBJ_pkcs9,14L
+
+# define SN_name "name"
+# define LN_name "name"
+# define NID_name 173
+# define OBJ_name OBJ_X509,41L
+
+# define SN_dnQualifier "dnQualifier"
+# define LN_dnQualifier "dnQualifier"
+# define NID_dnQualifier 174
+# define OBJ_dnQualifier OBJ_X509,46L
+
+# define SN_id_pe "id-pe"
+# define NID_id_pe 175
+# define OBJ_id_pe OBJ_id_pkix,1L
+
+# define SN_id_ad "id-ad"
+# define NID_id_ad 176
+# define OBJ_id_ad OBJ_id_pkix,48L
+
+# define SN_info_access "authorityInfoAccess"
+# define LN_info_access "Authority Information Access"
+# define NID_info_access 177
+# define OBJ_info_access OBJ_id_pe,1L
+
+# define SN_ad_OCSP "OCSP"
+# define LN_ad_OCSP "OCSP"
+# define NID_ad_OCSP 178
+# define OBJ_ad_OCSP OBJ_id_ad,1L
+
+# define SN_ad_ca_issuers "caIssuers"
+# define LN_ad_ca_issuers "CA Issuers"
+# define NID_ad_ca_issuers 179
+# define OBJ_ad_ca_issuers OBJ_id_ad,2L
+
+# define SN_OCSP_sign "OCSPSigning"
+# define LN_OCSP_sign "OCSP Signing"
+# define NID_OCSP_sign 180
+# define OBJ_OCSP_sign OBJ_id_kp,9L
+# endif /* USE_OBJ_MAC */
+
+# include <openssl/bio.h>
+# include <openssl/asn1.h>
+
+# define OBJ_NAME_TYPE_UNDEF 0x00
+# define OBJ_NAME_TYPE_MD_METH 0x01
+# define OBJ_NAME_TYPE_CIPHER_METH 0x02
+# define OBJ_NAME_TYPE_PKEY_METH 0x03
+# define OBJ_NAME_TYPE_COMP_METH 0x04
+# define OBJ_NAME_TYPE_NUM 0x05
+
+# define OBJ_NAME_ALIAS 0x8000
+
+# define OBJ_BSEARCH_VALUE_ON_NOMATCH 0x01
+# define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH 0x02
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct obj_name_st {
+ int type;
+ int alias;
+ const char *name;
+ const char *data;
+} OBJ_NAME;
+
+# define OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c)
+
+int OBJ_NAME_init(void);
+int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *),
+ int (*cmp_func) (const char *, const char *),
+ void (*free_func) (const char *, int, const char *));
+const char *OBJ_NAME_get(const char *name, int type);
+int OBJ_NAME_add(const char *name, int type, const char *data);
+int OBJ_NAME_remove(const char *name, int type);
+void OBJ_NAME_cleanup(int type); /* -1 for everything */
+void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg),
+ void *arg);
+void OBJ_NAME_do_all_sorted(int type,
+ void (*fn) (const OBJ_NAME *, void *arg),
+ void *arg);
+
+ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o);
+ASN1_OBJECT *OBJ_nid2obj(int n);
+const char *OBJ_nid2ln(int n);
+const char *OBJ_nid2sn(int n);
+int OBJ_obj2nid(const ASN1_OBJECT *o);
+ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name);
+int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name);
+int OBJ_txt2nid(const char *s);
+int OBJ_ln2nid(const char *s);
+int OBJ_sn2nid(const char *s);
+int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b);
+const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
+ int (*cmp) (const void *, const void *));
+const void *OBJ_bsearch_ex_(const void *key, const void *base, int num,
+ int size,
+ int (*cmp) (const void *, const void *),
+ int flags);
+
+# define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm) \
+ static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \
+ static int nm##_cmp(type1 const *, type2 const *); \
+ scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
+
+# define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp) \
+ _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp)
+# define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \
+ type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
+
+/*-
+ * Unsolved problem: if a type is actually a pointer type, like
+ * nid_triple is, then its impossible to get a const where you need
+ * it. Consider:
+ *
+ * typedef int nid_triple[3];
+ * const void *a_;
+ * const nid_triple const *a = a_;
+ *
+ * The assignement discards a const because what you really want is:
+ *
+ * const int const * const *a = a_;
+ *
+ * But if you do that, you lose the fact that a is an array of 3 ints,
+ * which breaks comparison functions.
+ *
+ * Thus we end up having to cast, sadly, or unpack the
+ * declarations. Or, as I finally did in this case, delcare nid_triple
+ * to be a struct, which it should have been in the first place.
+ *
+ * Ben, August 2008.
+ *
+ * Also, strictly speaking not all types need be const, but handling
+ * the non-constness means a lot of complication, and in practice
+ * comparison routines do always not touch their arguments.
+ */
+
+# define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm) \
+ static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \
+ { \
+ type1 const *a = a_; \
+ type2 const *b = b_; \
+ return nm##_cmp(a,b); \
+ } \
+ static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
+ { \
+ return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
+ nm##_cmp_BSEARCH_CMP_FN); \
+ } \
+ extern void dummy_prototype(void)
+
+# define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \
+ static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \
+ { \
+ type1 const *a = a_; \
+ type2 const *b = b_; \
+ return nm##_cmp(a,b); \
+ } \
+ type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
+ { \
+ return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
+ nm##_cmp_BSEARCH_CMP_FN); \
+ } \
+ extern void dummy_prototype(void)
+
+# define OBJ_bsearch(type1,key,type2,base,num,cmp) \
+ ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
+ num,sizeof(type2), \
+ ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \
+ (void)CHECKED_PTR_OF(type2,cmp##_type_2), \
+ cmp##_BSEARCH_CMP_FN)))
+
+# define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags) \
+ ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
+ num,sizeof(type2), \
+ ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \
+ (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \
+ cmp##_BSEARCH_CMP_FN)),flags)
+
+int OBJ_new_nid(int num);
+int OBJ_add_object(const ASN1_OBJECT *obj);
+int OBJ_create(const char *oid, const char *sn, const char *ln);
+void OBJ_cleanup(void);
+int OBJ_create_objects(BIO *in);
+
+int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid);
+int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid);
+int OBJ_add_sigid(int signid, int dig_id, int pkey_id);
+void OBJ_sigid_free(void);
+
+extern int obj_cleanup_defer;
+void check_defer(int nid);
+
+/* 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.
+ */
+void ERR_load_OBJ_strings(void);
+
+/* Error codes for the OBJ functions. */
+
+/* Function codes. */
+# define OBJ_F_OBJ_ADD_OBJECT 105
+# define OBJ_F_OBJ_CREATE 100
+# define OBJ_F_OBJ_DUP 101
+# define OBJ_F_OBJ_NAME_NEW_INDEX 106
+# define OBJ_F_OBJ_NID2LN 102
+# define OBJ_F_OBJ_NID2OBJ 103
+# define OBJ_F_OBJ_NID2SN 104
+
+/* Reason codes. */
+# define OBJ_R_MALLOC_FAILURE 100
+# define OBJ_R_UNKNOWN_NID 101
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/opensslconf.h b/openssl/opensslconf.h
new file mode 100644
index 0000000..33c3027
--- /dev/null
+++ b/openssl/opensslconf.h
@@ -0,0 +1,138 @@
+/*
+ *
+ * Copyright (c) 2011-2015 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * This document is the property of Nest. It is considered
+ * confidential and proprietary information.
+ *
+ * This document may not be reproduced or transmitted in any form,
+ * in whole or in part, without the express written permission of
+ * Nest.
+ *
+ * Description:
+ * Configuration options for emssl
+ *
+ * NOTE: Unlike in OpenSSL, this file is generated by hand with the specific set
+ * of options required for Topaz.
+ */
+
+/* OpenSSL options
+ */
+
+#ifndef OPENSSL_CONF_H
+#define OPENSSL_CONF_H
+
+#ifndef OPENSSL_NO_ENGINE
+#define OPENSSL_NO_ENGINE
+#endif
+
+#ifndef OPENSSL_NO_ERR
+#define OPENSSL_NO_ERR
+#endif
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+#define OPENSSL_SMALL_FOOTPRINT
+#endif
+
+#ifndef OPENSSL_NO_SHA512
+#define OPENSSL_NO_SHA512
+#endif
+
+#ifndef OPENSSL_NO_SHA0
+#define OPENSSL_NO_SHA0
+#endif
+
+#ifndef OPENSSL_NO_LOCKING
+#define OPENSSL_NO_LOCKING
+#endif
+
+#ifndef OPENSSL_NO_LHASH
+#define OPENSSL_NO_LHASH
+#endif
+
+#ifndef OPENSSL_NO_RSA
+#define OPENSSL_NO_RSA
+#endif
+
+#ifndef OPENSSL_NO_DSA
+#define OPENSSL_NO_DSA
+#endif
+
+#ifndef OPENSSL_NO_DEPRECATED
+#define OPENSSL_NO_DEPRECATED
+#endif
+
+#ifndef OPENSSL_NO_FP_API
+#define OPENSSL_NO_FP_API
+#endif
+
+#ifndef L_ENDIAN
+#define L_ENDIAN
+#endif
+
+#ifndef NO_SYSLOG
+#define NO_SYSLOG
+#endif
+
+#ifndef NO_CHMOD
+#define NO_CHMOD
+#endif
+
+#ifndef TERMIOS
+#define TERMIOS
+#endif
+
+#ifndef OPENSSL_EXPERIMENTAL_JPAKE
+#define OPENSSL_EXPERIMENTAL_JPAKE
+#endif
+
+#ifndef THIRTY_TWO_BIT
+#define THIRTY_TWO_BIT
+#endif
+
+#ifndef BN_LLONG
+#define BN_LLONG
+#endif
+
+#ifndef OPENSSL_NO_EC2M
+#define OPENSSL_NO_EC2M
+#endif
+
+#ifndef OPENSSL_BN_ASM_MONT
+#define OPENSSL_BN_ASM_MONT
+#endif
+
+#ifndef OPENSSL_NO_UNIT_TEST
+#define OPENSSL_NO_UNIT_TEST
+#endif
+
+/* emssl-specific compilation options
+ */
+
+#ifndef DISABLE_UNUSED_EC_FUNCTS
+#define DISABLE_UNUSED_EC_FUNCTS
+#endif
+
+#ifndef SIMPLIFIED_MAKE_AFFINE
+#define SIMPLIFIED_MAKE_AFFINE
+#endif
+
+#ifndef NO_ECPOINT_MULTIPLY_PRECOMP
+#define NO_ECPOINT_MULTIPLY_PRECOMP
+#endif
+
+#ifndef NO_TIME_BN_RAND
+#define NO_TIME_BN_RAND
+#endif
+
+#ifndef FORCE_SIMPLE_EC_METHOD
+/* #define FORCE_SIMPLE_EC_METHOD */
+#endif
+
+#ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+/* #define SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+#endif
+
+#endif
+
diff --git a/openssl/opensslv.h b/openssl/opensslv.h
new file mode 100644
index 0000000..daf3905
--- /dev/null
+++ b/openssl/opensslv.h
@@ -0,0 +1,97 @@
+#ifndef HEADER_OPENSSLV_H
+# define HEADER_OPENSSLV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-
+ * Numeric release version identifier:
+ * MNNFFPPS: major minor fix patch status
+ * The status nibble has one of the values 0 for development, 1 to e for betas
+ * 1 to 14, and f for release. The patch level is exactly that.
+ * For example:
+ * 0.9.3-dev 0x00903000
+ * 0.9.3-beta1 0x00903001
+ * 0.9.3-beta2-dev 0x00903002
+ * 0.9.3-beta2 0x00903002 (same as ...beta2-dev)
+ * 0.9.3 0x0090300f
+ * 0.9.3a 0x0090301f
+ * 0.9.4 0x0090400f
+ * 1.2.3z 0x102031af
+ *
+ * For continuity reasons (because 0.9.5 is already out, and is coded
+ * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
+ * part is slightly different, by setting the highest bit. This means
+ * that 0.9.5a looks like this: 0x0090581f. At 0.9.6, we can start
+ * with 0x0090600S...
+ *
+ * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
+ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
+ * major minor fix final patch/beta)
+ */
+# define OPENSSL_VERSION_NUMBER 0x100010dfL
+# ifdef OPENSSL_FIPS
+# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1m-fips 19 Mar 2015"
+# else
+# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1m 19 Mar 2015"
+# endif
+# define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
+
+/*-
+ * The macros below are to be used for shared library (.so, .dll, ...)
+ * versioning. That kind of versioning works a bit differently between
+ * operating systems. The most usual scheme is to set a major and a minor
+ * number, and have the runtime loader check that the major number is equal
+ * to what it was at application link time, while the minor number has to
+ * be greater or equal to what it was at application link time. With this
+ * scheme, the version number is usually part of the file name, like this:
+ *
+ * libcrypto.so.0.9
+ *
+ * Some unixen also make a softlink with the major verson number only:
+ *
+ * libcrypto.so.0
+ *
+ * On Tru64 and IRIX 6.x it works a little bit differently. There, the
+ * shared library version is stored in the file, and is actually a series
+ * of versions, separated by colons. The rightmost version present in the
+ * library when linking an application is stored in the application to be
+ * matched at run time. When the application is run, a check is done to
+ * see if the library version stored in the application matches any of the
+ * versions in the version string of the library itself.
+ * This version string can be constructed in any way, depending on what
+ * kind of matching is desired. However, to implement the same scheme as
+ * the one used in the other unixen, all compatible versions, from lowest
+ * to highest, should be part of the string. Consecutive builds would
+ * give the following versions strings:
+ *
+ * 3.0
+ * 3.0:3.1
+ * 3.0:3.1:3.2
+ * 4.0
+ * 4.0:4.1
+ *
+ * Notice how version 4 is completely incompatible with version, and
+ * therefore give the breach you can see.
+ *
+ * There may be other schemes as well that I haven't yet discovered.
+ *
+ * So, here's the way it works here: first of all, the library version
+ * number doesn't need at all to match the overall OpenSSL version.
+ * However, it's nice and more understandable if it actually does.
+ * The current library version is stored in the macro SHLIB_VERSION_NUMBER,
+ * which is just a piece of text in the format "M.m.e" (Major, minor, edit).
+ * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways,
+ * we need to keep a history of version numbers, which is done in the
+ * macro SHLIB_VERSION_HISTORY. The numbers are separated by colons and
+ * should only keep the versions that are binary compatible with the current.
+ */
+# define SHLIB_VERSION_HISTORY ""
+# define SHLIB_VERSION_NUMBER "1.0.0"
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* HEADER_OPENSSLV_H */
diff --git a/openssl/ossl_typ.h b/openssl/ossl_typ.h
new file mode 100644
index 0000000..0fcb0ce
--- /dev/null
+++ b/openssl/ossl_typ.h
@@ -0,0 +1,209 @@
+/* ====================================================================
+ * Copyright (c) 1998-2001 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 HEADER_OPENSSL_TYPES_H
+# define HEADER_OPENSSL_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# include <openssl/e_os2.h>
+
+# ifdef NO_ASN1_TYPEDEFS
+# define ASN1_INTEGER ASN1_STRING
+# define ASN1_ENUMERATED ASN1_STRING
+# define ASN1_BIT_STRING ASN1_STRING
+# define ASN1_OCTET_STRING ASN1_STRING
+# define ASN1_PRINTABLESTRING ASN1_STRING
+# define ASN1_T61STRING ASN1_STRING
+# define ASN1_IA5STRING ASN1_STRING
+# define ASN1_UTCTIME ASN1_STRING
+# define ASN1_GENERALIZEDTIME ASN1_STRING
+# define ASN1_TIME ASN1_STRING
+# define ASN1_GENERALSTRING ASN1_STRING
+# define ASN1_UNIVERSALSTRING ASN1_STRING
+# define ASN1_BMPSTRING ASN1_STRING
+# define ASN1_VISIBLESTRING ASN1_STRING
+# define ASN1_UTF8STRING ASN1_STRING
+# define ASN1_BOOLEAN int
+# define ASN1_NULL int
+# else
+typedef struct asn1_string_st ASN1_INTEGER;
+typedef struct asn1_string_st ASN1_ENUMERATED;
+typedef struct asn1_string_st ASN1_BIT_STRING;
+typedef struct asn1_string_st ASN1_OCTET_STRING;
+typedef struct asn1_string_st ASN1_PRINTABLESTRING;
+typedef struct asn1_string_st ASN1_T61STRING;
+typedef struct asn1_string_st ASN1_IA5STRING;
+typedef struct asn1_string_st ASN1_GENERALSTRING;
+typedef struct asn1_string_st ASN1_UNIVERSALSTRING;
+typedef struct asn1_string_st ASN1_BMPSTRING;
+typedef struct asn1_string_st ASN1_UTCTIME;
+typedef struct asn1_string_st ASN1_TIME;
+typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
+typedef struct asn1_string_st ASN1_VISIBLESTRING;
+typedef struct asn1_string_st ASN1_UTF8STRING;
+typedef struct asn1_string_st ASN1_STRING;
+typedef int ASN1_BOOLEAN;
+typedef int ASN1_NULL;
+# endif
+
+typedef struct ASN1_ITEM_st ASN1_ITEM;
+typedef struct asn1_pctx_st ASN1_PCTX;
+
+# ifdef OPENSSL_SYS_WIN32
+# undef X509_NAME
+# undef X509_EXTENSIONS
+# undef X509_CERT_PAIR
+# undef PKCS7_ISSUER_AND_SERIAL
+# undef OCSP_REQUEST
+# undef OCSP_RESPONSE
+# endif
+
+# ifdef BIGNUM
+# undef BIGNUM
+# endif
+typedef struct bignum_st BIGNUM;
+typedef struct bignum_ctx BN_CTX;
+typedef struct bn_blinding_st BN_BLINDING;
+typedef struct bn_mont_ctx_st BN_MONT_CTX;
+typedef struct bn_recp_ctx_st BN_RECP_CTX;
+typedef struct bn_gencb_st BN_GENCB;
+
+typedef struct buf_mem_st BUF_MEM;
+
+typedef struct evp_cipher_st EVP_CIPHER;
+typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
+typedef struct env_md_st EVP_MD;
+typedef struct env_md_ctx_st EVP_MD_CTX;
+typedef struct evp_pkey_st EVP_PKEY;
+
+typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
+
+typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
+typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
+
+typedef struct dh_st DH;
+typedef struct dh_method DH_METHOD;
+
+typedef struct dsa_st DSA;
+typedef struct dsa_method DSA_METHOD;
+
+typedef struct rsa_st RSA;
+typedef struct rsa_meth_st RSA_METHOD;
+
+typedef struct rand_meth_st RAND_METHOD;
+
+typedef struct ecdh_method ECDH_METHOD;
+typedef struct ecdsa_method ECDSA_METHOD;
+
+typedef struct x509_st X509;
+typedef struct X509_algor_st X509_ALGOR;
+typedef struct X509_crl_st X509_CRL;
+typedef struct x509_crl_method_st X509_CRL_METHOD;
+typedef struct x509_revoked_st X509_REVOKED;
+typedef struct X509_name_st X509_NAME;
+typedef struct X509_pubkey_st X509_PUBKEY;
+typedef struct x509_store_st X509_STORE;
+typedef struct x509_store_ctx_st X509_STORE_CTX;
+
+typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
+
+typedef struct v3_ext_ctx X509V3_CTX;
+typedef struct conf_st CONF;
+
+typedef struct store_st STORE;
+typedef struct store_method_st STORE_METHOD;
+
+typedef struct ui_st UI;
+typedef struct ui_method_st UI_METHOD;
+
+typedef struct st_ERR_FNS ERR_FNS;
+
+typedef struct engine_st ENGINE;
+typedef struct ssl_st SSL;
+typedef struct ssl_ctx_st SSL_CTX;
+
+typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
+typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
+typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
+typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
+
+typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
+typedef struct DIST_POINT_st DIST_POINT;
+typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT;
+typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS;
+
+ /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */
+# define DECLARE_PKCS12_STACK_OF(type)/* Nothing */
+# define IMPLEMENT_PKCS12_STACK_OF(type)/* Nothing */
+
+typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
+/* Callback types for crypto.h */
+typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+ int idx, long argl, void *argp);
+typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+ int idx, long argl, void *argp);
+typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from,
+ void *from_d, int idx, long argl, void *argp);
+
+typedef struct ocsp_req_ctx_st OCSP_REQ_CTX;
+typedef struct ocsp_response_st OCSP_RESPONSE;
+typedef struct ocsp_responder_id_st OCSP_RESPID;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* def HEADER_OPENSSL_TYPES_H */
diff --git a/openssl/patches/openssl-1.0.1m-emssl-diffs.patch b/openssl/patches/openssl-1.0.1m-emssl-diffs.patch
new file mode 100644
index 0000000..545d2b3
--- /dev/null
+++ b/openssl/patches/openssl-1.0.1m-emssl-diffs.patch
@@ -0,0 +1,583 @@
+diff -r -c -x Makefile -x opensslconf.h openssl-1.0.1m/bn/bn_asm.c openssl/bn/bn_asm.c
+*** openssl-1.0.1m/bn/bn_asm.c 2015-03-19 06:37:10.000000000 -0700
+--- openssl/bn/bn_asm.c 2015-03-30 19:57:20.956149250 -0700
+***************
+*** 66,71 ****
+--- 66,75 ----
+ #include "cryptlib.h"
+ #include "bn_lcl.h"
+
++ #ifdef OPENSSL_SMALL_FOOTPRINT
++ #undef OPENSSL_SMALL_FOOTPRINT
++ #endif
++
+ #if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
+
+ BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
+diff -r -c -x Makefile -x opensslconf.h openssl-1.0.1m/bn/bn_rand.c openssl/bn/bn_rand.c
+*** openssl-1.0.1m/bn/bn_rand.c 2015-03-19 06:19:00.000000000 -0700
+--- openssl/bn/bn_rand.c 2015-04-01 14:03:10.792764003 -0700
+***************
+*** 137,144 ****
+--- 137,146 ----
+ }
+
+ /* make a random number and set the top and bottom bits */
++ #ifndef NO_TIME_BN_RAND
+ time(&tim);
+ RAND_add(&tim, sizeof(tim), 0.0);
++ #endif /* NO_TIME_BN_RAND */
+
+ if (pseudorand) {
+ if (RAND_pseudo_bytes(buf, bytes) == -1)
+diff -r -c -x Makefile -x opensslconf.h openssl-1.0.1m/ec/ec_cvt.c openssl/ec/ec_cvt.c
+*** openssl-1.0.1m/ec/ec_cvt.c 2015-03-19 06:37:10.000000000 -0700
+--- openssl/ec/ec_cvt.c 2015-03-30 20:09:59.140126497 -0700
+***************
+*** 78,83 ****
+--- 78,101 ----
+ const EC_METHOD *meth;
+ EC_GROUP *ret;
+
++ #ifdef FORCE_SIMPLE_EC_METHOD
++
++ meth = EC_GFp_simple_method();
++
++ ret = EC_GROUP_new(meth);
++ if (ret == NULL)
++ return NULL;
++
++ if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
++ {
++ EC_GROUP_free(ret);
++ return NULL;
++ }
++
++ return ret;
++
++ #else /* FORCE_SIMPLE_EC_METHOD */
++
+ #if defined(OPENSSL_BN_ASM_MONT)
+ /*
+ * This might appear controversial, but the fact is that generic
+***************
+*** 142,147 ****
+--- 160,167 ----
+ }
+ }
+
++ #endif /* FORCE_SIMPLE_EC_METHOD */
++
+ return ret;
+ }
+
+diff -r -c -x Makefile -x opensslconf.h openssl-1.0.1m/ec/ec_mult.c openssl/ec/ec_mult.c
+*** openssl-1.0.1m/ec/ec_mult.c 2015-03-19 06:19:00.000000000 -0700
+--- openssl/ec/ec_mult.c 2015-03-30 20:07:05.080131720 -0700
+***************
+*** 385,390 ****
+--- 385,392 ----
+ goto err;
+ }
+
++ #ifndef NO_ECPOINT_MULTIPLY_PRECOMP
++
+ /* look if we can use precomputed multiples of generator */
+
+ pre_comp =
+***************
+*** 415,421 ****
+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+! } else {
+ /* can't use precomputation */
+ pre_comp = NULL;
+ numblocks = 1;
+--- 417,425 ----
+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+! } else
+! #endif /* NO_ECPOINT_MULTIPLY_PRECOMP */
+! {
+ /* can't use precomputation */
+ pre_comp = NULL;
+ numblocks = 1;
+***************
+*** 465,476 ****
+--- 469,483 ----
+ if (numblocks) {
+ /* we go here iff scalar != NULL */
+
++ #ifndef NO_ECPOINT_MULTIPLY_PRECOMP
+ if (pre_comp == NULL) {
++ #endif /* NO_ECPOINT_MULTIPLY_PRECOMP */
+ if (num_scalar != 1) {
+ ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ /* we have already generated a wNAF for 'scalar' */
++ #ifndef NO_ECPOINT_MULTIPLY_PRECOMP
+ } else {
+ signed char *tmp_wNAF = NULL;
+ size_t tmp_len = 0;
+***************
+*** 569,574 ****
+--- 576,582 ----
+ OPENSSL_free(tmp_wNAF);
+ }
+ }
++ #endif /* NO_ECPOINT_MULTIPLY_PRECOMP */
+ }
+
+ /*
+diff -r -c -x Makefile -x opensslconf.h openssl-1.0.1m/ec/ecp_mont.c openssl/ec/ecp_mont.c
+*** openssl-1.0.1m/ec/ecp_mont.c 2015-03-19 06:19:00.000000000 -0700
+--- openssl/ec/ecp_mont.c 2015-03-30 20:01:40.968141447 -0700
+***************
+*** 79,87 ****
+--- 79,93 ----
+ ec_GFp_mont_group_clear_finish,
+ ec_GFp_mont_group_copy,
+ ec_GFp_mont_group_set_curve,
++ #ifdef DISABLE_UNUSED_EC_FUNCTS
++ 0,
++ 0,
++ 0,
++ #else
+ ec_GFp_simple_group_get_curve,
+ ec_GFp_simple_group_get_degree,
+ ec_GFp_simple_group_check_discriminant,
++ #endif
+ ec_GFp_simple_point_init,
+ ec_GFp_simple_point_finish,
+ ec_GFp_simple_point_clear_finish,
+***************
+*** 97,103 ****
+--- 103,113 ----
+ ec_GFp_simple_invert,
+ ec_GFp_simple_is_at_infinity,
+ ec_GFp_simple_is_on_curve,
++ #ifdef DISABLE_UNUSED_EC_FUNCTS
++ 0,
++ #else
+ ec_GFp_simple_cmp,
++ #endif
+ ec_GFp_simple_make_affine,
+ ec_GFp_simple_points_make_affine,
+ 0 /* mul */ ,
+diff -r -c -x Makefile -x opensslconf.h openssl-1.0.1m/ec/ecp_smpl.c openssl/ec/ecp_smpl.c
+*** openssl-1.0.1m/ec/ecp_smpl.c 2015-03-19 06:19:00.000000000 -0700
+--- openssl/ec/ecp_smpl.c 2015-03-30 20:24:36.384100170 -0700
+***************
+*** 82,90 ****
+--- 82,96 ----
+ ec_GFp_simple_group_clear_finish,
+ ec_GFp_simple_group_copy,
+ ec_GFp_simple_group_set_curve,
++ #ifdef DISABLE_UNUSED_EC_FUNCTS
++ 0,
++ 0,
++ 0,
++ #else /* DISABLE_UNUSED_EC_FUNCTS */
+ ec_GFp_simple_group_get_curve,
+ ec_GFp_simple_group_get_degree,
+ ec_GFp_simple_group_check_discriminant,
++ #endif /* DISABLE_UNUSED_EC_FUNCTS */
+ ec_GFp_simple_point_init,
+ ec_GFp_simple_point_finish,
+ ec_GFp_simple_point_clear_finish,
+***************
+*** 100,106 ****
+--- 106,116 ----
+ ec_GFp_simple_invert,
+ ec_GFp_simple_is_at_infinity,
+ ec_GFp_simple_is_on_curve,
++ #ifdef DISABLE_UNUSED_EC_FUNCTS
++ 0,
++ #else /* DISABLE_UNUSED_EC_FUNCTS */
+ ec_GFp_simple_cmp,
++ #endif /* DISABLE_UNUSED_EC_FUNCTS */
+ ec_GFp_simple_make_affine,
+ ec_GFp_simple_points_make_affine,
+ 0 /* mul */ ,
+***************
+*** 206,223 ****
+ /* group->a */
+ if (!BN_nnmod(tmp_a, a, p, ctx))
+ goto err;
+ if (group->meth->field_encode) {
+ if (!group->meth->field_encode(group, &group->a, tmp_a, ctx))
+ goto err;
+! } else if (!BN_copy(&group->a, tmp_a))
+! goto err;
+
+ /* group->b */
+ if (!BN_nnmod(&group->b, b, p, ctx))
+ goto err;
+ if (group->meth->field_encode)
+ if (!group->meth->field_encode(group, &group->b, &group->b, ctx))
+ goto err;
+
+ /* group->a_is_minus3 */
+ if (!BN_add_word(tmp_a, 3))
+--- 216,238 ----
+ /* group->a */
+ if (!BN_nnmod(tmp_a, a, p, ctx))
+ goto err;
++ #ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode) {
+ if (!group->meth->field_encode(group, &group->a, tmp_a, ctx))
+ goto err;
+! } else
+! #endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+! if (!BN_copy(&group->a, tmp_a))
+! goto err;
+
+ /* group->b */
+ if (!BN_nnmod(&group->b, b, p, ctx))
+ goto err;
++ #ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode)
+ if (!group->meth->field_encode(group, &group->b, &group->b, ctx))
+ goto err;
++ #endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+
+ /* group->a_is_minus3 */
+ if (!BN_add_word(tmp_a, 3))
+***************
+*** 245,250 ****
+--- 260,266 ----
+ }
+
+ if (a != NULL || b != NULL) {
++ #ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_decode) {
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+***************
+*** 259,265 ****
+ if (!group->meth->field_decode(group, b, &group->b, ctx))
+ goto err;
+ }
+! } else {
+ if (a != NULL) {
+ if (!BN_copy(a, &group->a))
+ goto err;
+--- 275,283 ----
+ if (!group->meth->field_decode(group, b, &group->b, ctx))
+ goto err;
+ }
+! } else
+! #endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+! {
+ if (a != NULL) {
+ if (!BN_copy(a, &group->a))
+ goto err;
+***************
+*** 308,319 ****
+ if (order == NULL)
+ goto err;
+
+ if (group->meth->field_decode) {
+ if (!group->meth->field_decode(group, a, &group->a, ctx))
+ goto err;
+ if (!group->meth->field_decode(group, b, &group->b, ctx))
+ goto err;
+! } else {
+ if (!BN_copy(a, &group->a))
+ goto err;
+ if (!BN_copy(b, &group->b))
+--- 326,340 ----
+ if (order == NULL)
+ goto err;
+
++ #ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_decode) {
+ if (!group->meth->field_decode(group, a, &group->a, ctx))
+ goto err;
+ if (!group->meth->field_decode(group, b, &group->b, ctx))
+ goto err;
+! } else
+! #endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+! {
+ if (!BN_copy(a, &group->a))
+ goto err;
+ if (!BN_copy(b, &group->b))
+***************
+*** 423,441 ****
+--- 444,466 ----
+ if (x != NULL) {
+ if (!BN_nnmod(&point->X, x, &group->field, ctx))
+ goto err;
++ #ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode) {
+ if (!group->meth->field_encode(group, &point->X, &point->X, ctx))
+ goto err;
+ }
++ #endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ }
+
+ if (y != NULL) {
+ if (!BN_nnmod(&point->Y, y, &group->field, ctx))
+ goto err;
++ #ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode) {
+ if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx))
+ goto err;
+ }
++ #endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ }
+
+ if (z != NULL) {
+***************
+*** 444,449 ****
+--- 469,475 ----
+ if (!BN_nnmod(&point->Z, z, &group->field, ctx))
+ goto err;
+ Z_is_one = BN_is_one(&point->Z);
++ #ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode) {
+ if (Z_is_one && (group->meth->field_set_to_one != 0)) {
+ if (!group->meth->field_set_to_one(group, &point->Z, ctx))
+***************
+*** 454,459 ****
+--- 480,486 ----
+ goto err;
+ }
+ }
++ #endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+ point->Z_is_one = Z_is_one;
+ }
+
+***************
+*** 473,478 ****
+--- 500,506 ----
+ BN_CTX *new_ctx = NULL;
+ int ret = 0;
+
++ #ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_decode != 0) {
+ if (ctx == NULL) {
+ ctx = new_ctx = BN_CTX_new();
+***************
+*** 492,498 ****
+ if (!group->meth->field_decode(group, z, &point->Z, ctx))
+ goto err;
+ }
+! } else {
+ if (x != NULL) {
+ if (!BN_copy(x, &point->X))
+ goto err;
+--- 520,528 ----
+ if (!group->meth->field_decode(group, z, &point->Z, ctx))
+ goto err;
+ }
+! } else
+! #endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+! {
+ if (x != NULL) {
+ if (!BN_copy(x, &point->X))
+ goto err;
+***************
+*** 565,579 ****
+
+ /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
+
+ if (group->meth->field_decode) {
+ if (!group->meth->field_decode(group, Z, &point->Z, ctx))
+ goto err;
+ Z_ = Z;
+! } else {
+ Z_ = &point->Z;
+ }
+
+ if (BN_is_one(Z_)) {
+ if (group->meth->field_decode) {
+ if (x != NULL) {
+ if (!group->meth->field_decode(group, x, &point->X, ctx))
+--- 595,613 ----
+
+ /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
+
++ #ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_decode) {
+ if (!group->meth->field_decode(group, Z, &point->Z, ctx))
+ goto err;
+ Z_ = Z;
+! } else
+! #endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+! {
+ Z_ = &point->Z;
+ }
+
+ if (BN_is_one(Z_)) {
++ #ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_decode) {
+ if (x != NULL) {
+ if (!group->meth->field_decode(group, x, &point->X, ctx))
+***************
+*** 583,589 ****
+ if (!group->meth->field_decode(group, y, &point->Y, ctx))
+ goto err;
+ }
+! } else {
+ if (x != NULL) {
+ if (!BN_copy(x, &point->X))
+ goto err;
+--- 617,625 ----
+ if (!group->meth->field_decode(group, y, &point->Y, ctx))
+ goto err;
+ }
+! } else
+! #endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+! {
+ if (x != NULL) {
+ if (!BN_copy(x, &point->X))
+ goto err;
+***************
+*** 600,610 ****
+ goto err;
+ }
+
+ if (group->meth->field_encode == 0) {
+ /* field_sqr works on standard representation */
+ if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
+ goto err;
+! } else {
+ if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx))
+ goto err;
+ }
+--- 636,649 ----
+ goto err;
+ }
+
++ #ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode == 0) {
+ /* field_sqr works on standard representation */
+ if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
+ goto err;
+! } else
+! #endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+! {
+ if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx))
+ goto err;
+ }
+***************
+*** 619,631 ****
+ }
+
+ if (y != NULL) {
+ if (group->meth->field_encode == 0) {
+ /*
+ * field_mul works on standard representation
+ */
+ if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
+ goto err;
+! } else {
+ if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx))
+ goto err;
+ }
+--- 658,673 ----
+ }
+
+ if (y != NULL) {
++ #ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode == 0) {
+ /*
+ * field_mul works on standard representation
+ */
+ if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
+ goto err;
+! } else
+! #endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+! {
+ if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx))
+ goto err;
+ }
+***************
+*** 1249,1254 ****
+--- 1291,1309 ----
+ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
+ EC_POINT *points[], BN_CTX *ctx)
+ {
++ #ifdef SIMPLIFIED_MAKE_AFFINE
++ int ret = 1;
++ size_t i;
++
++ for (i = 0; i < num; i++)
++ {
++ ret = ec_GFp_simple_make_affine(group, points[i], ctx);
++ if (!ret)
++ break;
++ }
++
++ return ret;
++ #else /* SIMPLIFIED_MAKE_AFFINE */
+ BN_CTX *new_ctx = NULL;
+ BIGNUM *tmp, *tmp_Z;
+ BIGNUM **prod_Z = NULL;
+***************
+*** 1317,1322 ****
+--- 1372,1378 ----
+ ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
+ goto err;
+ }
++ #ifndef SIMPLE_EC_NO_FIELD_ENCODE_DECODE
+ if (group->meth->field_encode != 0) {
+ /*
+ * In the Montgomery case, we just turned R*H (representing H) into
+***************
+*** 1328,1333 ****
+--- 1384,1390 ----
+ if (!group->meth->field_encode(group, tmp, tmp, ctx))
+ goto err;
+ }
++ #endif /* SIMPLE_EC_NO_FIELD_ENCODE_DECODE */
+
+ for (i = num - 1; i > 0; --i) {
+ /*
+***************
+*** 1403,1408 ****
+--- 1460,1466 ----
+ OPENSSL_free(prod_Z);
+ }
+ return ret;
++ #endif /* !SIMPLIFIED_MAKE_AFFINE */
+ }
+
+ int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+diff -r -c -x Makefile -x opensslconf.h openssl-1.0.1m/jpake/jpake.c openssl/jpake/jpake.c
+*** openssl-1.0.1m/jpake/jpake.c 2015-03-19 06:37:10.000000000 -0700
+--- openssl/jpake/jpake.c 2015-03-31 16:16:20.828385916 -0700
+***************
+*** 3,9 ****
+ #include <openssl/crypto.h>
+ #include <openssl/sha.h>
+ #include <openssl/err.h>
+! #include <memory.h>
+
+ /*
+ * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or
+--- 3,9 ----
+ #include <openssl/crypto.h>
+ #include <openssl/sha.h>
+ #include <openssl/err.h>
+! #include <string.h>
+
+ /*
+ * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or
+diff -r -c -x Makefile -x opensslconf.h openssl-1.0.1m/rand/rand.h openssl/rand/rand.h
+*** openssl-1.0.1m/rand/rand.h 2015-03-19 06:19:00.000000000 -0700
+--- openssl/rand/rand.h 2015-03-30 19:48:30.056165183 -0700
+***************
+*** 143,148 ****
+--- 143,149 ----
+ # define RAND_R_ERROR_INSTANTIATING_DRBG 103
+ # define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101
+ # define RAND_R_PRNG_NOT_SEEDED 100
++ # define RAND_R_PRNG_ERROR 108
+
+ #ifdef __cplusplus
+ }
diff --git a/openssl/pkcs7.h b/openssl/pkcs7.h
new file mode 120000
index 0000000..490b6e5
--- /dev/null
+++ b/openssl/pkcs7.h
@@ -0,0 +1 @@
+pkcs7/pkcs7.h
\ No newline at end of file
diff --git a/openssl/pkcs7/pkcs7.h b/openssl/pkcs7/pkcs7.h
new file mode 100644
index 0000000..b51b386
--- /dev/null
+++ b/openssl/pkcs7/pkcs7.h
@@ -0,0 +1,481 @@
+/* crypto/pkcs7/pkcs7.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_PKCS7_H
+# define HEADER_PKCS7_H
+
+# include <openssl/asn1.h>
+# include <openssl/bio.h>
+# include <openssl/e_os2.h>
+
+# include <openssl/symhacks.h>
+# include <openssl/ossl_typ.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# ifdef OPENSSL_SYS_WIN32
+/* Under Win32 thes are defined in wincrypt.h */
+# undef PKCS7_ISSUER_AND_SERIAL
+# undef PKCS7_SIGNER_INFO
+# endif
+
+/*-
+Encryption_ID DES-CBC
+Digest_ID MD5
+Digest_Encryption_ID rsaEncryption
+Key_Encryption_ID rsaEncryption
+*/
+
+typedef struct pkcs7_issuer_and_serial_st {
+ X509_NAME *issuer;
+ ASN1_INTEGER *serial;
+} PKCS7_ISSUER_AND_SERIAL;
+
+typedef struct pkcs7_signer_info_st {
+ ASN1_INTEGER *version; /* version 1 */
+ PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
+ X509_ALGOR *digest_alg;
+ STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */
+ X509_ALGOR *digest_enc_alg;
+ ASN1_OCTET_STRING *enc_digest;
+ STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */
+ /* The private key to sign with */
+ EVP_PKEY *pkey;
+} PKCS7_SIGNER_INFO;
+
+DECLARE_STACK_OF(PKCS7_SIGNER_INFO)
+DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO)
+
+typedef struct pkcs7_recip_info_st {
+ ASN1_INTEGER *version; /* version 0 */
+ PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
+ X509_ALGOR *key_enc_algor;
+ ASN1_OCTET_STRING *enc_key;
+ X509 *cert; /* get the pub-key from this */
+} PKCS7_RECIP_INFO;
+
+DECLARE_STACK_OF(PKCS7_RECIP_INFO)
+DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO)
+
+typedef struct pkcs7_signed_st {
+ ASN1_INTEGER *version; /* version 1 */
+ STACK_OF(X509_ALGOR) *md_algs; /* md used */
+ STACK_OF(X509) *cert; /* [ 0 ] */
+ STACK_OF(X509_CRL) *crl; /* [ 1 ] */
+ STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
+ struct pkcs7_st *contents;
+} PKCS7_SIGNED;
+/*
+ * The above structure is very very similar to PKCS7_SIGN_ENVELOPE. How about
+ * merging the two
+ */
+
+typedef struct pkcs7_enc_content_st {
+ ASN1_OBJECT *content_type;
+ X509_ALGOR *algorithm;
+ ASN1_OCTET_STRING *enc_data; /* [ 0 ] */
+ const EVP_CIPHER *cipher;
+} PKCS7_ENC_CONTENT;
+
+typedef struct pkcs7_enveloped_st {
+ ASN1_INTEGER *version; /* version 0 */
+ STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;
+ PKCS7_ENC_CONTENT *enc_data;
+} PKCS7_ENVELOPE;
+
+typedef struct pkcs7_signedandenveloped_st {
+ ASN1_INTEGER *version; /* version 1 */
+ STACK_OF(X509_ALGOR) *md_algs; /* md used */
+ STACK_OF(X509) *cert; /* [ 0 ] */
+ STACK_OF(X509_CRL) *crl; /* [ 1 ] */
+ STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
+ PKCS7_ENC_CONTENT *enc_data;
+ STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;
+} PKCS7_SIGN_ENVELOPE;
+
+typedef struct pkcs7_digest_st {
+ ASN1_INTEGER *version; /* version 0 */
+ X509_ALGOR *md; /* md used */
+ struct pkcs7_st *contents;
+ ASN1_OCTET_STRING *digest;
+} PKCS7_DIGEST;
+
+typedef struct pkcs7_encrypted_st {
+ ASN1_INTEGER *version; /* version 0 */
+ PKCS7_ENC_CONTENT *enc_data;
+} PKCS7_ENCRYPT;
+
+typedef struct pkcs7_st {
+ /*
+ * The following is non NULL if it contains ASN1 encoding of this
+ * structure
+ */
+ unsigned char *asn1;
+ long length;
+# define PKCS7_S_HEADER 0
+# define PKCS7_S_BODY 1
+# define PKCS7_S_TAIL 2
+ int state; /* used during processing */
+ int detached;
+ ASN1_OBJECT *type;
+ /* content as defined by the type */
+ /*
+ * all encryption/message digests are applied to the 'contents', leaving
+ * out the 'type' field.
+ */
+ union {
+ char *ptr;
+ /* NID_pkcs7_data */
+ ASN1_OCTET_STRING *data;
+ /* NID_pkcs7_signed */
+ PKCS7_SIGNED *sign;
+ /* NID_pkcs7_enveloped */
+ PKCS7_ENVELOPE *enveloped;
+ /* NID_pkcs7_signedAndEnveloped */
+ PKCS7_SIGN_ENVELOPE *signed_and_enveloped;
+ /* NID_pkcs7_digest */
+ PKCS7_DIGEST *digest;
+ /* NID_pkcs7_encrypted */
+ PKCS7_ENCRYPT *encrypted;
+ /* Anything else */
+ ASN1_TYPE *other;
+ } d;
+} PKCS7;
+
+DECLARE_STACK_OF(PKCS7)
+DECLARE_ASN1_SET_OF(PKCS7)
+DECLARE_PKCS12_STACK_OF(PKCS7)
+
+# define PKCS7_OP_SET_DETACHED_SIGNATURE 1
+# define PKCS7_OP_GET_DETACHED_SIGNATURE 2
+
+# define PKCS7_get_signed_attributes(si) ((si)->auth_attr)
+# define PKCS7_get_attributes(si) ((si)->unauth_attr)
+
+# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
+# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
+# define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped)
+# define PKCS7_type_is_signedAndEnveloped(a) \
+ (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
+# define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
+# define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
+
+# define PKCS7_set_detached(p,v) \
+ PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
+# define PKCS7_get_detached(p) \
+ PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL)
+
+# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
+
+/* S/MIME related flags */
+
+# define PKCS7_TEXT 0x1
+# define PKCS7_NOCERTS 0x2
+# define PKCS7_NOSIGS 0x4
+# define PKCS7_NOCHAIN 0x8
+# define PKCS7_NOINTERN 0x10
+# define PKCS7_NOVERIFY 0x20
+# define PKCS7_DETACHED 0x40
+# define PKCS7_BINARY 0x80
+# define PKCS7_NOATTR 0x100
+# define PKCS7_NOSMIMECAP 0x200
+# define PKCS7_NOOLDMIMETYPE 0x400
+# define PKCS7_CRLFEOL 0x800
+# define PKCS7_STREAM 0x1000
+# define PKCS7_NOCRL 0x2000
+# define PKCS7_PARTIAL 0x4000
+# define PKCS7_REUSE_DIGEST 0x8000
+
+/* Flags: for compatibility with older code */
+
+# define SMIME_TEXT PKCS7_TEXT
+# define SMIME_NOCERTS PKCS7_NOCERTS
+# define SMIME_NOSIGS PKCS7_NOSIGS
+# define SMIME_NOCHAIN PKCS7_NOCHAIN
+# define SMIME_NOINTERN PKCS7_NOINTERN
+# define SMIME_NOVERIFY PKCS7_NOVERIFY
+# define SMIME_DETACHED PKCS7_DETACHED
+# define SMIME_BINARY PKCS7_BINARY
+# define SMIME_NOATTR PKCS7_NOATTR
+
+DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
+
+int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,
+ const EVP_MD *type, unsigned char *md,
+ unsigned int *len);
+# ifndef OPENSSL_NO_FP_API
+PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7);
+int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7);
+# endif
+PKCS7 *PKCS7_dup(PKCS7 *p7);
+PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7);
+int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7);
+int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
+int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
+
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
+DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
+DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
+DECLARE_ASN1_FUNCTIONS(PKCS7)
+
+DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN)
+DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)
+
+DECLARE_ASN1_NDEF_FUNCTION(PKCS7)
+DECLARE_ASN1_PRINT_FUNCTION(PKCS7)
+
+long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
+
+int PKCS7_set_type(PKCS7 *p7, int type);
+int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other);
+int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+ const EVP_MD *dgst);
+int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si);
+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
+int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
+int PKCS7_content_new(PKCS7 *p7, int nid);
+int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
+ BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
+ X509 *x509);
+
+BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
+int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);
+
+PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
+ EVP_PKEY *pkey, const EVP_MD *dgst);
+X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md);
+STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
+
+PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
+void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
+ X509_ALGOR **pdig, X509_ALGOR **psig);
+void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc);
+int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
+int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
+int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7);
+
+PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
+ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type,
+ void *data);
+int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+ void *value);
+ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid);
+ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid);
+int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
+ STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
+ STACK_OF(X509_ATTRIBUTE) *sk);
+
+PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+ BIO *data, int flags);
+
+PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7,
+ X509 *signcert, EVP_PKEY *pkey,
+ const EVP_MD *md, int flags);
+
+int PKCS7_final(PKCS7 *p7, BIO *data, int flags);
+int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
+ BIO *indata, BIO *out, int flags);
+STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs,
+ int flags);
+PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
+ int flags);
+int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data,
+ int flags);
+
+int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
+ STACK_OF(X509_ALGOR) *cap);
+STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
+int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);
+
+int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid);
+int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t);
+int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
+ const unsigned char *md, int mdlen);
+
+int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
+PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
+
+BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7);
+
+/* 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.
+ */
+void ERR_load_PKCS7_strings(void);
+
+/* Error codes for the PKCS7 functions. */
+
+/* Function codes. */
+# define PKCS7_F_B64_READ_PKCS7 120
+# define PKCS7_F_B64_WRITE_PKCS7 121
+# define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136
+# define PKCS7_F_I2D_PKCS7_BIO_STREAM 140
+# define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135
+# define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118
+# define PKCS7_F_PKCS7_ADD_CERTIFICATE 100
+# define PKCS7_F_PKCS7_ADD_CRL 101
+# define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102
+# define PKCS7_F_PKCS7_ADD_SIGNATURE 131
+# define PKCS7_F_PKCS7_ADD_SIGNER 103
+# define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125
+# define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138
+# define PKCS7_F_PKCS7_CTRL 104
+# define PKCS7_F_PKCS7_DATADECODE 112
+# define PKCS7_F_PKCS7_DATAFINAL 128
+# define PKCS7_F_PKCS7_DATAINIT 105
+# define PKCS7_F_PKCS7_DATASIGN 106
+# define PKCS7_F_PKCS7_DATAVERIFY 107
+# define PKCS7_F_PKCS7_DECRYPT 114
+# define PKCS7_F_PKCS7_DECRYPT_RINFO 133
+# define PKCS7_F_PKCS7_ENCODE_RINFO 132
+# define PKCS7_F_PKCS7_ENCRYPT 115
+# define PKCS7_F_PKCS7_FINAL 134
+# define PKCS7_F_PKCS7_FIND_DIGEST 127
+# define PKCS7_F_PKCS7_GET0_SIGNERS 124
+# define PKCS7_F_PKCS7_RECIP_INFO_SET 130
+# define PKCS7_F_PKCS7_SET_CIPHER 108
+# define PKCS7_F_PKCS7_SET_CONTENT 109
+# define PKCS7_F_PKCS7_SET_DIGEST 126
+# define PKCS7_F_PKCS7_SET_TYPE 110
+# define PKCS7_F_PKCS7_SIGN 116
+# define PKCS7_F_PKCS7_SIGNATUREVERIFY 113
+# define PKCS7_F_PKCS7_SIGNER_INFO_SET 129
+# define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139
+# define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137
+# define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119
+# define PKCS7_F_PKCS7_VERIFY 117
+# define PKCS7_F_SMIME_READ_PKCS7 122
+# define PKCS7_F_SMIME_TEXT 123
+
+/* Reason codes. */
+# define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117
+# define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144
+# define PKCS7_R_CIPHER_NOT_INITIALIZED 116
+# define PKCS7_R_CONTENT_AND_DATA_PRESENT 118
+# define PKCS7_R_CTRL_ERROR 152
+# define PKCS7_R_DECODE_ERROR 130
+# define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100
+# define PKCS7_R_DECRYPT_ERROR 119
+# define PKCS7_R_DIGEST_FAILURE 101
+# define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149
+# define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150
+# define PKCS7_R_ERROR_ADDING_RECIPIENT 120
+# define PKCS7_R_ERROR_SETTING_CIPHER 121
+# define PKCS7_R_INVALID_MIME_TYPE 131
+# define PKCS7_R_INVALID_NULL_POINTER 143
+# define PKCS7_R_INVALID_SIGNED_DATA_TYPE 155
+# define PKCS7_R_MIME_NO_CONTENT_TYPE 132
+# define PKCS7_R_MIME_PARSE_ERROR 133
+# define PKCS7_R_MIME_SIG_PARSE_ERROR 134
+# define PKCS7_R_MISSING_CERIPEND_INFO 103
+# define PKCS7_R_NO_CONTENT 122
+# define PKCS7_R_NO_CONTENT_TYPE 135
+# define PKCS7_R_NO_DEFAULT_DIGEST 151
+# define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154
+# define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136
+# define PKCS7_R_NO_MULTIPART_BOUNDARY 137
+# define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115
+# define PKCS7_R_NO_RECIPIENT_MATCHES_KEY 146
+# define PKCS7_R_NO_SIGNATURES_ON_DATA 123
+# define PKCS7_R_NO_SIGNERS 142
+# define PKCS7_R_NO_SIG_CONTENT_TYPE 138
+# define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104
+# define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124
+# define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153
+# define PKCS7_R_PKCS7_DATAFINAL 126
+# define PKCS7_R_PKCS7_DATAFINAL_ERROR 125
+# define PKCS7_R_PKCS7_DATASIGN 145
+# define PKCS7_R_PKCS7_PARSE_ERROR 139
+# define PKCS7_R_PKCS7_SIG_PARSE_ERROR 140
+# define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127
+# define PKCS7_R_SIGNATURE_FAILURE 105
+# define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128
+# define PKCS7_R_SIGNING_CTRL_FAILURE 147
+# define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148
+# define PKCS7_R_SIG_INVALID_MIME_TYPE 141
+# define PKCS7_R_SMIME_TEXT_ERROR 129
+# define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106
+# define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107
+# define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108
+# define PKCS7_R_UNKNOWN_DIGEST_TYPE 109
+# define PKCS7_R_UNKNOWN_OPERATION 110
+# define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111
+# define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112
+# define PKCS7_R_WRONG_CONTENT_TYPE 113
+# define PKCS7_R_WRONG_PKCS7_TYPE 114
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/rand.h b/openssl/rand.h
new file mode 120000
index 0000000..20283a4
--- /dev/null
+++ b/openssl/rand.h
@@ -0,0 +1 @@
+rand/rand.h
\ No newline at end of file
diff --git a/openssl/rand/rand.h b/openssl/rand/rand.h
new file mode 100644
index 0000000..24c0c88
--- /dev/null
+++ b/openssl/rand/rand.h
@@ -0,0 +1,151 @@
+/* crypto/rand/rand.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RAND_H
+# define HEADER_RAND_H
+
+# include <stdlib.h>
+# include <openssl/ossl_typ.h>
+# include <openssl/e_os2.h>
+
+# if defined(OPENSSL_SYS_WINDOWS)
+# include <windows.h>
+# endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# if defined(OPENSSL_FIPS)
+# define FIPS_RAND_SIZE_T size_t
+# endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct rand_meth_st RAND_METHOD; */
+
+struct rand_meth_st {
+ void (*seed) (const void *buf, int num);
+ int (*bytes) (unsigned char *buf, int num);
+ void (*cleanup) (void);
+ void (*add) (const void *buf, int num, double entropy);
+ int (*pseudorand) (unsigned char *buf, int num);
+ int (*status) (void);
+};
+
+# ifdef BN_DEBUG
+extern int rand_predictable;
+# endif
+
+int RAND_set_rand_method(const RAND_METHOD *meth);
+const RAND_METHOD *RAND_get_rand_method(void);
+# ifndef OPENSSL_NO_ENGINE
+int RAND_set_rand_engine(ENGINE *engine);
+# endif
+RAND_METHOD *RAND_SSLeay(void);
+void RAND_cleanup(void);
+int RAND_bytes(unsigned char *buf, int num);
+int RAND_pseudo_bytes(unsigned char *buf, int num);
+void RAND_seed(const void *buf, int num);
+void RAND_add(const void *buf, int num, double entropy);
+int RAND_load_file(const char *file, long max_bytes);
+int RAND_write_file(const char *file);
+const char *RAND_file_name(char *file, size_t num);
+int RAND_status(void);
+int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
+int RAND_egd(const char *path);
+int RAND_egd_bytes(const char *path, int bytes);
+int RAND_poll(void);
+
+# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+
+void RAND_screen(void);
+int RAND_event(UINT, WPARAM, LPARAM);
+
+# endif
+
+# ifdef OPENSSL_FIPS
+void RAND_set_fips_drbg_type(int type, int flags);
+int RAND_init_fips(void);
+# endif
+
+/* 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.
+ */
+void ERR_load_RAND_strings(void);
+
+/* Error codes for the RAND functions. */
+
+/* Function codes. */
+# define RAND_F_RAND_GET_RAND_METHOD 101
+# define RAND_F_RAND_INIT_FIPS 102
+# define RAND_F_SSLEAY_RAND_BYTES 100
+
+/* Reason codes. */
+# define RAND_R_DUAL_EC_DRBG_DISABLED 104
+# define RAND_R_ERROR_INITIALISING_DRBG 102
+# define RAND_R_ERROR_INSTANTIATING_DRBG 103
+# define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101
+# define RAND_R_PRNG_NOT_SEEDED 100
+# define RAND_R_PRNG_ERROR 108
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/safestack.h b/openssl/safestack.h
new file mode 120000
index 0000000..908008d
--- /dev/null
+++ b/openssl/safestack.h
@@ -0,0 +1 @@
+stack/safestack.h
\ No newline at end of file
diff --git a/openssl/sha.h b/openssl/sha.h
new file mode 120000
index 0000000..c88e890
--- /dev/null
+++ b/openssl/sha.h
@@ -0,0 +1 @@
+sha/sha.h
\ No newline at end of file
diff --git a/openssl/sha/sha.h b/openssl/sha/sha.h
new file mode 100644
index 0000000..e5169e4
--- /dev/null
+++ b/openssl/sha/sha.h
@@ -0,0 +1,214 @@
+/* crypto/sha/sha.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SHA_H
+# define HEADER_SHA_H
+
+# include <openssl/e_os2.h>
+# include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1))
+# error SHA is disabled.
+# endif
+
+# if defined(OPENSSL_FIPS)
+# define FIPS_SHA_SIZE_T size_t
+# endif
+
+/*-
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! SHA_LONG_LOG2 has to be defined along. !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+# if defined(__LP32__)
+# define SHA_LONG unsigned long
+# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+# define SHA_LONG unsigned long
+# define SHA_LONG_LOG2 3
+# else
+# define SHA_LONG unsigned int
+# endif
+
+# define SHA_LBLOCK 16
+# define SHA_CBLOCK (SHA_LBLOCK*4)/* SHA treats input data as a
+ * contiguous array of 32 bit wide
+ * big-endian values. */
+# define SHA_LAST_BLOCK (SHA_CBLOCK-8)
+# define SHA_DIGEST_LENGTH 20
+
+typedef struct SHAstate_st {
+ SHA_LONG h0, h1, h2, h3, h4;
+ SHA_LONG Nl, Nh;
+ SHA_LONG data[SHA_LBLOCK];
+ unsigned int num;
+} SHA_CTX;
+
+# ifndef OPENSSL_NO_SHA0
+# ifdef OPENSSL_FIPS
+int private_SHA_Init(SHA_CTX *c);
+# endif
+int SHA_Init(SHA_CTX *c);
+int SHA_Update(SHA_CTX *c, const void *data, size_t len);
+int SHA_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md);
+void SHA_Transform(SHA_CTX *c, const unsigned char *data);
+# endif
+# ifndef OPENSSL_NO_SHA1
+# ifdef OPENSSL_FIPS
+int private_SHA1_Init(SHA_CTX *c);
+# endif
+int SHA1_Init(SHA_CTX *c);
+int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
+int SHA1_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md);
+void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
+# endif
+
+# define SHA256_CBLOCK (SHA_LBLOCK*4)/* SHA-256 treats input data as a
+ * contiguous array of 32 bit wide
+ * big-endian values. */
+# define SHA224_DIGEST_LENGTH 28
+# define SHA256_DIGEST_LENGTH 32
+
+typedef struct SHA256state_st {
+ SHA_LONG h[8];
+ SHA_LONG Nl, Nh;
+ SHA_LONG data[SHA_LBLOCK];
+ unsigned int num, md_len;
+} SHA256_CTX;
+
+# ifndef OPENSSL_NO_SHA256
+# ifdef OPENSSL_FIPS
+int private_SHA224_Init(SHA256_CTX *c);
+int private_SHA256_Init(SHA256_CTX *c);
+# endif
+int SHA224_Init(SHA256_CTX *c);
+int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
+int SHA224_Final(unsigned char *md, SHA256_CTX *c);
+unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md);
+int SHA256_Init(SHA256_CTX *c);
+int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
+int SHA256_Final(unsigned char *md, SHA256_CTX *c);
+unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md);
+void SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
+# endif
+
+# define SHA384_DIGEST_LENGTH 48
+# define SHA512_DIGEST_LENGTH 64
+
+# ifndef OPENSSL_NO_SHA512
+/*
+ * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
+ * being exactly 64-bit wide. See Implementation Notes in sha512.c
+ * for further details.
+ */
+/*
+ * SHA-512 treats input data as a
+ * contiguous array of 64 bit
+ * wide big-endian values.
+ */
+# define SHA512_CBLOCK (SHA_LBLOCK*8)
+# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+# define SHA_LONG64 unsigned __int64
+# define U64(C) C##UI64
+# elif defined(__arch64__)
+# define SHA_LONG64 unsigned long
+# define U64(C) C##UL
+# else
+# define SHA_LONG64 unsigned long long
+# define U64(C) C##ULL
+# endif
+
+typedef struct SHA512state_st {
+ SHA_LONG64 h[8];
+ SHA_LONG64 Nl, Nh;
+ union {
+ SHA_LONG64 d[SHA_LBLOCK];
+ unsigned char p[SHA512_CBLOCK];
+ } u;
+ unsigned int num, md_len;
+} SHA512_CTX;
+# endif
+
+# ifndef OPENSSL_NO_SHA512
+# ifdef OPENSSL_FIPS
+int private_SHA384_Init(SHA512_CTX *c);
+int private_SHA512_Init(SHA512_CTX *c);
+# endif
+int SHA384_Init(SHA512_CTX *c);
+int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
+int SHA384_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md);
+int SHA512_Init(SHA512_CTX *c);
+int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
+int SHA512_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md);
+void SHA512_Transform(SHA512_CTX *c, const unsigned char *data);
+# endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/sha/sha_locl.h b/openssl/sha/sha_locl.h
new file mode 100644
index 0000000..03bd411
--- /dev/null
+++ b/openssl/sha/sha_locl.h
@@ -0,0 +1,500 @@
+/* crypto/sha/sha_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h>
+#include <openssl/sha.h>
+
+#define DATA_ORDER_IS_BIG_ENDIAN
+
+#define HASH_LONG SHA_LONG
+#define HASH_CTX SHA_CTX
+#define HASH_CBLOCK SHA_CBLOCK
+#define HASH_MAKE_STRING(c,s) do { \
+ unsigned long ll; \
+ ll=(c)->h0; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->h1; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->h2; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->h3; (void)HOST_l2c(ll,(s)); \
+ ll=(c)->h4; (void)HOST_l2c(ll,(s)); \
+ } while (0)
+
+#if defined(SHA_0)
+
+# define HASH_UPDATE SHA_Update
+# define HASH_TRANSFORM SHA_Transform
+# define HASH_FINAL SHA_Final
+# define HASH_INIT SHA_Init
+# define HASH_BLOCK_DATA_ORDER sha_block_data_order
+# define Xupdate(a,ix,ia,ib,ic,id) (ix=(a)=(ia^ib^ic^id))
+
+static void sha_block_data_order(SHA_CTX *c, const void *p, size_t num);
+
+#elif defined(SHA_1)
+
+# define HASH_UPDATE SHA1_Update
+# define HASH_TRANSFORM SHA1_Transform
+# define HASH_FINAL SHA1_Final
+# define HASH_INIT SHA1_Init
+# define HASH_BLOCK_DATA_ORDER sha1_block_data_order
+# if defined(__MWERKS__) && defined(__MC68K__)
+ /* Metrowerks for Motorola fails otherwise:-( <appro@fy.chalmers.se> */
+# define Xupdate(a,ix,ia,ib,ic,id) do { (a)=(ia^ib^ic^id); \
+ ix=(a)=ROTATE((a),1); \
+ } while (0)
+# else
+# define Xupdate(a,ix,ia,ib,ic,id) ( (a)=(ia^ib^ic^id), \
+ ix=(a)=ROTATE((a),1) \
+ )
+# endif
+
+# ifndef SHA1_ASM
+static
+# endif
+void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num);
+
+#else
+# error "Either SHA_0 or SHA_1 must be defined."
+#endif
+
+#include "md32_common.h"
+
+#define INIT_DATA_h0 0x67452301UL
+#define INIT_DATA_h1 0xefcdab89UL
+#define INIT_DATA_h2 0x98badcfeUL
+#define INIT_DATA_h3 0x10325476UL
+#define INIT_DATA_h4 0xc3d2e1f0UL
+
+#ifdef SHA_0
+fips_md_init(SHA)
+#else
+fips_md_init_ctx(SHA1, SHA)
+#endif
+{
+ memset(c, 0, sizeof(*c));
+ c->h0 = INIT_DATA_h0;
+ c->h1 = INIT_DATA_h1;
+ c->h2 = INIT_DATA_h2;
+ c->h3 = INIT_DATA_h3;
+ c->h4 = INIT_DATA_h4;
+ return 1;
+}
+
+#define K_00_19 0x5a827999UL
+#define K_20_39 0x6ed9eba1UL
+#define K_40_59 0x8f1bbcdcUL
+#define K_60_79 0xca62c1d6UL
+
+/*
+ * As pointed out by Wei Dai <weidai@eskimo.com>, F() below can be simplified
+ * to the code in F_00_19. Wei attributes these optimisations to Peter
+ * Gutmann's SHS code, and he attributes it to Rich Schroeppel. #define
+ * F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) I've just become aware of another
+ * tweak to be made, again from Wei Dai, in F_40_59, (x&a)|(y&a) -> (x|y)&a
+ */
+#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
+#define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
+#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d)))
+#define F_60_79(b,c,d) F_20_39(b,c,d)
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+
+# define BODY_00_15(i,a,b,c,d,e,f,xi) \
+ (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+# define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+ Xupdate(f,xi,xa,xb,xc,xd); \
+ (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+# define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+ Xupdate(f,xi,xa,xb,xc,xd); \
+ (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+# define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+ Xupdate(f,xa,xa,xb,xc,xd); \
+ (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+# define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+ Xupdate(f,xa,xa,xb,xc,xd); \
+ (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+# define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+ Xupdate(f,xa,xa,xb,xc,xd); \
+ (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
+ (b)=ROTATE((b),30);
+
+# ifdef X
+# undef X
+# endif
+# ifndef MD32_XARRAY
+ /*
+ * Originally X was an array. As it's automatic it's natural
+ * to expect RISC compiler to accomodate at least part of it in
+ * the register bank, isn't it? Unfortunately not all compilers
+ * "find" this expectation reasonable:-( On order to make such
+ * compilers generate better code I replace X[] with a bunch of
+ * X0, X1, etc. See the function body below...
+ * <appro@fy.chalmers.se>
+ */
+# define X(i) XX##i
+# else
+ /*
+ * However! Some compilers (most notably HP C) get overwhelmed by
+ * that many local variables so that we have to have the way to
+ * fall down to the original behavior.
+ */
+# define X(i) XX[i]
+# endif
+
+# if !defined(SHA_1) || !defined(SHA1_ASM)
+static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num)
+{
+ const unsigned char *data = p;
+ register unsigned MD32_REG_T A, B, C, D, E, T, l;
+# ifndef MD32_XARRAY
+ unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+ XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
+# else
+ SHA_LONG XX[16];
+# endif
+
+ A = c->h0;
+ B = c->h1;
+ C = c->h2;
+ D = c->h3;
+ E = c->h4;
+
+ for (;;) {
+ const union {
+ long one;
+ char little;
+ } is_endian = {
+ 1
+ };
+
+ if (!is_endian.little && sizeof(SHA_LONG) == 4
+ && ((size_t)p % 4) == 0) {
+ const SHA_LONG *W = (const SHA_LONG *)data;
+
+ X(0) = W[0];
+ X(1) = W[1];
+ BODY_00_15(0, A, B, C, D, E, T, X(0));
+ X(2) = W[2];
+ BODY_00_15(1, T, A, B, C, D, E, X(1));
+ X(3) = W[3];
+ BODY_00_15(2, E, T, A, B, C, D, X(2));
+ X(4) = W[4];
+ BODY_00_15(3, D, E, T, A, B, C, X(3));
+ X(5) = W[5];
+ BODY_00_15(4, C, D, E, T, A, B, X(4));
+ X(6) = W[6];
+ BODY_00_15(5, B, C, D, E, T, A, X(5));
+ X(7) = W[7];
+ BODY_00_15(6, A, B, C, D, E, T, X(6));
+ X(8) = W[8];
+ BODY_00_15(7, T, A, B, C, D, E, X(7));
+ X(9) = W[9];
+ BODY_00_15(8, E, T, A, B, C, D, X(8));
+ X(10) = W[10];
+ BODY_00_15(9, D, E, T, A, B, C, X(9));
+ X(11) = W[11];
+ BODY_00_15(10, C, D, E, T, A, B, X(10));
+ X(12) = W[12];
+ BODY_00_15(11, B, C, D, E, T, A, X(11));
+ X(13) = W[13];
+ BODY_00_15(12, A, B, C, D, E, T, X(12));
+ X(14) = W[14];
+ BODY_00_15(13, T, A, B, C, D, E, X(13));
+ X(15) = W[15];
+ BODY_00_15(14, E, T, A, B, C, D, X(14));
+ BODY_00_15(15, D, E, T, A, B, C, X(15));
+
+ data += SHA_CBLOCK;
+ } else {
+ (void)HOST_c2l(data, l);
+ X(0) = l;
+ (void)HOST_c2l(data, l);
+ X(1) = l;
+ BODY_00_15(0, A, B, C, D, E, T, X(0));
+ (void)HOST_c2l(data, l);
+ X(2) = l;
+ BODY_00_15(1, T, A, B, C, D, E, X(1));
+ (void)HOST_c2l(data, l);
+ X(3) = l;
+ BODY_00_15(2, E, T, A, B, C, D, X(2));
+ (void)HOST_c2l(data, l);
+ X(4) = l;
+ BODY_00_15(3, D, E, T, A, B, C, X(3));
+ (void)HOST_c2l(data, l);
+ X(5) = l;
+ BODY_00_15(4, C, D, E, T, A, B, X(4));
+ (void)HOST_c2l(data, l);
+ X(6) = l;
+ BODY_00_15(5, B, C, D, E, T, A, X(5));
+ (void)HOST_c2l(data, l);
+ X(7) = l;
+ BODY_00_15(6, A, B, C, D, E, T, X(6));
+ (void)HOST_c2l(data, l);
+ X(8) = l;
+ BODY_00_15(7, T, A, B, C, D, E, X(7));
+ (void)HOST_c2l(data, l);
+ X(9) = l;
+ BODY_00_15(8, E, T, A, B, C, D, X(8));
+ (void)HOST_c2l(data, l);
+ X(10) = l;
+ BODY_00_15(9, D, E, T, A, B, C, X(9));
+ (void)HOST_c2l(data, l);
+ X(11) = l;
+ BODY_00_15(10, C, D, E, T, A, B, X(10));
+ (void)HOST_c2l(data, l);
+ X(12) = l;
+ BODY_00_15(11, B, C, D, E, T, A, X(11));
+ (void)HOST_c2l(data, l);
+ X(13) = l;
+ BODY_00_15(12, A, B, C, D, E, T, X(12));
+ (void)HOST_c2l(data, l);
+ X(14) = l;
+ BODY_00_15(13, T, A, B, C, D, E, X(13));
+ (void)HOST_c2l(data, l);
+ X(15) = l;
+ BODY_00_15(14, E, T, A, B, C, D, X(14));
+ BODY_00_15(15, D, E, T, A, B, C, X(15));
+ }
+
+ BODY_16_19(16, C, D, E, T, A, B, X(0), X(0), X(2), X(8), X(13));
+ BODY_16_19(17, B, C, D, E, T, A, X(1), X(1), X(3), X(9), X(14));
+ BODY_16_19(18, A, B, C, D, E, T, X(2), X(2), X(4), X(10), X(15));
+ BODY_16_19(19, T, A, B, C, D, E, X(3), X(3), X(5), X(11), X(0));
+
+ BODY_20_31(20, E, T, A, B, C, D, X(4), X(4), X(6), X(12), X(1));
+ BODY_20_31(21, D, E, T, A, B, C, X(5), X(5), X(7), X(13), X(2));
+ BODY_20_31(22, C, D, E, T, A, B, X(6), X(6), X(8), X(14), X(3));
+ BODY_20_31(23, B, C, D, E, T, A, X(7), X(7), X(9), X(15), X(4));
+ BODY_20_31(24, A, B, C, D, E, T, X(8), X(8), X(10), X(0), X(5));
+ BODY_20_31(25, T, A, B, C, D, E, X(9), X(9), X(11), X(1), X(6));
+ BODY_20_31(26, E, T, A, B, C, D, X(10), X(10), X(12), X(2), X(7));
+ BODY_20_31(27, D, E, T, A, B, C, X(11), X(11), X(13), X(3), X(8));
+ BODY_20_31(28, C, D, E, T, A, B, X(12), X(12), X(14), X(4), X(9));
+ BODY_20_31(29, B, C, D, E, T, A, X(13), X(13), X(15), X(5), X(10));
+ BODY_20_31(30, A, B, C, D, E, T, X(14), X(14), X(0), X(6), X(11));
+ BODY_20_31(31, T, A, B, C, D, E, X(15), X(15), X(1), X(7), X(12));
+
+ BODY_32_39(32, E, T, A, B, C, D, X(0), X(2), X(8), X(13));
+ BODY_32_39(33, D, E, T, A, B, C, X(1), X(3), X(9), X(14));
+ BODY_32_39(34, C, D, E, T, A, B, X(2), X(4), X(10), X(15));
+ BODY_32_39(35, B, C, D, E, T, A, X(3), X(5), X(11), X(0));
+ BODY_32_39(36, A, B, C, D, E, T, X(4), X(6), X(12), X(1));
+ BODY_32_39(37, T, A, B, C, D, E, X(5), X(7), X(13), X(2));
+ BODY_32_39(38, E, T, A, B, C, D, X(6), X(8), X(14), X(3));
+ BODY_32_39(39, D, E, T, A, B, C, X(7), X(9), X(15), X(4));
+
+ BODY_40_59(40, C, D, E, T, A, B, X(8), X(10), X(0), X(5));
+ BODY_40_59(41, B, C, D, E, T, A, X(9), X(11), X(1), X(6));
+ BODY_40_59(42, A, B, C, D, E, T, X(10), X(12), X(2), X(7));
+ BODY_40_59(43, T, A, B, C, D, E, X(11), X(13), X(3), X(8));
+ BODY_40_59(44, E, T, A, B, C, D, X(12), X(14), X(4), X(9));
+ BODY_40_59(45, D, E, T, A, B, C, X(13), X(15), X(5), X(10));
+ BODY_40_59(46, C, D, E, T, A, B, X(14), X(0), X(6), X(11));
+ BODY_40_59(47, B, C, D, E, T, A, X(15), X(1), X(7), X(12));
+ BODY_40_59(48, A, B, C, D, E, T, X(0), X(2), X(8), X(13));
+ BODY_40_59(49, T, A, B, C, D, E, X(1), X(3), X(9), X(14));
+ BODY_40_59(50, E, T, A, B, C, D, X(2), X(4), X(10), X(15));
+ BODY_40_59(51, D, E, T, A, B, C, X(3), X(5), X(11), X(0));
+ BODY_40_59(52, C, D, E, T, A, B, X(4), X(6), X(12), X(1));
+ BODY_40_59(53, B, C, D, E, T, A, X(5), X(7), X(13), X(2));
+ BODY_40_59(54, A, B, C, D, E, T, X(6), X(8), X(14), X(3));
+ BODY_40_59(55, T, A, B, C, D, E, X(7), X(9), X(15), X(4));
+ BODY_40_59(56, E, T, A, B, C, D, X(8), X(10), X(0), X(5));
+ BODY_40_59(57, D, E, T, A, B, C, X(9), X(11), X(1), X(6));
+ BODY_40_59(58, C, D, E, T, A, B, X(10), X(12), X(2), X(7));
+ BODY_40_59(59, B, C, D, E, T, A, X(11), X(13), X(3), X(8));
+
+ BODY_60_79(60, A, B, C, D, E, T, X(12), X(14), X(4), X(9));
+ BODY_60_79(61, T, A, B, C, D, E, X(13), X(15), X(5), X(10));
+ BODY_60_79(62, E, T, A, B, C, D, X(14), X(0), X(6), X(11));
+ BODY_60_79(63, D, E, T, A, B, C, X(15), X(1), X(7), X(12));
+ BODY_60_79(64, C, D, E, T, A, B, X(0), X(2), X(8), X(13));
+ BODY_60_79(65, B, C, D, E, T, A, X(1), X(3), X(9), X(14));
+ BODY_60_79(66, A, B, C, D, E, T, X(2), X(4), X(10), X(15));
+ BODY_60_79(67, T, A, B, C, D, E, X(3), X(5), X(11), X(0));
+ BODY_60_79(68, E, T, A, B, C, D, X(4), X(6), X(12), X(1));
+ BODY_60_79(69, D, E, T, A, B, C, X(5), X(7), X(13), X(2));
+ BODY_60_79(70, C, D, E, T, A, B, X(6), X(8), X(14), X(3));
+ BODY_60_79(71, B, C, D, E, T, A, X(7), X(9), X(15), X(4));
+ BODY_60_79(72, A, B, C, D, E, T, X(8), X(10), X(0), X(5));
+ BODY_60_79(73, T, A, B, C, D, E, X(9), X(11), X(1), X(6));
+ BODY_60_79(74, E, T, A, B, C, D, X(10), X(12), X(2), X(7));
+ BODY_60_79(75, D, E, T, A, B, C, X(11), X(13), X(3), X(8));
+ BODY_60_79(76, C, D, E, T, A, B, X(12), X(14), X(4), X(9));
+ BODY_60_79(77, B, C, D, E, T, A, X(13), X(15), X(5), X(10));
+ BODY_60_79(78, A, B, C, D, E, T, X(14), X(0), X(6), X(11));
+ BODY_60_79(79, T, A, B, C, D, E, X(15), X(1), X(7), X(12));
+
+ c->h0 = (c->h0 + E) & 0xffffffffL;
+ c->h1 = (c->h1 + T) & 0xffffffffL;
+ c->h2 = (c->h2 + A) & 0xffffffffL;
+ c->h3 = (c->h3 + B) & 0xffffffffL;
+ c->h4 = (c->h4 + C) & 0xffffffffL;
+
+ if (--num == 0)
+ break;
+
+ A = c->h0;
+ B = c->h1;
+ C = c->h2;
+ D = c->h3;
+ E = c->h4;
+
+ }
+}
+# endif
+
+#else /* OPENSSL_SMALL_FOOTPRINT */
+
+# define BODY_00_15(xi) do { \
+ T=E+K_00_19+F_00_19(B,C,D); \
+ E=D, D=C, C=ROTATE(B,30), B=A; \
+ A=ROTATE(A,5)+T+xi; } while(0)
+
+# define BODY_16_19(xa,xb,xc,xd) do { \
+ Xupdate(T,xa,xa,xb,xc,xd); \
+ T+=E+K_00_19+F_00_19(B,C,D); \
+ E=D, D=C, C=ROTATE(B,30), B=A; \
+ A=ROTATE(A,5)+T; } while(0)
+
+# define BODY_20_39(xa,xb,xc,xd) do { \
+ Xupdate(T,xa,xa,xb,xc,xd); \
+ T+=E+K_20_39+F_20_39(B,C,D); \
+ E=D, D=C, C=ROTATE(B,30), B=A; \
+ A=ROTATE(A,5)+T; } while(0)
+
+# define BODY_40_59(xa,xb,xc,xd) do { \
+ Xupdate(T,xa,xa,xb,xc,xd); \
+ T+=E+K_40_59+F_40_59(B,C,D); \
+ E=D, D=C, C=ROTATE(B,30), B=A; \
+ A=ROTATE(A,5)+T; } while(0)
+
+# define BODY_60_79(xa,xb,xc,xd) do { \
+ Xupdate(T,xa,xa,xb,xc,xd); \
+ T=E+K_60_79+F_60_79(B,C,D); \
+ E=D, D=C, C=ROTATE(B,30), B=A; \
+ A=ROTATE(A,5)+T+xa; } while(0)
+
+# if !defined(SHA_1) || !defined(SHA1_ASM)
+static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num)
+{
+ const unsigned char *data = p;
+ register unsigned MD32_REG_T A, B, C, D, E, T, l;
+ int i;
+ SHA_LONG X[16];
+
+ A = c->h0;
+ B = c->h1;
+ C = c->h2;
+ D = c->h3;
+ E = c->h4;
+
+ for (;;) {
+ for (i = 0; i < 16; i++) {
+ HOST_c2l(data, l);
+ X[i] = l;
+ BODY_00_15(X[i]);
+ }
+ for (i = 0; i < 4; i++) {
+ BODY_16_19(X[i], X[i + 2], X[i + 8], X[(i + 13) & 15]);
+ }
+ for (; i < 24; i++) {
+ BODY_20_39(X[i & 15], X[(i + 2) & 15], X[(i + 8) & 15],
+ X[(i + 13) & 15]);
+ }
+ for (i = 0; i < 20; i++) {
+ BODY_40_59(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15],
+ X[(i + 5) & 15]);
+ }
+ for (i = 4; i < 24; i++) {
+ BODY_60_79(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15],
+ X[(i + 5) & 15]);
+ }
+
+ c->h0 = (c->h0 + A) & 0xffffffffL;
+ c->h1 = (c->h1 + B) & 0xffffffffL;
+ c->h2 = (c->h2 + C) & 0xffffffffL;
+ c->h3 = (c->h3 + D) & 0xffffffffL;
+ c->h4 = (c->h4 + E) & 0xffffffffL;
+
+ if (--num == 0)
+ break;
+
+ A = c->h0;
+ B = c->h1;
+ C = c->h2;
+ D = c->h3;
+ E = c->h4;
+
+ }
+}
+# endif
+
+#endif
diff --git a/openssl/stack.h b/openssl/stack.h
new file mode 120000
index 0000000..a7f88ef
--- /dev/null
+++ b/openssl/stack.h
@@ -0,0 +1 @@
+stack/stack.h
\ No newline at end of file
diff --git a/openssl/stack/safestack.h b/openssl/stack/safestack.h
new file mode 100644
index 0000000..519649b
--- /dev/null
+++ b/openssl/stack/safestack.h
@@ -0,0 +1,2536 @@
+/* ====================================================================
+ * Copyright (c) 1999 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 HEADER_SAFESTACK_H
+# define HEADER_SAFESTACK_H
+
+# include <openssl/stack.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# ifndef CHECKED_PTR_OF
+# define CHECKED_PTR_OF(type, p) \
+ ((void*) (1 ? p : (type*)0))
+# endif
+
+/*
+ * In C++ we get problems because an explicit cast is needed from (void *) we
+ * use CHECKED_STACK_OF to ensure the correct type is passed in the macros
+ * below.
+ */
+
+# define CHECKED_STACK_OF(type, p) \
+ ((_STACK*) (1 ? p : (STACK_OF(type)*)0))
+
+# define CHECKED_SK_FREE_FUNC(type, p) \
+ ((void (*)(void *)) ((1 ? p : (void (*)(type *))0)))
+
+# define CHECKED_SK_FREE_FUNC2(type, p) \
+ ((void (*)(void *)) ((1 ? p : (void (*)(type))0)))
+
+# define CHECKED_SK_CMP_FUNC(type, p) \
+ ((int (*)(const void *, const void *)) \
+ ((1 ? p : (int (*)(const type * const *, const type * const *))0)))
+
+# define STACK_OF(type) struct stack_st_##type
+# define PREDECLARE_STACK_OF(type) STACK_OF(type);
+
+# define DECLARE_STACK_OF(type) \
+STACK_OF(type) \
+ { \
+ _STACK stack; \
+ };
+# define DECLARE_SPECIAL_STACK_OF(type, type2) \
+STACK_OF(type) \
+ { \
+ _STACK stack; \
+ };
+
+/* nada (obsolete in new safestack approach)*/
+# define IMPLEMENT_STACK_OF(type)
+
+/*-
+ * Strings are special: normally an lhash entry will point to a single
+ * (somewhat) mutable object. In the case of strings:
+ *
+ * a) Instead of a single char, there is an array of chars, NUL-terminated.
+ * b) The string may have be immutable.
+ *
+ * So, they need their own declarations. Especially important for
+ * type-checking tools, such as Deputy.
+ *
+ * In practice, however, it appears to be hard to have a const
+ * string. For now, I'm settling for dealing with the fact it is a
+ * string at all.
+ */
+typedef char *OPENSSL_STRING;
+
+typedef const char *OPENSSL_CSTRING;
+
+/*
+ * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but
+ * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned
+ * above, instead of a single char each entry is a NUL-terminated array of
+ * chars. So, we have to implement STRING specially for STACK_OF. This is
+ * dealt with in the autogenerated macros below.
+ */
+
+DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
+
+/*
+ * Similarly, we sometimes use a block of characters, NOT nul-terminated.
+ * These should also be distinguished from "normal" stacks.
+ */
+typedef void *OPENSSL_BLOCK;
+DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
+
+/*
+ * SKM_sk_... stack macros are internal to safestack.h: never use them
+ * directly, use sk_<type>_... instead
+ */
+# define SKM_sk_new(type, cmp) \
+ ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp)))
+# define SKM_sk_new_null(type) \
+ ((STACK_OF(type) *)sk_new_null())
+# define SKM_sk_free(type, st) \
+ sk_free(CHECKED_STACK_OF(type, st))
+# define SKM_sk_num(type, st) \
+ sk_num(CHECKED_STACK_OF(type, st))
+# define SKM_sk_value(type, st,i) \
+ ((type *)sk_value(CHECKED_STACK_OF(type, st), i))
+# define SKM_sk_set(type, st,i,val) \
+ sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val))
+# define SKM_sk_zero(type, st) \
+ sk_zero(CHECKED_STACK_OF(type, st))
+# define SKM_sk_push(type, st, val) \
+ sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+# define SKM_sk_unshift(type, st, val) \
+ sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+# define SKM_sk_find(type, st, val) \
+ sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val))
+# define SKM_sk_find_ex(type, st, val) \
+ sk_find_ex(CHECKED_STACK_OF(type, st), \
+ CHECKED_PTR_OF(type, val))
+# define SKM_sk_delete(type, st, i) \
+ (type *)sk_delete(CHECKED_STACK_OF(type, st), i)
+# define SKM_sk_delete_ptr(type, st, ptr) \
+ (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr))
+# define SKM_sk_insert(type, st,val, i) \
+ sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i)
+# define SKM_sk_set_cmp_func(type, st, cmp) \
+ ((int (*)(const type * const *,const type * const *)) \
+ sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp)))
+# define SKM_sk_dup(type, st) \
+ (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st))
+# define SKM_sk_pop_free(type, st, free_func) \
+ sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func))
+# define SKM_sk_shift(type, st) \
+ (type *)sk_shift(CHECKED_STACK_OF(type, st))
+# define SKM_sk_pop(type, st) \
+ (type *)sk_pop(CHECKED_STACK_OF(type, st))
+# define SKM_sk_sort(type, st) \
+ sk_sort(CHECKED_STACK_OF(type, st))
+# define SKM_sk_is_sorted(type, st) \
+ sk_is_sorted(CHECKED_STACK_OF(type, st))
+# define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ (STACK_OF(type) *)d2i_ASN1_SET( \
+ (STACK_OF(OPENSSL_BLOCK) **)CHECKED_PTR_OF(STACK_OF(type)*, st), \
+ pp, length, \
+ CHECKED_D2I_OF(type, d2i_func), \
+ CHECKED_SK_FREE_FUNC(type, free_func), \
+ ex_tag, ex_class)
+# define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \
+ CHECKED_I2D_OF(type, i2d_func), \
+ ex_tag, ex_class, is_set)
+# define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
+ ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \
+ CHECKED_I2D_OF(type, i2d_func), buf, len)
+# define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
+ (STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func))
+# define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
+ (STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \
+ CHECKED_D2I_OF(type, d2i_func), \
+ CHECKED_SK_FREE_FUNC(type, free_func), \
+ pass, passlen, oct, seq)
+/*
+ * This block of defines is updated by util/mkstack.pl, please do not touch!
+ */
+# define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp))
+# define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION)
+# define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st))
+# define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st))
+# define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i))
+# define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val))
+# define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st))
+# define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val))
+# define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val))
+# define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val))
+# define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val))
+# define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i))
+# define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr))
+# define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i))
+# define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp))
+# define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st)
+# define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func))
+# define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st))
+# define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st))
+# define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
+# define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
+# define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp))
+# define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange)
+# define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st))
+# define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st))
+# define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i))
+# define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val))
+# define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st))
+# define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val))
+# define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val))
+# define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val))
+# define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val))
+# define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i))
+# define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr))
+# define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i))
+# define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp))
+# define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st)
+# define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func))
+# define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st))
+# define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st))
+# define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st))
+# define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st))
+# define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp))
+# define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
+# define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i))
+# define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val))
+# define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val))
+# define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val))
+# define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val))
+# define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val))
+# define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i))
+# define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr))
+# define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i))
+# define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp))
+# define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st)
+# define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func))
+# define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st))
+# define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp))
+# define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER)
+# define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st))
+# define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st))
+# define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i))
+# define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val))
+# define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st))
+# define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val))
+# define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val))
+# define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val))
+# define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val))
+# define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i))
+# define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr))
+# define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i))
+# define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp))
+# define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st)
+# define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func))
+# define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st))
+# define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st))
+# define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st))
+# define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st))
+# define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp))
+# define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT)
+# define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st))
+# define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st))
+# define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i))
+# define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val))
+# define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st))
+# define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val))
+# define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val))
+# define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val))
+# define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val))
+# define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i))
+# define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr))
+# define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i))
+# define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp))
+# define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st)
+# define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func))
+# define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st))
+# define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st))
+# define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st))
+# define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st))
+# define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp))
+# define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE)
+# define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i))
+# define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val))
+# define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val))
+# define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val))
+# define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val))
+# define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val))
+# define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i))
+# define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr))
+# define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i))
+# define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp))
+# define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st)
+# define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func))
+# define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st))
+# define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp))
+# define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE)
+# define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st))
+# define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st))
+# define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i))
+# define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val))
+# define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st))
+# define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val))
+# define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val))
+# define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val))
+# define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val))
+# define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i))
+# define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr))
+# define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i))
+# define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp))
+# define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st)
+# define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func))
+# define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st))
+# define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st))
+# define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st))
+# define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st))
+# define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp))
+# define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING)
+# define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st))
+# define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st))
+# define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i))
+# define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val))
+# define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st))
+# define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val))
+# define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val))
+# define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val))
+# define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val))
+# define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i))
+# define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr))
+# define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i))
+# define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp))
+# define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st)
+# define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func))
+# define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st))
+# define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st))
+# define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st))
+# define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st))
+# define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp))
+# define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE)
+# define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st))
+# define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st))
+# define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i))
+# define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val))
+# define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st))
+# define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val))
+# define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val))
+# define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val))
+# define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val))
+# define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i))
+# define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr))
+# define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i))
+# define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp))
+# define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st)
+# define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func))
+# define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st))
+# define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st))
+# define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st))
+# define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st))
+# define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp))
+# define sk_BIO_new_null() SKM_sk_new_null(BIO)
+# define sk_BIO_free(st) SKM_sk_free(BIO, (st))
+# define sk_BIO_num(st) SKM_sk_num(BIO, (st))
+# define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i))
+# define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val))
+# define sk_BIO_zero(st) SKM_sk_zero(BIO, (st))
+# define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val))
+# define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val))
+# define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val))
+# define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val))
+# define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i))
+# define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr))
+# define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i))
+# define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp))
+# define sk_BIO_dup(st) SKM_sk_dup(BIO, st)
+# define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func))
+# define sk_BIO_shift(st) SKM_sk_shift(BIO, (st))
+# define sk_BIO_pop(st) SKM_sk_pop(BIO, (st))
+# define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
+# define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
+# define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp))
+# define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY)
+# define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i))
+# define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val))
+# define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val))
+# define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val))
+# define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val))
+# define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val))
+# define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i))
+# define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr))
+# define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i))
+# define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp))
+# define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st)
+# define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func))
+# define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st))
+# define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp))
+# define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH)
+# define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st))
+# define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st))
+# define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i))
+# define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val))
+# define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st))
+# define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val))
+# define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val))
+# define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val))
+# define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val))
+# define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i))
+# define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr))
+# define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i))
+# define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp))
+# define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st)
+# define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func))
+# define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st))
+# define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st))
+# define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st))
+# define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st))
+# define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp))
+# define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices)
+# define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st))
+# define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st))
+# define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i))
+# define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val))
+# define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st))
+# define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val))
+# define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val))
+# define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val))
+# define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val))
+# define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i))
+# define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr))
+# define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i))
+# define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp))
+# define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st)
+# define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func))
+# define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st))
+# define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st))
+# define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st))
+# define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st))
+# define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp))
+# define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo)
+# define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st))
+# define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st))
+# define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i))
+# define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val))
+# define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st))
+# define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val))
+# define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val))
+# define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val))
+# define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val))
+# define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i))
+# define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr))
+# define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i))
+# define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp))
+# define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st)
+# define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func))
+# define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st))
+# define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st))
+# define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st))
+# define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st))
+# define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp))
+# define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice)
+# define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i))
+# define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val))
+# define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val))
+# define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val))
+# define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val))
+# define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val))
+# define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i))
+# define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr))
+# define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i))
+# define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp))
+# define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st)
+# define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func))
+# define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st))
+# define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp))
+# define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo)
+# define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st))
+# define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st))
+# define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i))
+# define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val))
+# define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st))
+# define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val))
+# define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val))
+# define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val))
+# define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val))
+# define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i))
+# define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr))
+# define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i))
+# define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp))
+# define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st)
+# define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func))
+# define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st))
+# define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st))
+# define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st))
+# define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st))
+# define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp))
+# define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
+# define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
+# define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st))
+# define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i))
+# define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val))
+# define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st))
+# define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val))
+# define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val))
+# define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val))
+# define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val))
+# define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i))
+# define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr))
+# define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i))
+# define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp))
+# define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st)
+# define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func))
+# define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st))
+# define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st))
+# define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st))
+# define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st))
+# define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp))
+# define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE)
+# define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st))
+# define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st))
+# define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i))
+# define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val))
+# define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st))
+# define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val))
+# define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val))
+# define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val))
+# define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val))
+# define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i))
+# define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr))
+# define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i))
+# define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp))
+# define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st)
+# define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func))
+# define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st))
+# define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st))
+# define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st))
+# define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st))
+# define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp))
+# define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE)
+# define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st))
+# define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st))
+# define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i))
+# define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val))
+# define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st))
+# define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val))
+# define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val))
+# define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val))
+# define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val))
+# define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i))
+# define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr))
+# define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i))
+# define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp))
+# define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st)
+# define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func))
+# define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st))
+# define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st))
+# define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st))
+# define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp))
+# define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS)
+# define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i))
+# define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val))
+# define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val))
+# define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val))
+# define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val))
+# define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val))
+# define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i))
+# define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr))
+# define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i))
+# define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp))
+# define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st)
+# define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func))
+# define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st))
+# define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp))
+# define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock)
+# define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st))
+# define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st))
+# define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i))
+# define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val))
+# define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st))
+# define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val))
+# define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val))
+# define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val))
+# define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val))
+# define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i))
+# define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr))
+# define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i))
+# define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp))
+# define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st)
+# define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func))
+# define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st))
+# define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st))
+# define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st))
+# define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st))
+# define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp))
+# define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT)
+# define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st))
+# define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st))
+# define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i))
+# define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val))
+# define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st))
+# define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val))
+# define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val))
+# define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val))
+# define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val))
+# define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i))
+# define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr))
+# define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i))
+# define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp))
+# define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st)
+# define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func))
+# define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st))
+# define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st))
+# define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st))
+# define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st))
+# define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp))
+# define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE)
+# define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st))
+# define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st))
+# define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i))
+# define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val))
+# define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st))
+# define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val))
+# define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val))
+# define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val))
+# define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val))
+# define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i))
+# define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr))
+# define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i))
+# define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp))
+# define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st)
+# define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func))
+# define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st))
+# define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st))
+# define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st))
+# define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st))
+# define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp))
+# define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM)
+# define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i))
+# define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val))
+# define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val))
+# define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val))
+# define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val))
+# define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val))
+# define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i))
+# define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr))
+# define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i))
+# define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp))
+# define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st)
+# define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func))
+# define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st))
+# define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp))
+# define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID)
+# define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st))
+# define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st))
+# define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i))
+# define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val))
+# define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st))
+# define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val))
+# define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val))
+# define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val))
+# define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val))
+# define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i))
+# define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr))
+# define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i))
+# define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp))
+# define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st)
+# define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func))
+# define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st))
+# define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st))
+# define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st))
+# define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st))
+# define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp))
+# define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD)
+# define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st))
+# define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st))
+# define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i))
+# define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val))
+# define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st))
+# define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val))
+# define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val))
+# define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val))
+# define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val))
+# define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i))
+# define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr))
+# define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i))
+# define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp))
+# define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st)
+# define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func))
+# define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st))
+# define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st))
+# define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st))
+# define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st))
+# define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp))
+# define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL)
+# define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st))
+# define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st))
+# define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i))
+# define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val))
+# define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st))
+# define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val))
+# define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val))
+# define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val))
+# define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val))
+# define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i))
+# define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr))
+# define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i))
+# define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp))
+# define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st)
+# define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func))
+# define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st))
+# define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st))
+# define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st))
+# define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp))
+# define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD)
+# define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i))
+# define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val))
+# define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val))
+# define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val))
+# define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val))
+# define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val))
+# define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i))
+# define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr))
+# define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i))
+# define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp))
+# define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st)
+# define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func))
+# define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp))
+# define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD)
+# define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i))
+# define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val))
+# define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val))
+# define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val))
+# define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val))
+# define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val))
+# define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i))
+# define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr))
+# define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i))
+# define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp))
+# define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st)
+# define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func))
+# define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st))
+# define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st))
+# define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp))
+# define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME)
+# define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st))
+# define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st))
+# define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i))
+# define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val))
+# define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st))
+# define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val))
+# define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val))
+# define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val))
+# define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val))
+# define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i))
+# define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr))
+# define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i))
+# define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp))
+# define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st)
+# define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func))
+# define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st))
+# define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st))
+# define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
+# define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
+# define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp))
+# define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES)
+# define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st))
+# define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st))
+# define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i))
+# define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val))
+# define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st))
+# define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val))
+# define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val))
+# define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val))
+# define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val))
+# define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i))
+# define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr))
+# define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i))
+# define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp))
+# define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st)
+# define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func))
+# define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st))
+# define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st))
+# define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st))
+# define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st))
+# define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp))
+# define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
+# define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
+# define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st))
+# define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i))
+# define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val))
+# define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st))
+# define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val))
+# define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val))
+# define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val))
+# define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val))
+# define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i))
+# define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr))
+# define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i))
+# define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp))
+# define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st)
+# define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func))
+# define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st))
+# define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st))
+# define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
+# define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
+# define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp))
+# define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily)
+# define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st))
+# define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st))
+# define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i))
+# define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val))
+# define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st))
+# define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val))
+# define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val))
+# define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val))
+# define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val))
+# define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i))
+# define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr))
+# define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i))
+# define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp))
+# define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st)
+# define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func))
+# define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st))
+# define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st))
+# define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st))
+# define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st))
+# define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp))
+# define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange)
+# define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st))
+# define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st))
+# define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i))
+# define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val))
+# define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st))
+# define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val))
+# define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val))
+# define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val))
+# define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val))
+# define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i))
+# define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr))
+# define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i))
+# define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp))
+# define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st)
+# define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func))
+# define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st))
+# define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st))
+# define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st))
+# define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st))
+# define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp))
+# define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
+# define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
+# define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st))
+# define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i))
+# define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val))
+# define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st))
+# define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val))
+# define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val))
+# define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val))
+# define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val))
+# define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i))
+# define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr))
+# define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i))
+# define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp))
+# define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st)
+# define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func))
+# define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st))
+# define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st))
+# define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st))
+# define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st))
+# define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp))
+# define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA)
+# define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i))
+# define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val))
+# define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val))
+# define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val))
+# define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val))
+# define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val))
+# define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i))
+# define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr))
+# define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i))
+# define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp))
+# define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st)
+# define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func))
+# define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st))
+# define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp))
+# define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY)
+# define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i))
+# define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val))
+# define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val))
+# define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val))
+# define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val))
+# define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val))
+# define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i))
+# define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr))
+# define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i))
+# define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp))
+# define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st)
+# define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func))
+# define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st))
+# define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp))
+# define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM)
+# define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st))
+# define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st))
+# define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i))
+# define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val))
+# define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st))
+# define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val))
+# define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val))
+# define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val))
+# define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val))
+# define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i))
+# define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr))
+# define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i))
+# define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp))
+# define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st)
+# define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func))
+# define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st))
+# define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st))
+# define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st))
+# define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st))
+# define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp))
+# define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA)
+# define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i))
+# define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val))
+# define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val))
+# define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val))
+# define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val))
+# define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val))
+# define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i))
+# define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr))
+# define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i))
+# define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp))
+# define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st)
+# define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func))
+# define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st))
+# define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp))
+# define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY)
+# define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st))
+# define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st))
+# define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i))
+# define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val))
+# define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st))
+# define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val))
+# define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val))
+# define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val))
+# define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val))
+# define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i))
+# define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr))
+# define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i))
+# define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp))
+# define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st)
+# define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func))
+# define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st))
+# define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st))
+# define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st))
+# define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st))
+# define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp))
+# define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME)
+# define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st))
+# define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st))
+# define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i))
+# define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val))
+# define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st))
+# define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val))
+# define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val))
+# define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val))
+# define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val))
+# define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i))
+# define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr))
+# define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i))
+# define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp))
+# define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st)
+# define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func))
+# define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st))
+# define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st))
+# define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st))
+# define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st))
+# define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp))
+# define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY)
+# define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st))
+# define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st))
+# define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i))
+# define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val))
+# define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st))
+# define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val))
+# define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val))
+# define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val))
+# define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val))
+# define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i))
+# define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr))
+# define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i))
+# define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp))
+# define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st)
+# define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func))
+# define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st))
+# define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st))
+# define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st))
+# define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st))
+# define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp))
+# define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA)
+# define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st))
+# define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st))
+# define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i))
+# define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val))
+# define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st))
+# define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val))
+# define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val))
+# define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val))
+# define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val))
+# define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i))
+# define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr))
+# define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i))
+# define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp))
+# define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st)
+# define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func))
+# define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st))
+# define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st))
+# define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st))
+# define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st))
+# define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp))
+# define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER)
+# define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st))
+# define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st))
+# define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i))
+# define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val))
+# define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st))
+# define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val))
+# define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val))
+# define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val))
+# define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val))
+# define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i))
+# define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr))
+# define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i))
+# define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp))
+# define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st)
+# define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func))
+# define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st))
+# define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st))
+# define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
+# define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
+# define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp))
+# define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
+# define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
+# define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st))
+# define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i))
+# define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val))
+# define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st))
+# define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val))
+# define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val))
+# define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val))
+# define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val))
+# define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i))
+# define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr))
+# define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i))
+# define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp))
+# define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st)
+# define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func))
+# define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st))
+# define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st))
+# define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st))
+# define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st))
+# define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp))
+# define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS)
+# define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st))
+# define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st))
+# define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i))
+# define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val))
+# define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st))
+# define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val))
+# define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val))
+# define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val))
+# define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val))
+# define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i))
+# define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr))
+# define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i))
+# define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp))
+# define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st)
+# define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func))
+# define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st))
+# define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st))
+# define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st))
+# define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st))
+# define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp))
+# define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID)
+# define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st))
+# define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st))
+# define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i))
+# define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val))
+# define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st))
+# define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val))
+# define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val))
+# define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val))
+# define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val))
+# define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i))
+# define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr))
+# define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i))
+# define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp))
+# define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st)
+# define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func))
+# define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st))
+# define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st))
+# define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st))
+# define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st))
+# define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp))
+# define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ)
+# define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st))
+# define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st))
+# define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i))
+# define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val))
+# define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st))
+# define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val))
+# define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val))
+# define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val))
+# define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val))
+# define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i))
+# define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr))
+# define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i))
+# define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp))
+# define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st)
+# define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func))
+# define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st))
+# define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st))
+# define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st))
+# define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st))
+# define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp))
+# define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID)
+# define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st))
+# define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st))
+# define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i))
+# define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val))
+# define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st))
+# define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val))
+# define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val))
+# define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val))
+# define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val))
+# define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i))
+# define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr))
+# define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i))
+# define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp))
+# define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st)
+# define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func))
+# define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st))
+# define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st))
+# define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st))
+# define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st))
+# define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp))
+# define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP)
+# define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st))
+# define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st))
+# define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i))
+# define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val))
+# define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st))
+# define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val))
+# define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val))
+# define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val))
+# define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val))
+# define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i))
+# define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr))
+# define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i))
+# define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp))
+# define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st)
+# define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func))
+# define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st))
+# define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st))
+# define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st))
+# define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st))
+# define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp))
+# define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG)
+# define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st))
+# define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st))
+# define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i))
+# define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val))
+# define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st))
+# define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val))
+# define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val))
+# define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val))
+# define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val))
+# define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i))
+# define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr))
+# define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i))
+# define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp))
+# define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st)
+# define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func))
+# define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st))
+# define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st))
+# define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st))
+# define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st))
+# define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp))
+# define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7)
+# define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st))
+# define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st))
+# define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i))
+# define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val))
+# define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st))
+# define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val))
+# define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val))
+# define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val))
+# define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val))
+# define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i))
+# define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr))
+# define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i))
+# define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp))
+# define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st)
+# define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func))
+# define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st))
+# define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st))
+# define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st))
+# define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st))
+# define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp))
+# define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO)
+# define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i))
+# define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val))
+# define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val))
+# define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val))
+# define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val))
+# define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val))
+# define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i))
+# define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr))
+# define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i))
+# define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp))
+# define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st)
+# define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func))
+# define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp))
+# define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO)
+# define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i))
+# define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val))
+# define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val))
+# define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val))
+# define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val))
+# define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val))
+# define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i))
+# define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr))
+# define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i))
+# define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp))
+# define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st)
+# define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func))
+# define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st))
+# define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st))
+# define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp))
+# define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO)
+# define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st))
+# define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st))
+# define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i))
+# define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val))
+# define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st))
+# define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val))
+# define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val))
+# define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val))
+# define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val))
+# define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i))
+# define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr))
+# define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i))
+# define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp))
+# define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st)
+# define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func))
+# define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st))
+# define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st))
+# define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st))
+# define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st))
+# define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp))
+# define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO)
+# define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st))
+# define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st))
+# define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i))
+# define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val))
+# define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st))
+# define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val))
+# define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val))
+# define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val))
+# define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val))
+# define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i))
+# define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr))
+# define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i))
+# define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp))
+# define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st)
+# define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func))
+# define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st))
+# define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st))
+# define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st))
+# define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st))
+# define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp))
+# define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING)
+# define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st))
+# define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st))
+# define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i))
+# define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val))
+# define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st))
+# define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val))
+# define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val))
+# define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val))
+# define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val))
+# define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i))
+# define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr))
+# define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i))
+# define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp))
+# define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st)
+# define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func))
+# define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st))
+# define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st))
+# define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
+# define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
+# define sk_SRP_gN_new(cmp) SKM_sk_new(SRP_gN, (cmp))
+# define sk_SRP_gN_new_null() SKM_sk_new_null(SRP_gN)
+# define sk_SRP_gN_free(st) SKM_sk_free(SRP_gN, (st))
+# define sk_SRP_gN_num(st) SKM_sk_num(SRP_gN, (st))
+# define sk_SRP_gN_value(st, i) SKM_sk_value(SRP_gN, (st), (i))
+# define sk_SRP_gN_set(st, i, val) SKM_sk_set(SRP_gN, (st), (i), (val))
+# define sk_SRP_gN_zero(st) SKM_sk_zero(SRP_gN, (st))
+# define sk_SRP_gN_push(st, val) SKM_sk_push(SRP_gN, (st), (val))
+# define sk_SRP_gN_unshift(st, val) SKM_sk_unshift(SRP_gN, (st), (val))
+# define sk_SRP_gN_find(st, val) SKM_sk_find(SRP_gN, (st), (val))
+# define sk_SRP_gN_find_ex(st, val) SKM_sk_find_ex(SRP_gN, (st), (val))
+# define sk_SRP_gN_delete(st, i) SKM_sk_delete(SRP_gN, (st), (i))
+# define sk_SRP_gN_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN, (st), (ptr))
+# define sk_SRP_gN_insert(st, val, i) SKM_sk_insert(SRP_gN, (st), (val), (i))
+# define sk_SRP_gN_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN, (st), (cmp))
+# define sk_SRP_gN_dup(st) SKM_sk_dup(SRP_gN, st)
+# define sk_SRP_gN_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN, (st), (free_func))
+# define sk_SRP_gN_shift(st) SKM_sk_shift(SRP_gN, (st))
+# define sk_SRP_gN_pop(st) SKM_sk_pop(SRP_gN, (st))
+# define sk_SRP_gN_sort(st) SKM_sk_sort(SRP_gN, (st))
+# define sk_SRP_gN_is_sorted(st) SKM_sk_is_sorted(SRP_gN, (st))
+# define sk_SRP_gN_cache_new(cmp) SKM_sk_new(SRP_gN_cache, (cmp))
+# define sk_SRP_gN_cache_new_null() SKM_sk_new_null(SRP_gN_cache)
+# define sk_SRP_gN_cache_free(st) SKM_sk_free(SRP_gN_cache, (st))
+# define sk_SRP_gN_cache_num(st) SKM_sk_num(SRP_gN_cache, (st))
+# define sk_SRP_gN_cache_value(st, i) SKM_sk_value(SRP_gN_cache, (st), (i))
+# define sk_SRP_gN_cache_set(st, i, val) SKM_sk_set(SRP_gN_cache, (st), (i), (val))
+# define sk_SRP_gN_cache_zero(st) SKM_sk_zero(SRP_gN_cache, (st))
+# define sk_SRP_gN_cache_push(st, val) SKM_sk_push(SRP_gN_cache, (st), (val))
+# define sk_SRP_gN_cache_unshift(st, val) SKM_sk_unshift(SRP_gN_cache, (st), (val))
+# define sk_SRP_gN_cache_find(st, val) SKM_sk_find(SRP_gN_cache, (st), (val))
+# define sk_SRP_gN_cache_find_ex(st, val) SKM_sk_find_ex(SRP_gN_cache, (st), (val))
+# define sk_SRP_gN_cache_delete(st, i) SKM_sk_delete(SRP_gN_cache, (st), (i))
+# define sk_SRP_gN_cache_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN_cache, (st), (ptr))
+# define sk_SRP_gN_cache_insert(st, val, i) SKM_sk_insert(SRP_gN_cache, (st), (val), (i))
+# define sk_SRP_gN_cache_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN_cache, (st), (cmp))
+# define sk_SRP_gN_cache_dup(st) SKM_sk_dup(SRP_gN_cache, st)
+# define sk_SRP_gN_cache_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN_cache, (st), (free_func))
+# define sk_SRP_gN_cache_shift(st) SKM_sk_shift(SRP_gN_cache, (st))
+# define sk_SRP_gN_cache_pop(st) SKM_sk_pop(SRP_gN_cache, (st))
+# define sk_SRP_gN_cache_sort(st) SKM_sk_sort(SRP_gN_cache, (st))
+# define sk_SRP_gN_cache_is_sorted(st) SKM_sk_is_sorted(SRP_gN_cache, (st))
+# define sk_SRP_user_pwd_new(cmp) SKM_sk_new(SRP_user_pwd, (cmp))
+# define sk_SRP_user_pwd_new_null() SKM_sk_new_null(SRP_user_pwd)
+# define sk_SRP_user_pwd_free(st) SKM_sk_free(SRP_user_pwd, (st))
+# define sk_SRP_user_pwd_num(st) SKM_sk_num(SRP_user_pwd, (st))
+# define sk_SRP_user_pwd_value(st, i) SKM_sk_value(SRP_user_pwd, (st), (i))
+# define sk_SRP_user_pwd_set(st, i, val) SKM_sk_set(SRP_user_pwd, (st), (i), (val))
+# define sk_SRP_user_pwd_zero(st) SKM_sk_zero(SRP_user_pwd, (st))
+# define sk_SRP_user_pwd_push(st, val) SKM_sk_push(SRP_user_pwd, (st), (val))
+# define sk_SRP_user_pwd_unshift(st, val) SKM_sk_unshift(SRP_user_pwd, (st), (val))
+# define sk_SRP_user_pwd_find(st, val) SKM_sk_find(SRP_user_pwd, (st), (val))
+# define sk_SRP_user_pwd_find_ex(st, val) SKM_sk_find_ex(SRP_user_pwd, (st), (val))
+# define sk_SRP_user_pwd_delete(st, i) SKM_sk_delete(SRP_user_pwd, (st), (i))
+# define sk_SRP_user_pwd_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_user_pwd, (st), (ptr))
+# define sk_SRP_user_pwd_insert(st, val, i) SKM_sk_insert(SRP_user_pwd, (st), (val), (i))
+# define sk_SRP_user_pwd_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_user_pwd, (st), (cmp))
+# define sk_SRP_user_pwd_dup(st) SKM_sk_dup(SRP_user_pwd, st)
+# define sk_SRP_user_pwd_pop_free(st, free_func) SKM_sk_pop_free(SRP_user_pwd, (st), (free_func))
+# define sk_SRP_user_pwd_shift(st) SKM_sk_shift(SRP_user_pwd, (st))
+# define sk_SRP_user_pwd_pop(st) SKM_sk_pop(SRP_user_pwd, (st))
+# define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st))
+# define sk_SRP_user_pwd_is_sorted(st) SKM_sk_is_sorted(SRP_user_pwd, (st))
+# define sk_SRTP_PROTECTION_PROFILE_new(cmp) SKM_sk_new(SRTP_PROTECTION_PROFILE, (cmp))
+# define sk_SRTP_PROTECTION_PROFILE_new_null() SKM_sk_new_null(SRTP_PROTECTION_PROFILE)
+# define sk_SRTP_PROTECTION_PROFILE_free(st) SKM_sk_free(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SRTP_PROTECTION_PROFILE_num(st) SKM_sk_num(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SRTP_PROTECTION_PROFILE_value(st, i) SKM_sk_value(SRTP_PROTECTION_PROFILE, (st), (i))
+# define sk_SRTP_PROTECTION_PROFILE_set(st, i, val) SKM_sk_set(SRTP_PROTECTION_PROFILE, (st), (i), (val))
+# define sk_SRTP_PROTECTION_PROFILE_zero(st) SKM_sk_zero(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SRTP_PROTECTION_PROFILE_push(st, val) SKM_sk_push(SRTP_PROTECTION_PROFILE, (st), (val))
+# define sk_SRTP_PROTECTION_PROFILE_unshift(st, val) SKM_sk_unshift(SRTP_PROTECTION_PROFILE, (st), (val))
+# define sk_SRTP_PROTECTION_PROFILE_find(st, val) SKM_sk_find(SRTP_PROTECTION_PROFILE, (st), (val))
+# define sk_SRTP_PROTECTION_PROFILE_find_ex(st, val) SKM_sk_find_ex(SRTP_PROTECTION_PROFILE, (st), (val))
+# define sk_SRTP_PROTECTION_PROFILE_delete(st, i) SKM_sk_delete(SRTP_PROTECTION_PROFILE, (st), (i))
+# define sk_SRTP_PROTECTION_PROFILE_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRTP_PROTECTION_PROFILE, (st), (ptr))
+# define sk_SRTP_PROTECTION_PROFILE_insert(st, val, i) SKM_sk_insert(SRTP_PROTECTION_PROFILE, (st), (val), (i))
+# define sk_SRTP_PROTECTION_PROFILE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRTP_PROTECTION_PROFILE, (st), (cmp))
+# define sk_SRTP_PROTECTION_PROFILE_dup(st) SKM_sk_dup(SRTP_PROTECTION_PROFILE, st)
+# define sk_SRTP_PROTECTION_PROFILE_pop_free(st, free_func) SKM_sk_pop_free(SRTP_PROTECTION_PROFILE, (st), (free_func))
+# define sk_SRTP_PROTECTION_PROFILE_shift(st) SKM_sk_shift(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SRTP_PROTECTION_PROFILE_pop(st) SKM_sk_pop(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SRTP_PROTECTION_PROFILE_sort(st) SKM_sk_sort(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SRTP_PROTECTION_PROFILE_is_sorted(st) SKM_sk_is_sorted(SRTP_PROTECTION_PROFILE, (st))
+# define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
+# define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
+# define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
+# define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st))
+# define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i))
+# define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val))
+# define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st))
+# define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val))
+# define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val))
+# define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val))
+# define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val))
+# define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i))
+# define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr))
+# define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i))
+# define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp))
+# define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st)
+# define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func))
+# define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st))
+# define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st))
+# define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st))
+# define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st))
+# define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp))
+# define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP)
+# define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st))
+# define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st))
+# define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i))
+# define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val))
+# define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st))
+# define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val))
+# define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val))
+# define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val))
+# define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val))
+# define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i))
+# define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr))
+# define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i))
+# define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp))
+# define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st)
+# define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func))
+# define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st))
+# define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st))
+# define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st))
+# define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp))
+# define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY)
+# define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i))
+# define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val))
+# define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val))
+# define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val))
+# define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val))
+# define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val))
+# define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i))
+# define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr))
+# define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i))
+# define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp))
+# define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st)
+# define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func))
+# define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st))
+# define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp))
+# define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO)
+# define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st))
+# define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st))
+# define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i))
+# define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val))
+# define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st))
+# define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val))
+# define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val))
+# define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val))
+# define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val))
+# define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i))
+# define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr))
+# define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i))
+# define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp))
+# define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st)
+# define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func))
+# define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st))
+# define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st))
+# define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st))
+# define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st))
+# define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp))
+# define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT)
+# define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st))
+# define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st))
+# define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i))
+# define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val))
+# define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st))
+# define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val))
+# define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val))
+# define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val))
+# define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val))
+# define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i))
+# define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr))
+# define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i))
+# define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp))
+# define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st)
+# define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func))
+# define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st))
+# define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st))
+# define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st))
+# define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st))
+# define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp))
+# define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID)
+# define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st))
+# define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st))
+# define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i))
+# define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val))
+# define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st))
+# define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val))
+# define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val))
+# define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val))
+# define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val))
+# define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i))
+# define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr))
+# define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i))
+# define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp))
+# define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st)
+# define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func))
+# define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st))
+# define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st))
+# define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st))
+# define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st))
+# define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp))
+# define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING)
+# define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st))
+# define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st))
+# define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i))
+# define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val))
+# define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st))
+# define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val))
+# define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val))
+# define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val))
+# define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val))
+# define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i))
+# define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr))
+# define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i))
+# define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp))
+# define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st)
+# define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func))
+# define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st))
+# define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st))
+# define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st))
+# define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st))
+# define sk_X509_new(cmp) SKM_sk_new(X509, (cmp))
+# define sk_X509_new_null() SKM_sk_new_null(X509)
+# define sk_X509_free(st) SKM_sk_free(X509, (st))
+# define sk_X509_num(st) SKM_sk_num(X509, (st))
+# define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i))
+# define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val))
+# define sk_X509_zero(st) SKM_sk_zero(X509, (st))
+# define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val))
+# define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val))
+# define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val))
+# define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val))
+# define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i))
+# define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr))
+# define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i))
+# define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp))
+# define sk_X509_dup(st) SKM_sk_dup(X509, st)
+# define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func))
+# define sk_X509_shift(st) SKM_sk_shift(X509, (st))
+# define sk_X509_pop(st) SKM_sk_pop(X509, (st))
+# define sk_X509_sort(st) SKM_sk_sort(X509, (st))
+# define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st))
+# define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp))
+# define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD)
+# define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st))
+# define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st))
+# define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i))
+# define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val))
+# define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st))
+# define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val))
+# define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val))
+# define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val))
+# define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val))
+# define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i))
+# define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr))
+# define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i))
+# define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp))
+# define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st)
+# define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func))
+# define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st))
+# define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st))
+# define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st))
+# define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st))
+# define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp))
+# define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR)
+# define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st))
+# define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st))
+# define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i))
+# define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val))
+# define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st))
+# define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val))
+# define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val))
+# define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val))
+# define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val))
+# define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i))
+# define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr))
+# define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i))
+# define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp))
+# define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st)
+# define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func))
+# define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st))
+# define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st))
+# define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st))
+# define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st))
+# define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp))
+# define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE)
+# define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st))
+# define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st))
+# define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i))
+# define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val))
+# define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st))
+# define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val))
+# define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val))
+# define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val))
+# define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val))
+# define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i))
+# define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr))
+# define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i))
+# define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp))
+# define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st)
+# define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func))
+# define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st))
+# define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st))
+# define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st))
+# define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st))
+# define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp))
+# define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL)
+# define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st))
+# define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st))
+# define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i))
+# define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val))
+# define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st))
+# define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val))
+# define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val))
+# define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val))
+# define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val))
+# define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i))
+# define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr))
+# define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i))
+# define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp))
+# define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st)
+# define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func))
+# define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st))
+# define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st))
+# define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st))
+# define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st))
+# define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp))
+# define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION)
+# define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st))
+# define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st))
+# define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i))
+# define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val))
+# define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st))
+# define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val))
+# define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val))
+# define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val))
+# define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val))
+# define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i))
+# define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr))
+# define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i))
+# define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp))
+# define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st)
+# define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func))
+# define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st))
+# define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st))
+# define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st))
+# define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st))
+# define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp))
+# define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO)
+# define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st))
+# define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st))
+# define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i))
+# define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val))
+# define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st))
+# define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val))
+# define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val))
+# define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val))
+# define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val))
+# define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i))
+# define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr))
+# define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i))
+# define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp))
+# define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st)
+# define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func))
+# define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st))
+# define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st))
+# define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st))
+# define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st))
+# define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp))
+# define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP)
+# define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st))
+# define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st))
+# define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i))
+# define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val))
+# define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st))
+# define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val))
+# define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val))
+# define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val))
+# define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val))
+# define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i))
+# define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr))
+# define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i))
+# define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp))
+# define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st)
+# define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func))
+# define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st))
+# define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st))
+# define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st))
+# define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st))
+# define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp))
+# define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME)
+# define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st))
+# define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st))
+# define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i))
+# define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val))
+# define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st))
+# define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val))
+# define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val))
+# define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val))
+# define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val))
+# define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i))
+# define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr))
+# define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i))
+# define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp))
+# define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st)
+# define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func))
+# define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st))
+# define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st))
+# define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st))
+# define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st))
+# define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp))
+# define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY)
+# define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st))
+# define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st))
+# define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i))
+# define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val))
+# define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st))
+# define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val))
+# define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val))
+# define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val))
+# define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val))
+# define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i))
+# define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr))
+# define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i))
+# define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp))
+# define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st)
+# define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func))
+# define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st))
+# define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st))
+# define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st))
+# define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st))
+# define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp))
+# define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT)
+# define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st))
+# define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st))
+# define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i))
+# define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val))
+# define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st))
+# define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val))
+# define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val))
+# define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val))
+# define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val))
+# define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i))
+# define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr))
+# define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i))
+# define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp))
+# define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st)
+# define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func))
+# define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st))
+# define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st))
+# define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st))
+# define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st))
+# define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp))
+# define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA)
+# define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i))
+# define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val))
+# define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val))
+# define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val))
+# define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val))
+# define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val))
+# define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i))
+# define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr))
+# define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i))
+# define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp))
+# define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st)
+# define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func))
+# define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st))
+# define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp))
+# define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE)
+# define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st))
+# define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st))
+# define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i))
+# define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val))
+# define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st))
+# define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val))
+# define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val))
+# define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val))
+# define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val))
+# define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i))
+# define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr))
+# define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i))
+# define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp))
+# define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st)
+# define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func))
+# define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st))
+# define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st))
+# define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st))
+# define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st))
+# define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp))
+# define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE)
+# define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st))
+# define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st))
+# define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i))
+# define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val))
+# define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st))
+# define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val))
+# define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val))
+# define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val))
+# define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val))
+# define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i))
+# define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr))
+# define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i))
+# define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp))
+# define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st)
+# define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func))
+# define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st))
+# define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st))
+# define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st))
+# define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st))
+# define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp))
+# define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED)
+# define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st))
+# define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st))
+# define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i))
+# define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val))
+# define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st))
+# define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val))
+# define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val))
+# define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val))
+# define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val))
+# define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i))
+# define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr))
+# define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i))
+# define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp))
+# define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st)
+# define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func))
+# define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st))
+# define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st))
+# define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st))
+# define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st))
+# define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp))
+# define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST)
+# define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st))
+# define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st))
+# define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i))
+# define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val))
+# define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st))
+# define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val))
+# define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val))
+# define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val))
+# define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val))
+# define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i))
+# define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr))
+# define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i))
+# define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp))
+# define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st)
+# define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func))
+# define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st))
+# define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st))
+# define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st))
+# define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st))
+# define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp))
+# define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM)
+# define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st))
+# define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st))
+# define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i))
+# define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val))
+# define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st))
+# define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val))
+# define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val))
+# define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val))
+# define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val))
+# define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i))
+# define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr))
+# define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i))
+# define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp))
+# define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st)
+# define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func))
+# define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st))
+# define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st))
+# define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st))
+# define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st))
+# define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp))
+# define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple)
+# define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st))
+# define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st))
+# define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i))
+# define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val))
+# define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st))
+# define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val))
+# define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val))
+# define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val))
+# define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val))
+# define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i))
+# define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr))
+# define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i))
+# define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp))
+# define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st)
+# define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func))
+# define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st))
+# define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st))
+# define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st))
+# define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st))
+# define sk_void_new(cmp) SKM_sk_new(void, (cmp))
+# define sk_void_new_null() SKM_sk_new_null(void)
+# define sk_void_free(st) SKM_sk_free(void, (st))
+# define sk_void_num(st) SKM_sk_num(void, (st))
+# define sk_void_value(st, i) SKM_sk_value(void, (st), (i))
+# define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val))
+# define sk_void_zero(st) SKM_sk_zero(void, (st))
+# define sk_void_push(st, val) SKM_sk_push(void, (st), (val))
+# define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val))
+# define sk_void_find(st, val) SKM_sk_find(void, (st), (val))
+# define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val))
+# define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i))
+# define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr))
+# define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i))
+# define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp))
+# define sk_void_dup(st) SKM_sk_dup(void, st)
+# define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func))
+# define sk_void_shift(st) SKM_sk_shift(void, (st))
+# define sk_void_pop(st) SKM_sk_pop(void, (st))
+# define sk_void_sort(st) SKM_sk_sort(void, (st))
+# define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st))
+# define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp)))
+# define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null())
+# define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
+# define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
+# define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i))
+# define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st)
+# define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func))
+# define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i)
+# define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st)
+# define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val))
+# define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st))
+# define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val))
+# define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val))
+# define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i))
+# define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr))
+# define sk_OPENSSL_STRING_set_cmp_func(st, cmp) \
+ ((int (*)(const char * const *,const char * const *)) \
+ sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp)))
+# define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st)
+# define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st))
+# define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st))
+# define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st))
+# define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st))
+# define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp)))
+# define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null())
+# define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
+# define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
+# define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i))
+# define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st)
+# define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_FREE_FUNC2(OPENSSL_BLOCK, free_func))
+# define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val), i)
+# define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st)
+# define sk_OPENSSL_BLOCK_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i, CHECKED_PTR_OF(void, val))
+# define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st))
+# define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val))
+# define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val))
+# define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i))
+# define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, ptr))
+# define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp) \
+ ((int (*)(const void * const *,const void * const *)) \
+ sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_CMP_FUNC(void, cmp)))
+# define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st)
+# define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st))
+# define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop(CHECKED_STACK_OF(OPENSSL_BLOCK, st))
+# define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st))
+# define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st))
+# define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+# define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null())
+# define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+# define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+# define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i))
+# define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st)
+# define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func))
+# define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i)
+# define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st)
+# define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val))
+# define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st))
+# define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val))
+# define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val))
+# define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i))
+# define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr))
+# define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \
+ ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \
+ sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp)))
+# define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st)
+# define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st))
+# define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st))
+# define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st))
+# define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st))
+# define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func))
+# define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+ SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
+# define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+ SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+# define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \
+ SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len))
+# define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \
+ SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func))
+# define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \
+ SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+# define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \
+ SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+# define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj)
+# define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst)
+# define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst)
+# define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst)
+# define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn)
+# define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg)
+# define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh)
+# define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh)
+# define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh)
+# define lh_ADDED_OBJ_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(ADDED_OBJ,lh,out)
+# define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out)
+# define lh_ADDED_OBJ_stats_bio(lh,out) \
+ LHM_lh_stats_bio(ADDED_OBJ,lh,out)
+# define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh)
+# define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info)
+# define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst)
+# define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst)
+# define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst)
+# define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn)
+# define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg)
+# define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh)
+# define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh)
+# define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh)
+# define lh_APP_INFO_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(APP_INFO,lh,out)
+# define lh_APP_INFO_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(APP_INFO,lh,out)
+# define lh_APP_INFO_stats_bio(lh,out) \
+ LHM_lh_stats_bio(APP_INFO,lh,out)
+# define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh)
+# define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value)
+# define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst)
+# define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst)
+# define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst)
+# define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn)
+# define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg)
+# define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh)
+# define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh)
+# define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh)
+# define lh_CONF_VALUE_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(CONF_VALUE,lh,out)
+# define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out)
+# define lh_CONF_VALUE_stats_bio(lh,out) \
+ LHM_lh_stats_bio(CONF_VALUE,lh,out)
+# define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh)
+# define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile)
+# define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst)
+# define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst)
+# define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst)
+# define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn)
+# define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg)
+# define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh)
+# define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh)
+# define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh)
+# define lh_ENGINE_PILE_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(ENGINE_PILE,lh,out)
+# define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out)
+# define lh_ENGINE_PILE_stats_bio(lh,out) \
+ LHM_lh_stats_bio(ENGINE_PILE,lh,out)
+# define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh)
+# define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state)
+# define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst)
+# define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst)
+# define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst)
+# define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn)
+# define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg)
+# define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh)
+# define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh)
+# define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh)
+# define lh_ERR_STATE_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(ERR_STATE,lh,out)
+# define lh_ERR_STATE_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out)
+# define lh_ERR_STATE_stats_bio(lh,out) \
+ LHM_lh_stats_bio(ERR_STATE,lh,out)
+# define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh)
+# define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data)
+# define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst)
+# define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst)
+# define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst)
+# define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn)
+# define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg)
+# define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh)
+# define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh)
+# define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh)
+# define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out)
+# define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out)
+# define lh_ERR_STRING_DATA_stats_bio(lh,out) \
+ LHM_lh_stats_bio(ERR_STRING_DATA,lh,out)
+# define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh)
+# define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item)
+# define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst)
+# define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst)
+# define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst)
+# define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn)
+# define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg)
+# define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh)
+# define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh)
+# define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh)
+# define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out)
+# define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out)
+# define lh_EX_CLASS_ITEM_stats_bio(lh,out) \
+ LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out)
+# define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh)
+# define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function)
+# define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst)
+# define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst)
+# define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst)
+# define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn)
+# define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg)
+# define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh)
+# define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh)
+# define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh)
+# define lh_FUNCTION_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(FUNCTION,lh,out)
+# define lh_FUNCTION_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(FUNCTION,lh,out)
+# define lh_FUNCTION_stats_bio(lh,out) \
+ LHM_lh_stats_bio(FUNCTION,lh,out)
+# define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh)
+# define lh_MEM_new() LHM_lh_new(MEM,mem)
+# define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst)
+# define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst)
+# define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst)
+# define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn)
+# define lh_MEM_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg)
+# define lh_MEM_error(lh) LHM_lh_error(MEM,lh)
+# define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh)
+# define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh)
+# define lh_MEM_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(MEM,lh,out)
+# define lh_MEM_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(MEM,lh,out)
+# define lh_MEM_stats_bio(lh,out) \
+ LHM_lh_stats_bio(MEM,lh,out)
+# define lh_MEM_free(lh) LHM_lh_free(MEM,lh)
+# define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name)
+# define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst)
+# define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst)
+# define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst)
+# define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn)
+# define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg)
+# define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh)
+# define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh)
+# define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh)
+# define lh_OBJ_NAME_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(OBJ_NAME,lh,out)
+# define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out)
+# define lh_OBJ_NAME_stats_bio(lh,out) \
+ LHM_lh_stats_bio(OBJ_NAME,lh,out)
+# define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh)
+# define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring)
+# define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst)
+# define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst)
+# define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst)
+# define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn)
+# define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg)
+# define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh)
+# define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh)
+# define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh)
+# define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out)
+# define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out)
+# define lh_OPENSSL_CSTRING_stats_bio(lh,out) \
+ LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out)
+# define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh)
+# define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string)
+# define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst)
+# define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst)
+# define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst)
+# define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn)
+# define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg)
+# define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh)
+# define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh)
+# define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh)
+# define lh_OPENSSL_STRING_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out)
+# define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out)
+# define lh_OPENSSL_STRING_stats_bio(lh,out) \
+ LHM_lh_stats_bio(OPENSSL_STRING,lh,out)
+# define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh)
+# define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session)
+# define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst)
+# define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst)
+# define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst)
+# define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn)
+# define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \
+ LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg)
+# define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh)
+# define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh)
+# define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh)
+# define lh_SSL_SESSION_node_stats_bio(lh,out) \
+ LHM_lh_node_stats_bio(SSL_SESSION,lh,out)
+# define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \
+ LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out)
+# define lh_SSL_SESSION_stats_bio(lh,out) \
+ LHM_lh_stats_bio(SSL_SESSION,lh,out)
+# define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh)
+#ifdef __cplusplus
+}
+#endif
+#endif /* !defined HEADER_SAFESTACK_H */
diff --git a/openssl/stack/stack.c b/openssl/stack/stack.c
new file mode 100644
index 0000000..331f907
--- /dev/null
+++ b/openssl/stack/stack.c
@@ -0,0 +1,350 @@
+/* crypto/stack/stack.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*-
+ * Code for stacks
+ * Author - Eric Young v 1.0
+ * 1.2 eay 12-Mar-97 - Modified sk_find so that it _DOES_ return the
+ * lowest index for the searched item.
+ *
+ * 1.1 eay - Take from netdb and added to SSLeay
+ *
+ * 1.0 eay - First version 29/07/92
+ */
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/stack.h>
+#include <openssl/objects.h>
+
+#undef MIN_NODES
+#define MIN_NODES 4
+
+const char STACK_version[] = "Stack" OPENSSL_VERSION_PTEXT;
+
+#include <errno.h>
+
+int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *)))
+ (const void *, const void *) {
+ int (*old) (const void *, const void *) = sk->comp;
+
+ if (sk->comp != c)
+ sk->sorted = 0;
+ sk->comp = c;
+
+ return old;
+}
+
+_STACK *sk_dup(_STACK *sk)
+{
+ _STACK *ret;
+ char **s;
+
+ if ((ret = sk_new(sk->comp)) == NULL)
+ goto err;
+ s = (char **)OPENSSL_realloc((char *)ret->data,
+ (unsigned int)sizeof(char *) *
+ sk->num_alloc);
+ if (s == NULL)
+ goto err;
+ ret->data = s;
+
+ ret->num = sk->num;
+ memcpy(ret->data, sk->data, sizeof(char *) * sk->num);
+ ret->sorted = sk->sorted;
+ ret->num_alloc = sk->num_alloc;
+ ret->comp = sk->comp;
+ return (ret);
+ err:
+ if (ret)
+ sk_free(ret);
+ return (NULL);
+}
+
+_STACK *sk_new_null(void)
+{
+ return sk_new((int (*)(const void *, const void *))0);
+}
+
+_STACK *sk_new(int (*c) (const void *, const void *))
+{
+ _STACK *ret;
+ int i;
+
+ if ((ret = OPENSSL_malloc(sizeof(_STACK))) == NULL)
+ goto err;
+ if ((ret->data = OPENSSL_malloc(sizeof(char *) * MIN_NODES)) == NULL)
+ goto err;
+ for (i = 0; i < MIN_NODES; i++)
+ ret->data[i] = NULL;
+ ret->comp = c;
+ ret->num_alloc = MIN_NODES;
+ ret->num = 0;
+ ret->sorted = 0;
+ return (ret);
+ err:
+ if (ret)
+ OPENSSL_free(ret);
+ return (NULL);
+}
+
+int sk_insert(_STACK *st, void *data, int loc)
+{
+ char **s;
+
+ if (st == NULL)
+ return 0;
+ if (st->num_alloc <= st->num + 1) {
+ s = OPENSSL_realloc((char *)st->data,
+ (unsigned int)sizeof(char *) * st->num_alloc * 2);
+ if (s == NULL)
+ return (0);
+ st->data = s;
+ st->num_alloc *= 2;
+ }
+ if ((loc >= (int)st->num) || (loc < 0))
+ st->data[st->num] = data;
+ else {
+ int i;
+ char **f, **t;
+
+ f = st->data;
+ t = &(st->data[1]);
+ for (i = st->num; i >= loc; i--)
+ t[i] = f[i];
+
+#ifdef undef /* no memmove on sunos :-( */
+ memmove(&(st->data[loc + 1]),
+ &(st->data[loc]), sizeof(char *) * (st->num - loc));
+#endif
+ st->data[loc] = data;
+ }
+ st->num++;
+ st->sorted = 0;
+ return (st->num);
+}
+
+void *sk_delete_ptr(_STACK *st, void *p)
+{
+ int i;
+
+ for (i = 0; i < st->num; i++)
+ if (st->data[i] == p)
+ return (sk_delete(st, i));
+ return (NULL);
+}
+
+void *sk_delete(_STACK *st, int loc)
+{
+ char *ret;
+ int i, j;
+
+ if (!st || (loc < 0) || (loc >= st->num))
+ return NULL;
+
+ ret = st->data[loc];
+ if (loc != st->num - 1) {
+ j = st->num - 1;
+ for (i = loc; i < j; i++)
+ st->data[i] = st->data[i + 1];
+ /*
+ * In theory memcpy is not safe for this memcpy( &(st->data[loc]),
+ * &(st->data[loc+1]), sizeof(char *)*(st->num-loc-1));
+ */
+ }
+ st->num--;
+ return (ret);
+}
+
+static int internal_find(_STACK *st, void *data, int ret_val_options)
+{
+ const void *const *r;
+ int i;
+
+ if (st == NULL)
+ return -1;
+
+ if (st->comp == NULL) {
+ for (i = 0; i < st->num; i++)
+ if (st->data[i] == data)
+ return (i);
+ return (-1);
+ }
+ sk_sort(st);
+ if (data == NULL)
+ return (-1);
+ r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp,
+ ret_val_options);
+ if (r == NULL)
+ return (-1);
+ return (int)((char **)r - st->data);
+}
+
+int sk_find(_STACK *st, void *data)
+{
+ return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);
+}
+
+int sk_find_ex(_STACK *st, void *data)
+{
+ return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
+}
+
+int sk_push(_STACK *st, void *data)
+{
+ return (sk_insert(st, data, st->num));
+}
+
+int sk_unshift(_STACK *st, void *data)
+{
+ return (sk_insert(st, data, 0));
+}
+
+void *sk_shift(_STACK *st)
+{
+ if (st == NULL)
+ return (NULL);
+ if (st->num <= 0)
+ return (NULL);
+ return (sk_delete(st, 0));
+}
+
+void *sk_pop(_STACK *st)
+{
+ if (st == NULL)
+ return (NULL);
+ if (st->num <= 0)
+ return (NULL);
+ return (sk_delete(st, st->num - 1));
+}
+
+void sk_zero(_STACK *st)
+{
+ if (st == NULL)
+ return;
+ if (st->num <= 0)
+ return;
+ memset((char *)st->data, 0, sizeof(*st->data) * st->num);
+ st->num = 0;
+}
+
+void sk_pop_free(_STACK *st, void (*func) (void *))
+{
+ int i;
+
+ if (st == NULL)
+ return;
+ for (i = 0; i < st->num; i++)
+ if (st->data[i] != NULL)
+ func(st->data[i]);
+ sk_free(st);
+}
+
+void sk_free(_STACK *st)
+{
+ if (st == NULL)
+ return;
+ if (st->data != NULL)
+ OPENSSL_free(st->data);
+ OPENSSL_free(st);
+}
+
+int sk_num(const _STACK *st)
+{
+ if (st == NULL)
+ return -1;
+ return st->num;
+}
+
+void *sk_value(const _STACK *st, int i)
+{
+ if (!st || (i < 0) || (i >= st->num))
+ return NULL;
+ return st->data[i];
+}
+
+void *sk_set(_STACK *st, int i, void *value)
+{
+ if (!st || (i < 0) || (i >= st->num))
+ return NULL;
+ return (st->data[i] = value);
+}
+
+void sk_sort(_STACK *st)
+{
+ if (st && !st->sorted) {
+ int (*comp_func) (const void *, const void *);
+
+ /*
+ * same comment as in sk_find ... previously st->comp was declared as
+ * a (void*,void*) callback type, but this made the population of the
+ * callback pointer illogical - our callbacks compare type** with
+ * type**, so we leave the casting until absolutely necessary (ie.
+ * "now").
+ */
+ comp_func = (int (*)(const void *, const void *))(st->comp);
+ qsort(st->data, st->num, sizeof(char *), comp_func);
+ st->sorted = 1;
+ }
+}
+
+int sk_is_sorted(const _STACK *st)
+{
+ if (!st)
+ return 1;
+ return st->sorted;
+}
diff --git a/openssl/stack/stack.h b/openssl/stack/stack.h
new file mode 100644
index 0000000..8d6e939
--- /dev/null
+++ b/openssl/stack/stack.h
@@ -0,0 +1,106 @@
+/* crypto/stack/stack.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_STACK_H
+# define HEADER_STACK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct stack_st {
+ int num;
+ char **data;
+ int sorted;
+ int num_alloc;
+ int (*comp) (const void *, const void *);
+} _STACK; /* Use STACK_OF(...) instead */
+
+# define M_sk_num(sk) ((sk) ? (sk)->num:-1)
+# define M_sk_value(sk,n) ((sk) ? (sk)->data[n] : NULL)
+
+int sk_num(const _STACK *);
+void *sk_value(const _STACK *, int);
+
+void *sk_set(_STACK *, int, void *);
+
+_STACK *sk_new(int (*cmp) (const void *, const void *));
+_STACK *sk_new_null(void);
+void sk_free(_STACK *);
+void sk_pop_free(_STACK *st, void (*func) (void *));
+int sk_insert(_STACK *sk, void *data, int where);
+void *sk_delete(_STACK *st, int loc);
+void *sk_delete_ptr(_STACK *st, void *p);
+int sk_find(_STACK *st, void *data);
+int sk_find_ex(_STACK *st, void *data);
+int sk_push(_STACK *st, void *data);
+int sk_unshift(_STACK *st, void *data);
+void *sk_shift(_STACK *st);
+void *sk_pop(_STACK *st);
+void sk_zero(_STACK *st);
+int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *)))
+ (const void *, const void *);
+_STACK *sk_dup(_STACK *st);
+void sk_sort(_STACK *st);
+int sk_is_sorted(const _STACK *st);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/openssl/symhacks.h b/openssl/symhacks.h
new file mode 100644
index 0000000..2eadf7f
--- /dev/null
+++ b/openssl/symhacks.h
@@ -0,0 +1,486 @@
+/* ====================================================================
+ * Copyright (c) 1999 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 HEADER_SYMHACKS_H
+# define HEADER_SYMHACKS_H
+
+# include <openssl/e_os2.h>
+
+/*
+ * Hacks to solve the problem with linkers incapable of handling very long
+ * symbol names. In the case of VMS, the limit is 31 characters on VMS for
+ * VAX.
+ */
+/*
+ * Note that this affects util/libeay.num and util/ssleay.num... you may
+ * change those manually, but that's not recommended, as those files are
+ * controlled centrally and updated on Unix, and the central definition may
+ * disagree with yours, which in turn may come with shareable library
+ * incompatibilities.
+ */
+# ifdef OPENSSL_SYS_VMS
+
+/* Hack a long name in crypto/ex_data.c */
+# undef CRYPTO_get_ex_data_implementation
+# define CRYPTO_get_ex_data_implementation CRYPTO_get_ex_data_impl
+# undef CRYPTO_set_ex_data_implementation
+# define CRYPTO_set_ex_data_implementation CRYPTO_set_ex_data_impl
+
+/* Hack a long name in crypto/asn1/a_mbstr.c */
+# undef ASN1_STRING_set_default_mask_asc
+# define ASN1_STRING_set_default_mask_asc ASN1_STRING_set_def_mask_asc
+
+# if 0 /* No longer needed, since safestack macro
+ * magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) */
+# undef i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO
+# define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO i2d_ASN1_SET_OF_PKCS7_SIGINF
+# undef d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO
+# define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO d2i_ASN1_SET_OF_PKCS7_SIGINF
+# endif
+
+# if 0 /* No longer needed, since safestack macro
+ * magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) */
+# undef i2d_ASN1_SET_OF_PKCS7_RECIP_INFO
+# define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO i2d_ASN1_SET_OF_PKCS7_RECINF
+# undef d2i_ASN1_SET_OF_PKCS7_RECIP_INFO
+# define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO d2i_ASN1_SET_OF_PKCS7_RECINF
+# endif
+
+# if 0 /* No longer needed, since safestack macro
+ * magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) */
+# undef i2d_ASN1_SET_OF_ACCESS_DESCRIPTION
+# define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION i2d_ASN1_SET_OF_ACC_DESC
+# undef d2i_ASN1_SET_OF_ACCESS_DESCRIPTION
+# define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION d2i_ASN1_SET_OF_ACC_DESC
+# endif
+
+/* Hack the names created with DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE) */
+# undef PEM_read_NETSCAPE_CERT_SEQUENCE
+# define PEM_read_NETSCAPE_CERT_SEQUENCE PEM_read_NS_CERT_SEQ
+# undef PEM_write_NETSCAPE_CERT_SEQUENCE
+# define PEM_write_NETSCAPE_CERT_SEQUENCE PEM_write_NS_CERT_SEQ
+# undef PEM_read_bio_NETSCAPE_CERT_SEQUENCE
+# define PEM_read_bio_NETSCAPE_CERT_SEQUENCE PEM_read_bio_NS_CERT_SEQ
+# undef PEM_write_bio_NETSCAPE_CERT_SEQUENCE
+# define PEM_write_bio_NETSCAPE_CERT_SEQUENCE PEM_write_bio_NS_CERT_SEQ
+# undef PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE
+# define PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE PEM_write_cb_bio_NS_CERT_SEQ
+
+/* Hack the names created with DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO) */
+# undef PEM_read_PKCS8_PRIV_KEY_INFO
+# define PEM_read_PKCS8_PRIV_KEY_INFO PEM_read_P8_PRIV_KEY_INFO
+# undef PEM_write_PKCS8_PRIV_KEY_INFO
+# define PEM_write_PKCS8_PRIV_KEY_INFO PEM_write_P8_PRIV_KEY_INFO
+# undef PEM_read_bio_PKCS8_PRIV_KEY_INFO
+# define PEM_read_bio_PKCS8_PRIV_KEY_INFO PEM_read_bio_P8_PRIV_KEY_INFO
+# undef PEM_write_bio_PKCS8_PRIV_KEY_INFO
+# define PEM_write_bio_PKCS8_PRIV_KEY_INFO PEM_write_bio_P8_PRIV_KEY_INFO
+# undef PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO
+# define PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO PEM_wrt_cb_bio_P8_PRIV_KEY_INFO
+
+/* Hack other PEM names */
+# undef PEM_write_bio_PKCS8PrivateKey_nid
+# define PEM_write_bio_PKCS8PrivateKey_nid PEM_write_bio_PKCS8PrivKey_nid
+
+/* Hack some long X509 names */
+# undef X509_REVOKED_get_ext_by_critical
+# define X509_REVOKED_get_ext_by_critical X509_REVOKED_get_ext_by_critic
+# undef X509_policy_tree_get0_user_policies
+# define X509_policy_tree_get0_user_policies X509_pcy_tree_get0_usr_policies
+# undef X509_policy_node_get0_qualifiers
+# define X509_policy_node_get0_qualifiers X509_pcy_node_get0_qualifiers
+# undef X509_STORE_CTX_get_explicit_policy
+# define X509_STORE_CTX_get_explicit_policy X509_STORE_CTX_get_expl_policy
+# undef X509_STORE_CTX_get0_current_issuer
+# define X509_STORE_CTX_get0_current_issuer X509_STORE_CTX_get0_cur_issuer
+
+/* Hack some long CRYPTO names */
+# undef CRYPTO_set_dynlock_destroy_callback
+# define CRYPTO_set_dynlock_destroy_callback CRYPTO_set_dynlock_destroy_cb
+# undef CRYPTO_set_dynlock_create_callback
+# define CRYPTO_set_dynlock_create_callback CRYPTO_set_dynlock_create_cb
+# undef CRYPTO_set_dynlock_lock_callback
+# define CRYPTO_set_dynlock_lock_callback CRYPTO_set_dynlock_lock_cb
+# undef CRYPTO_get_dynlock_lock_callback
+# define CRYPTO_get_dynlock_lock_callback CRYPTO_get_dynlock_lock_cb
+# undef CRYPTO_get_dynlock_destroy_callback
+# define CRYPTO_get_dynlock_destroy_callback CRYPTO_get_dynlock_destroy_cb
+# undef CRYPTO_get_dynlock_create_callback
+# define CRYPTO_get_dynlock_create_callback CRYPTO_get_dynlock_create_cb
+# undef CRYPTO_set_locked_mem_ex_functions
+# define CRYPTO_set_locked_mem_ex_functions CRYPTO_set_locked_mem_ex_funcs
+# undef CRYPTO_get_locked_mem_ex_functions
+# define CRYPTO_get_locked_mem_ex_functions CRYPTO_get_locked_mem_ex_funcs
+
+/* Hack some long SSL names */
+# undef SSL_CTX_set_default_verify_paths
+# define SSL_CTX_set_default_verify_paths SSL_CTX_set_def_verify_paths
+# undef SSL_get_ex_data_X509_STORE_CTX_idx
+# define SSL_get_ex_data_X509_STORE_CTX_idx SSL_get_ex_d_X509_STORE_CTX_idx
+# undef SSL_add_file_cert_subjects_to_stack
+# define SSL_add_file_cert_subjects_to_stack SSL_add_file_cert_subjs_to_stk
+# undef SSL_add_dir_cert_subjects_to_stack
+# define SSL_add_dir_cert_subjects_to_stack SSL_add_dir_cert_subjs_to_stk
+# undef SSL_CTX_use_certificate_chain_file
+# define SSL_CTX_use_certificate_chain_file SSL_CTX_use_cert_chain_file
+# undef SSL_CTX_set_cert_verify_callback
+# define SSL_CTX_set_cert_verify_callback SSL_CTX_set_cert_verify_cb
+# undef SSL_CTX_set_default_passwd_cb_userdata
+# define SSL_CTX_set_default_passwd_cb_userdata SSL_CTX_set_def_passwd_cb_ud
+# undef SSL_COMP_get_compression_methods
+# define SSL_COMP_get_compression_methods SSL_COMP_get_compress_methods
+# undef ssl_add_clienthello_renegotiate_ext
+# define ssl_add_clienthello_renegotiate_ext ssl_add_clienthello_reneg_ext
+# undef ssl_add_serverhello_renegotiate_ext
+# define ssl_add_serverhello_renegotiate_ext ssl_add_serverhello_reneg_ext
+# undef ssl_parse_clienthello_renegotiate_ext
+# define ssl_parse_clienthello_renegotiate_ext ssl_parse_clienthello_reneg_ext
+# undef ssl_parse_serverhello_renegotiate_ext
+# define ssl_parse_serverhello_renegotiate_ext ssl_parse_serverhello_reneg_ext
+# undef SSL_srp_server_param_with_username
+# define SSL_srp_server_param_with_username SSL_srp_server_param_with_un
+# undef SSL_CTX_set_srp_client_pwd_callback
+# define SSL_CTX_set_srp_client_pwd_callback SSL_CTX_set_srp_client_pwd_cb
+# undef SSL_CTX_set_srp_verify_param_callback
+# define SSL_CTX_set_srp_verify_param_callback SSL_CTX_set_srp_vfy_param_cb
+# undef SSL_CTX_set_srp_username_callback
+# define SSL_CTX_set_srp_username_callback SSL_CTX_set_srp_un_cb
+# undef ssl_add_clienthello_use_srtp_ext
+# define ssl_add_clienthello_use_srtp_ext ssl_add_clihello_use_srtp_ext
+# undef ssl_add_serverhello_use_srtp_ext
+# define ssl_add_serverhello_use_srtp_ext ssl_add_serhello_use_srtp_ext
+# undef ssl_parse_clienthello_use_srtp_ext
+# define ssl_parse_clienthello_use_srtp_ext ssl_parse_clihello_use_srtp_ext
+# undef ssl_parse_serverhello_use_srtp_ext
+# define ssl_parse_serverhello_use_srtp_ext ssl_parse_serhello_use_srtp_ext
+# undef SSL_CTX_set_next_protos_advertised_cb
+# define SSL_CTX_set_next_protos_advertised_cb SSL_CTX_set_next_protos_adv_cb
+# undef SSL_CTX_set_next_proto_select_cb
+# define SSL_CTX_set_next_proto_select_cb SSL_CTX_set_next_proto_sel_cb
+# undef ssl3_cbc_record_digest_supported
+# define ssl3_cbc_record_digest_supported ssl3_cbc_record_digest_support
+# undef ssl_check_clienthello_tlsext_late
+# define ssl_check_clienthello_tlsext_late ssl_check_clihello_tlsext_late
+# undef ssl_check_clienthello_tlsext_early
+# define ssl_check_clienthello_tlsext_early ssl_check_clihello_tlsext_early
+
+/* Hack some long ENGINE names */
+# undef ENGINE_get_default_BN_mod_exp_crt
+# define ENGINE_get_default_BN_mod_exp_crt ENGINE_get_def_BN_mod_exp_crt
+# undef ENGINE_set_default_BN_mod_exp_crt
+# define ENGINE_set_default_BN_mod_exp_crt ENGINE_set_def_BN_mod_exp_crt
+# undef ENGINE_set_load_privkey_function
+# define ENGINE_set_load_privkey_function ENGINE_set_load_privkey_fn
+# undef ENGINE_get_load_privkey_function
+# define ENGINE_get_load_privkey_function ENGINE_get_load_privkey_fn
+# undef ENGINE_unregister_pkey_asn1_meths
+# define ENGINE_unregister_pkey_asn1_meths ENGINE_unreg_pkey_asn1_meths
+# undef ENGINE_register_all_pkey_asn1_meths
+# define ENGINE_register_all_pkey_asn1_meths ENGINE_reg_all_pkey_asn1_meths
+# undef ENGINE_set_default_pkey_asn1_meths
+# define ENGINE_set_default_pkey_asn1_meths ENGINE_set_def_pkey_asn1_meths
+# undef ENGINE_get_pkey_asn1_meth_engine
+# define ENGINE_get_pkey_asn1_meth_engine ENGINE_get_pkey_asn1_meth_eng
+# undef ENGINE_set_load_ssl_client_cert_function
+# define ENGINE_set_load_ssl_client_cert_function \
+ ENGINE_set_ld_ssl_clnt_cert_fn
+# undef ENGINE_get_ssl_client_cert_function
+# define ENGINE_get_ssl_client_cert_function ENGINE_get_ssl_client_cert_fn
+
+/* Hack some long OCSP names */
+# undef OCSP_REQUEST_get_ext_by_critical
+# define OCSP_REQUEST_get_ext_by_critical OCSP_REQUEST_get_ext_by_crit
+# undef OCSP_BASICRESP_get_ext_by_critical
+# define OCSP_BASICRESP_get_ext_by_critical OCSP_BASICRESP_get_ext_by_crit
+# undef OCSP_SINGLERESP_get_ext_by_critical
+# define OCSP_SINGLERESP_get_ext_by_critical OCSP_SINGLERESP_get_ext_by_crit
+
+/* Hack some long DES names */
+# undef _ossl_old_des_ede3_cfb64_encrypt
+# define _ossl_old_des_ede3_cfb64_encrypt _ossl_odes_ede3_cfb64_encrypt
+# undef _ossl_old_des_ede3_ofb64_encrypt
+# define _ossl_old_des_ede3_ofb64_encrypt _ossl_odes_ede3_ofb64_encrypt
+
+/* Hack some long EVP names */
+# undef OPENSSL_add_all_algorithms_noconf
+# define OPENSSL_add_all_algorithms_noconf OPENSSL_add_all_algo_noconf
+# undef OPENSSL_add_all_algorithms_conf
+# define OPENSSL_add_all_algorithms_conf OPENSSL_add_all_algo_conf
+# undef EVP_PKEY_meth_set_verify_recover
+# define EVP_PKEY_meth_set_verify_recover EVP_PKEY_meth_set_vrfy_recover
+
+/* Hack some long EC names */
+# undef EC_GROUP_set_point_conversion_form
+# define EC_GROUP_set_point_conversion_form EC_GROUP_set_point_conv_form
+# undef EC_GROUP_get_point_conversion_form
+# define EC_GROUP_get_point_conversion_form EC_GROUP_get_point_conv_form
+# undef EC_GROUP_clear_free_all_extra_data
+# define EC_GROUP_clear_free_all_extra_data EC_GROUP_clr_free_all_xtra_data
+# undef EC_KEY_set_public_key_affine_coordinates
+# define EC_KEY_set_public_key_affine_coordinates \
+ EC_KEY_set_pub_key_aff_coords
+# undef EC_POINT_set_Jprojective_coordinates_GFp
+# define EC_POINT_set_Jprojective_coordinates_GFp \
+ EC_POINT_set_Jproj_coords_GFp
+# undef EC_POINT_get_Jprojective_coordinates_GFp
+# define EC_POINT_get_Jprojective_coordinates_GFp \
+ EC_POINT_get_Jproj_coords_GFp
+# undef EC_POINT_set_affine_coordinates_GFp
+# define EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coords_GFp
+# undef EC_POINT_get_affine_coordinates_GFp
+# define EC_POINT_get_affine_coordinates_GFp EC_POINT_get_affine_coords_GFp
+# undef EC_POINT_set_compressed_coordinates_GFp
+# define EC_POINT_set_compressed_coordinates_GFp EC_POINT_set_compr_coords_GFp
+# undef EC_POINT_set_affine_coordinates_GF2m
+# define EC_POINT_set_affine_coordinates_GF2m EC_POINT_set_affine_coords_GF2m
+# undef EC_POINT_get_affine_coordinates_GF2m
+# define EC_POINT_get_affine_coordinates_GF2m EC_POINT_get_affine_coords_GF2m
+# undef EC_POINT_set_compressed_coordinates_GF2m
+# define EC_POINT_set_compressed_coordinates_GF2m \
+ EC_POINT_set_compr_coords_GF2m
+# undef ec_GF2m_simple_group_clear_finish
+# define ec_GF2m_simple_group_clear_finish ec_GF2m_simple_grp_clr_finish
+# undef ec_GF2m_simple_group_check_discriminant
+# define ec_GF2m_simple_group_check_discriminant ec_GF2m_simple_grp_chk_discrim
+# undef ec_GF2m_simple_point_clear_finish
+# define ec_GF2m_simple_point_clear_finish ec_GF2m_simple_pt_clr_finish
+# undef ec_GF2m_simple_point_set_to_infinity
+# define ec_GF2m_simple_point_set_to_infinity ec_GF2m_simple_pt_set_to_inf
+# undef ec_GF2m_simple_points_make_affine
+# define ec_GF2m_simple_points_make_affine ec_GF2m_simple_pts_make_affine
+# undef ec_GF2m_simple_point_set_affine_coordinates
+# define ec_GF2m_simple_point_set_affine_coordinates \
+ ec_GF2m_smp_pt_set_af_coords
+# undef ec_GF2m_simple_point_get_affine_coordinates
+# define ec_GF2m_simple_point_get_affine_coordinates \
+ ec_GF2m_smp_pt_get_af_coords
+# undef ec_GF2m_simple_set_compressed_coordinates
+# define ec_GF2m_simple_set_compressed_coordinates \
+ ec_GF2m_smp_set_compr_coords
+# undef ec_GFp_simple_group_set_curve_GFp
+# define ec_GFp_simple_group_set_curve_GFp ec_GFp_simple_grp_set_curve_GFp
+# undef ec_GFp_simple_group_get_curve_GFp
+# define ec_GFp_simple_group_get_curve_GFp ec_GFp_simple_grp_get_curve_GFp
+# undef ec_GFp_simple_group_clear_finish
+# define ec_GFp_simple_group_clear_finish ec_GFp_simple_grp_clear_finish
+# undef ec_GFp_simple_group_set_generator
+# define ec_GFp_simple_group_set_generator ec_GFp_simple_grp_set_generator
+# undef ec_GFp_simple_group_get0_generator
+# define ec_GFp_simple_group_get0_generator ec_GFp_simple_grp_gt0_generator
+# undef ec_GFp_simple_group_get_cofactor
+# define ec_GFp_simple_group_get_cofactor ec_GFp_simple_grp_get_cofactor
+# undef ec_GFp_simple_point_clear_finish
+# define ec_GFp_simple_point_clear_finish ec_GFp_simple_pt_clear_finish
+# undef ec_GFp_simple_point_set_to_infinity
+# define ec_GFp_simple_point_set_to_infinity ec_GFp_simple_pt_set_to_inf
+# undef ec_GFp_simple_points_make_affine
+# define ec_GFp_simple_points_make_affine ec_GFp_simple_pts_make_affine
+# undef ec_GFp_simple_set_Jprojective_coordinates_GFp
+# define ec_GFp_simple_set_Jprojective_coordinates_GFp \
+ ec_GFp_smp_set_Jproj_coords_GFp
+# undef ec_GFp_simple_get_Jprojective_coordinates_GFp
+# define ec_GFp_simple_get_Jprojective_coordinates_GFp \
+ ec_GFp_smp_get_Jproj_coords_GFp
+# undef ec_GFp_simple_point_set_affine_coordinates_GFp
+# define ec_GFp_simple_point_set_affine_coordinates_GFp \
+ ec_GFp_smp_pt_set_af_coords_GFp
+# undef ec_GFp_simple_point_get_affine_coordinates_GFp
+# define ec_GFp_simple_point_get_affine_coordinates_GFp \
+ ec_GFp_smp_pt_get_af_coords_GFp
+# undef ec_GFp_simple_set_compressed_coordinates_GFp
+# define ec_GFp_simple_set_compressed_coordinates_GFp \
+ ec_GFp_smp_set_compr_coords_GFp
+# undef ec_GFp_simple_point_set_affine_coordinates
+# define ec_GFp_simple_point_set_affine_coordinates \
+ ec_GFp_smp_pt_set_af_coords
+# undef ec_GFp_simple_point_get_affine_coordinates
+# define ec_GFp_simple_point_get_affine_coordinates \
+ ec_GFp_smp_pt_get_af_coords
+# undef ec_GFp_simple_set_compressed_coordinates
+# define ec_GFp_simple_set_compressed_coordinates \
+ ec_GFp_smp_set_compr_coords
+# undef ec_GFp_simple_group_check_discriminant
+# define ec_GFp_simple_group_check_discriminant ec_GFp_simple_grp_chk_discrim
+
+/* Hack som long STORE names */
+# undef STORE_method_set_initialise_function
+# define STORE_method_set_initialise_function STORE_meth_set_initialise_fn
+# undef STORE_method_set_cleanup_function
+# define STORE_method_set_cleanup_function STORE_meth_set_cleanup_fn
+# undef STORE_method_set_generate_function
+# define STORE_method_set_generate_function STORE_meth_set_generate_fn
+# undef STORE_method_set_modify_function
+# define STORE_method_set_modify_function STORE_meth_set_modify_fn
+# undef STORE_method_set_revoke_function
+# define STORE_method_set_revoke_function STORE_meth_set_revoke_fn
+# undef STORE_method_set_delete_function
+# define STORE_method_set_delete_function STORE_meth_set_delete_fn
+# undef STORE_method_set_list_start_function
+# define STORE_method_set_list_start_function STORE_meth_set_list_start_fn
+# undef STORE_method_set_list_next_function
+# define STORE_method_set_list_next_function STORE_meth_set_list_next_fn
+# undef STORE_method_set_list_end_function
+# define STORE_method_set_list_end_function STORE_meth_set_list_end_fn
+# undef STORE_method_set_update_store_function
+# define STORE_method_set_update_store_function STORE_meth_set_update_store_fn
+# undef STORE_method_set_lock_store_function
+# define STORE_method_set_lock_store_function STORE_meth_set_lock_store_fn
+# undef STORE_method_set_unlock_store_function
+# define STORE_method_set_unlock_store_function STORE_meth_set_unlock_store_fn
+# undef STORE_method_get_initialise_function
+# define STORE_method_get_initialise_function STORE_meth_get_initialise_fn
+# undef STORE_method_get_cleanup_function
+# define STORE_method_get_cleanup_function STORE_meth_get_cleanup_fn
+# undef STORE_method_get_generate_function
+# define STORE_method_get_generate_function STORE_meth_get_generate_fn
+# undef STORE_method_get_modify_function
+# define STORE_method_get_modify_function STORE_meth_get_modify_fn
+# undef STORE_method_get_revoke_function
+# define STORE_method_get_revoke_function STORE_meth_get_revoke_fn
+# undef STORE_method_get_delete_function
+# define STORE_method_get_delete_function STORE_meth_get_delete_fn
+# undef STORE_method_get_list_start_function
+# define STORE_method_get_list_start_function STORE_meth_get_list_start_fn
+# undef STORE_method_get_list_next_function
+# define STORE_method_get_list_next_function STORE_meth_get_list_next_fn
+# undef STORE_method_get_list_end_function
+# define STORE_method_get_list_end_function STORE_meth_get_list_end_fn
+# undef STORE_method_get_update_store_function
+# define STORE_method_get_update_store_function STORE_meth_get_update_store_fn
+# undef STORE_method_get_lock_store_function
+# define STORE_method_get_lock_store_function STORE_meth_get_lock_store_fn
+# undef STORE_method_get_unlock_store_function
+# define STORE_method_get_unlock_store_function STORE_meth_get_unlock_store_fn
+
+/* Hack some long TS names */
+# undef TS_RESP_CTX_set_status_info_cond
+# define TS_RESP_CTX_set_status_info_cond TS_RESP_CTX_set_stat_info_cond
+# undef TS_RESP_CTX_set_clock_precision_digits
+# define TS_RESP_CTX_set_clock_precision_digits TS_RESP_CTX_set_clk_prec_digits
+# undef TS_CONF_set_clock_precision_digits
+# define TS_CONF_set_clock_precision_digits TS_CONF_set_clk_prec_digits
+
+/* Hack some long CMS names */
+# undef CMS_RecipientInfo_ktri_get0_algs
+# define CMS_RecipientInfo_ktri_get0_algs CMS_RecipInfo_ktri_get0_algs
+# undef CMS_RecipientInfo_ktri_get0_signer_id
+# define CMS_RecipientInfo_ktri_get0_signer_id CMS_RecipInfo_ktri_get0_sigr_id
+# undef CMS_OtherRevocationInfoFormat_it
+# define CMS_OtherRevocationInfoFormat_it CMS_OtherRevocInfoFormat_it
+# undef CMS_KeyAgreeRecipientIdentifier_it
+# define CMS_KeyAgreeRecipientIdentifier_it CMS_KeyAgreeRecipIdentifier_it
+# undef CMS_OriginatorIdentifierOrKey_it
+# define CMS_OriginatorIdentifierOrKey_it CMS_OriginatorIdOrKey_it
+# undef cms_SignerIdentifier_get0_signer_id
+# define cms_SignerIdentifier_get0_signer_id cms_SignerId_get0_signer_id
+
+/* Hack some long DTLS1 names */
+# undef dtls1_retransmit_buffered_messages
+# define dtls1_retransmit_buffered_messages dtls1_retransmit_buffered_msgs
+
+/* Hack some long SRP names */
+# undef SRP_generate_server_master_secret
+# define SRP_generate_server_master_secret SRP_gen_server_master_secret
+# undef SRP_generate_client_master_secret
+# define SRP_generate_client_master_secret SRP_gen_client_master_secret
+
+/* Hack some long UI names */
+# undef UI_method_get_prompt_constructor
+# define UI_method_get_prompt_constructor UI_method_get_prompt_constructr
+# undef UI_method_set_prompt_constructor
+# define UI_method_set_prompt_constructor UI_method_set_prompt_constructr
+
+# endif /* defined OPENSSL_SYS_VMS */
+
+/* Case insensitive linking causes problems.... */
+# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2)
+# undef ERR_load_CRYPTO_strings
+# define ERR_load_CRYPTO_strings ERR_load_CRYPTOlib_strings
+# undef OCSP_crlID_new
+# define OCSP_crlID_new OCSP_crlID2_new
+
+# undef d2i_ECPARAMETERS
+# define d2i_ECPARAMETERS d2i_UC_ECPARAMETERS
+# undef i2d_ECPARAMETERS
+# define i2d_ECPARAMETERS i2d_UC_ECPARAMETERS
+# undef d2i_ECPKPARAMETERS
+# define d2i_ECPKPARAMETERS d2i_UC_ECPKPARAMETERS
+# undef i2d_ECPKPARAMETERS
+# define i2d_ECPKPARAMETERS i2d_UC_ECPKPARAMETERS
+
+/*
+ * These functions do not seem to exist! However, I'm paranoid... Original
+ * command in x509v3.h: These functions are being redefined in another
+ * directory, and clash when the linker is case-insensitive, so let's hide
+ * them a little, by giving them an extra 'o' at the beginning of the name...
+ */
+# undef X509v3_cleanup_extensions
+# define X509v3_cleanup_extensions oX509v3_cleanup_extensions
+# undef X509v3_add_extension
+# define X509v3_add_extension oX509v3_add_extension
+# undef X509v3_add_netscape_extensions
+# define X509v3_add_netscape_extensions oX509v3_add_netscape_extensions
+# undef X509v3_add_standard_extensions
+# define X509v3_add_standard_extensions oX509v3_add_standard_extensions
+
+/* This one clashes with CMS_data_create */
+# undef cms_Data_create
+# define cms_Data_create priv_cms_Data_create
+
+# endif
+
+#endif /* ! defined HEADER_VMS_IDHACKS_H */
diff --git a/openssl/x509.h b/openssl/x509.h
new file mode 120000
index 0000000..b8febb1
--- /dev/null
+++ b/openssl/x509.h
@@ -0,0 +1 @@
+x509/x509.h
\ No newline at end of file
diff --git a/openssl/x509/x509.h b/openssl/x509/x509.h
new file mode 100644
index 0000000..a491174
--- /dev/null
+++ b/openssl/x509/x509.h
@@ -0,0 +1,1301 @@
+/* crypto/x509/x509.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * 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_X509_H
+# define HEADER_X509_H
+
+# include <openssl/e_os2.h>
+# include <openssl/symhacks.h>
+# ifndef OPENSSL_NO_BUFFER
+# include <openssl/buffer.h>
+# endif
+# ifndef OPENSSL_NO_EVP
+# include <openssl/evp.h>
+# endif
+# ifndef OPENSSL_NO_BIO
+# include <openssl/bio.h>
+# endif
+# include <openssl/stack.h>
+# include <openssl/asn1.h>
+# include <openssl/safestack.h>
+
+# ifndef OPENSSL_NO_EC
+# include <openssl/ec.h>
+# endif
+
+# ifndef OPENSSL_NO_ECDSA
+# include <openssl/ecdsa.h>
+# endif
+
+# ifndef OPENSSL_NO_ECDH
+# include <openssl/ecdh.h>
+# endif
+
+# ifndef OPENSSL_NO_DEPRECATED
+# ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# endif
+# ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+# endif
+# ifndef OPENSSL_NO_DH
+# include <openssl/dh.h>
+# endif
+# endif
+
+# ifndef OPENSSL_NO_SHA
+# include <openssl/sha.h>
+# endif
+# include <openssl/ossl_typ.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# ifdef OPENSSL_SYS_WIN32
+/* Under Win32 these are defined in wincrypt.h */
+# undef X509_NAME
+# undef X509_CERT_PAIR
+# undef X509_EXTENSIONS
+# endif
+
+# define X509_FILETYPE_PEM 1
+# define X509_FILETYPE_ASN1 2
+# define X509_FILETYPE_DEFAULT 3
+
+# define X509v3_KU_DIGITAL_SIGNATURE 0x0080
+# define X509v3_KU_NON_REPUDIATION 0x0040
+# define X509v3_KU_KEY_ENCIPHERMENT 0x0020
+# define X509v3_KU_DATA_ENCIPHERMENT 0x0010
+# define X509v3_KU_KEY_AGREEMENT 0x0008
+# define X509v3_KU_KEY_CERT_SIGN 0x0004
+# define X509v3_KU_CRL_SIGN 0x0002
+# define X509v3_KU_ENCIPHER_ONLY 0x0001
+# define X509v3_KU_DECIPHER_ONLY 0x8000
+# define X509v3_KU_UNDEF 0xffff
+
+typedef struct X509_objects_st {
+ int nid;
+ int (*a2i) (void);
+ int (*i2a) (void);
+} X509_OBJECTS;
+
+struct X509_algor_st {
+ ASN1_OBJECT *algorithm;
+ ASN1_TYPE *parameter;
+} /* X509_ALGOR */ ;
+
+DECLARE_ASN1_SET_OF(X509_ALGOR)
+
+typedef STACK_OF(X509_ALGOR) X509_ALGORS;
+
+typedef struct X509_val_st {
+ ASN1_TIME *notBefore;
+ ASN1_TIME *notAfter;
+} X509_VAL;
+
+struct X509_pubkey_st {
+ X509_ALGOR *algor;
+ ASN1_BIT_STRING *public_key;
+ EVP_PKEY *pkey;
+};
+
+typedef struct X509_sig_st {
+ X509_ALGOR *algor;
+ ASN1_OCTET_STRING *digest;
+} X509_SIG;
+
+typedef struct X509_name_entry_st {
+ ASN1_OBJECT *object;
+ ASN1_STRING *value;
+ int set;
+ int size; /* temp variable */
+} X509_NAME_ENTRY;
+
+DECLARE_STACK_OF(X509_NAME_ENTRY)
+DECLARE_ASN1_SET_OF(X509_NAME_ENTRY)
+
+/* we always keep X509_NAMEs in 2 forms. */
+struct X509_name_st {
+ STACK_OF(X509_NAME_ENTRY) *entries;
+ int modified; /* true if 'bytes' needs to be built */
+# ifndef OPENSSL_NO_BUFFER
+ BUF_MEM *bytes;
+# else
+ char *bytes;
+# endif
+/* unsigned long hash; Keep the hash around for lookups */
+ unsigned char *canon_enc;
+ int canon_enclen;
+} /* X509_NAME */ ;
+
+DECLARE_STACK_OF(X509_NAME)
+
+# define X509_EX_V_NETSCAPE_HACK 0x8000
+# define X509_EX_V_INIT 0x0001
+typedef struct X509_extension_st {
+ ASN1_OBJECT *object;
+ ASN1_BOOLEAN critical;
+ ASN1_OCTET_STRING *value;
+} X509_EXTENSION;
+
+typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
+
+DECLARE_STACK_OF(X509_EXTENSION)
+DECLARE_ASN1_SET_OF(X509_EXTENSION)
+
+/* a sequence of these are used */
+typedef struct x509_attributes_st {
+ ASN1_OBJECT *object;
+ int single; /* 0 for a set, 1 for a single item (which is
+ * wrong) */
+ union {
+ char *ptr;
+ /*
+ * 0
+ */ STACK_OF(ASN1_TYPE) *set;
+ /*
+ * 1
+ */ ASN1_TYPE *single;
+ } value;
+} X509_ATTRIBUTE;
+
+DECLARE_STACK_OF(X509_ATTRIBUTE)
+DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)
+
+typedef struct X509_req_info_st {
+ ASN1_ENCODING enc;
+ ASN1_INTEGER *version;
+ X509_NAME *subject;
+ X509_PUBKEY *pubkey;
+ /* d=2 hl=2 l= 0 cons: cont: 00 */
+ STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+} X509_REQ_INFO;
+
+typedef struct X509_req_st {
+ X509_REQ_INFO *req_info;
+ X509_ALGOR *sig_alg;
+ ASN1_BIT_STRING *signature;
+ int references;
+} X509_REQ;
+
+typedef struct x509_cinf_st {
+ ASN1_INTEGER *version; /* [ 0 ] default of v1 */
+ ASN1_INTEGER *serialNumber;
+ X509_ALGOR *signature;
+ X509_NAME *issuer;
+ X509_VAL *validity;
+ X509_NAME *subject;
+ X509_PUBKEY *key;
+ ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */
+ ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */
+ STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */
+ ASN1_ENCODING enc;
+} X509_CINF;
+
+/*
+ * This stuff is certificate "auxiliary info" it contains details which are
+ * useful in certificate stores and databases. When used this is tagged onto
+ * the end of the certificate itself
+ */
+
+typedef struct x509_cert_aux_st {
+ STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */
+ STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */
+ ASN1_UTF8STRING *alias; /* "friendly name" */
+ ASN1_OCTET_STRING *keyid; /* key id of private key */
+ STACK_OF(X509_ALGOR) *other; /* other unspecified info */
+} X509_CERT_AUX;
+
+struct x509_st {
+ X509_CINF *cert_info;
+ X509_ALGOR *sig_alg;
+ ASN1_BIT_STRING *signature;
+ int valid;
+ int references;
+ char *name;
+ CRYPTO_EX_DATA ex_data;
+ /* These contain copies of various extension values */
+ long ex_pathlen;
+ long ex_pcpathlen;
+ unsigned long ex_flags;
+ unsigned long ex_kusage;
+ unsigned long ex_xkusage;
+ unsigned long ex_nscert;
+ ASN1_OCTET_STRING *skid;
+ AUTHORITY_KEYID *akid;
+ X509_POLICY_CACHE *policy_cache;
+ STACK_OF(DIST_POINT) *crldp;
+ STACK_OF(GENERAL_NAME) *altname;
+ NAME_CONSTRAINTS *nc;
+# ifndef OPENSSL_NO_RFC3779
+ STACK_OF(IPAddressFamily) *rfc3779_addr;
+ struct ASIdentifiers_st *rfc3779_asid;
+# endif
+# ifndef OPENSSL_NO_SHA
+ unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+# endif
+ X509_CERT_AUX *aux;
+} /* X509 */ ;
+
+DECLARE_STACK_OF(X509)
+DECLARE_ASN1_SET_OF(X509)
+
+/* This is used for a table of trust checking functions */
+
+typedef struct x509_trust_st {
+ int trust;
+ int flags;
+ int (*check_trust) (struct x509_trust_st *, X509 *, int);
+ char *name;
+ int arg1;
+ void *arg2;
+} X509_TRUST;
+
+DECLARE_STACK_OF(X509_TRUST)
+
+typedef struct x509_cert_pair_st {
+ X509 *forward;
+ X509 *reverse;
+} X509_CERT_PAIR;
+
+/* standard trust ids */
+
+# define X509_TRUST_DEFAULT -1/* Only valid in purpose settings */
+
+# define X509_TRUST_COMPAT 1
+# define X509_TRUST_SSL_CLIENT 2
+# define X509_TRUST_SSL_SERVER 3
+# define X509_TRUST_EMAIL 4
+# define X509_TRUST_OBJECT_SIGN 5
+# define X509_TRUST_OCSP_SIGN 6
+# define X509_TRUST_OCSP_REQUEST 7
+# define X509_TRUST_TSA 8
+
+/* Keep these up to date! */
+# define X509_TRUST_MIN 1
+# define X509_TRUST_MAX 8
+
+/* trust_flags values */
+# define X509_TRUST_DYNAMIC 1
+# define X509_TRUST_DYNAMIC_NAME 2
+
+/* check_trust return codes */
+
+# define X509_TRUST_TRUSTED 1
+# define X509_TRUST_REJECTED 2
+# define X509_TRUST_UNTRUSTED 3
+
+/* Flags for X509_print_ex() */
+
+# define X509_FLAG_COMPAT 0
+# define X509_FLAG_NO_HEADER 1L
+# define X509_FLAG_NO_VERSION (1L << 1)
+# define X509_FLAG_NO_SERIAL (1L << 2)
+# define X509_FLAG_NO_SIGNAME (1L << 3)
+# define X509_FLAG_NO_ISSUER (1L << 4)
+# define X509_FLAG_NO_VALIDITY (1L << 5)
+# define X509_FLAG_NO_SUBJECT (1L << 6)
+# define X509_FLAG_NO_PUBKEY (1L << 7)
+# define X509_FLAG_NO_EXTENSIONS (1L << 8)
+# define X509_FLAG_NO_SIGDUMP (1L << 9)
+# define X509_FLAG_NO_AUX (1L << 10)
+# define X509_FLAG_NO_ATTRIBUTES (1L << 11)
+
+/* Flags specific to X509_NAME_print_ex() */
+
+/* The field separator information */
+
+# define XN_FLAG_SEP_MASK (0xf << 16)
+
+# define XN_FLAG_COMPAT 0/* Traditional SSLeay: use old
+ * X509_NAME_print */
+# define XN_FLAG_SEP_COMMA_PLUS (1 << 16)/* RFC2253 ,+ */
+# define XN_FLAG_SEP_CPLUS_SPC (2 << 16)/* ,+ spaced: more readable */
+# define XN_FLAG_SEP_SPLUS_SPC (3 << 16)/* ;+ spaced */
+# define XN_FLAG_SEP_MULTILINE (4 << 16)/* One line per field */
+
+# define XN_FLAG_DN_REV (1 << 20)/* Reverse DN order */
+
+/* How the field name is shown */
+
+# define XN_FLAG_FN_MASK (0x3 << 21)
+
+# define XN_FLAG_FN_SN 0/* Object short name */
+# define XN_FLAG_FN_LN (1 << 21)/* Object long name */
+# define XN_FLAG_FN_OID (2 << 21)/* Always use OIDs */
+# define XN_FLAG_FN_NONE (3 << 21)/* No field names */
+
+# define XN_FLAG_SPC_EQ (1 << 23)/* Put spaces round '=' */
+
+/*
+ * This determines if we dump fields we don't recognise: RFC2253 requires
+ * this.
+ */
+
+# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)
+
+# define XN_FLAG_FN_ALIGN (1 << 25)/* Align field names to 20
+ * characters */
+
+/* Complete set of RFC2253 flags */
+
+# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
+ XN_FLAG_SEP_COMMA_PLUS | \
+ XN_FLAG_DN_REV | \
+ XN_FLAG_FN_SN | \
+ XN_FLAG_DUMP_UNKNOWN_FIELDS)
+
+/* readable oneline form */
+
+# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
+ ASN1_STRFLGS_ESC_QUOTE | \
+ XN_FLAG_SEP_CPLUS_SPC | \
+ XN_FLAG_SPC_EQ | \
+ XN_FLAG_FN_SN)
+
+/* readable multiline form */
+
+# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
+ ASN1_STRFLGS_ESC_MSB | \
+ XN_FLAG_SEP_MULTILINE | \
+ XN_FLAG_SPC_EQ | \
+ XN_FLAG_FN_LN | \
+ XN_FLAG_FN_ALIGN)
+
+struct x509_revoked_st {
+ ASN1_INTEGER *serialNumber;
+ ASN1_TIME *revocationDate;
+ STACK_OF(X509_EXTENSION) /* optional */ *extensions;
+ /* Set up if indirect CRL */
+ STACK_OF(GENERAL_NAME) *issuer;
+ /* Revocation reason */
+ int reason;
+ int sequence; /* load sequence */
+};
+
+DECLARE_STACK_OF(X509_REVOKED)
+DECLARE_ASN1_SET_OF(X509_REVOKED)
+
+typedef struct X509_crl_info_st {
+ ASN1_INTEGER *version;
+ X509_ALGOR *sig_alg;
+ X509_NAME *issuer;
+ ASN1_TIME *lastUpdate;
+ ASN1_TIME *nextUpdate;
+ STACK_OF(X509_REVOKED) *revoked;
+ STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
+ ASN1_ENCODING enc;
+} X509_CRL_INFO;
+
+struct X509_crl_st {
+ /* actual signature */
+ X509_CRL_INFO *crl;
+ X509_ALGOR *sig_alg;
+ ASN1_BIT_STRING *signature;
+ int references;
+ int flags;
+ /* Copies of various extensions */
+ AUTHORITY_KEYID *akid;
+ ISSUING_DIST_POINT *idp;
+ /* Convenient breakdown of IDP */
+ int idp_flags;
+ int idp_reasons;
+ /* CRL and base CRL numbers for delta processing */
+ ASN1_INTEGER *crl_number;
+ ASN1_INTEGER *base_crl_number;
+# ifndef OPENSSL_NO_SHA
+ unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+# endif
+ STACK_OF(GENERAL_NAMES) *issuers;
+ const X509_CRL_METHOD *meth;
+ void *meth_data;
+} /* X509_CRL */ ;
+
+DECLARE_STACK_OF(X509_CRL)
+DECLARE_ASN1_SET_OF(X509_CRL)
+
+typedef struct private_key_st {
+ int version;
+ /* The PKCS#8 data types */
+ X509_ALGOR *enc_algor;
+ ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */
+ /* When decrypted, the following will not be NULL */
+ EVP_PKEY *dec_pkey;
+ /* used to encrypt and decrypt */
+ int key_length;
+ char *key_data;
+ int key_free; /* true if we should auto free key_data */
+ /* expanded version of 'enc_algor' */
+ EVP_CIPHER_INFO cipher;
+ int references;
+} X509_PKEY;
+
+# ifndef OPENSSL_NO_EVP
+typedef struct X509_info_st {
+ X509 *x509;
+ X509_CRL *crl;
+ X509_PKEY *x_pkey;
+ EVP_CIPHER_INFO enc_cipher;
+ int enc_len;
+ char *enc_data;
+ int references;
+} X509_INFO;
+
+DECLARE_STACK_OF(X509_INFO)
+# endif
+
+/*
+ * The next 2 structures and their 8 routines were sent to me by Pat Richard
+ * <patr@x509.com> and are used to manipulate Netscapes spki structures -
+ * useful if you are writing a CA web page
+ */
+typedef struct Netscape_spkac_st {
+ X509_PUBKEY *pubkey;
+ ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */
+} NETSCAPE_SPKAC;
+
+typedef struct Netscape_spki_st {
+ NETSCAPE_SPKAC *spkac; /* signed public key and challenge */
+ X509_ALGOR *sig_algor;
+ ASN1_BIT_STRING *signature;
+} NETSCAPE_SPKI;
+
+/* Netscape certificate sequence structure */
+typedef struct Netscape_certificate_sequence {
+ ASN1_OBJECT *type;
+ STACK_OF(X509) *certs;
+} NETSCAPE_CERT_SEQUENCE;
+
+/*- Unused (and iv length is wrong)
+typedef struct CBCParameter_st
+ {
+ unsigned char iv[8];
+ } CBC_PARAM;
+*/
+
+/* Password based encryption structure */
+
+typedef struct PBEPARAM_st {
+ ASN1_OCTET_STRING *salt;
+ ASN1_INTEGER *iter;
+} PBEPARAM;
+
+/* Password based encryption V2 structures */
+
+typedef struct PBE2PARAM_st {
+ X509_ALGOR *keyfunc;
+ X509_ALGOR *encryption;
+} PBE2PARAM;
+
+typedef struct PBKDF2PARAM_st {
+/* Usually OCTET STRING but could be anything */
+ ASN1_TYPE *salt;
+ ASN1_INTEGER *iter;
+ ASN1_INTEGER *keylength;
+ X509_ALGOR *prf;
+} PBKDF2PARAM;
+
+/* PKCS#8 private key info structure */
+
+struct pkcs8_priv_key_info_st {
+ /* Flag for various broken formats */
+ int broken;
+# define PKCS8_OK 0
+# define PKCS8_NO_OCTET 1
+# define PKCS8_EMBEDDED_PARAM 2
+# define PKCS8_NS_DB 3
+# define PKCS8_NEG_PRIVKEY 4
+ ASN1_INTEGER *version;
+ X509_ALGOR *pkeyalg;
+ /* Should be OCTET STRING but some are broken */
+ ASN1_TYPE *pkey;
+ STACK_OF(X509_ATTRIBUTE) *attributes;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+# include <openssl/x509_vfy.h>
+# include <openssl/pkcs7.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# define X509_EXT_PACK_UNKNOWN 1
+# define X509_EXT_PACK_STRING 2
+
+# define X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version)
+/* #define X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */
+# define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
+# define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
+# define X509_extract_key(x) X509_get_pubkey(x)/*****/
+# define X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version)
+# define X509_REQ_get_subject_name(x) ((x)->req_info->subject)
+# define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a)
+# define X509_name_cmp(a,b) X509_NAME_cmp((a),(b))
+# define X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm))
+
+# define X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version)
+# define X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate)
+# define X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate)
+# define X509_CRL_get_issuer(x) ((x)->crl->issuer)
+# define X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
+
+void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
+X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
+ int (*crl_free) (X509_CRL *crl),
+ int (*crl_lookup) (X509_CRL *crl,
+ X509_REVOKED **ret,
+ ASN1_INTEGER *ser,
+ X509_NAME *issuer),
+ int (*crl_verify) (X509_CRL *crl,
+ EVP_PKEY *pk));
+void X509_CRL_METHOD_free(X509_CRL_METHOD *m);
+
+void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
+void *X509_CRL_get_meth_data(X509_CRL *crl);
+
+/*
+ * This one is only used so that a binary form can output, as in
+ * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf)
+ */
+# define X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
+
+const char *X509_verify_cert_error_string(long n);
+
+# ifndef OPENSSL_NO_EVP
+int X509_verify(X509 *a, EVP_PKEY *r);
+
+int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
+int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
+
+NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len);
+char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
+
+int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent);
+int X509_signature_print(BIO *bp, X509_ALGOR *alg, ASN1_STRING *sig);
+
+int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
+int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
+int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
+
+int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
+ unsigned char *md, unsigned int *len);
+int X509_digest(const X509 *data, const EVP_MD *type,
+ unsigned char *md, unsigned int *len);
+int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
+ unsigned char *md, unsigned int *len);
+int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
+ unsigned char *md, unsigned int *len);
+int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
+ unsigned char *md, unsigned int *len);
+# endif
+
+# ifndef OPENSSL_NO_FP_API
+X509 *d2i_X509_fp(FILE *fp, X509 **x509);
+int i2d_X509_fp(FILE *fp, X509 *x509);
+X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl);
+int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req);
+int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req);
+# ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa);
+int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa);
+RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa);
+int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa);
+RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa);
+int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa);
+# endif
+# ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
+int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
+int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
+# endif
+# ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
+int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
+int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
+# endif
+X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8);
+int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
+ PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
+int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
+int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
+# endif
+
+# ifndef OPENSSL_NO_BIO
+X509 *d2i_X509_bio(BIO *bp, X509 **x509);
+int i2d_X509_bio(BIO *bp, X509 *x509);
+X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl);
+int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req);
+int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req);
+# ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa);
+int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa);
+RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa);
+int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa);
+RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa);
+int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa);
+# endif
+# ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
+int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
+int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
+# endif
+# ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
+int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
+int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
+# endif
+X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8);
+int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
+ PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
+int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
+int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
+# endif
+
+X509 *X509_dup(X509 *x509);
+X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
+X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
+X509_CRL *X509_CRL_dup(X509_CRL *crl);
+X509_REQ *X509_REQ_dup(X509_REQ *req);
+X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
+int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype,
+ void *pval);
+void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
+ X509_ALGOR *algor);
+void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
+
+X509_NAME *X509_NAME_dup(X509_NAME *xn);
+X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
+
+int X509_cmp_time(const ASN1_TIME *s, time_t *t);
+int X509_cmp_current_time(const ASN1_TIME *s);
+ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
+ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
+ int offset_day, long offset_sec, time_t *t);
+ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj);
+
+const char *X509_get_default_cert_area(void);
+const char *X509_get_default_cert_dir(void);
+const char *X509_get_default_cert_file(void);
+const char *X509_get_default_cert_dir_env(void);
+const char *X509_get_default_cert_file_env(void);
+const char *X509_get_default_private_dir(void);
+
+X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey);
+
+DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
+DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS)
+DECLARE_ASN1_FUNCTIONS(X509_VAL)
+
+DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)
+
+int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
+EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key);
+int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain);
+int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp);
+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length);
+# ifndef OPENSSL_NO_RSA
+int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp);
+RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length);
+# endif
+# ifndef OPENSSL_NO_DSA
+int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp);
+DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length);
+# endif
+# ifndef OPENSSL_NO_EC
+int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp);
+EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length);
+# endif
+
+DECLARE_ASN1_FUNCTIONS(X509_SIG)
+DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_REQ)
+
+DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
+X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
+
+DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
+DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME)
+
+int X509_NAME_set(X509_NAME **xn, X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(X509_CINF)
+
+DECLARE_ASN1_FUNCTIONS(X509)
+DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
+
+DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR)
+
+int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int X509_set_ex_data(X509 *r, int idx, void *arg);
+void *X509_get_ex_data(X509 *r, int idx);
+int i2d_X509_AUX(X509 *a, unsigned char **pp);
+X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length);
+
+int X509_alias_set1(X509 *x, unsigned char *name, int len);
+int X509_keyid_set1(X509 *x, unsigned char *id, int len);
+unsigned char *X509_alias_get0(X509 *x, int *len);
+unsigned char *X509_keyid_get0(X509 *x, int *len);
+int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
+ int);
+int X509_TRUST_set(int *t, int trust);
+int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
+int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
+void X509_trust_clear(X509 *x);
+void X509_reject_clear(X509 *x);
+
+DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
+DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_CRL)
+
+int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
+int X509_CRL_get0_by_serial(X509_CRL *crl,
+ X509_REVOKED **ret, ASN1_INTEGER *serial);
+int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
+
+X509_PKEY *X509_PKEY_new(void);
+void X509_PKEY_free(X509_PKEY *a);
+int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp);
+X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp,
+ long length);
+
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
+
+# ifndef OPENSSL_NO_EVP
+X509_INFO *X509_INFO_new(void);
+void X509_INFO_free(X509_INFO *a);
+char *X509_NAME_oneline(X509_NAME *a, char *buf, int size);
+
+int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
+ ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey);
+
+int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
+ unsigned char *md, unsigned int *len);
+
+int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1,
+ X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
+ char *data, EVP_PKEY *pkey, const EVP_MD *type);
+
+int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data,
+ unsigned char *md, unsigned int *len);
+
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
+ ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey);
+
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
+ X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data,
+ EVP_PKEY *pkey, const EVP_MD *type);
+int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
+ X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
+ void *asn, EVP_MD_CTX *ctx);
+# endif
+
+int X509_set_version(X509 *x, long version);
+int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
+ASN1_INTEGER *X509_get_serialNumber(X509 *x);
+int X509_set_issuer_name(X509 *x, X509_NAME *name);
+X509_NAME *X509_get_issuer_name(X509 *a);
+int X509_set_subject_name(X509 *x, X509_NAME *name);
+X509_NAME *X509_get_subject_name(X509 *a);
+int X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
+int X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
+int X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
+EVP_PKEY *X509_get_pubkey(X509 *x);
+ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x);
+int X509_certificate_type(X509 *x, EVP_PKEY *pubkey /* optional */ );
+
+int X509_REQ_set_version(X509_REQ *x, long version);
+int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name);
+int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
+EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req);
+int X509_REQ_extension_nid(int nid);
+int *X509_REQ_get_extension_nids(void);
+void X509_REQ_set_extension_nids(int *nids);
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
+int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
+ int nid);
+int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
+int X509_REQ_get_attr_count(const X509_REQ *req);
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos);
+int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
+ int lastpos);
+X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
+X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
+int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
+int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
+ const ASN1_OBJECT *obj, int type,
+ const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_NID(X509_REQ *req,
+ int nid, int type,
+ const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_txt(X509_REQ *req,
+ const char *attrname, int type,
+ const unsigned char *bytes, int len);
+
+int X509_CRL_set_version(X509_CRL *x, long version);
+int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
+int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
+int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
+int X509_CRL_sort(X509_CRL *crl);
+
+int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
+int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
+
+int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey);
+
+int X509_check_private_key(X509 *x509, EVP_PKEY *pkey);
+
+int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
+unsigned long X509_issuer_and_serial_hash(X509 *a);
+
+int X509_issuer_name_cmp(const X509 *a, const X509 *b);
+unsigned long X509_issuer_name_hash(X509 *a);
+
+int X509_subject_name_cmp(const X509 *a, const X509 *b);
+unsigned long X509_subject_name_hash(X509 *x);
+
+# ifndef OPENSSL_NO_MD5
+unsigned long X509_issuer_name_hash_old(X509 *a);
+unsigned long X509_subject_name_hash_old(X509 *x);
+# endif
+
+int X509_cmp(const X509 *a, const X509 *b);
+int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
+unsigned long X509_NAME_hash(X509_NAME *x);
+unsigned long X509_NAME_hash_old(X509_NAME *x);
+
+int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
+int X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
+# ifndef OPENSSL_NO_FP_API
+int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag,
+ unsigned long cflag);
+int X509_print_fp(FILE *bp, X509 *x);
+int X509_CRL_print_fp(FILE *bp, X509_CRL *x);
+int X509_REQ_print_fp(FILE *bp, X509_REQ *req);
+int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent,
+ unsigned long flags);
+# endif
+
+# ifndef OPENSSL_NO_BIO
+int X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
+int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent,
+ unsigned long flags);
+int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag,
+ unsigned long cflag);
+int X509_print(BIO *bp, X509 *x);
+int X509_ocspid_print(BIO *bp, X509 *x);
+int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent);
+int X509_CRL_print(BIO *bp, X509_CRL *x);
+int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag,
+ unsigned long cflag);
+int X509_REQ_print(BIO *bp, X509_REQ *req);
+# endif
+
+int X509_NAME_entry_count(X509_NAME *name);
+int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len);
+int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
+ char *buf, int len);
+
+/*
+ * NOTE: you should be passsing -1, not 0 as lastpos. The functions that use
+ * lastpos, search after that position on.
+ */
+int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos);
+int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
+ int lastpos);
+X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
+X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
+int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne,
+ int loc, int set);
+int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
+ unsigned char *bytes, int len, int loc,
+ int set);
+int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
+ unsigned char *bytes, int len, int loc,
+ int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
+ const char *field, int type,
+ const unsigned char *bytes,
+ int len);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
+ int type, unsigned char *bytes,
+ int len);
+int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
+ const unsigned char *bytes, int len, int loc,
+ int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
+ ASN1_OBJECT *obj, int type,
+ const unsigned char *bytes,
+ int len);
+int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj);
+int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
+ const unsigned char *bytes, int len);
+ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
+ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
+
+int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
+int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
+ int nid, int lastpos);
+int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
+ ASN1_OBJECT *obj, int lastpos);
+int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
+ int crit, int lastpos);
+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+ X509_EXTENSION *ex, int loc);
+
+int X509_get_ext_count(X509 *x);
+int X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
+int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos);
+int X509_get_ext_by_critical(X509 *x, int crit, int lastpos);
+X509_EXTENSION *X509_get_ext(X509 *x, int loc);
+X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
+int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
+void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
+int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
+ unsigned long flags);
+
+int X509_CRL_get_ext_count(X509_CRL *x);
+int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
+int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos);
+int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos);
+X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
+X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
+int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
+void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
+int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
+ unsigned long flags);
+
+int X509_REVOKED_get_ext_count(X509_REVOKED *x);
+int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
+int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj,
+ int lastpos);
+int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos);
+X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
+X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
+int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
+void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
+int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
+ unsigned long flags);
+
+X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
+ int nid, int crit,
+ ASN1_OCTET_STRING *data);
+X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
+ ASN1_OBJECT *obj, int crit,
+ ASN1_OCTET_STRING *data);
+int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj);
+int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
+int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data);
+ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex);
+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
+int X509_EXTENSION_get_critical(X509_EXTENSION *ex);
+
+int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
+int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
+ int lastpos);
+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
+ ASN1_OBJECT *obj, int lastpos);
+X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
+X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+ X509_ATTRIBUTE *attr);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
+ **x, const ASN1_OBJECT *obj,
+ int type,
+ const unsigned char *bytes,
+ int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
+ **x, int nid, int type,
+ const unsigned char *bytes,
+ int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
+ **x, const char *attrname,
+ int type,
+ const unsigned char *bytes,
+ int len);
+void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, ASN1_OBJECT *obj,
+ int lastpos, int type);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
+ int atrtype, const void *data,
+ int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
+ const ASN1_OBJECT *obj,
+ int atrtype, const void *data,
+ int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
+ const char *atrname, int type,
+ const unsigned char *bytes,
+ int len);
+int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
+ const void *data, int len);
+void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype,
+ void *data);
+int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr);
+ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
+ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
+
+int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
+int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos);
+int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
+ int lastpos);
+X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
+X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
+int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
+int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
+ const ASN1_OBJECT *obj, int type,
+ const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
+ int nid, int type,
+ const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
+ const char *attrname, int type,
+ const unsigned char *bytes, int len);
+
+int X509_verify_cert(X509_STORE_CTX *ctx);
+
+/* lookup a cert from a X509 STACK */
+X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
+ ASN1_INTEGER *serial);
+X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(PBEPARAM)
+DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
+DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
+
+int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+ const unsigned char *salt, int saltlen);
+
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
+ const unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+ unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
+ unsigned char *salt, int saltlen,
+ unsigned char *aiv, int prf_nid);
+
+X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
+ int prf_nid, int keylen);
+
+/* PKCS#8 utilities */
+
+DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
+PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
+
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+ int version, int ptype, void *pval,
+ unsigned char *penc, int penclen);
+int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
+ const unsigned char **pk, int *ppklen,
+ X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8);
+
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
+ int ptype, void *pval,
+ unsigned char *penc, int penclen);
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+ const unsigned char **pk, int *ppklen,
+ X509_ALGOR **pa, X509_PUBKEY *pub);
+
+int X509_check_trust(X509 *x, int id, int flags);
+int X509_TRUST_get_count(void);
+X509_TRUST *X509_TRUST_get0(int idx);
+int X509_TRUST_get_by_id(int id);
+int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
+ char *name, int arg1, void *arg2);
+void X509_TRUST_cleanup(void);
+int X509_TRUST_get_flags(X509_TRUST *xp);
+char *X509_TRUST_get0_name(X509_TRUST *xp);
+int X509_TRUST_get_trust(X509_TRUST *xp);
+
+/* 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.
+ */
+void ERR_load_X509_strings(void);
+
+/* Error codes for the X509 functions. */
+
+/* Function codes. */
+# define X509_F_ADD_CERT_DIR 100
+# define X509_F_BY_FILE_CTRL 101
+# define X509_F_CHECK_POLICY 145
+# define X509_F_DIR_CTRL 102
+# define X509_F_GET_CERT_BY_SUBJECT 103
+# define X509_F_NETSCAPE_SPKI_B64_DECODE 129
+# define X509_F_NETSCAPE_SPKI_B64_ENCODE 130
+# define X509_F_X509AT_ADD1_ATTR 135
+# define X509_F_X509V3_ADD_EXT 104
+# define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136
+# define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137
+# define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140
+# define X509_F_X509_ATTRIBUTE_GET0_DATA 139
+# define X509_F_X509_ATTRIBUTE_SET1_DATA 138
+# define X509_F_X509_CHECK_PRIVATE_KEY 128
+# define X509_F_X509_CRL_PRINT_FP 147
+# define X509_F_X509_EXTENSION_CREATE_BY_NID 108
+# define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109
+# define X509_F_X509_GET_PUBKEY_PARAMETERS 110
+# define X509_F_X509_LOAD_CERT_CRL_FILE 132
+# define X509_F_X509_LOAD_CERT_FILE 111
+# define X509_F_X509_LOAD_CRL_FILE 112
+# define X509_F_X509_NAME_ADD_ENTRY 113
+# define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114
+# define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131
+# define X509_F_X509_NAME_ENTRY_SET_OBJECT 115
+# define X509_F_X509_NAME_ONELINE 116
+# define X509_F_X509_NAME_PRINT 117
+# define X509_F_X509_PRINT_EX_FP 118
+# define X509_F_X509_PUBKEY_GET 119
+# define X509_F_X509_PUBKEY_SET 120
+# define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144
+# define X509_F_X509_REQ_PRINT_EX 121
+# define X509_F_X509_REQ_PRINT_FP 122
+# define X509_F_X509_REQ_TO_X509 123
+# define X509_F_X509_STORE_ADD_CERT 124
+# define X509_F_X509_STORE_ADD_CRL 125
+# define X509_F_X509_STORE_CTX_GET1_ISSUER 146
+# define X509_F_X509_STORE_CTX_INIT 143
+# define X509_F_X509_STORE_CTX_NEW 142
+# define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134
+# define X509_F_X509_TO_X509_REQ 126
+# define X509_F_X509_TRUST_ADD 133
+# define X509_F_X509_TRUST_SET 141
+# define X509_F_X509_VERIFY_CERT 127
+
+/* Reason codes. */
+# define X509_R_BAD_X509_FILETYPE 100
+# define X509_R_BASE64_DECODE_ERROR 118
+# define X509_R_CANT_CHECK_DH_KEY 114
+# define X509_R_CERT_ALREADY_IN_HASH_TABLE 101
+# define X509_R_ERR_ASN1_LIB 102
+# define X509_R_INVALID_DIRECTORY 113
+# define X509_R_INVALID_FIELD_NAME 119
+# define X509_R_INVALID_TRUST 123
+# define X509_R_KEY_TYPE_MISMATCH 115
+# define X509_R_KEY_VALUES_MISMATCH 116
+# define X509_R_LOADING_CERT_DIR 103
+# define X509_R_LOADING_DEFAULTS 104
+# define X509_R_METHOD_NOT_SUPPORTED 124
+# define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105
+# define X509_R_PUBLIC_KEY_DECODE_ERROR 125
+# define X509_R_PUBLIC_KEY_ENCODE_ERROR 126
+# define X509_R_SHOULD_RETRY 106
+# define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107
+# define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108
+# define X509_R_UNKNOWN_KEY_TYPE 117
+# define X509_R_UNKNOWN_NID 109
+# define X509_R_UNKNOWN_PURPOSE_ID 121
+# define X509_R_UNKNOWN_TRUST_ID 120
+# define X509_R_UNSUPPORTED_ALGORITHM 111
+# define X509_R_WRONG_LOOKUP_TYPE 112
+# define X509_R_WRONG_TYPE 122
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/x509/x509_vfy.h b/openssl/x509/x509_vfy.h
new file mode 100644
index 0000000..1f8c0ec
--- /dev/null
+++ b/openssl/x509/x509_vfy.h
@@ -0,0 +1,589 @@
+/* crypto/x509/x509_vfy.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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 acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS 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 AUTHOR OR 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.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_X509_H
+# include <openssl/x509.h>
+/*
+ * openssl/x509.h ends up #include-ing this file at about the only
+ * appropriate moment.
+ */
+#endif
+
+#ifndef HEADER_X509_VFY_H
+# define HEADER_X509_VFY_H
+
+# include <openssl/opensslconf.h>
+# ifndef OPENSSL_NO_LHASH
+# include <openssl/lhash.h>
+# endif
+# include <openssl/bio.h>
+# include <openssl/crypto.h>
+# include <openssl/symhacks.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# if 0
+/* Outer object */
+typedef struct x509_hash_dir_st {
+ int num_dirs;
+ char **dirs;
+ int *dirs_type;
+ int num_dirs_alloced;
+} X509_HASH_DIR_CTX;
+# endif
+
+typedef struct x509_file_st {
+ int num_paths; /* number of paths to files or directories */
+ int num_alloced;
+ char **paths; /* the list of paths or directories */
+ int *path_type;
+} X509_CERT_FILE_CTX;
+
+/*******************************/
+/*-
+SSL_CTX -> X509_STORE
+ -> X509_LOOKUP
+ ->X509_LOOKUP_METHOD
+ -> X509_LOOKUP
+ ->X509_LOOKUP_METHOD
+
+SSL -> X509_STORE_CTX
+ ->X509_STORE
+
+The X509_STORE holds the tables etc for verification stuff.
+A X509_STORE_CTX is used while validating a single certificate.
+The X509_STORE has X509_LOOKUPs for looking up certs.
+The X509_STORE then calls a function to actually verify the
+certificate chain.
+*/
+
+# define X509_LU_RETRY -1
+# define X509_LU_FAIL 0
+# define X509_LU_X509 1
+# define X509_LU_CRL 2
+# define X509_LU_PKEY 3
+
+typedef struct x509_object_st {
+ /* one of the above types */
+ int type;
+ union {
+ char *ptr;
+ X509 *x509;
+ X509_CRL *crl;
+ EVP_PKEY *pkey;
+ } data;
+} X509_OBJECT;
+
+typedef struct x509_lookup_st X509_LOOKUP;
+
+DECLARE_STACK_OF(X509_LOOKUP)
+DECLARE_STACK_OF(X509_OBJECT)
+
+/* This is a static that defines the function interface */
+typedef struct x509_lookup_method_st {
+ const char *name;
+ int (*new_item) (X509_LOOKUP *ctx);
+ void (*free) (X509_LOOKUP *ctx);
+ int (*init) (X509_LOOKUP *ctx);
+ int (*shutdown) (X509_LOOKUP *ctx);
+ int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
+ char **ret);
+ int (*get_by_subject) (X509_LOOKUP *ctx, int type, X509_NAME *name,
+ X509_OBJECT *ret);
+ int (*get_by_issuer_serial) (X509_LOOKUP *ctx, int type, X509_NAME *name,
+ ASN1_INTEGER *serial, X509_OBJECT *ret);
+ int (*get_by_fingerprint) (X509_LOOKUP *ctx, int type,
+ unsigned char *bytes, int len,
+ X509_OBJECT *ret);
+ int (*get_by_alias) (X509_LOOKUP *ctx, int type, char *str, int len,
+ X509_OBJECT *ret);
+} X509_LOOKUP_METHOD;
+
+/*
+ * This structure hold all parameters associated with a verify operation by
+ * including an X509_VERIFY_PARAM structure in related structures the
+ * parameters used can be customized
+ */
+
+typedef struct X509_VERIFY_PARAM_st {
+ char *name;
+ time_t check_time; /* Time to use */
+ unsigned long inh_flags; /* Inheritance flags */
+ unsigned long flags; /* Various verify flags */
+ int purpose; /* purpose to check untrusted certificates */
+ int trust; /* trust setting to check */
+ int depth; /* Verify depth */
+ STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */
+} X509_VERIFY_PARAM;
+
+DECLARE_STACK_OF(X509_VERIFY_PARAM)
+
+/*
+ * This is used to hold everything. It is used for all certificate
+ * validation. Once we have a certificate chain, the 'verify' function is
+ * then called to actually check the cert chain.
+ */
+struct x509_store_st {
+ /* The following is a cache of trusted certs */
+ int cache; /* if true, stash any hits */
+ STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */
+ /* These are external lookup methods */
+ STACK_OF(X509_LOOKUP) *get_cert_methods;
+ X509_VERIFY_PARAM *param;
+ /* Callbacks for various operations */
+ /* called to verify a certificate */
+ int (*verify) (X509_STORE_CTX *ctx);
+ /* error callback */
+ int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
+ /* get issuers cert from ctx */
+ int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+ /* check issued */
+ int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
+ /* Check revocation status of chain */
+ int (*check_revocation) (X509_STORE_CTX *ctx);
+ /* retrieve CRL */
+ int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
+ /* Check CRL validity */
+ int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
+ /* Check certificate against CRL */
+ int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
+ STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
+ STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
+ int (*cleanup) (X509_STORE_CTX *ctx);
+ CRYPTO_EX_DATA ex_data;
+ int references;
+} /* X509_STORE */ ;
+
+int X509_STORE_set_depth(X509_STORE *store, int depth);
+
+# define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func))
+# define X509_STORE_set_verify_func(ctx,func) ((ctx)->verify=(func))
+
+/* This is the functions plus an instance of the local variables. */
+struct x509_lookup_st {
+ int init; /* have we been started */
+ int skip; /* don't use us. */
+ X509_LOOKUP_METHOD *method; /* the functions */
+ char *method_data; /* method data */
+ X509_STORE *store_ctx; /* who owns us */
+} /* X509_LOOKUP */ ;
+
+/*
+ * This is a used when verifying cert chains. Since the gathering of the
+ * cert chain can take some time (and have to be 'retried', this needs to be
+ * kept and passed around.
+ */
+struct x509_store_ctx_st { /* X509_STORE_CTX */
+ X509_STORE *ctx;
+ /* used when looking up certs */
+ int current_method;
+ /* The following are set by the caller */
+ /* The cert to check */
+ X509 *cert;
+ /* chain of X509s - untrusted - passed in */
+ STACK_OF(X509) *untrusted;
+ /* set of CRLs passed in */
+ STACK_OF(X509_CRL) *crls;
+ X509_VERIFY_PARAM *param;
+ /* Other info for use with get_issuer() */
+ void *other_ctx;
+ /* Callbacks for various operations */
+ /* called to verify a certificate */
+ int (*verify) (X509_STORE_CTX *ctx);
+ /* error callback */
+ int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
+ /* get issuers cert from ctx */
+ int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+ /* check issued */
+ int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
+ /* Check revocation status of chain */
+ int (*check_revocation) (X509_STORE_CTX *ctx);
+ /* retrieve CRL */
+ int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
+ /* Check CRL validity */
+ int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
+ /* Check certificate against CRL */
+ int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
+ int (*check_policy) (X509_STORE_CTX *ctx);
+ STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
+ STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
+ int (*cleanup) (X509_STORE_CTX *ctx);
+ /* The following is built up */
+ /* if 0, rebuild chain */
+ int valid;
+ /* index of last untrusted cert */
+ int last_untrusted;
+ /* chain of X509s - built up and trusted */
+ STACK_OF(X509) *chain;
+ /* Valid policy tree */
+ X509_POLICY_TREE *tree;
+ /* Require explicit policy value */
+ int explicit_policy;
+ /* When something goes wrong, this is why */
+ int error_depth;
+ int error;
+ X509 *current_cert;
+ /* cert currently being tested as valid issuer */
+ X509 *current_issuer;
+ /* current CRL */
+ X509_CRL *current_crl;
+ /* score of current CRL */
+ int current_crl_score;
+ /* Reason mask */
+ unsigned int current_reasons;
+ /* For CRL path validation: parent context */
+ X509_STORE_CTX *parent;
+ CRYPTO_EX_DATA ex_data;
+} /* X509_STORE_CTX */ ;
+
+void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
+
+# define X509_STORE_CTX_set_app_data(ctx,data) \
+ X509_STORE_CTX_set_ex_data(ctx,0,data)
+# define X509_STORE_CTX_get_app_data(ctx) \
+ X509_STORE_CTX_get_ex_data(ctx,0)
+
+# define X509_L_FILE_LOAD 1
+# define X509_L_ADD_DIR 2
+
+# define X509_LOOKUP_load_file(x,name,type) \
+ X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL)
+
+# define X509_LOOKUP_add_dir(x,name,type) \
+ X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL)
+
+# define X509_V_OK 0
+/* illegal error (for uninitialized values, to avoid X509_V_OK): 1 */
+
+# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2
+# define X509_V_ERR_UNABLE_TO_GET_CRL 3
+# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4
+# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5
+# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6
+# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7
+# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8
+# define X509_V_ERR_CERT_NOT_YET_VALID 9
+# define X509_V_ERR_CERT_HAS_EXPIRED 10
+# define X509_V_ERR_CRL_NOT_YET_VALID 11
+# define X509_V_ERR_CRL_HAS_EXPIRED 12
+# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13
+# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14
+# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15
+# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16
+# define X509_V_ERR_OUT_OF_MEM 17
+# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18
+# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19
+# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20
+# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21
+# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22
+# define X509_V_ERR_CERT_REVOKED 23
+# define X509_V_ERR_INVALID_CA 24
+# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25
+# define X509_V_ERR_INVALID_PURPOSE 26
+# define X509_V_ERR_CERT_UNTRUSTED 27
+# define X509_V_ERR_CERT_REJECTED 28
+/* These are 'informational' when looking for issuer cert */
+# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29
+# define X509_V_ERR_AKID_SKID_MISMATCH 30
+# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31
+# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32
+
+# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33
+# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34
+# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35
+# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36
+# define X509_V_ERR_INVALID_NON_CA 37
+# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38
+# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39
+# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40
+
+# define X509_V_ERR_INVALID_EXTENSION 41
+# define X509_V_ERR_INVALID_POLICY_EXTENSION 42
+# define X509_V_ERR_NO_EXPLICIT_POLICY 43
+# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44
+# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45
+
+# define X509_V_ERR_UNNESTED_RESOURCE 46
+
+# define X509_V_ERR_PERMITTED_VIOLATION 47
+# define X509_V_ERR_EXCLUDED_VIOLATION 48
+# define X509_V_ERR_SUBTREE_MINMAX 49
+# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51
+# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52
+# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53
+# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54
+
+/* The application is not happy */
+# define X509_V_ERR_APPLICATION_VERIFICATION 50
+
+/* Certificate verify flags */
+
+/* Send issuer+subject checks to verify_cb */
+# define X509_V_FLAG_CB_ISSUER_CHECK 0x1
+/* Use check time instead of current time */
+# define X509_V_FLAG_USE_CHECK_TIME 0x2
+/* Lookup CRLs */
+# define X509_V_FLAG_CRL_CHECK 0x4
+/* Lookup CRLs for whole chain */
+# define X509_V_FLAG_CRL_CHECK_ALL 0x8
+/* Ignore unhandled critical extensions */
+# define X509_V_FLAG_IGNORE_CRITICAL 0x10
+/* Disable workarounds for broken certificates */
+# define X509_V_FLAG_X509_STRICT 0x20
+/* Enable proxy certificate validation */
+# define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40
+/* Enable policy checking */
+# define X509_V_FLAG_POLICY_CHECK 0x80
+/* Policy variable require-explicit-policy */
+# define X509_V_FLAG_EXPLICIT_POLICY 0x100
+/* Policy variable inhibit-any-policy */
+# define X509_V_FLAG_INHIBIT_ANY 0x200
+/* Policy variable inhibit-policy-mapping */
+# define X509_V_FLAG_INHIBIT_MAP 0x400
+/* Notify callback that policy is OK */
+# define X509_V_FLAG_NOTIFY_POLICY 0x800
+/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
+# define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000
+/* Delta CRL support */
+# define X509_V_FLAG_USE_DELTAS 0x2000
+/* Check selfsigned CA signature */
+# define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000
+
+# define X509_VP_FLAG_DEFAULT 0x1
+# define X509_VP_FLAG_OVERWRITE 0x2
+# define X509_VP_FLAG_RESET_FLAGS 0x4
+# define X509_VP_FLAG_LOCKED 0x8
+# define X509_VP_FLAG_ONCE 0x10
+
+/* Internal use: mask of policy related options */
+# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \
+ | X509_V_FLAG_EXPLICIT_POLICY \
+ | X509_V_FLAG_INHIBIT_ANY \
+ | X509_V_FLAG_INHIBIT_MAP)
+
+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
+ X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
+ int type, X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
+ X509_OBJECT *x);
+void X509_OBJECT_up_ref_count(X509_OBJECT *a);
+void X509_OBJECT_free_contents(X509_OBJECT *a);
+X509_STORE *X509_STORE_new(void);
+void X509_STORE_free(X509_STORE *v);
+
+STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
+STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
+int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
+int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
+int X509_STORE_set_trust(X509_STORE *ctx, int trust);
+int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
+
+void X509_STORE_set_verify_cb(X509_STORE *ctx,
+ int (*verify_cb) (int, X509_STORE_CTX *));
+
+X509_STORE_CTX *X509_STORE_CTX_new(void);
+
+int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+
+void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
+ X509 *x509, STACK_OF(X509) *chain);
+void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
+void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
+
+X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
+
+X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
+X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
+
+int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
+int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
+
+int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
+ X509_OBJECT *ret);
+
+int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
+ long argl, char **ret);
+
+# ifndef OPENSSL_NO_STDIO
+int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+# endif
+
+X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
+void X509_LOOKUP_free(X509_LOOKUP *ctx);
+int X509_LOOKUP_init(X509_LOOKUP *ctx);
+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
+ X509_OBJECT *ret);
+int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
+ ASN1_INTEGER *serial, X509_OBJECT *ret);
+int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
+ unsigned char *bytes, int len,
+ X509_OBJECT *ret);
+int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
+ X509_OBJECT *ret);
+int X509_LOOKUP_shutdown(X509_LOOKUP *ctx);
+
+# ifndef OPENSSL_NO_STDIO
+int X509_STORE_load_locations(X509_STORE *ctx,
+ const char *file, const char *dir);
+int X509_STORE_set_default_paths(X509_STORE *ctx);
+# endif
+
+int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
+ CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func);
+int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data);
+void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx);
+int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s);
+int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
+X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
+X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
+X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x);
+void X509_STORE_CTX_set_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk);
+void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk);
+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
+int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+ int purpose, int trust);
+void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
+void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
+ time_t t);
+void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
+ int (*verify_cb) (int, X509_STORE_CTX *));
+
+X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx);
+
+X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
+int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
+
+/* X509_VERIFY_PARAM functions */
+
+X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
+void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
+ const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
+ const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
+int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param,
+ unsigned long flags);
+int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
+ unsigned long flags);
+unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
+int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
+void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
+void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
+int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
+ ASN1_OBJECT *policy);
+int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
+ STACK_OF(ASN1_OBJECT) *policies);
+int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
+
+int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
+void X509_VERIFY_PARAM_table_cleanup(void);
+
+int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
+ STACK_OF(X509) *certs,
+ STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags);
+
+void X509_policy_tree_free(X509_POLICY_TREE *tree);
+
+int X509_policy_tree_level_count(const X509_POLICY_TREE *tree);
+X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree,
+ int i);
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const
+ X509_POLICY_TREE
+ *tree);
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const
+ X509_POLICY_TREE
+ *tree);
+
+int X509_policy_level_node_count(X509_POLICY_LEVEL *level);
+
+X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level,
+ int i);
+
+const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node);
+
+STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const
+ X509_POLICY_NODE
+ *node);
+const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE
+ *node);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/openssl/x509_vfy.h b/openssl/x509_vfy.h
new file mode 120000
index 0000000..1341bc1
--- /dev/null
+++ b/openssl/x509_vfy.h
@@ -0,0 +1 @@
+x509/x509_vfy.h
\ No newline at end of file
diff --git a/polarssl/Makefile b/polarssl/Makefile
new file mode 100644
index 0000000..d582241
--- /dev/null
+++ b/polarssl/Makefile
@@ -0,0 +1,56 @@
+# Copyright 2010 by Nest Labs, Inc. All rights reserved.
+#
+# This program is confidential and proprietary to Nest Labs, Inc.,
+# and may not be reproduced, published or disclosed to others without
+# company authorization.
+#
+
+DEPTH = ../
+
+include $(DEPTH)Makefile.config
+
+OUTDIR = $(OBJ_DIR)
+SRCDIR = ./
+INCDIR = ./
+
+OBJECT_FILES = \
+ aes
+
+HEADER_FILES = \
+ aes
+
+OBJECTS = $(OBJECT_FILES:%=$(OUTDIR)/%.o)
+HEADERS = $(HEADER_FILES:%=$(INCDIR)/%.h)
+
+.PHONY: ctrdrbg
+
+all: $(OUTDIR) ctrdrbg $(LIB_DIR)/libpolarssl.a
+
+$(OUTDIR):
+ $(MKDIR) $(OUTDIR)
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.c $(HEADERS)
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.cpp $(HEADERS)
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(OUTDIR)/libpolarssl.a: $(OBJECTS)
+ $(ARCHIVE) $@ $(OBJECTS)
+ $(RANLIB) $@
+
+$(LIB_DIR)/libpolarssl.a: $(OUTDIR)/libpolarssl.a
+ $(MKDIR) $(dir $@)
+ $(CP) $< $@
+
+$(OUTDIR)/aes.o: aes.c aes.h
+ $(CC) $(CFLAGS) -c $(AES_IMPL_REDIRECT) $< -o $@
+
+
+ctrdrbg:
+ $(MAKE) -C $@
+
+clean:
+ $(MAKE) -C ctrdrbg clean
+ $(RM) $(OUTDIR)
+
diff --git a/polarssl/README.third_party b/polarssl/README.third_party
new file mode 100644
index 0000000..cbb6192
--- /dev/null
+++ b/polarssl/README.third_party
@@ -0,0 +1,20 @@
+URL: https://tls.mbed.org/download/polarssl-1.2.8-gpl.tgz
+Version: 1.2.8
+License: GPL and closed source commercial license
+License File: <none>
+
+Description:
+
+ An implementation of the NIST AES-CTR DRBG based on PolarSSL.
+
+ NOTE: Nest has acquired a license for the PolarSSL source that allows for commercial use by Nest
+ without the restrictions of the GPL. This license DOES NOT include the right to redistribute
+ the source code to third parties.
+
+Local Modifications:
+
+ Only the PolarSSL files that implement the AES-CTR DRBG algorithm are included in this library
+ (ctr_drbg.h and ctr_drbg.c). These files are unmodified from the original source.
+
+ The library also functions to map the PolarSSL AES API onto the equivalent OpenSSL API.
+
diff --git a/polarssl/aes.c b/polarssl/aes.c
new file mode 100644
index 0000000..b036d4e
--- /dev/null
+++ b/polarssl/aes.c
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright (c) 2011-2015 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * This document is the property of Nest. It is considered
+ * confidential and proprietary information.
+ *
+ * This document may not be reproduced or transmitted in any form,
+ * in whole or in part, without the express written permission of
+ * Nest.
+ *
+ * Description:
+ * Implementation of PolarSSL AES functions that maps calls onto OpenSSL's
+ * functions.
+ */
+
+#include "aes.h"
+
+#include <stdio.h>
+
+int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int keysize )
+{
+ AES_set_encrypt_key(key, (int)keysize, ctx);
+ return 0;
+}
+
+int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int keysize )
+{
+ AES_set_decrypt_key(key, (int)keysize, ctx);
+ return 0;
+}
+
+
+int aes_crypt_ecb( aes_context *ctx,
+ int mode,
+ const unsigned char input[16],
+ unsigned char output[16] )
+{
+ /* Only encryption supported (and needed) for now.
+ */
+ if (mode != AES_ENCRYPT)
+ return -1;
+ AES_encrypt(input, output, ctx);
+ return 0;
+}
+
diff --git a/polarssl/aes.h b/polarssl/aes.h
new file mode 100644
index 0000000..05d672c
--- /dev/null
+++ b/polarssl/aes.h
@@ -0,0 +1,70 @@
+/*
+ *
+ * Copyright (c) 2011-2015 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * This document is the property of Nest. It is considered
+ * confidential and proprietary information.
+ *
+ * This document may not be reproduced or transmitted in any form,
+ * in whole or in part, without the express written permission of
+ * Nest.
+ *
+ * Description:
+ * Mapping of PolarSSL's AES API onto OpenSSL's functions.
+ */
+
+#ifndef AES_H
+#define AES_H
+
+#include <stdint.h>
+
+#include <openssl/aes.h>
+
+#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
+#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
+
+/* Define PolarSSL's aes_context as an OpenSSL AES_KEY structure.
+ */
+typedef AES_KEY aes_context;
+
+/**
+* \brief AES key schedule (encryption)
+*
+* \param ctx AES context to be initialized
+* \param key encryption key
+* \param keysize must be 128, 192 or 256
+*
+* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
+*/
+int aes_setkey_enc( aes_context *ctx, const unsigned char *key, unsigned int keysize );
+
+/**
+* \brief AES key schedule (decryption)
+*
+* \param ctx AES context to be initialized
+* \param key decryption key
+* \param keysize must be 128, 192 or 256
+*
+* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
+*/
+int aes_setkey_dec( aes_context *ctx, const unsigned char *key, unsigned int keysize );
+
+/**
+* \brief AES-ECB block encryption/decryption
+*
+* \param ctx AES context
+* \param mode AES_ENCRYPT or AES_DECRYPT
+* \param input 16-byte input block
+* \param output 16-byte output block
+*
+* \return 0 if successful
+*/
+int aes_crypt_ecb( aes_context *ctx,
+ int mode,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+
+#endif
+
diff --git a/polarssl/config.h b/polarssl/config.h
new file mode 100644
index 0000000..16ee35f
--- /dev/null
+++ b/polarssl/config.h
@@ -0,0 +1,10 @@
+#ifndef POLARSSL_CTR_DRBG_C
+#define POLARSSL_CTR_DRBG_C
+#endif
+
+#ifdef DEBUG
+#ifndef POLARSSL_SELF_TEST
+#define POLARSSL_SELF_TEST
+#endif
+#endif
+
diff --git a/polarssl/ctr_drbg.h b/polarssl/ctr_drbg.h
new file mode 100644
index 0000000..e937d46
--- /dev/null
+++ b/polarssl/ctr_drbg.h
@@ -0,0 +1,232 @@
+/**
+ * \file ctr_drbg.h
+ *
+ * \brief CTR_DRBG based on AES-256 (NIST SP 800-90)
+ *
+ * Copyright (C) 2006-2013, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef POLARSSL_CTR_DRBG_H
+#define POLARSSL_CTR_DRBG_H
+
+#include <string.h>
+
+#include "aes.h"
+
+#define POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */
+#define POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< Too many random requested in single call. */
+#define POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< Input too large (Entropy + additional). */
+#define POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read/write error in file. */
+
+#define CTR_DRBG_BLOCKSIZE 16 /**< Block size used by the cipher */
+#define CTR_DRBG_KEYSIZE 32 /**< Key size used by the cipher */
+#define CTR_DRBG_KEYBITS ( CTR_DRBG_KEYSIZE * 8 )
+#define CTR_DRBG_SEEDLEN ( CTR_DRBG_KEYSIZE + CTR_DRBG_BLOCKSIZE )
+ /**< The seed length (counter + AES key) */
+
+#if !defined(POLARSSL_CONFIG_OPTIONS)
+#define CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default */
+#define CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
+#define CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
+#define CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
+#define CTR_DRBG_MAX_SEED_INPUT 128 /**< Maximum size of (re)seed buffer */
+#endif /* !POLARSSL_CONFIG_OPTIONS */
+
+#define CTR_DRBG_PR_OFF 0 /**< No prediction resistance */
+#define CTR_DRBG_PR_ON 1 /**< Prediction resistance enabled */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief CTR_DRBG context structure
+ */
+typedef struct
+{
+ unsigned char counter[16]; /*!< counter (V) */
+ int reseed_counter; /*!< reseed counter */
+ int prediction_resistance; /*!< enable prediction resistance (Automatic
+ reseed before every random generation) */
+ size_t entropy_len; /*!< amount of entropy grabbed on each (re)seed */
+ int reseed_interval; /*!< reseed interval */
+
+ aes_context aes_ctx; /*!< AES context */
+
+ /*
+ * Callbacks (Entropy)
+ */
+ int (*f_entropy)(void *, unsigned char *, size_t);
+
+ void *p_entropy; /*!< context for the entropy function */
+}
+ctr_drbg_context;
+
+/**
+ * \brief CTR_DRBG initialization
+ *
+ * Note: Personalization data can be provided in addition to the more generic
+ * entropy source to make this instantiation as unique as possible.
+ *
+ * \param ctx CTR_DRBG context to be initialized
+ * \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer
+ * length)
+ * \param p_entropy Entropy context
+ * \param custom Personalization data (Device specific identifiers)
+ * (Can be NULL)
+ * \param len Length of personalization data
+ *
+ * \return 0 if successful, or
+ * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
+ */
+int ctr_drbg_init( ctr_drbg_context *ctx,
+ int (*f_entropy)(void *, unsigned char *, size_t),
+ void *p_entropy,
+ const unsigned char *custom,
+ size_t len );
+
+/**
+ * \brief Enable / disable prediction resistance (Default: Off)
+ *
+ * Note: If enabled, entropy is used for ctx->entropy_len before each call!
+ * Only use this if you have ample supply of good entropy!
+ *
+ * \param ctx CTR_DRBG context
+ * \param resistance CTR_DRBG_PR_ON or CTR_DRBG_PR_OFF
+ */
+void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx,
+ int resistance );
+
+/**
+ * \brief Set the amount of entropy grabbed on each (re)seed
+ * (Default: CTR_DRBG_ENTROPY_LEN)
+ *
+ * \param ctx CTR_DRBG context
+ * \param len Amount of entropy to grab
+ */
+void ctr_drbg_set_entropy_len( ctr_drbg_context *ctx,
+ size_t len );
+
+/**
+ * \brief Set the reseed interval
+ * (Default: CTR_DRBG_RESEED_INTERVAL)
+ *
+ * \param ctx CTR_DRBG context
+ * \param interval Reseed interval
+ */
+void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx,
+ int interval );
+
+/**
+ * \brief CTR_DRBG reseeding (extracts data from entropy source)
+ *
+ * \param ctx CTR_DRBG context
+ * \param additional Additional data to add to state (Can be NULL)
+ * \param len Length of additional data
+ *
+ * \return 0 if successful, or
+ * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
+ */
+int ctr_drbg_reseed( ctr_drbg_context *ctx,
+ const unsigned char *additional, size_t len );
+
+/**
+ * \brief CTR_DRBG update state
+ *
+ * \param ctx CTR_DRBG context
+ * \param additional Additional data to update state with
+ * \param add_len Length of additional data
+ */
+void ctr_drbg_update( ctr_drbg_context *ctx,
+ const unsigned char *additional, size_t add_len );
+
+/**
+ * \brief CTR_DRBG generate random with additional update input
+ *
+ * Note: Automatically reseeds if reseed_counter is reached.
+ *
+ * \param p_rng CTR_DRBG context
+ * \param output Buffer to fill
+ * \param output_len Length of the buffer
+ * \param additional Additional data to update with (Can be NULL)
+ * \param add_len Length of additional data
+ *
+ * \return 0 if successful, or
+ * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or
+ * POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG
+ */
+int ctr_drbg_random_with_add( void *p_rng,
+ unsigned char *output, size_t output_len,
+ const unsigned char *additional, size_t add_len );
+
+/**
+ * \brief CTR_DRBG generate random
+ *
+ * Note: Automatically reseeds if reseed_counter is reached.
+ *
+ * \param p_rng CTR_DRBG context
+ * \param output Buffer to fill
+ * \param output_len Length of the buffer
+ *
+ * \return 0 if successful, or
+ * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or
+ * POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG
+ */
+int ctr_drbg_random( void *p_rng,
+ unsigned char *output, size_t output_len );
+
+#if defined(POLARSSL_FS_IO)
+/**
+ * \brief Write a seed file
+ *
+ * \param path Name of the file
+ *
+ * \return 0 if successful, 1 on file error, or
+ * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
+ */
+int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path );
+
+/**
+ * \brief Read and update a seed file. Seed is added to this
+ * instance
+ *
+ * \param path Name of the file
+ *
+ * \return 0 if successful, 1 on file error,
+ * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or
+ * POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG
+ */
+int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path );
+#endif
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int ctr_drbg_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ctr_drbg.h */
+
diff --git a/polarssl/ctrdrbg/Makefile b/polarssl/ctrdrbg/Makefile
new file mode 100644
index 0000000..e3c96a4
--- /dev/null
+++ b/polarssl/ctrdrbg/Makefile
@@ -0,0 +1,47 @@
+# Copyright 2010 by Nest Labs, Inc. All rights reserved.
+#
+# This program is confidential and proprietary to Nest Labs, Inc.,
+# and may not be reproduced, published or disclosed to others without
+# company authorization.
+#
+
+DEPTH = ../../
+
+include $(DEPTH)Makefile.config
+
+CFLAGS += -Os
+
+OUTDIR = $(OBJ_DIR)
+SRCDIR = ./
+INCDIR = ./
+
+OBJECT_FILES = \
+ ctr_drbg
+
+HEADER_FILES =
+
+OBJECTS = $(OBJECT_FILES:%=$(OUTDIR)/%.o)
+HEADERS = $(HEADER_FILES:%=$(INCDIR)/%.h)
+
+all: $(OUTDIR) $(LIB_DIR)/libctrdrbg.a
+
+$(OUTDIR):
+ $(MKDIR) $(OUTDIR)
+
+clean:
+ $(RM) $(OUTDIR)
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.c $(HEADERS)
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.cpp $(HEADERS)
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(OUTDIR)/libctrdrbg.a: $(OBJECTS)
+ $(ARCHIVE) $@ $(OBJECTS)
+ $(RANLIB) $@
+
+$(LIB_DIR)/libctrdrbg.a: $(OUTDIR)/libctrdrbg.a
+ $(MKDIR) $(dir $@)
+ $(CP) $< $@
+
diff --git a/polarssl/ctrdrbg/ctr_drbg.c b/polarssl/ctrdrbg/ctr_drbg.c
new file mode 100644
index 0000000..7e9850b
--- /dev/null
+++ b/polarssl/ctrdrbg/ctr_drbg.c
@@ -0,0 +1,563 @@
+/*
+ * CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
+ *
+ * Copyright (C) 2006-2011, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/*
+ * The NIST SP 800-90 DRBGs are described in the following publucation.
+ *
+ * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
+ */
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_CTR_DRBG_C)
+
+#include "polarssl/ctr_drbg.h"
+
+#if defined(POLARSSL_FS_IO)
+#include <stdio.h>
+#endif
+
+/*
+ * Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST
+ * tests to succeed (which require known length fixed entropy)
+ */
+int ctr_drbg_init_entropy_len(
+ ctr_drbg_context *ctx,
+ int (*f_entropy)(void *, unsigned char *, size_t),
+ void *p_entropy,
+ const unsigned char *custom,
+ size_t len,
+ size_t entropy_len )
+{
+ int ret;
+ unsigned char key[CTR_DRBG_KEYSIZE];
+
+ memset( ctx, 0, sizeof(ctr_drbg_context) );
+ memset( key, 0, CTR_DRBG_KEYSIZE );
+
+ ctx->f_entropy = f_entropy;
+ ctx->p_entropy = p_entropy;
+
+ ctx->entropy_len = entropy_len;
+ ctx->reseed_interval = CTR_DRBG_RESEED_INTERVAL;
+
+ /*
+ * Initialize with an empty key
+ */
+ aes_setkey_enc( &ctx->aes_ctx, key, CTR_DRBG_KEYBITS );
+
+ if( ( ret = ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
+ return( ret );
+
+ return( 0 );
+}
+
+int ctr_drbg_init( ctr_drbg_context *ctx,
+ int (*f_entropy)(void *, unsigned char *, size_t),
+ void *p_entropy,
+ const unsigned char *custom,
+ size_t len )
+{
+ return( ctr_drbg_init_entropy_len( ctx, f_entropy, p_entropy, custom, len,
+ CTR_DRBG_ENTROPY_LEN ) );
+}
+
+void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx, int resistance )
+{
+ ctx->prediction_resistance = resistance;
+}
+
+void ctr_drbg_set_entropy_len( ctr_drbg_context *ctx, size_t len )
+{
+ ctx->entropy_len = len;
+}
+
+void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx, int interval )
+{
+ ctx->reseed_interval = interval;
+}
+
+int block_cipher_df( unsigned char *output,
+ const unsigned char *data, size_t data_len )
+{
+ unsigned char buf[CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16];
+ unsigned char tmp[CTR_DRBG_SEEDLEN];
+ unsigned char key[CTR_DRBG_KEYSIZE];
+ unsigned char chain[CTR_DRBG_BLOCKSIZE];
+ unsigned char *p = buf, *iv;
+ aes_context aes_ctx;
+
+ int i, j, buf_len, use_len;
+
+ memset( buf, 0, CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16 );
+
+ /*
+ * Construct IV (16 bytes) and S in buffer
+ * IV = Counter (in 32-bits) padded to 16 with zeroes
+ * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
+ * data || 0x80
+ * (Total is padded to a multiple of 16-bytes with zeroes)
+ */
+ p = buf + CTR_DRBG_BLOCKSIZE;
+ *p++ = ( data_len >> 24 ) & 0xff;
+ *p++ = ( data_len >> 16 ) & 0xff;
+ *p++ = ( data_len >> 8 ) & 0xff;
+ *p++ = ( data_len ) & 0xff;
+ p += 3;
+ *p++ = CTR_DRBG_SEEDLEN;
+ memcpy( p, data, data_len );
+ p[data_len] = 0x80;
+
+ buf_len = CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
+
+ for( i = 0; i < CTR_DRBG_KEYSIZE; i++ )
+ key[i] = i;
+
+ aes_setkey_enc( &aes_ctx, key, CTR_DRBG_KEYBITS );
+
+ /*
+ * Reduce data to POLARSSL_CTR_DRBG_SEEDLEN bytes of data
+ */
+ for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
+ {
+ p = buf;
+ memset( chain, 0, CTR_DRBG_BLOCKSIZE );
+ use_len = buf_len;
+
+ while( use_len > 0 )
+ {
+ for( i = 0; i < CTR_DRBG_BLOCKSIZE; i++ )
+ chain[i] ^= p[i];
+ p += CTR_DRBG_BLOCKSIZE;
+ use_len -= CTR_DRBG_BLOCKSIZE;
+
+ aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, chain, chain );
+ }
+
+ memcpy( tmp + j, chain, CTR_DRBG_BLOCKSIZE );
+
+ /*
+ * Update IV
+ */
+ buf[3]++;
+ }
+
+ /*
+ * Do final encryption with reduced data
+ */
+ aes_setkey_enc( &aes_ctx, tmp, CTR_DRBG_KEYBITS );
+ iv = tmp + CTR_DRBG_KEYSIZE;
+ p = output;
+
+ for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
+ {
+ aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, iv, iv );
+ memcpy( p, iv, CTR_DRBG_BLOCKSIZE );
+ p += CTR_DRBG_BLOCKSIZE;
+ }
+
+ return( 0 );
+}
+
+int ctr_drbg_update_internal( ctr_drbg_context *ctx,
+ const unsigned char data[CTR_DRBG_SEEDLEN] )
+{
+ unsigned char tmp[CTR_DRBG_SEEDLEN];
+ unsigned char *p = tmp;
+ int i, j;
+
+ memset( tmp, 0, CTR_DRBG_SEEDLEN );
+
+ for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE )
+ {
+ /*
+ * Increase counter
+ */
+ for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- )
+ if( ++ctx->counter[i - 1] != 0 )
+ break;
+
+ /*
+ * Crypt counter block
+ */
+ aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, p );
+
+ p += CTR_DRBG_BLOCKSIZE;
+ }
+
+ for( i = 0; i < CTR_DRBG_SEEDLEN; i++ )
+ tmp[i] ^= data[i];
+
+ /*
+ * Update key and counter
+ */
+ aes_setkey_enc( &ctx->aes_ctx, tmp, CTR_DRBG_KEYBITS );
+ memcpy( ctx->counter, tmp + CTR_DRBG_KEYSIZE, CTR_DRBG_BLOCKSIZE );
+
+ return( 0 );
+}
+
+void ctr_drbg_update( ctr_drbg_context *ctx,
+ const unsigned char *additional, size_t add_len )
+{
+ unsigned char add_input[CTR_DRBG_SEEDLEN];
+
+ if( add_len > 0 )
+ {
+ block_cipher_df( add_input, additional, add_len );
+ ctr_drbg_update_internal( ctx, add_input );
+ }
+}
+
+int ctr_drbg_reseed( ctr_drbg_context *ctx,
+ const unsigned char *additional, size_t len )
+{
+ unsigned char seed[CTR_DRBG_MAX_SEED_INPUT];
+ size_t seedlen = 0;
+
+ if( ctx->entropy_len + len > CTR_DRBG_MAX_SEED_INPUT )
+ return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
+
+ memset( seed, 0, CTR_DRBG_MAX_SEED_INPUT );
+
+ /*
+ * Gather enropy_len bytes of entropy to seed state
+ */
+ if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
+ ctx->entropy_len ) )
+ {
+ return( POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
+ }
+
+ seedlen += ctx->entropy_len;
+
+ /*
+ * Add additional data
+ */
+ if( additional && len )
+ {
+ memcpy( seed + seedlen, additional, len );
+ seedlen += len;
+ }
+
+ /*
+ * Reduce to 384 bits
+ */
+ block_cipher_df( seed, seed, seedlen );
+
+ /*
+ * Update state
+ */
+ ctr_drbg_update_internal( ctx, seed );
+ ctx->reseed_counter = 1;
+
+ return( 0 );
+}
+
+int ctr_drbg_random_with_add( void *p_rng,
+ unsigned char *output, size_t output_len,
+ const unsigned char *additional, size_t add_len )
+{
+ int ret = 0;
+ ctr_drbg_context *ctx = (ctr_drbg_context *) p_rng;
+ unsigned char add_input[CTR_DRBG_SEEDLEN];
+ unsigned char *p = output;
+ unsigned char tmp[CTR_DRBG_BLOCKSIZE];
+ int i;
+ size_t use_len;
+
+ if( output_len > CTR_DRBG_MAX_REQUEST )
+ return( POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG );
+
+ if( add_len > CTR_DRBG_MAX_INPUT )
+ return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
+
+ memset( add_input, 0, CTR_DRBG_SEEDLEN );
+
+ if( ctx->reseed_counter > ctx->reseed_interval ||
+ ctx->prediction_resistance )
+ {
+ if( ( ret = ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
+ return( ret );
+
+ add_len = 0;
+ }
+
+ if( add_len > 0 )
+ {
+ block_cipher_df( add_input, additional, add_len );
+ ctr_drbg_update_internal( ctx, add_input );
+ }
+
+ while( output_len > 0 )
+ {
+ /*
+ * Increase counter
+ */
+ for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- )
+ if( ++ctx->counter[i - 1] != 0 )
+ break;
+
+ /*
+ * Crypt counter block
+ */
+ aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, tmp );
+
+ use_len = (output_len > CTR_DRBG_BLOCKSIZE ) ? CTR_DRBG_BLOCKSIZE : output_len;
+ /*
+ * Copy random block to destination
+ */
+ memcpy( p, tmp, use_len );
+ p += use_len;
+ output_len -= use_len;
+ }
+
+ ctr_drbg_update_internal( ctx, add_input );
+
+ ctx->reseed_counter++;
+
+ return( 0 );
+}
+
+int ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
+{
+ return ctr_drbg_random_with_add( p_rng, output, output_len, NULL, 0 );
+}
+
+#if defined(POLARSSL_FS_IO)
+int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path )
+{
+ int ret;
+ FILE *f;
+ unsigned char buf[ CTR_DRBG_MAX_INPUT ];
+
+ if( ( f = fopen( path, "wb" ) ) == NULL )
+ return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
+
+ if( ( ret = ctr_drbg_random( ctx, buf, CTR_DRBG_MAX_INPUT ) ) != 0 )
+ return( ret );
+
+ if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT, f ) != CTR_DRBG_MAX_INPUT )
+ {
+ fclose( f );
+ return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
+ }
+
+ fclose( f );
+ return( 0 );
+}
+
+int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path )
+{
+ FILE *f;
+ size_t n;
+ unsigned char buf[ CTR_DRBG_MAX_INPUT ];
+
+ if( ( f = fopen( path, "rb" ) ) == NULL )
+ return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
+
+ fseek( f, 0, SEEK_END );
+ n = (size_t) ftell( f );
+ fseek( f, 0, SEEK_SET );
+
+ if( n > CTR_DRBG_MAX_INPUT )
+ return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );
+
+ if( fread( buf, 1, n, f ) != n )
+ {
+ fclose( f );
+ return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR );
+ }
+
+ ctr_drbg_update( ctx, buf, n );
+
+ fclose( f );
+
+ return( ctr_drbg_write_seed_file( ctx, path ) );
+}
+#endif /* POLARSSL_FS_IO */
+
+#if defined(POLARSSL_SELF_TEST)
+
+#include <stdio.h>
+
+unsigned char entropy_source_pr[96] =
+ { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
+ 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
+ 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
+ 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
+ 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
+ 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
+ 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
+ 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
+ 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
+ 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
+ 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
+ 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
+
+unsigned char entropy_source_nopr[64] =
+ { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
+ 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
+ 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
+ 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
+ 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
+ 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
+ 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
+ 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
+
+unsigned char nonce_pers_pr[16] =
+ { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
+ 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
+
+unsigned char nonce_pers_nopr[16] =
+ { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
+ 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
+
+unsigned char result_pr[16] =
+ { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
+ 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
+
+unsigned char result_nopr[16] =
+ { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
+ 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
+
+int test_offset;
+int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, size_t len )
+{
+ unsigned char *p = data;
+ memcpy( buf, p + test_offset, len );
+ test_offset += 32;
+ return( 0 );
+}
+
+/*
+ * Checkup routine
+ */
+int ctr_drbg_self_test( int verbose )
+{
+ ctr_drbg_context ctx;
+ unsigned char buf[16];
+
+ /*
+ * Based on a NIST CTR_DRBG test vector (PR = True)
+ */
+ if( verbose != 0 )
+ printf( " CTR_DRBG (PR = TRUE) : " );
+
+ test_offset = 0;
+ if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_pr, nonce_pers_pr, 16, 32 ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+ ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON );
+
+ if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ /*
+ * Based on a NIST CTR_DRBG test vector (PR = FALSE)
+ */
+ if( verbose != 0 )
+ printf( " CTR_DRBG (PR = FALSE): " );
+
+ test_offset = 0;
+ if( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, entropy_source_nopr, nonce_pers_nopr, 16, 32 ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( ctr_drbg_reseed( &ctx, NULL, 0 ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( ctr_drbg_random( &ctx, buf, 16 ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( memcmp( buf, result_nopr, 16 ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ if( verbose != 0 )
+ printf( "\n" );
+
+ return( 0 );
+}
+#endif
+
+#endif
+