diff options
Diffstat (limited to 'lib/dns/sec')
237 files changed, 32793 insertions, 0 deletions
diff --git a/lib/dns/sec/.cvsignore b/lib/dns/sec/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/lib/dns/sec/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/lib/dns/sec/Makefile.in b/lib/dns/sec/Makefile.in new file mode 100644 index 00000000..281e6008 --- /dev/null +++ b/lib/dns/sec/Makefile.in @@ -0,0 +1,23 @@ +# Copyright (C) 1998, 1999, 2000 Internet Software Consortium. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS +# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE +# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +# SOFTWARE. + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +SUBDIRS = dnssafe dst openssl +TARGETS = + +@BIND9_MAKE_RULES@ diff --git a/lib/dns/sec/dnssafe/.cvsignore b/lib/dns/sec/dnssafe/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/lib/dns/sec/dnssafe/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/lib/dns/sec/dnssafe/Makefile.in b/lib/dns/sec/dnssafe/Makefile.in new file mode 100644 index 00000000..127568eb --- /dev/null +++ b/lib/dns/sec/dnssafe/Makefile.in @@ -0,0 +1,77 @@ +# Copyright (C) 1998, 1999, 2000 Internet Software Consortium. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS +# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE +# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +# SOFTWARE. + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_INCLUDES@ + +CINCLUDES = -I${srcdir} ${ISC_INCLUDES} + +CDEFINES = +CWARNINGS = + +LIBS = @LIBS@ + +# Alphabetically +OBJS = ahchdig.@O@ ahchencr.@O@ ahchgen.@O@ ahchrand.@O@ \ + ahdigest.@O@ ahencryp.@O@ ahgen.@O@ ahrandom.@O@ \ + ahrsaenc.@O@ ahrsaepr.@O@ ahrsaepu.@O@ aichdig.@O@ \ + aichenc8.@O@ aichencn.@O@ aichencr.@O@ aichgen.@O@ \ + aichrand.@O@ aimd5.@O@ aimd5ran.@O@ ainfotyp.@O@ \ + ainull.@O@ airsaepr.@O@ airsaepu.@O@ airsakgn.@O@ \ + airsaprv.@O@ airsapub.@O@ algchoic.@O@ algobj.@O@ \ + amcrte.@O@ ammd5.@O@ ammd5r.@O@ amrkg.@O@ amrsae.@O@ \ + balg.@O@ bgclrbit.@O@ bgmdmpyx.@O@ bgmdsqx.@O@ \ + bgmodexp.@O@ bgpegcd.@O@ big2exp.@O@ bigabs.@O@ \ + bigacc.@O@ bigarith.@O@ bigcmp.@O@ bigconst.@O@ \ + biginv.@O@ biglen.@O@ bigmodx.@O@ bigmpy.@O@ \ + bigpdiv.@O@ bigpmpy.@O@ bigpmpyh.@O@ bigpmpyl.@O@ \ + bigpsq.@O@ bigqrx.@O@ bigsmod.@O@ bigtocan.@O@ \ + bigu.@O@ bigunexp.@O@ binfocsh.@O@ bkey.@O@ \ + bmempool.@O@ cantobig.@O@ crt2.@O@ digest.@O@ \ + digrand.@O@ encrypt.@O@ generate.@O@ intbits.@O@ \ + intitem.@O@ keyobj.@O@ ki8byte.@O@ kiitem.@O@ \ + kinfotyp.@O@ kifulprv.@O@ kipkcrpr.@O@ kirsacrt.@O@ \ + kirsapub.@O@ md5.@O@ md5rand.@O@ prime.@O@ random.@O@ \ + rsa.@O@ rsakeygn.@O@ seccbcd.@O@ seccbce.@O@ surrendr.@O@ + +SRCS = ahchdig.c ahchencr.c ahchgen.c ahchrand.c \ + ahdigest.c ahencryp.c ahgen.c ahrandom.c \ + ahrsaenc.c ahrsaepr.c ahrsaepu.c aichdig.c \ + aichenc8.c aichencn.c aichencr.c aichgen.c \ + aichrand.c aimd5.c aimd5ran.c ainfotyp.c \ + ainull.c airsaepr.c airsaepu.c airsakgn.c \ + airsaprv.c airsapub.c algchoic.c algobj.c \ + amcrte.c ammd5.c ammd5r.c amrkg.c amrsae.c \ + balg.c bgclrbit.c bgmdmpyx.c bgmdsqx.c \ + bgmodexp.c bgpegcd.c big2exp.c bigabs.c \ + bigacc.c bigarith.c bigcmp.c bigconst.c \ + biginv.c biglen.c bigmodx.c bigmpy.c \ + bigpdiv.c bigpmpy.c bigpmpyh.c bigpmpyl.c \ + bigpsq.c bigqrx.c bigsmod.c bigtocan.c \ + bigu.c bigunexp.c binfocsh.c bkey.c \ + bmempool.c cantobig.c crt2.c digest.c \ + digrand.c encrypt.c generate.c intbits.c \ + intitem.c keyobj.c ki8byte.c kiitem.c \ + kinfotyp.c kifulprv.c kipkcrpr.c kirsacrt.c \ + kirsapub.c md5.c md5rand.c prime.c random.c \ + rsa.c rsakeygn.c seccbcd.c seccbce.c surrendr.c + +SUBDIRS = +TARGETS = ${OBJS} + +@BIND9_MAKE_RULES@ diff --git a/lib/dns/sec/dnssafe/ahcbcpad.c b/lib/dns/sec/dnssafe/ahcbcpad.c new file mode 100644 index 00000000..5bc74383 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahcbcpad.c @@ -0,0 +1,174 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +/* Define this so that the type of the 'this' pointer in the + virtual functions will be correct for this derived class. + */ +struct AHSecretCBCPad; +#define THIS_ENCRYPT_DECRYPT struct AHSecretCBCPad + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ahcbcpad.h" + +#define GENERATE_BREAK(type) { \ + status = type; \ + break; \ + } + +/* Inherit the base class destructor, block size, + and decrypt init and update routines. + */ +static AHEncryptDecryptVTable V_TABLE = { + AHChooseEncryptDestructor, AHChooseEncryptGetBlockLen, + AHSecretCBCPadEncryptInit, AHChooseEncryptDecryptInit, + AHSecretCBCPadEncryptUpdate, AHChooseEncryptDecryptUpdate, + AHSecretCBCPadEncryptFinal, AHSecretCBCPadDecryptFinal +}; + +AHSecretCBCPad *AHSecretCBCPadConstructor2 (handler, infoType, info) +AHSecretCBCPad *handler; +struct B_AlgorithmInfoType *infoType; +POINTER info; +{ + if (handler == (AHSecretCBCPad *)NULL_PTR) { + /* This constructor is being used to do a new */ + if ((handler = (AHSecretCBCPad *)T_malloc (sizeof (*handler))) + == (AHSecretCBCPad *)NULL_PTR) + return (handler); + } + + /* Construct base class with the infoType and info. */ + AHChooseEncryptConstructor2 + (&handler->chooseEncryptDecrypt, infoType, info); + + handler->chooseEncryptDecrypt.encryptDecrypt.vTable = &V_TABLE; + return (handler); +} + +int AHSecretCBCPadEncryptInit (handler, key, chooser, surrenderContext) +AHSecretCBCPad *handler; +B_Key *key; +B_ALGORITHM_CHOOSER chooser; +A_SURRENDER_CTX *surrenderContext; +{ + /* For encryption, we need to track the input length */ + handler->_inputRemainder = 0; + + return (AHChooseEncryptEncryptInit + (handler, key, chooser, surrenderContext)); +} + +int AHSecretCBCPadEncryptUpdate + (handler, partOut, partOutLen, maxPartOutLen, partIn, partInLen, + randomAlgorithm, surrenderContext) +AHSecretCBCPad *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +unsigned char *partIn; +unsigned int partInLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + /* For encryption, we need to track the input length */ + handler->_inputRemainder = (handler->_inputRemainder + partInLen) % 8; + + return (AHChooseEncryptEncryptUpdate + (handler, partOut, partOutLen, maxPartOutLen, partIn, partInLen, + randomAlgorithm, surrenderContext)); +} + +int AHSecretCBCPadEncryptFinal + (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm, + surrenderContext) +AHSecretCBCPad *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + unsigned char finalBuffer[8]; + unsigned int padLen, dummyPartOutLen; + + padLen = 8 - handler->_inputRemainder; + T_memset ((POINTER)finalBuffer, padLen, padLen); + + /* Add the pad bytes. This should force the output of the final block. + */ + if ((status = AHChooseEncryptEncryptUpdate + (handler, partOut, partOutLen, maxPartOutLen, finalBuffer, padLen, + randomAlgorithm, surrenderContext)) != 0) + return (status); + + /* The encrypt final operation should have no output. */ + if ((status = AHChooseEncryptEncryptFinal + (handler, (unsigned char *)NULL_PTR, &dummyPartOutLen, 0, + (B_Algorithm *)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) + return (status); + + /* Restart the context. */ + handler->_inputRemainder = 0; + + /* No need to zeroize the finalBuffer since it only contains pad bytes. */ + return (0); +} + +int AHSecretCBCPadDecryptFinal + (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm, + surrenderContext) +AHSecretCBCPad *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + unsigned char finalBuffer[16], *padBuffer; + unsigned int padLen, localPartOutLen, i; + + do { + /* For now, the DecrypyFinal operations is set to output 16 bytes. + */ + if ((status = AHChooseEncryptDecryptFinal + (handler, finalBuffer, &localPartOutLen, sizeof (finalBuffer), + randomAlgorithm, surrenderContext)) != 0) + break; + + if (localPartOutLen == 8) + padBuffer = finalBuffer; + else if (localPartOutLen == 16) + padBuffer = finalBuffer + 8; + else + GENERATE_BREAK (BE_INPUT_LEN); + + /* Check that padding is one 1 to eight 8's. + */ + if ((padLen = (unsigned int)padBuffer[7]) == 0 || padLen > 8) + GENERATE_BREAK (BE_INPUT_DATA); + for (i = 8 - padLen; i < 8; i++) { + if ((unsigned int)padBuffer[i] != padLen) + GENERATE_BREAK (BE_INPUT_DATA); + } + + if ((*partOutLen = localPartOutLen - padLen) > maxPartOutLen) + GENERATE_BREAK (BE_OUTPUT_LEN); + + T_memcpy + ((POINTER)partOut, (POINTER)finalBuffer, *partOutLen); + } while (0); + + T_memset ((POINTER)finalBuffer, 0, sizeof (finalBuffer)); + return (status); +} + diff --git a/lib/dns/sec/dnssafe/ahcbcpad.h b/lib/dns/sec/dnssafe/ahcbcpad.h new file mode 100644 index 00000000..9daa2435 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahcbcpad.h @@ -0,0 +1,37 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AHCBCPAD_H_ +#define _AHCBCPAD_H_ + +#include "ahchencr.h" + +typedef struct AHSecretCBCPad { + AHChooseEncryptDecrypt chooseEncryptDecrypt; /* base class */ + + unsigned int _inputRemainder; /* Used for encrypt to compute pad length */ +} AHSecretCBCPad; + +AHSecretCBCPad *AHSecretCBCPadConstructor2 PROTO_LIST + ((AHSecretCBCPad *, struct B_AlgorithmInfoType *, POINTER)); + +int AHSecretCBCPadEncryptInit PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER, + A_SURRENDER_CTX *)); +int AHSecretCBCPadEncryptUpdate PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, + unsigned int, unsigned char *, unsigned int, B_Algorithm *, + A_SURRENDER_CTX *)); +int AHSecretCBCPadEncryptFinal PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, + unsigned int, B_Algorithm *, A_SURRENDER_CTX *)); +int AHSecretCBCPadDecryptFinal PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, + unsigned int, B_Algorithm *, A_SURRENDER_CTX *)); + +#endif diff --git a/lib/dns/sec/dnssafe/ahchdig.c b/lib/dns/sec/dnssafe/ahchdig.c new file mode 100644 index 00000000..8f4b4e23 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahchdig.c @@ -0,0 +1,130 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +/* Define this so that the type of the 'this' pointer in the + virtual functions will be correct for this derived class. + */ +struct AHChooseDigest; +#define THIS_DIGEST struct AHChooseDigest + +#include "global.h" +#include "algae.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "balgmeth.h" +#include "ahchdig.h" +#include "amdigest.h" + +static int InitDigestAlga PROTO_LIST + ((AlgaChoice *, POINTER, B_ALGORITHM_METHOD *, A_SURRENDER_CTX *)); + +static AHDigestVTable V_TABLE = { + AHChooseDigestDestructor, AHChooseDigestInit, AHChooseDigestUpdate, + AHChooseDigestFinal +}; + +AHChooseDigest *AHChooseDigestConstructor2 (handler, infoType, info) +AHChooseDigest *handler; +struct B_AlgorithmInfoType *infoType; +POINTER info; +{ + if (handler == (AHChooseDigest *)NULL_PTR) { + /* This constructor is being used to do a new */ + if ((handler = (AHChooseDigest *)T_malloc (sizeof (*handler))) + == (AHChooseDigest *)NULL_PTR) + return (handler); + } + + /* Construct base class */ + AHDigestConstructor (&handler->digest); + + ALGA_CHOICE_Constructor (&handler->algaChoice, InitDigestAlga); + handler->algaChoice._algorithmInfoType = infoType; + handler->algaChoice._algorithmInfo = info; + + handler->digest.vTable = &V_TABLE; + + return (handler); +} + +void AHChooseDigestDestructor (handler) +AHChooseDigest *handler; +{ + ALGA_CHOICE_Destructor (&handler->algaChoice); + /* There is no desructor to call for the base class. */ +} + +int AHChooseDigestInit (handler, key, chooser, surrenderContext) +AHChooseDigest *handler; +B_Key *key; +B_ALGORITHM_CHOOSER chooser; +A_SURRENDER_CTX *surrenderContext; +{ + return (AlgaChoiceChoose + (&handler->algaChoice, 0, key, chooser, surrenderContext)); +} + +int AHChooseDigestUpdate (handler, partIn, partInLen, surrenderContext) +AHChooseDigest *handler; +unsigned char *partIn; +unsigned int partInLen; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = (*((A_DIGEST_ALGA *)handler->algaChoice._alga)->Update) + (handler->algaChoice.context.z.context, partIn, partInLen, + surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + return (0); +} + +int AHChooseDigestFinal + (handler, partOut, partOutLen, maxPartOutLen, surrenderContext) +AHChooseDigest *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = (*((A_DIGEST_ALGA *)handler->algaChoice._alga)->Final) + (handler->algaChoice.context.z.context, partOut, partOutLen, + maxPartOutLen, surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + return (0); +} + +static int InitDigestAlga + (algaChoice, keyInfo, algorithmMethod, surrenderContext) +AlgaChoice *algaChoice; +POINTER keyInfo; +B_ALGORITHM_METHOD *algorithmMethod; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + unsigned int contextSize; + +UNUSED_ARG (keyInfo) + if ((status = (*((A_DIGEST_ALGA *)algorithmMethod->alga)->Query) + (&contextSize, algaChoice->_algorithmInfo)) != 0) + return (ConvertAlgaeError (status)); + + if ((status = ResizeContextMakeNewContext + (&algaChoice->context, contextSize)) != 0) + return (status); + + if ((status = (*((A_DIGEST_ALGA *)algorithmMethod->alga)->Init) + (algaChoice->context.z.context, algaChoice->_algorithmInfo, + surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + + return (0); +} diff --git a/lib/dns/sec/dnssafe/ahchdig.h b/lib/dns/sec/dnssafe/ahchdig.h new file mode 100644 index 00000000..d56df5ba --- /dev/null +++ b/lib/dns/sec/dnssafe/ahchdig.h @@ -0,0 +1,32 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AHCHDIG_H_ +#define _AHCHDIG_H_ 1 + +#include "ahdigest.h" +#include "algchoic.h" + +typedef struct AHChooseDigest { + AHDigest digest; /* base class */ + AlgaChoice algaChoice; +} AHChooseDigest; + +AHChooseDigest *AHChooseDigestConstructor2 PROTO_LIST + ((AHChooseDigest *, struct B_AlgorithmInfoType *, POINTER)); +void AHChooseDigestDestructor PROTO_LIST ((THIS_DIGEST *)); + +int AHChooseDigestInit PROTO_LIST + ((THIS_DIGEST *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int AHChooseDigestUpdate PROTO_LIST + ((THIS_DIGEST *, unsigned char *, unsigned int, A_SURRENDER_CTX *)); +int AHChooseDigestFinal PROTO_LIST + ((THIS_DIGEST *, unsigned char *, unsigned int *, unsigned int, + A_SURRENDER_CTX *)); + +#endif diff --git a/lib/dns/sec/dnssafe/ahchencr.c b/lib/dns/sec/dnssafe/ahchencr.c new file mode 100644 index 00000000..64cf959c --- /dev/null +++ b/lib/dns/sec/dnssafe/ahchencr.c @@ -0,0 +1,266 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +/* Define this so that the type of the 'this' pointer in the + virtual functions will be correct for this derived class. + */ +struct AHChooseEncryptDecrypt; +#define THIS_ENCRYPT_DECRYPT struct AHChooseEncryptDecrypt + +#include "global.h" +#include "algae.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "balgmeth.h" +#include "ahchencr.h" +#include "amencdec.h" + +static int InitEncryptDecryptAlga PROTO_LIST + ((AlgaChoice *, POINTER, B_ALGORITHM_METHOD *, A_SURRENDER_CTX *)); + +static AHEncryptDecryptVTable V_TABLE = { + AHChooseEncryptDestructor, AHChooseEncryptGetBlockLen, + AHChooseEncryptEncryptInit, AHChooseEncryptDecryptInit, + AHChooseEncryptEncryptUpdate, AHChooseEncryptDecryptUpdate, + AHChooseEncryptEncryptFinal, AHChooseEncryptDecryptFinal +}; + +/* In C++: +AHChooseEncryptDecrypt::AHChooseEncryptDecrypt + (B_AlgorithmInfoType *infoType, POINTER info) + : algaChoice (InitEncryptDecryptAlga) +{ + algaChoice.setAlgorithmInfoType (infoType); + algaChoice.setAlgorithmInfo (info); +} + */ +AHChooseEncryptDecrypt *AHChooseEncryptConstructor2 (handler, infoType, info) +AHChooseEncryptDecrypt *handler; +struct B_AlgorithmInfoType *infoType; +POINTER info; +{ + if (handler == (AHChooseEncryptDecrypt *)NULL_PTR) { + /* This constructor is being used to do a new */ + if ((handler = (AHChooseEncryptDecrypt *)T_malloc (sizeof (*handler))) + == (AHChooseEncryptDecrypt *)NULL_PTR) + return (handler); + } + + /* Construct base class */ + AHEncryptDecryptConstructor (&handler->encryptDecrypt); + + ALGA_CHOICE_Constructor (&handler->algaChoice, InitEncryptDecryptAlga); + handler->algaChoice._algorithmInfoType = infoType; + handler->algaChoice._algorithmInfo = info; + + handler->encryptDecrypt.vTable = &V_TABLE; + + return (handler); +} + +void AHChooseEncryptDestructor (handler) +AHChooseEncryptDecrypt *handler; +{ + ALGA_CHOICE_Destructor (&handler->algaChoice); + /* There is no desructor to call for the base class. */ +} + +int AHChooseEncryptGetBlockLen (handler, blockLen) +AHChooseEncryptDecrypt *handler; +unsigned int *blockLen; +{ + int status; + + if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)handler->algaChoice._alga)-> + GetBlockLen) + (handler->algaChoice.context.z.context, blockLen)) != 0) + return (ConvertAlgaeError (status)); + return (0); +} + +/* In C++: +int AHChooseEncryptDecrypt::encryptInit + (B_Key *key, B_ALGORITHM_CHOOSER chooser, A_SURRENDER_CTX *surrenderContext) +{ + return (algaChoice.choose (1, key, chooser, surrenderContext)); +} + */ +int AHChooseEncryptEncryptInit (handler, key, chooser, surrenderContext) +AHChooseEncryptDecrypt *handler; +B_Key *key; +B_ALGORITHM_CHOOSER chooser; +A_SURRENDER_CTX *surrenderContext; +{ + return (AlgaChoiceChoose + (&handler->algaChoice, 1, key, chooser, surrenderContext)); +} + +int AHChooseEncryptDecryptInit (handler, key, chooser, surrenderContext) +AHChooseEncryptDecrypt *handler; +B_Key *key; +B_ALGORITHM_CHOOSER chooser; +A_SURRENDER_CTX *surrenderContext; +{ + return (AlgaChoiceChoose + (&handler->algaChoice, 0, key, chooser, surrenderContext)); +} + +/* In C++: +int AHChooseEncryptDecrypt::encryptUpdate + (unsigned char *partOut, unsigned int *partOutLen, + unsigned int maxPartOutLen, unsigned char *partIn, unsigned int partInLen, + B_Algorithm *randomAlgorithm, A_SURRENDER_CTX *surrenderContext) +{ + int status; + + if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)algaChoice.alga ()) ->Update) + (algaChoice.context (), partOut, partOutLen, maxPartOutLen, + partIn, partInLen, surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + return (0); +} + */ +int AHChooseEncryptEncryptUpdate + (handler, partOut, partOutLen, maxPartOutLen, partIn, partInLen, + randomAlgorithm, surrenderContext) +AHChooseEncryptDecrypt *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +unsigned char *partIn; +unsigned int partInLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + +UNUSED_ARG (randomAlgorithm) + + if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)handler->algaChoice._alga)-> + Update) + (handler->algaChoice.context.z.context, partOut, partOutLen, + maxPartOutLen, partIn, partInLen, surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + return (0); +} + +int AHChooseEncryptDecryptUpdate + (handler, partOut, partOutLen, maxPartOutLen, partIn, partInLen, + randomAlgorithm, surrenderContext) +AHChooseEncryptDecrypt *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +unsigned char *partIn; +unsigned int partInLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + +UNUSED_ARG (randomAlgorithm) + + if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)handler->algaChoice._alga)-> + Update) + (handler->algaChoice.context.z.context, partOut, partOutLen, + maxPartOutLen, partIn, partInLen, surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + return (0); +} + +int AHChooseEncryptEncryptFinal + (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm, + surrenderContext) +AHChooseEncryptDecrypt *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + +UNUSED_ARG (randomAlgorithm) + + if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)handler->algaChoice._alga)->Final) + (handler->algaChoice.context.z.context, partOut, partOutLen, + maxPartOutLen, surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + return (0); +} + +int AHChooseEncryptDecryptFinal + (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm, + surrenderContext) +AHChooseEncryptDecrypt *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + +UNUSED_ARG (randomAlgorithm) + + if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)handler->algaChoice._alga)->Final) + (handler->algaChoice.context.z.context, partOut, partOutLen, + maxPartOutLen, surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + return (0); +} + +/* In C++: +static int InitEncryptDecryptAlga + (AlgaChoice *algaChoice, POINTER keyInfo, POINTER alga, + A_SURRENDER_CTX *surrenderContext) +{ + int status; + unsigned int contextSize; + + if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)alga)->Query) + (&contextSize, keyInfo, algaChoice->algorithmInfo ())) != 0) + return (ConvertAlgaeError (status)); + + if ((status = algaChoice->makeNewContext (contextSize)) != 0) + return (status); + + if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)alga)->Init) + (algaChoice->context (), keyInfo, algaChoice->algorithmInfo (), + surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + + return (0); +} + */ +static int InitEncryptDecryptAlga + (algaChoice, keyInfo, algorithmMethod, surrenderContext) +AlgaChoice *algaChoice; +POINTER keyInfo; +B_ALGORITHM_METHOD *algorithmMethod; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + unsigned int contextSize; + + if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)algorithmMethod->alga)->Query) + (&contextSize, keyInfo, algaChoice->_algorithmInfo)) != 0) + return (ConvertAlgaeError (status)); + + if ((status = ResizeContextMakeNewContext + (&algaChoice->context, contextSize)) != 0) + return (status); + + if ((status = (*((A_ENCRYPT_DECRYPT_ALGA *)algorithmMethod->alga)->Init) + (algaChoice->context.z.context, keyInfo, algaChoice->_algorithmInfo, + surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + + return (0); +} diff --git a/lib/dns/sec/dnssafe/ahchencr.h b/lib/dns/sec/dnssafe/ahchencr.h new file mode 100644 index 00000000..4befa783 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahchencr.h @@ -0,0 +1,74 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AHCHENCR_H_ +#define _AHCHENCR_H_ 1 + +#include "ahencryp.h" +#include "algchoic.h" + +/* In C++: +class AHChooseEncryptDecrypt : public AHEncryptDecrypt { +public: + AHChooseEncryptDecrypt (B_AlgorithmInfoType *, POINTER); + virtual ~AHChooseEncryptDecrypt () {}; + + virtual int getBlockLen (unsigned int *); + virtual int encryptInit (B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *); + virtual int decryptInit (B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *); + virtual int encryptUpdate + (unsigned char *, unsigned int *, unsigned int, unsigned char *, + unsigned int, B_Algorithm *, A_SURRENDER_CTX *); + virtual int decryptUpdate + (unsigned char *, unsigned int *, unsigned int, unsigned char *, + unsigned int, B_Algorithm *, A_SURRENDER_CTX *); + virtual int encryptFinal + (unsigned char *, unsigned int *, unsigned int, B_Algorithm *, + A_SURRENDER_CTX *); + virtual int decryptFinal + (unsigned char *, unsigned int *, unsigned int, B_Algorithm *, + A_SURRENDER_CTX *); + +private: + AlgaChoice algaChoice; +}; + */ + +typedef struct AHChooseEncryptDecrypt { + AHEncryptDecrypt encryptDecrypt; /* base class */ + AlgaChoice algaChoice; +} AHChooseEncryptDecrypt; + +AHChooseEncryptDecrypt *AHChooseEncryptConstructor2 PROTO_LIST + ((AHChooseEncryptDecrypt *, struct B_AlgorithmInfoType *, POINTER)); +void AHChooseEncryptDestructor PROTO_LIST ((THIS_ENCRYPT_DECRYPT *)); + +int AHChooseEncryptGetBlockLen PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned int *)); +int AHChooseEncryptEncryptInit PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER, + A_SURRENDER_CTX *)); +int AHChooseEncryptDecryptInit PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER, + A_SURRENDER_CTX *)); +int AHChooseEncryptEncryptUpdate PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, + unsigned int, unsigned char *, unsigned int, B_Algorithm *, + A_SURRENDER_CTX *)); +int AHChooseEncryptDecryptUpdate PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, + unsigned int, unsigned char *, unsigned int, B_Algorithm *, + A_SURRENDER_CTX *)); +int AHChooseEncryptEncryptFinal PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, + unsigned int, B_Algorithm *, A_SURRENDER_CTX *)); +int AHChooseEncryptDecryptFinal PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, + unsigned int, B_Algorithm *, A_SURRENDER_CTX *)); + +#endif diff --git a/lib/dns/sec/dnssafe/ahchgen.c b/lib/dns/sec/dnssafe/ahchgen.c new file mode 100644 index 00000000..f1d7bd7c --- /dev/null +++ b/lib/dns/sec/dnssafe/ahchgen.c @@ -0,0 +1,216 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +/* Define this so that the type of the 'this' pointer in the + virtual functions will be correct for this derived class. + */ +struct AHChooseGenerate; +#define THIS_GENERATE struct AHChooseGenerate + +/* Define this so that the type of the AlgaChoice pointer in the + INIT_ALGA functions will be correct for this derived class. + */ +struct GenerateAlgaChoice; +#define THIS_ALGA_CHOICE struct GenerateAlgaChoice + +#include "global.h" +#include "algae.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "balgmeth.h" +#include "ahchgen.h" +#include "amgen.h" + +static int InitGenerateAlga PROTO_LIST + ((GenerateAlgaChoice *, POINTER, B_ALGORITHM_METHOD *, A_SURRENDER_CTX *)); +static int GenerateResult PROTO_LIST + ((GenerateAlgaChoice *, POINTER *, B_Algorithm *, A_SURRENDER_CTX *)); + +static AHGenerateVTable V_TABLE = { + AHChooseGenerateDestructor, AHChooseGenerateInit, AHChooseGenerateKeypair, + AHChooseGenerateParameters +}; + +AHChooseGenerate *AHChooseGenerateConstructor2 (handler, infoType, info) +AHChooseGenerate *handler; +struct B_AlgorithmInfoType *infoType; +POINTER info; +{ + if (handler == (AHChooseGenerate *)NULL_PTR) { + /* This constructor is being used to do a new */ + if ((handler = (AHChooseGenerate *)T_malloc (sizeof (*handler))) + == (AHChooseGenerate *)NULL_PTR) + return (handler); + } + + /* Construct base class */ + AHGenerateConstructor (&handler->generate); + + ALGA_CHOICE_Constructor + (&handler->generateAlgaChoice.algaChoice, InitGenerateAlga); + ResizeContextConstructor (&handler->generateAlgaChoice.secondContext); + ResizeContextConstructor (&handler->generateAlgaChoice.randomBlock); + + /* Set algaChoice. + */ + handler->generateAlgaChoice.algaChoice._algorithmInfoType = infoType; + handler->generateAlgaChoice.algaChoice._algorithmInfo = info; + + handler->generate.vTable = &V_TABLE; + + return (handler); +} + +void AHChooseGenerateDestructor (handler) +AHChooseGenerate *handler; +{ + ResizeContextDestructor (&handler->generateAlgaChoice.secondContext); + ResizeContextDestructor (&handler->generateAlgaChoice.randomBlock); + ALGA_CHOICE_Destructor (&handler->generateAlgaChoice.algaChoice); + /* There is no desructor to call for the base class. */ +} + +int AHChooseGenerateInit (handler, chooser, surrenderContext) +AHChooseGenerate *handler; +B_ALGORITHM_CHOOSER chooser; +A_SURRENDER_CTX *surrenderContext; +{ + return (AlgaChoiceChoose + (&handler->generateAlgaChoice.algaChoice, 0, (B_Key *)NULL_PTR, + chooser, surrenderContext)); +} + +int AHChooseGenerateKeypair + (handler, publicKey, privateKey, randomAlgorithm, surrenderContext) +AHChooseGenerate *handler; +B_Key *publicKey; +B_Key *privateKey; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + POINTER result; + int status; + + if ((status = GenerateResult + (&handler->generateAlgaChoice, &result, randomAlgorithm, + surrenderContext)) != 0) + return (status); + if ((status = B_KeySetInfo + (publicKey, handler->generateAlgaChoice._resultInfoType, result)) != 0) + return (status); + return (B_KeySetInfo + (privateKey, handler->generateAlgaChoice._resultInfoType, result)); +} + +int AHChooseGenerateParameters + (handler, resultAlgorithm, randomAlgorithm, surrenderContext) +AHChooseGenerate *handler; +B_Algorithm *resultAlgorithm; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + POINTER result; + int status; + + if ((status = GenerateResult + (&handler->generateAlgaChoice, &result, randomAlgorithm, + surrenderContext)) != 0) + return (status); + + /* Force the resultInfoType into a B_AlgorithmInfoType since it is + supplied in the chooser as a B_KeyInfoType. */ + return (B_AlgorithmSetInfo + (resultAlgorithm, (struct B_AlgorithmInfoType *) + handler->generateAlgaChoice._resultInfoType, result)); +} + +static int InitGenerateAlga + (generateAlgaChoice, keyInfo, algorithmMethod, surrenderContext) +GenerateAlgaChoice *generateAlgaChoice; +POINTER keyInfo; +B_ALGORITHM_METHOD *algorithmMethod; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + unsigned int contextSize, secondContextSize; + +UNUSED_ARG (keyInfo) + /* Note that this also gets the resultInfoType which will be used later + by GenerateResult. */ + if ((status = (*((A_GENERATE_ALGA *)algorithmMethod->alga)->Query) + (&contextSize, &secondContextSize, &generateAlgaChoice->_randomBlockLen, + &generateAlgaChoice->_resultInfoType, + generateAlgaChoice->algaChoice._algorithmInfo)) != 0) + return (ConvertAlgaeError (status)); + + /* Create the context. + */ + if ((status = ResizeContextMakeNewContext + (&generateAlgaChoice->algaChoice.context, contextSize)) != 0) + return (status); + + /* Create the second context which is only passed during Init, but + must persist for all operations. */ + if ((status = ResizeContextMakeNewContext + (&generateAlgaChoice->secondContext, secondContextSize)) != 0) + return (status); + + /* Create randomBlock which will be filled in during GenerateResult. */ + if ((status = ResizeContextMakeNewContext + (&generateAlgaChoice->randomBlock, generateAlgaChoice->_randomBlockLen)) + != 0) + return (status); + + if ((status = (*((A_GENERATE_ALGA *)algorithmMethod->alga)->Init) + (generateAlgaChoice->algaChoice.context.z.context, + generateAlgaChoice->secondContext.z.context, + generateAlgaChoice->algaChoice._algorithmInfo, surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + + return (0); +} + +/* Call the generate procedure repeatedly with a new random block + until it succeeds. + */ +static int GenerateResult + (generateAlgaChoice, result, randomAlgorithm, surrenderContext) +GenerateAlgaChoice *generateAlgaChoice; +POINTER *result; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + /* Fill in the random block and try generating as long as the + the generate operation returns BE_NEED_RANDOM. + */ + do { + if ((status = B_AlgorithmGenerateRandomBytes + (randomAlgorithm, + (unsigned char *)generateAlgaChoice->randomBlock.z.context, + generateAlgaChoice->_randomBlockLen, surrenderContext)) != 0) + return (status); + + if ((status = (*((A_GENERATE_ALGA *) + generateAlgaChoice->algaChoice._alga)->Generate) + (generateAlgaChoice->algaChoice.context.z.context, result, + (unsigned char *)generateAlgaChoice->randomBlock.z.context, + surrenderContext)) != 0) { + if (status != AE_NEED_RANDOM) + return (ConvertAlgaeError (status)); + + /* Else continue and try again */ + } + else + /* Success, so return */ + return (0); + } while (1); +} + diff --git a/lib/dns/sec/dnssafe/ahchgen.h b/lib/dns/sec/dnssafe/ahchgen.h new file mode 100644 index 00000000..8e7ecf3d --- /dev/null +++ b/lib/dns/sec/dnssafe/ahchgen.h @@ -0,0 +1,44 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AHCHGEN_H_ +#define _AHCHGEN_H_ 1 + +#include "ahgen.h" +#include "algchoic.h" + +/* Make a new class derived from an AlgaChoice which records the + result algorithm info type and needed randomBlockLen. + */ +typedef struct GenerateAlgaChoice { + AlgaChoice algaChoice; /* base class */ + + struct B_KeyInfoType *_resultInfoType; + ResizeContext secondContext; /* used for scratch */ + ResizeContext randomBlock; + unsigned int _randomBlockLen; +} GenerateAlgaChoice; + +typedef struct AHChooseGenerate { + AHGenerate generate; /* base class */ + + GenerateAlgaChoice generateAlgaChoice; +} AHChooseGenerate; + +AHChooseGenerate *AHChooseGenerateConstructor2 PROTO_LIST + ((AHChooseGenerate *, struct B_AlgorithmInfoType *, POINTER)); +void AHChooseGenerateDestructor PROTO_LIST ((THIS_GENERATE *)); + +int AHChooseGenerateInit PROTO_LIST + ((THIS_GENERATE *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int AHChooseGenerateKeypair PROTO_LIST + ((THIS_GENERATE *, B_Key *, B_Key *, B_Algorithm *, A_SURRENDER_CTX *)); +int AHChooseGenerateParameters PROTO_LIST + ((THIS_GENERATE *, B_Algorithm *, B_Algorithm *, A_SURRENDER_CTX *)); + +#endif diff --git a/lib/dns/sec/dnssafe/ahchrand.c b/lib/dns/sec/dnssafe/ahchrand.c new file mode 100644 index 00000000..e565a1d9 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahchrand.c @@ -0,0 +1,128 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +/* Define this so that the type of the 'this' pointer in the + virtual functions will be correct for this derived class. + */ +struct AHChooseRandom; +#define THIS_RANDOM struct AHChooseRandom + +#include "global.h" +#include "algae.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "balgmeth.h" +#include "ahchrand.h" +#include "amrandom.h" + +static int InitRandomAlga PROTO_LIST + ((AlgaChoice *, POINTER, B_ALGORITHM_METHOD *, A_SURRENDER_CTX *)); + +static AHRandomVTable V_TABLE = { + AHChooseRandomDestructor, AHChooseRandomInit, AHChooseRandomUpdate, + AHChooseRandomGenerateBytes +}; + +AHChooseRandom *AHChooseRandomConstructor2 (handler, infoType, info) +AHChooseRandom *handler; +struct B_AlgorithmInfoType *infoType; +POINTER info; +{ + if (handler == (AHChooseRandom *)NULL_PTR) { + /* This constructor is being used to do a new */ + if ((handler = (AHChooseRandom *)T_malloc (sizeof (*handler))) + == (AHChooseRandom *)NULL_PTR) + return (handler); + } + + /* Construct base class */ + AHRandomConstructor (&handler->random); + + ALGA_CHOICE_Constructor (&handler->algaChoice, InitRandomAlga); + handler->algaChoice._algorithmInfoType = infoType; + handler->algaChoice._algorithmInfo = info; + + handler->random.vTable = &V_TABLE; + + return (handler); +} + +void AHChooseRandomDestructor (handler) +AHChooseRandom *handler; +{ + ALGA_CHOICE_Destructor (&handler->algaChoice); + /* There is no desructor to call for the base class. */ +} + +int AHChooseRandomInit (handler, chooser, surrenderContext) +AHChooseRandom *handler; +B_ALGORITHM_CHOOSER chooser; +A_SURRENDER_CTX *surrenderContext; +{ + return (AlgaChoiceChoose + (&handler->algaChoice, 0, (B_Key *)NULL_PTR, chooser, + surrenderContext)); +} + +int AHChooseRandomUpdate (handler, input, inputLen, surrenderContext) +AHChooseRandom *handler; +unsigned char *input; +unsigned int inputLen; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = (*((A_RANDOM_ALGA *)handler->algaChoice._alga)->Update) + (handler->algaChoice.context.z.context, input, inputLen, + surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + return (0); +} + +int AHChooseRandomGenerateBytes (handler, output, outputLen, surrenderContext) +AHChooseRandom *handler; +unsigned char *output; +unsigned int outputLen; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = (*((A_RANDOM_ALGA *)handler->algaChoice._alga)->Generate) + (handler->algaChoice.context.z.context, output, outputLen, + surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + return (0); +} + +static int InitRandomAlga + (algaChoice, keyInfo, algorithmMethod, surrenderContext) +AlgaChoice *algaChoice; +POINTER keyInfo; +B_ALGORITHM_METHOD *algorithmMethod; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + unsigned int contextSize; + +UNUSED_ARG (keyInfo) + if ((status = (*((A_RANDOM_ALGA *)algorithmMethod->alga)->Query) + (&contextSize, algaChoice->_algorithmInfo)) != 0) + return (ConvertAlgaeError (status)); + + if ((status = ResizeContextMakeNewContext + (&algaChoice->context, contextSize)) != 0) + return (status); + + if ((status = (*((A_RANDOM_ALGA *)algorithmMethod->alga)->Init) + (algaChoice->context.z.context, algaChoice->_algorithmInfo, + surrenderContext)) != 0) + return (ConvertAlgaeError (status)); + + return (0); +} diff --git a/lib/dns/sec/dnssafe/ahchrand.h b/lib/dns/sec/dnssafe/ahchrand.h new file mode 100644 index 00000000..51e0f984 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahchrand.h @@ -0,0 +1,31 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AHCHRAND_H_ +#define _AHCHRAND_H_ 1 + +#include "ahrandom.h" +#include "algchoic.h" + +typedef struct AHChooseRandom { + AHRandom random; /* base class */ + AlgaChoice algaChoice; +} AHChooseRandom; + +AHChooseRandom *AHChooseRandomConstructor2 PROTO_LIST + ((AHChooseRandom *, struct B_AlgorithmInfoType *, POINTER)); +void AHChooseRandomDestructor PROTO_LIST ((THIS_RANDOM *)); + +int AHChooseRandomInit PROTO_LIST + ((THIS_RANDOM *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int AHChooseRandomUpdate PROTO_LIST + ((THIS_RANDOM *, unsigned char *, unsigned int, A_SURRENDER_CTX *)); +int AHChooseRandomGenerateBytes PROTO_LIST + ((THIS_RANDOM *, unsigned char *, unsigned int, A_SURRENDER_CTX *)); + +#endif diff --git a/lib/dns/sec/dnssafe/ahdigest.c b/lib/dns/sec/dnssafe/ahdigest.c new file mode 100644 index 00000000..b1dc9f46 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahdigest.c @@ -0,0 +1,91 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ahdigest.h" + +static void TypedAHDigestDestructor PROTO_LIST ((B_TypeCheck *)); + +void AHDigestConstructor (handler) +AHDigest *handler; +{ + /* Construct base class, setting type tag. */ + B_TYPE_CHECK_Constructor + (&handler->typeCheck, TypedAHDigestDestructor); + + /* Don't set vTable since this is a pure virtual base class. */ +} + +int B_AlgorithmDigestInit + (algorithm, key, algorithmChooser, surrenderContext) +B_Algorithm *algorithm; +B_Key *key; +B_ALGORITHM_CHOOSER algorithmChooser; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckType + (algorithm, TypedAHDigestDestructor)) != 0) + return (status); + + if ((status = + (*((AHDigest *)algorithm->z.handler)->vTable->DigestInit) + ((AHDigest *)algorithm->z.handler, key, algorithmChooser, + surrenderContext)) != 0) + return (status); + + algorithm->z.initFlag = 1; + return (0); +} + +int B_AlgorithmDigestUpdate (algorithm, partIn, partInLen, surrenderContext) +B_Algorithm *algorithm; +unsigned char *partIn; +unsigned int partInLen; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckTypeAndInitFlag + (algorithm, TypedAHDigestDestructor)) != 0) + return (status); + + return ((*((AHDigest *)algorithm->z.handler)->vTable->DigestUpdate) + ((AHDigest *)algorithm->z.handler, partIn, partInLen, + surrenderContext)); +} + +int B_AlgorithmDigestFinal + (algorithm, partOut, partOutLen, maxPartOutLen, surrenderContext) +B_Algorithm *algorithm; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckTypeAndInitFlag + (algorithm, TypedAHDigestDestructor)) != 0) + return (status); + + return ((*((AHDigest *)algorithm->z.handler)->vTable->DigestFinal) + ((AHDigest *)algorithm->z.handler, partOut, partOutLen, + maxPartOutLen, surrenderContext)); +} + +static void TypedAHDigestDestructor (typeCheck) +B_TypeCheck *typeCheck; +{ + (*((AHDigest *)typeCheck)->vTable->Destructor) ((AHDigest *)typeCheck); +} + diff --git a/lib/dns/sec/dnssafe/ahdigest.h b/lib/dns/sec/dnssafe/ahdigest.h new file mode 100644 index 00000000..d7cc5f93 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahdigest.h @@ -0,0 +1,48 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AHDIGEST_H_ +#define _AHDIGEST_H_ 1 + +#include "btypechk.h" + +/* Use the THIS_DIGEST macro to define the type of object in the + virtual function prototype. It defaults to the most base class, but + derived modules may define the macro to a more derived class before + including this header file. + */ +#ifndef THIS_DIGEST +#define THIS_DIGEST struct AHDigest +#endif + +struct AHDigest; + +typedef struct { + void (*Destructor) PROTO_LIST ((THIS_DIGEST *)); + int (*DigestInit) PROTO_LIST + ((THIS_DIGEST *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); + int (*DigestUpdate) PROTO_LIST + ((THIS_DIGEST *, unsigned char *, unsigned int, A_SURRENDER_CTX *)); + int (*DigestFinal) PROTO_LIST + ((THIS_DIGEST *, unsigned char *, unsigned int *, unsigned int, + A_SURRENDER_CTX *)); +} AHDigestVTable; + +typedef struct AHDigest { + B_TypeCheck typeCheck; /* inherited */ + AHDigestVTable *vTable; /* pure virtual */ +} AHDigest; + +/* The constructor does not set the vTable since this is a pure base class. + */ +void AHDigestConstructor PROTO_LIST ((AHDigest *)); +/* No destructor because it is pure virtual. Also, do not call destructor + for B_TypeCheck, since this will just re-invoke this virtual + destructor. */ + +#endif diff --git a/lib/dns/sec/dnssafe/ahencryp.c b/lib/dns/sec/dnssafe/ahencryp.c new file mode 100644 index 00000000..255a5491 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahencryp.c @@ -0,0 +1,169 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ahencryp.h" + +static void TypedAHEncryptDecryptDestructor PROTO_LIST ((B_TypeCheck *)); + +void AHEncryptDecryptConstructor (handler) +AHEncryptDecrypt *handler; +{ + /* Construct base class, setting type tag. */ + B_TYPE_CHECK_Constructor + (&handler->typeCheck, TypedAHEncryptDecryptDestructor); + + /* Don't set vTable since this is a pure virtual base class. */ +} + +int B_AlgorithmEncryptInit + (algorithm, key, algorithmChooser, surrenderContext) +B_Algorithm *algorithm; +B_Key *key; +B_ALGORITHM_CHOOSER algorithmChooser; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckType + (algorithm, TypedAHEncryptDecryptDestructor)) != 0) + return (status); + + if ((status = + (*((AHEncryptDecrypt *)algorithm->z.handler)->vTable->EncryptInit) + ((AHEncryptDecrypt *)algorithm->z.handler, key, algorithmChooser, + surrenderContext)) != 0) + return (status); + + algorithm->z.initFlag = 1; + return (0); +} + +int B_AlgorithmDecryptInit + (algorithm, key, algorithmChooser, surrenderContext) +B_Algorithm *algorithm; +B_Key *key; +B_ALGORITHM_CHOOSER algorithmChooser; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckType + (algorithm, TypedAHEncryptDecryptDestructor)) != 0) + return (status); + + if ((status = + (*((AHEncryptDecrypt *)algorithm->z.handler)->vTable->DecryptInit) + ((AHEncryptDecrypt *)algorithm->z.handler, key, algorithmChooser, + surrenderContext)) != 0) + return (status); + + algorithm->z.initFlag = 1; + return (0); +} + +int B_AlgorithmEncryptUpdate + (algorithm, partOut, partOutLen, maxPartOutLen, partIn, partInLen, + randomAlgorithm, surrenderContext) +B_Algorithm *algorithm; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +unsigned char *partIn; +unsigned int partInLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckTypeAndInitFlag + (algorithm, TypedAHEncryptDecryptDestructor)) != 0) + return (status); + + return ((*((AHEncryptDecrypt *)algorithm->z.handler)->vTable->EncryptUpdate) + ((AHEncryptDecrypt *)algorithm->z.handler, partOut, partOutLen, + maxPartOutLen, partIn, partInLen, randomAlgorithm, + surrenderContext)); +} + +int B_AlgorithmDecryptUpdate + (algorithm, partOut, partOutLen, maxPartOutLen, partIn, partInLen, + randomAlgorithm, surrenderContext) +B_Algorithm *algorithm; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +unsigned char *partIn; +unsigned int partInLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckTypeAndInitFlag + (algorithm, TypedAHEncryptDecryptDestructor)) != 0) + return (status); + + return ((*((AHEncryptDecrypt *)algorithm->z.handler)->vTable->DecryptUpdate) + ((AHEncryptDecrypt *)algorithm->z.handler, partOut, partOutLen, + maxPartOutLen, partIn, partInLen, randomAlgorithm, + surrenderContext)); +} + +int B_AlgorithmEncryptFinal + (algorithm, partOut, partOutLen, maxPartOutLen, randomAlgorithm, + surrenderContext) +B_Algorithm *algorithm; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckTypeAndInitFlag + (algorithm, TypedAHEncryptDecryptDestructor)) != 0) + return (status); + + return ((*((AHEncryptDecrypt *)algorithm->z.handler)->vTable->EncryptFinal) + ((AHEncryptDecrypt *)algorithm->z.handler, partOut, partOutLen, + maxPartOutLen, randomAlgorithm, surrenderContext)); +} + +int B_AlgorithmDecryptFinal + (algorithm, partOut, partOutLen, maxPartOutLen, randomAlgorithm, + surrenderContext) +B_Algorithm *algorithm; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckTypeAndInitFlag + (algorithm, TypedAHEncryptDecryptDestructor)) != 0) + return (status); + + return ((*((AHEncryptDecrypt *)algorithm->z.handler)->vTable->DecryptFinal) + ((AHEncryptDecrypt *)algorithm->z.handler, partOut, partOutLen, + maxPartOutLen, randomAlgorithm, surrenderContext)); +} + +static void TypedAHEncryptDecryptDestructor (typeCheck) +B_TypeCheck *typeCheck; +{ + (*((AHEncryptDecrypt *)typeCheck)->vTable->Destructor) + ((AHEncryptDecrypt *)typeCheck); +} + diff --git a/lib/dns/sec/dnssafe/ahencryp.h b/lib/dns/sec/dnssafe/ahencryp.h new file mode 100644 index 00000000..f7ab14ca --- /dev/null +++ b/lib/dns/sec/dnssafe/ahencryp.h @@ -0,0 +1,85 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AHENCRYP_H_ +#define _AHENCRYP_H_ 1 + +#include "btypechk.h" + +/* In C++: +class AHEncryptDecrypt : public B_TypeCheck { + AHEncryptDecrypt (); + virtual ~AHEncryptDecrypt () = 0; + + virtual int getBlockLen (unsigned int *) = 0; + virtual int encryptInit + (B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *) = 0; + virtual int decryptInit + (B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *) = 0; + virtual int encryptUpdate + (unsigned char *, unsigned int *, unsigned int, unsigned char *, + unsigned int, B_Algorithm *, A_SURRENDER_CTX *) = 0; + virtual int decryptUpdate + (unsigned char *, unsigned int *, unsigned int, unsigned char *, + unsigned int, B_Algorithm *, A_SURRENDER_CTX *) = 0; + virtual int encryptFinal + (unsigned char *, unsigned int *, unsigned int, B_Algorithm *, + A_SURRENDER_CTX *) = 0; + virtual int decryptFinal + (unsigned char *, unsigned int *, unsigned int, B_Algorithm *, + A_SURRENDER_CTX *) = 0; +}; + */ + +/* Use the THIS_ENCRYPT_DECRYPT macro to define the type of object in the + virtual function prototype. It defaults to the most base class, but + derived modules may define the macro to a more derived class before + including this header file. + */ +#ifndef THIS_ENCRYPT_DECRYPT +#define THIS_ENCRYPT_DECRYPT struct AHEncryptDecrypt +#endif + +struct AHEncryptDecrypt; + +typedef struct { + void (*Destructor) PROTO_LIST ((THIS_ENCRYPT_DECRYPT *)); + int (*GetBlockLen) PROTO_LIST ((THIS_ENCRYPT_DECRYPT *, unsigned int *)); + int (*EncryptInit) PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER, + A_SURRENDER_CTX *)); + int (*DecryptInit) PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER, + A_SURRENDER_CTX *)); + int (*EncryptUpdate) PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int, B_Algorithm *, A_SURRENDER_CTX *)); + int (*DecryptUpdate) PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int, B_Algorithm *, A_SURRENDER_CTX *)); + int (*EncryptFinal) PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, unsigned int, + B_Algorithm *, A_SURRENDER_CTX *)); + int (*DecryptFinal) PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, unsigned int, + B_Algorithm *, A_SURRENDER_CTX *)); +} AHEncryptDecryptVTable; + +typedef struct AHEncryptDecrypt { + B_TypeCheck typeCheck; /* inherited */ + AHEncryptDecryptVTable *vTable; /* pure virtual */ +} AHEncryptDecrypt; + +/* The constructor does not set the vTable since this is a pure base class. + */ +void AHEncryptDecryptConstructor PROTO_LIST ((AHEncryptDecrypt *)); +/* No destructor because it is pure virtual. Also, do not call destructor + for B_TypeCheck, since this will just re-invoke this virtual + destructor. */ + +#endif diff --git a/lib/dns/sec/dnssafe/ahgen.c b/lib/dns/sec/dnssafe/ahgen.c new file mode 100644 index 00000000..34216683 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahgen.c @@ -0,0 +1,90 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ahgen.h" + +static void TypedAHGenerateDestructor PROTO_LIST ((B_TypeCheck *)); + +void AHGenerateConstructor (handler) +AHGenerate *handler; +{ + /* Construct base class, setting type tag. */ + B_TYPE_CHECK_Constructor + (&handler->typeCheck, TypedAHGenerateDestructor); + + /* Don't set vTable since this is a pure virtual base class. */ +} + +int B_AlgorithmGenerateInit (algorithm, algorithmChooser, surrenderContext) +B_Algorithm *algorithm; +B_ALGORITHM_CHOOSER algorithmChooser; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckType + (algorithm, TypedAHGenerateDestructor)) != 0) + return (status); + + if ((status = + (*((AHGenerate *)algorithm->z.handler)->vTable->GenerateInit) + ((AHGenerate *)algorithm->z.handler, algorithmChooser, + surrenderContext)) != 0) + return (status); + + algorithm->z.initFlag = 1; + return (0); +} + +int B_AlgorithmGenerateKeypair + (algorithm, publicKey, privateKey, randomAlgorithm, surrenderContext) +B_Algorithm *algorithm; +B_Key *publicKey; +B_Key *privateKey; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckTypeAndInitFlag + (algorithm, TypedAHGenerateDestructor)) != 0) + return (status); + + return ((*((AHGenerate *)algorithm->z.handler)->vTable->GenerateKeypair) + ((AHGenerate *)algorithm->z.handler, publicKey, privateKey, + randomAlgorithm, surrenderContext)); +} + +int B_AlgorithmGenerateParameters + (algorithm, resultAlgorithm, randomAlgorithm, surrenderContext) +B_Algorithm *algorithm; +B_Algorithm *resultAlgorithm; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckTypeAndInitFlag + (algorithm, TypedAHGenerateDestructor)) != 0) + return (status); + + return ((*((AHGenerate *)algorithm->z.handler)->vTable->GenerateParameters) + ((AHGenerate *)algorithm->z.handler, resultAlgorithm, + randomAlgorithm, surrenderContext)); +} + +static void TypedAHGenerateDestructor (typeCheck) +B_TypeCheck *typeCheck; +{ + (*((AHGenerate *)typeCheck)->vTable->Destructor) ((AHGenerate *)typeCheck); +} + diff --git a/lib/dns/sec/dnssafe/ahgen.h b/lib/dns/sec/dnssafe/ahgen.h new file mode 100644 index 00000000..7240e2e1 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahgen.h @@ -0,0 +1,47 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AHGEN_H_ +#define _AHGEN_H_ 1 + +#include "btypechk.h" + +/* Use the THIS_GENERATE macro to define the type of object in the + virtual function prototype. It defaults to the most base class, but + derived modules may define the macro to a more derived class before + including this header file. + */ +#ifndef THIS_GENERATE +#define THIS_GENERATE struct AHGenerate +#endif + +struct AHGenerate; + +typedef struct { + void (*Destructor) PROTO_LIST ((THIS_GENERATE *)); + int (*GenerateInit) PROTO_LIST + ((THIS_GENERATE *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); + int (*GenerateKeypair) PROTO_LIST + ((THIS_GENERATE *, B_Key *, B_Key *, B_Algorithm *, A_SURRENDER_CTX *)); + int (*GenerateParameters) PROTO_LIST + ((THIS_GENERATE *, B_Algorithm *, B_Algorithm *, A_SURRENDER_CTX *)); +} AHGenerateVTable; + +typedef struct AHGenerate { + B_TypeCheck typeCheck; /* inherited */ + AHGenerateVTable *vTable; /* pure virtual */ +} AHGenerate; + +/* The constructor does not set the vTable since this is a pure base class. + */ +void AHGenerateConstructor PROTO_LIST ((AHGenerate *)); +/* No destructor because it is pure virtual. Also, do not call destructor + for B_TypeCheck, since this will just re-invoke this virtual + destructor. */ + +#endif diff --git a/lib/dns/sec/dnssafe/ahrandom.c b/lib/dns/sec/dnssafe/ahrandom.c new file mode 100644 index 00000000..f6f27187 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahrandom.c @@ -0,0 +1,97 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ahrandom.h" + +static void TypedAHRandomDestructor PROTO_LIST ((B_TypeCheck *)); + +void AHRandomConstructor (handler) +AHRandom *handler; +{ + /* Construct base class, setting type tag. */ + B_TYPE_CHECK_Constructor + (&handler->typeCheck, TypedAHRandomDestructor); + + /* Don't set vTable since this is a pure virtual base class. */ +} + +int B_AlgorithmRandomInit (algorithm, algorithmChooser, surrenderContext) +B_Algorithm *algorithm; +B_ALGORITHM_CHOOSER algorithmChooser; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckType (algorithm, TypedAHRandomDestructor)) + != 0) + return (status); + + if ((status = + (*((AHRandom *)algorithm->z.handler)->vTable->RandomInit) + ((AHRandom *)algorithm->z.handler, algorithmChooser, surrenderContext)) + != 0) + return (status); + + algorithm->z.initFlag = 1; + return (0); +} + +int B_AlgorithmRandomUpdate (algorithm, input, inputLen, surrenderContext) +B_Algorithm *algorithm; +unsigned char *input; +unsigned int inputLen; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = B_AlgorithmCheckTypeAndInitFlag + (algorithm, TypedAHRandomDestructor)) != 0) + return (status == BE_ALGORITHM_NOT_INITIALIZED ? + BE_RANDOM_NOT_INITIALIZED : status); + + return ((*((AHRandom *)algorithm->z.handler)->vTable->RandomUpdate) + ((AHRandom *)algorithm->z.handler, input, inputLen, + surrenderContext)); +} + +int B_AlgorithmGenerateRandomBytes + (algorithm, output, outputLen, surrenderContext) +B_Algorithm *algorithm; +unsigned char *output; +unsigned int outputLen; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + /* As a special case, check here for a null this pointer when the object + is actually being used since many routines take a "dummy" null + random algorithm. + */ + if (algorithm == (B_Algorithm *)NULL_PTR) + return (BE_RANDOM_OBJ); + + if ((status = B_AlgorithmCheckTypeAndInitFlag + (algorithm, TypedAHRandomDestructor)) != 0) + return (status == BE_ALGORITHM_NOT_INITIALIZED ? + BE_RANDOM_NOT_INITIALIZED : status); + + return ((*((AHRandom *)algorithm->z.handler)->vTable->GenerateBytes) + ((AHRandom *)algorithm->z.handler, output, outputLen, + surrenderContext)); +} + +static void TypedAHRandomDestructor (typeCheck) +B_TypeCheck *typeCheck; +{ + (*((AHRandom *)typeCheck)->vTable->Destructor) ((AHRandom *)typeCheck); +} + diff --git a/lib/dns/sec/dnssafe/ahrandom.h b/lib/dns/sec/dnssafe/ahrandom.h new file mode 100644 index 00000000..aeb4f3b0 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahrandom.h @@ -0,0 +1,47 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AHRANDOM_H_ +#define _AHRANDOM_H_ 1 + +#include "btypechk.h" + +/* Use the THIS_RANDOM macro to define the type of object in the + virtual function prototype. It defaults to the most base class, but + derived modules may define the macro to a more derived class before + including this header file. + */ +#ifndef THIS_RANDOM +#define THIS_RANDOM struct AHRandom +#endif + +struct AHRandom; + +typedef struct { + void (*Destructor) PROTO_LIST ((THIS_RANDOM *)); + int (*RandomInit) PROTO_LIST + ((THIS_RANDOM *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); + int (*RandomUpdate) PROTO_LIST + ((THIS_RANDOM *, unsigned char *, unsigned int, A_SURRENDER_CTX *)); + int (*GenerateBytes) PROTO_LIST + ((THIS_RANDOM *, unsigned char *, unsigned int, A_SURRENDER_CTX *)); +} AHRandomVTable; + +typedef struct AHRandom { + B_TypeCheck typeCheck; /* inherited */ + AHRandomVTable *vTable; /* pure virtual */ +} AHRandom; + +/* The constructor does not set the vTable since this is a pure base class. + */ +void AHRandomConstructor PROTO_LIST ((AHRandom *)); +/* No destructor because it is pure virtual. Also, do not call destructor + for B_TypeCheck, since this will just re-invoke this virtual + destructor. */ + +#endif diff --git a/lib/dns/sec/dnssafe/ahrsaenc.c b/lib/dns/sec/dnssafe/ahrsaenc.c new file mode 100644 index 00000000..307d1fd8 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahrsaenc.c @@ -0,0 +1,241 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +/* Define this so that the type of the 'this' pointer in the + virtual functions will be correct for this derived class. + */ +struct AH_RSAEncryption; +#define THIS_ENCRYPT_DECRYPT struct AH_RSAEncryption + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ahrsaenc.h" + +static int AH_RSAEncryptionInitHelper PROTO_LIST ((AH_RSAEncryption *, int)); + +static AHEncryptDecryptVTable V_TABLE = { + AH_RSAEncryptionDestructor, AH_RSAEncryptionGetBlockLen, + AH_RSAEncryptionEncryptInit, AH_RSAEncryptionDecryptInit, + AH_RSAEncryptionUpdate, AH_RSAEncryptionUpdate, + AH_RSAEncryptionEncryptFinal, AH_RSAEncryptionDecryptFinal +}; + +void AH_RSAEncryptionConstructor1 (handler, infoType) +AH_RSAEncryption *handler; +struct B_AlgorithmInfoType *infoType; +{ + /* Construct base class with the infoType. Assume info is NULL_PTR. */ + AHChooseEncryptConstructor2 + (&handler->chooseEncryptDecrypt, infoType, NULL_PTR); + + T_memset ((POINTER)&handler->z, 0, sizeof (handler->z)); + /* Set the AHEncryptDecrypt vTable, but don't set the RSAEncryption vTable + since it is pure virtual. */ + handler->chooseEncryptDecrypt.encryptDecrypt.vTable = &V_TABLE; +} + +void AH_RSAEncryptionDestructor (handler) +AH_RSAEncryption *handler; +{ + T_memset ((POINTER)handler->z.block, 0, handler->z.blockLen); + T_free ((POINTER)handler->z.block); + + /* Call base class destructor */ + AHChooseEncryptDestructor (handler); +} + +int AH_RSAEncryptionGetBlockLen (handler, blockLen) +AH_RSAEncryption *handler; +unsigned int *blockLen; +{ +UNUSED_ARG (handler) +UNUSED_ARG (blockLen) + return (BE_NOT_SUPPORTED); +} + +int AH_RSAEncryptionEncryptInit (handler, key, chooser, surrenderContext) +AH_RSAEncryption *handler; +B_Key *key; +B_ALGORITHM_CHOOSER chooser; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AHChooseEncryptEncryptInit + (handler, key, chooser, surrenderContext)) != 0) + return (status); + + return (AH_RSAEncryptionInitHelper (handler, 1)); +} + +int AH_RSAEncryptionDecryptInit (handler, key, chooser, surrenderContext) +AH_RSAEncryption *handler; +B_Key *key; +B_ALGORITHM_CHOOSER chooser; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AHChooseEncryptDecryptInit + (handler, key, chooser, surrenderContext)) != 0) + return (status); + + return (AH_RSAEncryptionInitHelper (handler, 0)); +} + +/* Accumulate into the z.block. + */ +int AH_RSAEncryptionUpdate + (handler, partOut, partOutLen, maxPartOutLen, partIn, partInLen, + randomAlgorithm, surrenderContext) +AH_RSAEncryption *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +unsigned char *partIn; +unsigned int partInLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ +UNUSED_ARG (partOut) +UNUSED_ARG (maxPartOutLen) +UNUSED_ARG (randomAlgorithm) +UNUSED_ARG (surrenderContext) + *partOutLen = 0; + + if (handler->_inputLen + partInLen > handler->_maxInputLen) + return (BE_INPUT_LEN); + T_memcpy + ((POINTER)(handler->z.block + handler->_inputLen), (POINTER)partIn, + partInLen); + handler->_inputLen += partInLen; + return (0); +} + +int AH_RSAEncryptionEncryptFinal + (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm, + surrenderContext) +AH_RSAEncryption *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + unsigned int dummyPartOutLen; + + /* Encode methodContext in place. */ + if ((status = (*handler->vTable->EncodeBlock) + (handler, randomAlgorithm, surrenderContext)) != 0) + return (status); + + /* This should not return BE_INPUT_DATA since it is well-formatted. */ + if ((status = AHChooseEncryptEncryptUpdate + (handler, partOut, partOutLen, maxPartOutLen, handler->z.block, + handler->z.blockLen, (B_Algorithm *)NULL_PTR, surrenderContext)) != 0) + return (status); + + /* Expect final to return zero bytes. */ + if ((status = AHChooseEncryptEncryptFinal + (handler, (unsigned char *)NULL_PTR, &dummyPartOutLen, 0, + (B_Algorithm *)NULL_PTR, surrenderContext)) != 0) + return (status); + + /* Restart the handle for new input. */ + handler->_inputLen = 0; + return (0); +} + +int AH_RSAEncryptionDecryptFinal + (handler, partOut, partOutLen, maxPartOutLen, randomAlgorithm, + surrenderContext) +AH_RSAEncryption *handler; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + ITEM output; + int status; + unsigned int decryptedLen, dummyPartOutLen; + +UNUSED_ARG (randomAlgorithm) + /* Decrypt block in place. The block lenghts are already within limits. + */ + if ((status = AHChooseEncryptDecryptUpdate + (handler, handler->z.block, &decryptedLen, handler->z.blockLen, + handler->z.block, handler->_inputLen, (B_Algorithm *)NULL_PTR, + surrenderContext)) != 0) + return (status); + /* Expect final to return zero bytes. */ + if ((status = AHChooseEncryptDecryptFinal + (handler, (unsigned char *)NULL_PTR, &dummyPartOutLen, 0, + (B_Algorithm *)NULL_PTR, surrenderContext)) != 0) + return (status); + + /* Restart the handle for new input. */ + handler->_inputLen = 0; + + /* Now decode the block and copy the result to the partOut. + */ + if ((status = (*handler->vTable->DecodeBlock) + (handler, &output, decryptedLen)) != 0) + return (status); + + if (output.len > handler->z.blockLen - 11) + /* This implies that the block was encrypted with less than + 8 bytes of padding */ + return (BE_INPUT_DATA); + + if ((*partOutLen = output.len) > maxPartOutLen) + return (BE_OUTPUT_LEN); + T_memcpy ((POINTER)partOut, (POINTER)output.data, output.len); + + return (0); +} + +static int AH_RSAEncryptionInitHelper (handler, encryptFlag) +AH_RSAEncryption *handler; +int encryptFlag; +{ + int status; + unsigned int newBlockLen; + + if ((status = AHChooseEncryptGetBlockLen (handler, &newBlockLen)) != 0) + return (status); + + if (newBlockLen < 12) + /* PKCS Requires at least 12 bytes of modulus */ + return (BE_NOT_SUPPORTED); + + /* During encrypt, this will ensure that there are 8 bytes of padding. + During decrypt, the DecodeBlock procedure must check that the block + was encrypted with 8 bytes of padding. + */ + handler->_maxInputLen = encryptFlag ? (newBlockLen - 11) : newBlockLen; + + handler->_inputLen = 0; + + /* Zeroize old block and realloc to new size. + */ + T_memset ((POINTER)handler->z.block, 0, handler->z.blockLen); + if ((handler->z.block = (unsigned char *)T_realloc + ((POINTER)handler->z.block, newBlockLen)) + == (unsigned char *)NULL_PTR) { + handler->z.blockLen = 0; + return (BE_ALLOC); + } + + handler->z.blockLen = newBlockLen; + return (0); +} + diff --git a/lib/dns/sec/dnssafe/ahrsaenc.h b/lib/dns/sec/dnssafe/ahrsaenc.h new file mode 100644 index 00000000..ede21c78 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahrsaenc.h @@ -0,0 +1,68 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AHRSAENC_H_ +#define _AHRSAENC_H_ + +#include "ahchencr.h" + +struct AH_RSAEncryption; + +/* For EncodeBlock, the block to encode is left justified in the + z.block with length given by z._inputLen. EncodeBlock encodes the block + in place to fill it out to z.blockLen. + For DecodeBlock, return the contents in the given ITEM by decoding + the z.block value which has length given by decryptedLen. This + procedure must also ensure that the block was encrypted with 8 bytes + of padding. + */ +typedef struct { + int (*EncodeBlock) PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, B_Algorithm * /* randomAlgorithm */, + A_SURRENDER_CTX *)); + int (*DecodeBlock) PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, ITEM *, unsigned int /* decryptedLen */)); +} AH_RSAEncryptionVTable; + +typedef struct AH_RSAEncryption { + AHChooseEncryptDecrypt chooseEncryptDecrypt; /* base class */ + + struct { + unsigned char *block; + unsigned int blockLen; + } z; /* Zeroized by constructor */ + + unsigned int _inputLen; /* Length of data accumulated by Update */ + unsigned int _maxInputLen; /* used during update to check for overflow */ + AH_RSAEncryptionVTable *vTable; /* pure virtual */ +} AH_RSAEncryption; + +void AH_RSAEncryptionConstructor1 PROTO_LIST + ((AH_RSAEncryption *, struct B_AlgorithmInfoType *)); +void AH_RSAEncryptionDestructor PROTO_LIST ((AH_RSAEncryption *)); + +int AH_RSAEncryptionGetBlockLen PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned int *)); +int AH_RSAEncryptionEncryptInit PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER, + A_SURRENDER_CTX *)); +int AH_RSAEncryptionDecryptInit PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, B_Key *, B_ALGORITHM_CHOOSER, + A_SURRENDER_CTX *)); +int AH_RSAEncryptionUpdate PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, + unsigned int, unsigned char *, unsigned int, B_Algorithm *, + A_SURRENDER_CTX *)); +int AH_RSAEncryptionEncryptFinal PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, + unsigned int, B_Algorithm *, A_SURRENDER_CTX *)); +int AH_RSAEncryptionDecryptFinal PROTO_LIST + ((THIS_ENCRYPT_DECRYPT *, unsigned char *, unsigned int *, + unsigned int, B_Algorithm *, A_SURRENDER_CTX *)); + +#endif diff --git a/lib/dns/sec/dnssafe/ahrsaepr.c b/lib/dns/sec/dnssafe/ahrsaepr.c new file mode 100644 index 00000000..e6fba2b9 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahrsaepr.c @@ -0,0 +1,99 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +/* Define this so that the type of the 'this' pointer in the + virtual functions will be correct for this derived class. + */ +struct AH_RSAEncryption; +#define THIS_ENCRYPT_DECRYPT struct AH_RSAEncryption + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ahrsaepr.h" + +static int EncodeBlock1 PROTO_LIST + ((AH_RSAEncryptionPrivate *, B_Algorithm *, A_SURRENDER_CTX *)); +static int DecodeBlock2 PROTO_LIST + ((AH_RSAEncryptionPrivate *, ITEM *, unsigned int)); + +static AH_RSAEncryptionVTable ENCRYPTION_V_TABLE = + {EncodeBlock1, DecodeBlock2}; + +extern struct B_AlgorithmInfoType AIT_RSAPrivate; + +AH_RSAEncryptionPrivate *AH_RSAEncrypPrivateConstructor (handler) +AH_RSAEncryptionPrivate *handler; +{ + if (handler == (AH_RSAEncryptionPrivate *)NULL_PTR) { + /* This constructor is being used to do a new */ + if ((handler = (AH_RSAEncryptionPrivate *)T_malloc (sizeof (*handler))) + == (AH_RSAEncryptionPrivate *)NULL_PTR) + return (handler); + } + + /* Construct base class */ + AH_RSAEncryptionConstructor1 (handler, &AIT_RSAPrivate); + + handler->vTable = &ENCRYPTION_V_TABLE; + return (handler); +} + +/* block1 starts out with the input bytes of length inputLen left-justified. + Returns 0, BE_INPUT_LEN. + */ +static int EncodeBlock1 (handler, randomAlgorithm, surrenderContext) +AH_RSAEncryptionPrivate *handler; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + unsigned int padLen; + +UNUSED_ARG (randomAlgorithm) +UNUSED_ARG (surrenderContext) + if ((handler->_inputLen + 3) > handler->z.blockLen) + /* input is too large to make a block 1 */ + return (BE_INPUT_LEN); + + padLen = handler->z.blockLen - (handler->_inputLen + 3); + T_memmove + ((POINTER)(handler->z.block + padLen + 3), (POINTER)handler->z.block, + handler->_inputLen); + + handler->z.block[0] = 0; + handler->z.block[1] = 1; + T_memset ((POINTER)(handler->z.block + 2), 0xff, padLen); + handler->z.block[2 + padLen] = 0; + return (0); +} + +static int DecodeBlock2 (handler, output, block2Len) +AH_RSAEncryptionPrivate *handler; +ITEM *output; +unsigned int block2Len; +{ + unsigned int i; + + if ((handler->z.block[0] != 0) || (handler->z.block[1] != 2)) + return (BE_INPUT_DATA); + + /* Should be able to find the data after the first zero byte following + the random bytes. */ + for (i = 2; i < block2Len && handler->z.block[i] != 0; i++); + i++; + + if (i > block2Len) + /* The data is not zero terminated. */ + return (BE_INPUT_DATA); + + output->len = block2Len - i; + output->data = handler->z.block + i; + return (0); +} + diff --git a/lib/dns/sec/dnssafe/ahrsaepr.h b/lib/dns/sec/dnssafe/ahrsaepr.h new file mode 100644 index 00000000..f5847bc6 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahrsaepr.h @@ -0,0 +1,20 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AHRSAEPR_H_ +#define _AHRSAEPR_H_ + +#include "ahrsaenc.h" + +/* structure is identical to base class, so just re-typedef. */ +typedef AH_RSAEncryption AH_RSAEncryptionPrivate; + +AH_RSAEncryptionPrivate *AH_RSAEncrypPrivateConstructor PROTO_LIST + ((AH_RSAEncryptionPrivate *)); + +#endif diff --git a/lib/dns/sec/dnssafe/ahrsaepu.c b/lib/dns/sec/dnssafe/ahrsaepu.c new file mode 100644 index 00000000..000e8420 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahrsaepu.c @@ -0,0 +1,112 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +/* Define this so that the type of the 'this' pointer in the + virtual functions will be correct for this derived class. + */ +struct AH_RSAEncryption; +#define THIS_ENCRYPT_DECRYPT struct AH_RSAEncryption + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ahrsaepu.h" + +static int EncodeBlock2 PROTO_LIST + ((AH_RSAEncryptionPublic *, B_Algorithm *, A_SURRENDER_CTX *)); +static int DecodeBlock1 PROTO_LIST + ((AH_RSAEncryptionPublic *, ITEM *, unsigned int)); + +static AH_RSAEncryptionVTable ENCRYPTION_V_TABLE = + {EncodeBlock2, DecodeBlock1}; + +extern struct B_AlgorithmInfoType AIT_RSAPublic; + +AH_RSAEncryptionPublic *AH_RSAEncrypPublicConstructor (handler) +AH_RSAEncryptionPublic *handler; +{ + if (handler == (AH_RSAEncryptionPublic *)NULL_PTR) { + /* This constructor is being used to do a new */ + if ((handler = (AH_RSAEncryptionPublic *)T_malloc (sizeof (*handler))) + == (AH_RSAEncryptionPublic *)NULL_PTR) + return (handler); + } + + /* Construct base class */ + AH_RSAEncryptionConstructor1 (handler, &AIT_RSAPublic); + + handler->vTable = &ENCRYPTION_V_TABLE; + return (handler); +} + +/* block starts out with the input bytes of length inputLen left-justified. + */ +static int EncodeBlock2 (handler, randomAlgorithm, surrenderContext) +AH_RSAEncryptionPublic *handler; +B_Algorithm *randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + unsigned char randomByte; + unsigned int padLen, i; + + if ((handler->_inputLen + 3) > handler->z.blockLen) + /* input is too large to make a block 2 */ + return (BE_INPUT_LEN); + + padLen = handler->z.blockLen - (handler->_inputLen + 3); + T_memmove + ((POINTER)(handler->z.block + padLen + 3), (POINTER)handler->z.block, + handler->_inputLen); + + handler->z.block[0] = 0; + handler->z.block[1] = 2; + + /* Pad out with random bytes, making sure that none of the bytes is zero. + */ + for (i = 2; i < (padLen + 2); i++) { + do { + if ((status = B_AlgorithmGenerateRandomBytes + (randomAlgorithm, &randomByte, 1, surrenderContext)) != 0) + return (status); + } while (randomByte == 0); + + handler->z.block[i] = randomByte; + } + + handler->z.block[2 + padLen] = 0; + return (0); +} + +static int DecodeBlock1 (handler, output, block1Len) +AH_RSAEncryptionPublic *handler; +ITEM *output; +unsigned int block1Len; +{ + unsigned int i; + + /* Locate the digestInfo within the PKCS block 1. + */ + if (handler->z.block[0] != 0 || handler->z.block[1] != 1) + return (BE_INPUT_DATA); + + /* Should be able to find the data after the first zero byte following + the 0xff. */ + for (i = 2; i < block1Len && handler->z.block[i] == 0xff; i++); + i++; + + if (i > block1Len || handler->z.block[i - 1] != 0) + /* The data is not zero terminated, or a byte other than 0xff. */ + return (BE_INPUT_DATA); + + output->len = block1Len - i; + output->data = handler->z.block + i; + return (0); +} + diff --git a/lib/dns/sec/dnssafe/ahrsaepu.h b/lib/dns/sec/dnssafe/ahrsaepu.h new file mode 100644 index 00000000..0c13e204 --- /dev/null +++ b/lib/dns/sec/dnssafe/ahrsaepu.h @@ -0,0 +1,20 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AHRSAEPU_H_ +#define _AHRSAEPU_H_ + +#include "ahrsaenc.h" + +/* structure is identical to base class, so just re-typedef. */ +typedef AH_RSAEncryption AH_RSAEncryptionPublic; + +AH_RSAEncryptionPublic *AH_RSAEncrypPublicConstructor PROTO_LIST + ((AH_RSAEncryptionPublic *)); + +#endif diff --git a/lib/dns/sec/dnssafe/aichdig.c b/lib/dns/sec/dnssafe/aichdig.c new file mode 100644 index 00000000..7d86d89d --- /dev/null +++ b/lib/dns/sec/dnssafe/aichdig.c @@ -0,0 +1,36 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ahchdig.h" +#include "aichdig.h" + +B_TypeCheck *AITChooseDigestNullNewHandler PROTO_LIST + ((B_AlgorithmInfoType *, B_Algorithm *)); + +B_AlgorithmInfoTypeVTable AITChooseDigestNull_V_TABLE = + {AITNullAddInfo, AITChooseDigestNullNewHandler, + B_AlgorithmInfoTypeMakeError}; + +/* This always uses NULL_PTR for the info. + */ +B_TypeCheck *AITChooseDigestNullNewHandler (infoType, algorithm) +B_AlgorithmInfoType *infoType; +B_Algorithm *algorithm; +{ +UNUSED_ARG (algorithm) + + /* Pass in NULL_PTR so that constructor will allocate. + */ + return ((B_TypeCheck *)AHChooseDigestConstructor2 + ((AHChooseDigest *)NULL_PTR, infoType, NULL_PTR)); +} + diff --git a/lib/dns/sec/dnssafe/aichdig.h b/lib/dns/sec/dnssafe/aichdig.h new file mode 100644 index 00000000..e8228d91 --- /dev/null +++ b/lib/dns/sec/dnssafe/aichdig.h @@ -0,0 +1,17 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AICHDIG_H_ +#define _AICHDIG_H_ 1 + +#include "ainfotyp.h" +#include "ainull.h" + +extern B_AlgorithmInfoTypeVTable AITChooseDigestNull_V_TABLE; + +#endif diff --git a/lib/dns/sec/dnssafe/aichenc8.c b/lib/dns/sec/dnssafe/aichenc8.c new file mode 100644 index 00000000..3612ab05 --- /dev/null +++ b/lib/dns/sec/dnssafe/aichenc8.c @@ -0,0 +1,33 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "aichenc8.h" + +B_AlgorithmInfoTypeVTable AITChooseEncrypt8_V_TABLE = + {AIT_8AddInfo, AITChooseEncryptNewHandler, B_AlgorithmInfoTypeMakeError}; + +int AIT_8AddInfo (infoType, algorithm, info) +B_AlgorithmInfoType *infoType; +B_Algorithm *algorithm; +POINTER info; +{ + POINTER newInfo; + int status; + + if ((status = B_MemoryPoolAllocAndCopy + (&algorithm->infoCache.memoryPool, &newInfo, info, 8)) != 0) + return (status); + + return (B_InfoCacheAddInfo + (&algorithm->infoCache, (POINTER)infoType, newInfo)); +} + diff --git a/lib/dns/sec/dnssafe/aichenc8.h b/lib/dns/sec/dnssafe/aichenc8.h new file mode 100644 index 00000000..4c2096bd --- /dev/null +++ b/lib/dns/sec/dnssafe/aichenc8.h @@ -0,0 +1,19 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AICHENC8_H_ +#define _AICHENC8_H_ 1 + +#include "aichencr.h" + +extern B_AlgorithmInfoTypeVTable AITChooseEncrypt8_V_TABLE; + +int AIT_8AddInfo PROTO_LIST + ((THIS_ALGORITHM_INFO_TYPE *, B_Algorithm *, POINTER)); + +#endif diff --git a/lib/dns/sec/dnssafe/aichencn.c b/lib/dns/sec/dnssafe/aichencn.c new file mode 100644 index 00000000..58ffe2fd --- /dev/null +++ b/lib/dns/sec/dnssafe/aichencn.c @@ -0,0 +1,17 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "aichencn.h" + +B_AlgorithmInfoTypeVTable AITChooseEncryptNull_V_TABLE = + {AITNullAddInfo, AITChooseEncryptNewHandler, B_AlgorithmInfoTypeMakeError}; + diff --git a/lib/dns/sec/dnssafe/aichencn.h b/lib/dns/sec/dnssafe/aichencn.h new file mode 100644 index 00000000..11301573 --- /dev/null +++ b/lib/dns/sec/dnssafe/aichencn.h @@ -0,0 +1,17 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AICHENCN_H_ +#define _AICHENCN_H_ 1 + +#include "aichencr.h" +#include "ainull.h" + +extern B_AlgorithmInfoTypeVTable AITChooseEncryptNull_V_TABLE; + +#endif diff --git a/lib/dns/sec/dnssafe/aichencr.c b/lib/dns/sec/dnssafe/aichencr.c new file mode 100644 index 00000000..ccdb27cc --- /dev/null +++ b/lib/dns/sec/dnssafe/aichencr.c @@ -0,0 +1,31 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ahchencr.h" +#include "aichencr.h" + +B_TypeCheck *AITChooseEncryptNewHandler (infoType, algorithm) +B_AlgorithmInfoType *infoType; +B_Algorithm *algorithm; +{ + POINTER info; + + if (B_InfoCacheFindInfo (&algorithm->infoCache, &info, (POINTER)infoType) + != 0) + /* This really shouldn't happen since the info was just added. */ + return ((B_TypeCheck *)NULL_PTR); + + /* Pass in NULL_PTR so that constructor will allocate. */ + return ((B_TypeCheck *)AHChooseEncryptConstructor2 + ((AHChooseEncryptDecrypt *)NULL_PTR, infoType, info)); +} + diff --git a/lib/dns/sec/dnssafe/aichencr.h b/lib/dns/sec/dnssafe/aichencr.h new file mode 100644 index 00000000..2d99bfb0 --- /dev/null +++ b/lib/dns/sec/dnssafe/aichencr.h @@ -0,0 +1,17 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AICHENCR_H_ +#define _AICHENCR_H_ 1 + +#include "ainfotyp.h" + +struct B_TypeCheck *AITChooseEncryptNewHandler PROTO_LIST + ((B_AlgorithmInfoType *, B_Algorithm *)); + +#endif diff --git a/lib/dns/sec/dnssafe/aichgen.c b/lib/dns/sec/dnssafe/aichgen.c new file mode 100644 index 00000000..ecc3d51d --- /dev/null +++ b/lib/dns/sec/dnssafe/aichgen.c @@ -0,0 +1,31 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ahchgen.h" +#include "aichgen.h" + +B_TypeCheck *AITChooseGenerateNewHandler (infoType, algorithm) +B_AlgorithmInfoType *infoType; +B_Algorithm *algorithm; +{ + POINTER info; + + if (B_InfoCacheFindInfo (&algorithm->infoCache, &info, (POINTER)infoType) + != 0) + /* This really shouldn't happen since the info was just added. */ + return ((B_TypeCheck *)NULL_PTR); + + /* Pass in NULL_PTR so that constructor will allocate. */ + return ((B_TypeCheck *)AHChooseGenerateConstructor2 + ((AHChooseGenerate *)NULL_PTR, infoType, info)); +} + diff --git a/lib/dns/sec/dnssafe/aichgen.h b/lib/dns/sec/dnssafe/aichgen.h new file mode 100644 index 00000000..eebd9b72 --- /dev/null +++ b/lib/dns/sec/dnssafe/aichgen.h @@ -0,0 +1,17 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AICHGEN_H_ +#define _AICHGEN_H_ 1 + +#include "ainfotyp.h" + +struct B_TypeCheck *AITChooseGenerateNewHandler PROTO_LIST + ((B_AlgorithmInfoType *, B_Algorithm *)); + +#endif diff --git a/lib/dns/sec/dnssafe/aichrand.c b/lib/dns/sec/dnssafe/aichrand.c new file mode 100644 index 00000000..9319a07d --- /dev/null +++ b/lib/dns/sec/dnssafe/aichrand.c @@ -0,0 +1,36 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ahchrand.h" +#include "aichrand.h" + +B_TypeCheck *AITChooseRandomNullNewHandler PROTO_LIST + ((B_AlgorithmInfoType *, B_Algorithm *)); + +B_AlgorithmInfoTypeVTable AITChooseRandomNull_V_TABLE = + {AITNullAddInfo, AITChooseRandomNullNewHandler, + B_AlgorithmInfoTypeMakeError}; + +/* This always uses NULL_PTR for the info. + */ +B_TypeCheck *AITChooseRandomNullNewHandler (infoType, algorithm) +B_AlgorithmInfoType *infoType; +B_Algorithm *algorithm; +{ +UNUSED_ARG (algorithm) + + /* Pass in NULL_PTR so that constructor will allocate. + */ + return ((B_TypeCheck *)AHChooseRandomConstructor2 + ((AHChooseRandom *)NULL_PTR, infoType, NULL_PTR)); +} + diff --git a/lib/dns/sec/dnssafe/aichrand.h b/lib/dns/sec/dnssafe/aichrand.h new file mode 100644 index 00000000..6f188e18 --- /dev/null +++ b/lib/dns/sec/dnssafe/aichrand.h @@ -0,0 +1,17 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AICHRAND_H_ +#define _AICHRAND_H_ 1 + +#include "ainfotyp.h" +#include "ainull.h" + +extern B_AlgorithmInfoTypeVTable AITChooseRandomNull_V_TABLE; + +#endif diff --git a/lib/dns/sec/dnssafe/aimd5.c b/lib/dns/sec/dnssafe/aimd5.c new file mode 100644 index 00000000..be2ba4d9 --- /dev/null +++ b/lib/dns/sec/dnssafe/aimd5.c @@ -0,0 +1,25 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "aichdig.h" + +B_AlgorithmInfoType AIT_MD5 = {&AITChooseDigestNull_V_TABLE}; + +int AI_MD5 (infoType) +POINTER *infoType; +{ + *infoType = (POINTER)&AIT_MD5; + + /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */ + return (0); +} + diff --git a/lib/dns/sec/dnssafe/aimd5ran.c b/lib/dns/sec/dnssafe/aimd5ran.c new file mode 100644 index 00000000..a51a9b6f --- /dev/null +++ b/lib/dns/sec/dnssafe/aimd5ran.c @@ -0,0 +1,25 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "aichrand.h" + +B_AlgorithmInfoType AIT_MD5Random = {&AITChooseRandomNull_V_TABLE}; + +int AI_MD5Random (infoType) +POINTER *infoType; +{ + *infoType = (POINTER)&AIT_MD5Random; + + /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */ + return (0); +} + diff --git a/lib/dns/sec/dnssafe/ainfotyp.c b/lib/dns/sec/dnssafe/ainfotyp.c new file mode 100644 index 00000000..c71e0281 --- /dev/null +++ b/lib/dns/sec/dnssafe/ainfotyp.c @@ -0,0 +1,30 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ainfotyp.h" + +/* This is the default routine which algorithm info types point MakeInfo to + if not redefined by a derived class. + */ +int B_AlgorithmInfoTypeMakeError (infoType, info, algorithm) +B_AlgorithmInfoType *infoType; +POINTER *info; +B_Algorithm *algorithm; +{ +UNUSED_ARG (infoType) +UNUSED_ARG (info) +UNUSED_ARG (algorithm) + + /* Should already have been found in the cache. */ + return (BE_WRONG_ALGORITHM_INFO); +} + diff --git a/lib/dns/sec/dnssafe/ainfotyp.h b/lib/dns/sec/dnssafe/ainfotyp.h new file mode 100644 index 00000000..fa9f4a64 --- /dev/null +++ b/lib/dns/sec/dnssafe/ainfotyp.h @@ -0,0 +1,39 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _AINFOTYP_H_ +#define _AINFOTYP_H_ 1 + +/* Use the THIS_ALGORITHM_INFO_TYPE macro to define the type of object in the + virtual function prototype. It defaults to the most base class, but + derived modules may define the macro to a more derived class before + including this header file. + */ +#ifndef THIS_ALGORITHM_INFO_TYPE +#define THIS_ALGORITHM_INFO_TYPE struct B_AlgorithmInfoType +#endif + +struct B_AlgorithmInfoType; + +typedef struct { + int (*AddInfo) PROTO_LIST + ((THIS_ALGORITHM_INFO_TYPE *, B_Algorithm *, POINTER)); + struct B_TypeCheck * (*NewHandler) PROTO_LIST + ((THIS_ALGORITHM_INFO_TYPE *, B_Algorithm *)); + int (*MakeInfo) PROTO_LIST + ((THIS_ALGORITHM_INFO_TYPE *, POINTER *, B_Algorithm *)); +} B_AlgorithmInfoTypeVTable; + +typedef struct B_AlgorithmInfoType { + B_AlgorithmInfoTypeVTable *vTable; +} B_AlgorithmInfoType; + +int B_AlgorithmInfoTypeMakeError PROTO_LIST + ((THIS_ALGORITHM_INFO_TYPE *, POINTER *, B_Algorithm *)); + +#endif diff --git a/lib/dns/sec/dnssafe/ainull.c b/lib/dns/sec/dnssafe/ainull.c new file mode 100644 index 00000000..66e0e917 --- /dev/null +++ b/lib/dns/sec/dnssafe/ainull.c @@ -0,0 +1,26 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ainfotyp.h" +#include "ainull.h" + +int AITNullAddInfo (infoType, algorithm, info) +B_AlgorithmInfoType *infoType; +B_Algorithm *algorithm; +POINTER info; +{ +UNUSED_ARG (info) + /* Cache null parameters. */ + return (B_InfoCacheAddInfo + (&algorithm->infoCache, (POINTER)infoType, NULL_PTR)); +} + diff --git a/lib/dns/sec/dnssafe/ainull.h b/lib/dns/sec/dnssafe/ainull.h new file mode 100644 index 00000000..3b48901a --- /dev/null +++ b/lib/dns/sec/dnssafe/ainull.h @@ -0,0 +1,10 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +int AITNullAddInfo PROTO_LIST + ((THIS_ALGORITHM_INFO_TYPE *, B_Algorithm *, POINTER)); diff --git a/lib/dns/sec/dnssafe/airsaepr.c b/lib/dns/sec/dnssafe/airsaepr.c new file mode 100644 index 00000000..55a219a4 --- /dev/null +++ b/lib/dns/sec/dnssafe/airsaepr.c @@ -0,0 +1,45 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ainfotyp.h" +#include "ainull.h" +#include "ahrsaepr.h" + +B_TypeCheck *AIT_PKCS_RSAPrivateNewHandler PROTO_LIST + ((B_AlgorithmInfoType *, B_Algorithm *)); + +static B_AlgorithmInfoTypeVTable V_TABLE = + {AITNullAddInfo, AIT_PKCS_RSAPrivateNewHandler, + B_AlgorithmInfoTypeMakeError}; + +B_AlgorithmInfoType AIT_PKCS_RSAPrivate = {&V_TABLE}; + +int AI_PKCS_RSAPrivate (infoType) +POINTER *infoType; +{ + *infoType = (POINTER)&AIT_PKCS_RSAPrivate; + + /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */ + return (0); +} + +B_TypeCheck *AIT_PKCS_RSAPrivateNewHandler (infoType, algorithm) +B_AlgorithmInfoType *infoType; +B_Algorithm *algorithm; +{ +UNUSED_ARG (infoType) +UNUSED_ARG (algorithm) + /* Pass in NULL_PTR so that constructor will allocate. */ + return ((B_TypeCheck *)AH_RSAEncrypPrivateConstructor + ((AH_RSAEncryptionPrivate *)NULL_PTR)); +} + diff --git a/lib/dns/sec/dnssafe/airsaepu.c b/lib/dns/sec/dnssafe/airsaepu.c new file mode 100644 index 00000000..44d0a81b --- /dev/null +++ b/lib/dns/sec/dnssafe/airsaepu.c @@ -0,0 +1,45 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ainfotyp.h" +#include "ainull.h" +#include "ahrsaepu.h" + +B_TypeCheck *AIT_PKCS_RSAPublicNewHandler PROTO_LIST + ((B_AlgorithmInfoType *, B_Algorithm *)); + +static B_AlgorithmInfoTypeVTable V_TABLE = + {AITNullAddInfo, AIT_PKCS_RSAPublicNewHandler, + B_AlgorithmInfoTypeMakeError}; + +B_AlgorithmInfoType AIT_PKCS_RSAPublic = {&V_TABLE}; + +int AI_PKCS_RSAPublic (infoType) +POINTER *infoType; +{ + *infoType = (POINTER)&AIT_PKCS_RSAPublic; + + /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */ + return (0); +} + +B_TypeCheck *AIT_PKCS_RSAPublicNewHandler (infoType, algorithm) +B_AlgorithmInfoType *infoType; +B_Algorithm *algorithm; +{ +UNUSED_ARG (infoType) +UNUSED_ARG (algorithm) + /* Pass in NULL_PTR so that constructor will allocate. */ + return ((B_TypeCheck *)AH_RSAEncrypPublicConstructor + ((AH_RSAEncryptionPublic *)NULL_PTR)); +} + diff --git a/lib/dns/sec/dnssafe/airsakgn.c b/lib/dns/sec/dnssafe/airsakgn.c new file mode 100644 index 00000000..9856a007 --- /dev/null +++ b/lib/dns/sec/dnssafe/airsakgn.c @@ -0,0 +1,60 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "intitem.h" +#include "aichgen.h" + +int AIT_RSAKeyGenAddInfo PROTO_LIST + ((THIS_ALGORITHM_INFO_TYPE *, B_Algorithm *, POINTER)); + +static A_RSA_KEY_GEN_PARAMS STATIC_KEY_GEN_PARAMS; +static ITEM *KEY_GEN_PARAMS_ITEMS[] = {&STATIC_KEY_GEN_PARAMS.publicExponent}; + +static B_AlgorithmInfoTypeVTable V_TABLE = + {AIT_RSAKeyGenAddInfo, AITChooseGenerateNewHandler, + B_AlgorithmInfoTypeMakeError}; + +B_AlgorithmInfoType AIT_RSAKeyGen = {&V_TABLE}; + +int AI_RSAKeyGen (infoType) +POINTER *infoType; +{ + *infoType = (POINTER)&AIT_RSAKeyGen; + + /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */ + return (0); +} + +int AIT_RSAKeyGenAddInfo (infoType, algorithm, info) +B_AlgorithmInfoType *infoType; +B_Algorithm *algorithm; +POINTER info; +{ + A_RSA_KEY_GEN_PARAMS *newInfo; + int status; + + if ((status = B_MemoryPoolAlloc + (&algorithm->infoCache.memoryPool, (POINTER *)&newInfo, + sizeof (A_RSA_KEY_GEN_PARAMS))) != 0) + return (status); + if ((status = AllocAndCopyIntegerItems + ((POINTER)newInfo, info, (POINTER)&STATIC_KEY_GEN_PARAMS, + KEY_GEN_PARAMS_ITEMS, + sizeof (KEY_GEN_PARAMS_ITEMS) / sizeof (KEY_GEN_PARAMS_ITEMS[0]), + &algorithm->infoCache.memoryPool)) != 0) + return (status); + + newInfo->modulusBits = ((A_RSA_KEY_GEN_PARAMS *)info)->modulusBits; + return (B_InfoCacheAddInfo + (&algorithm->infoCache, (POINTER)infoType, (POINTER)newInfo)); +} + diff --git a/lib/dns/sec/dnssafe/airsaprv.c b/lib/dns/sec/dnssafe/airsaprv.c new file mode 100644 index 00000000..81193efc --- /dev/null +++ b/lib/dns/sec/dnssafe/airsaprv.c @@ -0,0 +1,25 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "aichencn.h" + +B_AlgorithmInfoType AIT_RSAPrivate = {&AITChooseEncryptNull_V_TABLE}; + +int AI_RSAPrivate (infoType) +POINTER *infoType; +{ + *infoType = (POINTER)&AIT_RSAPrivate; + + /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */ + return (0); +} + diff --git a/lib/dns/sec/dnssafe/airsapub.c b/lib/dns/sec/dnssafe/airsapub.c new file mode 100644 index 00000000..6167355f --- /dev/null +++ b/lib/dns/sec/dnssafe/airsapub.c @@ -0,0 +1,25 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "aichencn.h" + +B_AlgorithmInfoType AIT_RSAPublic = {&AITChooseEncryptNull_V_TABLE}; + +int AI_RSAPublic (infoType) +POINTER *infoType; +{ + *infoType = (POINTER)&AIT_RSAPublic; + + /* Return 0 to indicate a B_AlgorithmInfoType, not a B_KeyInfoType */ + return (0); +} + diff --git a/lib/dns/sec/dnssafe/algae.h b/lib/dns/sec/dnssafe/algae.h new file mode 100644 index 00000000..f1ceb62d --- /dev/null +++ b/lib/dns/sec/dnssafe/algae.h @@ -0,0 +1,66 @@ +/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _ALGAE_H_ +#define _ALGAE_H_ 1 + +#ifndef T_CALL +#define T_CALL +#endif + +/* Used to reduce the stack size in routines with big scratch buffers. + If set to 1, this will make ALGAE allocate these buffers on the heap. + */ +#ifndef USE_ALLOCED_FRAME +#define USE_ALLOCED_FRAME 1 +#endif + +#include "atypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define AE_CANCEL 0x0001 +#define AE_DATA 0x0002 +#define AE_EXPONENT_EVEN 0x0003 +#define AE_EXPONENT_LEN 0x0004 +#define AE_INPUT_DATA 0x0005 +#define AE_INPUT_LEN 0x0006 +#define AE_MODULUS_LEN 0x0007 +#define AE_NEED_RANDOM 0x0008 +#define AE_NOT_SUPPORTED 0x0009 +#define AE_OUTPUT_LEN 0x000a +#define AE_NOT_INITIALIZED 0x000b +#define AE_KEY_LEN 0x000c +#define AE_KEY_INFO 0x000d +#define AE_SEQUENCE 0x000e +#define AE_PARAMS 0x000f + +#if USE_ALLOCED_FRAME +/* Needed only for big number code heap allocation of scratch arrays. + */ +#define AE_ALLOC 0x0080 +POINTER T_malloc PROTO_LIST ((unsigned int)); +void T_free PROTO_LIST ((POINTER)); +#endif + +/* Routines supplied by the implementor. + */ +void T_memset PROTO_LIST ((POINTER, int, unsigned int)); +void T_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); +void T_memmove PROTO_LIST ((POINTER, POINTER, unsigned int)); +int T_memcmp PROTO_LIST ((POINTER, POINTER, unsigned int)); + +unsigned int A_IntegerBits PROTO_LIST ((unsigned char *, unsigned int)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/dnssafe/algchoic.c b/lib/dns/sec/dnssafe/algchoic.c new file mode 100644 index 00000000..e8b07699 --- /dev/null +++ b/lib/dns/sec/dnssafe/algchoic.c @@ -0,0 +1,167 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "algae.h" +#include "balgmeth.h" +#include "bkey.h" +#include "algchoic.h" + +/* In C++: +ResizeContext::ResizeContext () +{ + T_memset ((POINTER)&z, 0, sizeof (z)); +} + */ +void ResizeContextConstructor (resizeContext) +ResizeContext *resizeContext; +{ + T_memset ((POINTER)&resizeContext->z, 0, sizeof (resizeContext->z)); +} + +/* In C++: +ResizeContext::~ResizeContext () +{ + T_memset (z.context, 0, z.contextSize); + T_free (z.context); +} + */ +void ResizeContextDestructor (resizeContext) +ResizeContext *resizeContext; +{ + T_memset (resizeContext->z.context, 0, resizeContext->z.contextSize); + T_free (resizeContext->z.context); +} + +/* If the resizeContext's context is already the requested size, do nothing. + Otherwise, this memsets the existing context to zero, then allocates + the context as a buffer of the requested size. + If the allocate fails, the context size is set to + zero so that later calls will not zeroize non-existing buffers. + */ +int ResizeContextMakeNewContext (resizeContext, contextSize) +ResizeContext *resizeContext; +unsigned int contextSize; +{ + if (resizeContext->z.contextSize == contextSize) + return (0); + + /* Take care of zeroizing the previous context. + */ + T_memset (resizeContext->z.context, 0, resizeContext->z.contextSize); + + if ((resizeContext->z.context = T_realloc + (resizeContext->z.context, contextSize)) == NULL_PTR) { + resizeContext->z.contextSize = 0; + return (BE_ALLOC); + } + + resizeContext->z.contextSize = contextSize; + return (0); +} + +int AlgaChoiceChoose (algaChoice, encryptFlag, key, chooser, surrenderContext) +AlgaChoice *algaChoice; +int encryptFlag; +B_Key *key; +B_ALGORITHM_CHOOSER chooser; +A_SURRENDER_CTX *surrenderContext; +{ + POINTER keyInfo; + int status, overallStatus; + + /* Each alga init callback returns BE_NOT_SUPPORTED if the Query fails. + Each also may return a more specific error like BE_MODULUS_LEN if the + method is not supported, so return the more specific error if possible. + */ + overallStatus = BE_METHOD_NOT_IN_CHOOSER; + + for (; *chooser != (B_ALGORITHM_METHOD *)NULL_PTR; chooser++) { + if ((*chooser)->algorithmInfoType != algaChoice->_algorithmInfoType || + (*chooser)->encryptFlag != encryptFlag) + /* Wrong type of algorithm, or the encryptFlag is wrong */ + continue; + + if ((*chooser)->keyInfoType != (struct B_KeyInfoType *)NULL_PTR) { + if ((status = B_KeyGetInfo + (key, &keyInfo, (*chooser)->keyInfoType)) != 0) { + if (IS_FATAL_BSAFE_ERROR (status)) + return (status); + + /* Update the overall status with this more specific error. */ + overallStatus = status; + continue; + } + } + else + keyInfo = NULL_PTR; + + if ((status = (*algaChoice->_InitAlga) + (algaChoice, keyInfo, *chooser, surrenderContext)) != 0) { + if (IS_FATAL_BSAFE_ERROR (status)) + return (status); + + /* Update the overall status with this more specific error. */ + overallStatus = status; + continue; + } + + /* Succeeded */ + algaChoice->_alga = (*chooser)->alga; + return (0); + } + + return (overallStatus); +} + +/* Convert the ALGAE error to a BSAFE2 error. + This does not check for zero since BSAFE should not bother to call + this function if there is no error. + */ +int ConvertAlgaeError (type) +int type; +{ + switch (type) { + case AE_CANCEL: + return (BE_CANCEL); + case AE_DATA: + return (BE_DATA); + case AE_EXPONENT_EVEN: + return (BE_EXPONENT_EVEN); + case AE_EXPONENT_LEN: + return (BE_EXPONENT_LEN); + case AE_INPUT_DATA: + return (BE_INPUT_DATA); + case AE_INPUT_LEN: + return (BE_INPUT_LEN); + case AE_KEY_INFO: + return (BE_KEY_INFO); + case AE_KEY_LEN: + return (BE_KEY_LEN); + case AE_MODULUS_LEN: + return (BE_MODULUS_LEN); + case AE_NOT_INITIALIZED: + return (BE_NOT_INITIALIZED); + case AE_NOT_SUPPORTED: + return (BE_NOT_SUPPORTED); + case AE_OUTPUT_LEN: + return (BE_OUTPUT_LEN); + case AE_PARAMS: + return (BE_ALGORITHM_INFO); + +#if USE_ALLOCED_FRAME + case AE_ALLOC: + return (BE_ALLOC); +#endif + + default: + return (BE_DATA); + } +} + diff --git a/lib/dns/sec/dnssafe/algchoic.h b/lib/dns/sec/dnssafe/algchoic.h new file mode 100644 index 00000000..5743441d --- /dev/null +++ b/lib/dns/sec/dnssafe/algchoic.h @@ -0,0 +1,111 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _ALGCHOICE_H_ +#define _ALGCHOICE_H_ 1 + +#define IS_FATAL_BSAFE_ERROR(status) \ + (status == BE_ALLOC || status == BE_HARDWARE || status == BE_CANCEL) + +/* Use the THIS_ALGA_CHOICE macro to define the type of object in the + INIT_ALGA prototype. It defaults to the AlgaChoice, but + derived modules may define the macro to a more derived class before + including this header file. + */ +struct AlgaChoice; +#ifndef THIS_ALGA_CHOICE +#define THIS_ALGA_CHOICE struct AlgaChoice +#endif + +/* In C++: +class ResizeContext { +public: + ResizeContext (); + ~ResizeContext (); + int makeNewContext (unsigned int contextSize); + POINTER context () {return z.context;} + +private: + struct { + POINTER context; + unsigned int contextSize; + } z; +}; + +class AlgaChoice; +typedef int (*INIT_ALGA) + (THIS_ALGA_CHOICE *algaChoice, POINTER keyInfo, + struct B_ALGORITHM_METHOD *algorithmMethod, + A_SURRENDER_CTX *surrenderContext); + +class AlgaChoice { +public: + AlgaChoice (INIT_ALGA InitAlga) : _InitAlga (InitAlga) {} + ~AlgaChoice () {} + int choose + (int encryptFlag, B_Key *key, B_ALGORITHM_CHOOSER chooser, + A_SURRENDER_CTX *surrenderContext); + int makeNewContext (unsigned int contextSize) { + context.makeNewContext (contextSize); } + POINTER alga () {return _alga;} + POINTER algorithmInfo () {return _algorithmInfo;} + POINTER context () {return context.context ();} + void setAlgorithmInfoType (B_AlgorithmInfoType *algorithmInfoType) { + _algorithmInfoType = algorithmInfoType; + } + void setAlgorithmInfo (POINTER algorithmInfo) { + _algorithmInfo = algorithmInfo; + } + +private: + POINTER _alga; + B_AlgorithmInfoType *_algorithmInfoType; + POINTER _algorithmInfo; + INIT_ALGA _InitAlga; + + ResizeContext context; +}; + */ +struct B_AlgorithmInfoType; + +typedef struct ResizeContext { + struct { + POINTER context; + unsigned int contextSize; + } z; /* zeriozed by constructor */ +} ResizeContext; + +typedef int (*INIT_ALGA) PROTO_LIST + ((THIS_ALGA_CHOICE *, POINTER, struct B_ALGORITHM_METHOD *, + A_SURRENDER_CTX *)); + +typedef struct AlgaChoice { + POINTER _alga; + struct B_AlgorithmInfoType *_algorithmInfoType; + POINTER _algorithmInfo; + INIT_ALGA _InitAlga; + + ResizeContext context; +} AlgaChoice; + +void ResizeContextConstructor PROTO_LIST ((ResizeContext *)); +void ResizeContextDestructor PROTO_LIST ((ResizeContext *)); +int ResizeContextMakeNewContext PROTO_LIST ((ResizeContext *, unsigned int)); + +#define ALGA_CHOICE_Constructor(algaChoice, InitAlga)\ + (ResizeContextConstructor (&(algaChoice)->context), \ + (algaChoice)->_InitAlga = (InitAlga)) +#define ALGA_CHOICE_Destructor(algaChoice)\ + (ResizeContextDestructor (&(algaChoice)->context)) + +int AlgaChoiceChoose PROTO_LIST + ((AlgaChoice *, int, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); + +int ConvertAlgaeError PROTO_LIST ((int)); + +#endif diff --git a/lib/dns/sec/dnssafe/algobj.c b/lib/dns/sec/dnssafe/algobj.c new file mode 100644 index 00000000..d872d248 --- /dev/null +++ b/lib/dns/sec/dnssafe/algobj.c @@ -0,0 +1,121 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ainfotyp.h" +#include "keyobj.h" +#include "algobj.h" + +static char ALGORITHM_TYPE_TAG = 0; + +int B_CreateAlgorithmObject (algorithmObject) +B_ALGORITHM_OBJ *algorithmObject; +{ + AlgorithmWrap *algorithmWrap; + + if ((*algorithmObject = T_malloc (sizeof (*algorithmWrap))) == NULL_PTR) + return (BE_ALLOC); + + algorithmWrap = (AlgorithmWrap *)*algorithmObject; + + /* First construct base class */ + B_AlgorithmConstructor (&algorithmWrap->algorithm); + + algorithmWrap->typeTag = &ALGORITHM_TYPE_TAG; + algorithmWrap->selfCheck = algorithmWrap; + return (0); +} + +void B_DestroyAlgorithmObject (algorithmObject) +B_ALGORITHM_OBJ *algorithmObject; +{ + AlgorithmWrap *algorithmWrap = (AlgorithmWrap *)*algorithmObject; + + if (AlgorithmWrapCheck (algorithmWrap) == 0) { + /* zeroize self check to invalidate memory. */ + algorithmWrap->selfCheck = (AlgorithmWrap *)NULL_PTR; + + /* Call base class descructor */ + B_AlgorithmDestructor (&algorithmWrap->algorithm); + + T_free ((POINTER)algorithmWrap); + } + + *algorithmObject = NULL_PTR; +} + +int B_SetAlgorithmInfo (algorithmObject, infoType, info) +B_ALGORITHM_OBJ algorithmObject; +B_INFO_TYPE infoType; +POINTER info; +{ + B_AlgorithmInfoType *algorithmInfoType; + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + + /* Get the AlgorithmInfoType from the B_INFO_TYPE, which returns + zero for an AlgorithmInfoType, non-zero for KeyInfoType + */ + if ((*infoType) ((POINTER *)&algorithmInfoType) != 0) + return (BE_KEY_OPERATION_UNKNOWN); + + return (B_AlgorithmSetInfo + (&THE_ALG_WRAP->algorithm, algorithmInfoType, info)); +} + +int B_GetAlgorithmInfo (info, algorithmObject, infoType) +POINTER *info; +B_ALGORITHM_OBJ algorithmObject; +B_INFO_TYPE infoType; +{ + B_AlgorithmInfoType *algorithmInfoType; + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + + /* Get the AlgorithmInfoType from the B_INFO_TYPE, which returns + zero for an AlgorithmInfoType, non-zero for KeyInfoType + */ + if ((*infoType) ((POINTER *)&algorithmInfoType) != 0) + return (BE_KEY_OPERATION_UNKNOWN); + + return (B_AlgorithmGetInfo + (&THE_ALG_WRAP->algorithm, info, algorithmInfoType)); +} + +/* Return 0 if this is a valid AlgorithmWrap object. Return BE_ALGORITHM_OBJ if + algorithmWrap is NULL_PTR or invalid. + */ +int AlgorithmWrapCheck (algorithmWrap) +AlgorithmWrap *algorithmWrap; +{ + return ((algorithmWrap != (AlgorithmWrap *)NULL_PTR && + algorithmWrap->selfCheck == algorithmWrap && + algorithmWrap->typeTag == &ALGORITHM_TYPE_TAG) ? + 0 : BE_ALGORITHM_OBJ); +} + +/* Like AlgorithmWrapCheck except returns BE_RANDOM_OBJ for error. + Also, return OK status if randomAlgorithm is NULL_PTR. + */ +int RandomAlgorithmCheck (randomAlgorithm) +B_ALGORITHM_OBJ randomAlgorithm; +{ + if (randomAlgorithm == NULL_PTR) + return (0); + + return (AlgorithmWrapCheck ((AlgorithmWrap *)randomAlgorithm) ? + BE_RANDOM_OBJ : 0); +} + diff --git a/lib/dns/sec/dnssafe/algobj.h b/lib/dns/sec/dnssafe/algobj.h new file mode 100644 index 00000000..7f87cfae --- /dev/null +++ b/lib/dns/sec/dnssafe/algobj.h @@ -0,0 +1,19 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#define THE_ALG_WRAP ((AlgorithmWrap *)algorithmObject) + +typedef struct AlgorithmWrap { + B_Algorithm algorithm; + char *typeTag; + struct AlgorithmWrap *selfCheck; +} AlgorithmWrap; + +int AlgorithmWrapCheck PROTO_LIST ((AlgorithmWrap *)); +int RandomAlgorithmCheck PROTO_LIST ((B_ALGORITHM_OBJ)); + diff --git a/lib/dns/sec/dnssafe/amcrte.c b/lib/dns/sec/dnssafe/amcrte.c new file mode 100644 index 00000000..d1e1c2a8 --- /dev/null +++ b/lib/dns/sec/dnssafe/amcrte.c @@ -0,0 +1,117 @@ +/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "bsafe2.h" +#include "balgmeth.h" +#include "crt2.h" +#include "amencdec.h" + +static int RSA_CRT2Query PROTO_LIST ((unsigned int *, POINTER, POINTER)); +static int RSA_CRT2Init PROTO_LIST + ((POINTER, POINTER, POINTER, A_SURRENDER_CTX *)); +static int RSA_CRT2Update PROTO_LIST + ((POINTER, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int, A_SURRENDER_CTX *)); +static int RSA_CRT2Final PROTO_LIST + ((POINTER, unsigned char *, unsigned int *, unsigned int, + A_SURRENDER_CTX *)); +static int RSA_CRT2GetMaxOutputLen PROTO_LIST + ((POINTER, unsigned int *, unsigned int)); +static int RSA_CRT2GetBlockLen PROTO_LIST ((POINTER, unsigned int *)); + +extern struct B_AlgorithmInfoType AIT_RSAPrivate; +extern struct B_KeyInfoType KIT_RSA_CRT; + +static A_ENCRYPT_DECRYPT_ALGA A_RSA_CRT2_CRYPT = { + RSA_CRT2Query, RSA_CRT2Init, RSA_CRT2Update, RSA_CRT2Final, + RSA_CRT2GetMaxOutputLen, RSA_CRT2GetBlockLen +}; + +B_ALGORITHM_METHOD AM_RSA_CRT_DECRYPT = + {&AIT_RSAPrivate, 0, &KIT_RSA_CRT, (POINTER)&A_RSA_CRT2_CRYPT}; +B_ALGORITHM_METHOD AM_RSA_CRT_ENCRYPT = + {&AIT_RSAPrivate, 1, &KIT_RSA_CRT, (POINTER)&A_RSA_CRT2_CRYPT}; + +static int RSA_CRT2Query (contextLen, key, params) +unsigned int *contextLen; +POINTER key; +POINTER params; +{ +UNUSED_ARG (params) + + if (A_IntegerBits + (((A_RSA_CRT_KEY *)key)->modulus.data, + ((A_RSA_CRT_KEY *)key)->modulus.len) > MAX_RSA_MODULUS_BITS) + /* Key size is too big to handle. */ + return (AE_MODULUS_LEN); + + *contextLen = sizeof (A_RSA_CRT2_CTX); + return (0); +} + +static int RSA_CRT2Init (context, key, params, surrenderContext) +POINTER context; +POINTER key; +POINTER params; +A_SURRENDER_CTX *surrenderContext; +{ +UNUSED_ARG (params) +UNUSED_ARG (surrenderContext) + + return (A_RSA_CRT2Init ((A_RSA_CRT2_CTX *)context, (A_RSA_CRT_KEY *)key)); +} + +static int RSA_CRT2Update + (context, output, outputLen, maxOutputLen, input, inputLen, surrenderContext) +POINTER context; +unsigned char *output; +unsigned int *outputLen; +unsigned int maxOutputLen; +unsigned char *input; +unsigned int inputLen; +A_SURRENDER_CTX *surrenderContext; +{ + return (A_RSA_CRT2Update + ((A_RSA_CRT2_CTX *)context, output, outputLen, maxOutputLen, input, + inputLen, surrenderContext)); +} + +static int RSA_CRT2Final + (context, output, outputLen, maxOutputLen, surrenderContext) +POINTER context; +unsigned char *output; +unsigned int *outputLen; +unsigned int maxOutputLen; +A_SURRENDER_CTX * surrenderContext; +{ +UNUSED_ARG (output) +UNUSED_ARG (maxOutputLen) +UNUSED_ARG (surrenderContext) + + *outputLen = 0; + return (A_RSA_CRT2Final ((A_RSA_CRT2_CTX *)context)); +} + +static int RSA_CRT2GetMaxOutputLen (context, outputLen, inputLen) +POINTER context; +unsigned int *outputLen; +unsigned int inputLen; +{ + *outputLen = A_RSA_CRT2_MAX_OUTPUT_LEN ((A_RSA_CRT2_CTX *)context, inputLen); + return (0); +} + +static int RSA_CRT2GetBlockLen (context, blockLen) +POINTER context; +unsigned int *blockLen; +{ + *blockLen = A_RSA_CRT2_BLOCK_LEN ((A_RSA_CRT2_CTX *)context); + return(0); +} diff --git a/lib/dns/sec/dnssafe/amdigest.h b/lib/dns/sec/dnssafe/amdigest.h new file mode 100644 index 00000000..5b8f5662 --- /dev/null +++ b/lib/dns/sec/dnssafe/amdigest.h @@ -0,0 +1,19 @@ +/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +typedef struct { + int (*Query) PROTO_LIST ((unsigned int *, POINTER)); + int (*Init) PROTO_LIST ((POINTER, POINTER, A_SURRENDER_CTX *)); + int (*Update) PROTO_LIST + ((POINTER, unsigned char *, unsigned int, A_SURRENDER_CTX *)); + int (*Final) PROTO_LIST + ((POINTER, unsigned char *, unsigned int *, unsigned int, + A_SURRENDER_CTX *)); + int (*GetMaxOutputLen) PROTO_LIST ((POINTER, unsigned int *)); +} A_DIGEST_ALGA; + diff --git a/lib/dns/sec/dnssafe/amencdec.h b/lib/dns/sec/dnssafe/amencdec.h new file mode 100644 index 00000000..8f91a0fa --- /dev/null +++ b/lib/dns/sec/dnssafe/amencdec.h @@ -0,0 +1,21 @@ +/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +typedef struct { + int (*Query) PROTO_LIST ((unsigned int *, POINTER, POINTER)); + int (*Init) PROTO_LIST ((POINTER, POINTER, POINTER, A_SURRENDER_CTX *)); + int (*Update) PROTO_LIST + ((POINTER, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int, A_SURRENDER_CTX *)); + int (*Final) PROTO_LIST + ((POINTER, unsigned char *, unsigned int *, unsigned int, + A_SURRENDER_CTX *)); + int (*GetMaxOutputLen) PROTO_LIST ((POINTER, unsigned int *, unsigned int)); + int (*GetBlockLen) PROTO_LIST ((POINTER, unsigned int *)); +} A_ENCRYPT_DECRYPT_ALGA; + diff --git a/lib/dns/sec/dnssafe/amgen.h b/lib/dns/sec/dnssafe/amgen.h new file mode 100644 index 00000000..ffdf4576 --- /dev/null +++ b/lib/dns/sec/dnssafe/amgen.h @@ -0,0 +1,19 @@ +/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +struct B_KeyInfoType; + +typedef struct { + int (*Query) PROTO_LIST + ((unsigned int *, unsigned int *, unsigned int *, struct B_KeyInfoType **, + POINTER)); + int (*Init) PROTO_LIST ((POINTER, POINTER, POINTER, A_SURRENDER_CTX *)); + int (*Generate) PROTO_LIST + ((POINTER, POINTER *, unsigned char *, A_SURRENDER_CTX *)); +} A_GENERATE_ALGA; + diff --git a/lib/dns/sec/dnssafe/ammd5.c b/lib/dns/sec/dnssafe/ammd5.c new file mode 100644 index 00000000..ac8ac48c --- /dev/null +++ b/lib/dns/sec/dnssafe/ammd5.c @@ -0,0 +1,100 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "bsafe2.h" +#include "balgmeth.h" +#include "md5.h" +#include "amdigest.h" + +static int MD5Query PROTO_LIST ((unsigned int *, POINTER)); +static int MD5Init PROTO_LIST ((POINTER, POINTER, A_SURRENDER_CTX*)); +static int MD5Update PROTO_LIST + ((POINTER, unsigned char *, unsigned int, A_SURRENDER_CTX*)); +static int MD5Final PROTO_LIST + ((POINTER, unsigned char *, unsigned int *, unsigned int, A_SURRENDER_CTX*)); +static int MD5GetMaxOutputLen PROTO_LIST ((POINTER, unsigned int *)); + +static A_DIGEST_ALGA A_MD5_DIGEST = { + MD5Query, MD5Init, MD5Update, MD5Final, MD5GetMaxOutputLen +}; + +extern struct B_AlgorithmInfoType AIT_MD5; + +B_ALGORITHM_METHOD AM_MD5 = + {&AIT_MD5, 0, (struct B_KeyInfoType *)NULL_PTR, (POINTER)&A_MD5_DIGEST}; + +/* Returns 0. + */ +static int MD5Query (contextLen, params) +unsigned int *contextLen; +POINTER params; +{ +UNUSED_ARG (params) + + *contextLen = sizeof (A_MD5_CTX); + return (0); +} + +/* Returns 0. + */ +static int MD5Init (context, params, surrenderContext) +POINTER context; +POINTER params; +A_SURRENDER_CTX *surrenderContext; +{ +UNUSED_ARG (params) +UNUSED_ARG (surrenderContext) + + A_MD5Init ((A_MD5_CTX *)context); + return (0); +} + +/* Returns 0. + */ +static int MD5Update (context, input, inputLen, surrenderContext) +POINTER context; +unsigned char *input; +unsigned int inputLen; +A_SURRENDER_CTX *surrenderContext; +{ +UNUSED_ARG (surrenderContext) + + A_MD5Update ((A_MD5_CTX *)context, input, inputLen); + return (0); +} + +/* Returns 0, AE_OUTPUT_LEN if maxDigestLen is too small. + */ +static int MD5Final + (context, digest, digestLen, maxDigestLen, surrenderContext) +POINTER context; +unsigned char *digest; +unsigned int *digestLen; +unsigned int maxDigestLen; +A_SURRENDER_CTX *surrenderContext; +{ +UNUSED_ARG (surrenderContext) + + if ((*digestLen = A_MD5_DIGEST_LEN) > maxDigestLen) + return (AE_OUTPUT_LEN); + + A_MD5Final ((A_MD5_CTX *)context, digest); + return (0); +} + +static int MD5GetMaxOutputLen (context, outputLen) +POINTER context; +unsigned int *outputLen; +{ +UNUSED_ARG (context) + + *outputLen = A_MD5_DIGEST_LEN; + return(0); +} diff --git a/lib/dns/sec/dnssafe/ammd5r.c b/lib/dns/sec/dnssafe/ammd5r.c new file mode 100644 index 00000000..728bd7a3 --- /dev/null +++ b/lib/dns/sec/dnssafe/ammd5r.c @@ -0,0 +1,77 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "bsafe2.h" +#include "balgmeth.h" +#include "md5rand.h" +#include "amrandom.h" + +static int MD5RandomQuery PROTO_LIST ((unsigned int *, POINTER)); +static int MD5RandomInit PROTO_LIST ((POINTER, POINTER, A_SURRENDER_CTX *)); +static int MD5RandomUpdate PROTO_LIST + ((POINTER, unsigned char *, unsigned int, A_SURRENDER_CTX *)); +static int MD5RandomGenerateBytes PROTO_LIST + ((POINTER, unsigned char *, unsigned int, A_SURRENDER_CTX *)); + +extern struct B_AlgorithmInfoType AIT_MD5Random; + +static A_RANDOM_ALGA A_MD5_RANDOM = + {MD5RandomQuery, MD5RandomInit, MD5RandomUpdate, MD5RandomGenerateBytes}; + +B_ALGORITHM_METHOD AM_MD5_RANDOM = + {&AIT_MD5Random, 0, (struct B_KeyInfoType *)NULL_PTR, + (POINTER)&A_MD5_RANDOM}; + +static int MD5RandomQuery (contextLen, params) +unsigned int *contextLen; +POINTER params; +{ +UNUSED_ARG (params) + + *contextLen = sizeof (A_MD5_RANDOM_CTX); + return (0); +} + +static int MD5RandomInit (context, params, surrenderContext) +POINTER context; +POINTER params; +A_SURRENDER_CTX *surrenderContext; +{ +UNUSED_ARG (params) +UNUSED_ARG (surrenderContext) + + A_MD5RandomInit ((A_MD5_RANDOM_CTX *)context); + return (0); +} + +static int MD5RandomUpdate (context, input, inputLen, surrenderContext) +POINTER context; +unsigned char *input; +unsigned int inputLen; +A_SURRENDER_CTX *surrenderContext; +{ +UNUSED_ARG (surrenderContext) + + A_MD5RandomUpdate ((A_MD5_RANDOM_CTX *)context, input, inputLen); + return (0); +} + +static int MD5RandomGenerateBytes + (context, output, outputLen, surrenderContext) +POINTER context; +unsigned char *output; +unsigned int outputLen; +A_SURRENDER_CTX *surrenderContext; +{ +UNUSED_ARG (surrenderContext) + + A_MD5RandomGenerateBytes ((A_MD5_RANDOM_CTX *)context, output, outputLen); + return (0); +} diff --git a/lib/dns/sec/dnssafe/amrandom.h b/lib/dns/sec/dnssafe/amrandom.h new file mode 100644 index 00000000..3b9539a0 --- /dev/null +++ b/lib/dns/sec/dnssafe/amrandom.h @@ -0,0 +1,17 @@ +/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +typedef struct { + int (*Query) PROTO_LIST ((unsigned int *, POINTER)); + int (*Init) PROTO_LIST ((POINTER, POINTER, A_SURRENDER_CTX *)); + int (*Update) PROTO_LIST + ((POINTER, unsigned char *, unsigned int, A_SURRENDER_CTX *)); + int (*Generate) PROTO_LIST + ((POINTER, unsigned char *, unsigned int, A_SURRENDER_CTX *)); +} A_RANDOM_ALGA; + diff --git a/lib/dns/sec/dnssafe/amrkg.c b/lib/dns/sec/dnssafe/amrkg.c new file mode 100644 index 00000000..59b6e111 --- /dev/null +++ b/lib/dns/sec/dnssafe/amrkg.c @@ -0,0 +1,81 @@ +/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "algae.h" +#include "rsakeygn.h" +#include "balgmeth.h" +#include "amgen.h" + +#define THE_GEN_PARAMS ((A_RSA_KEY_GEN_PARAMS *)params) + +extern struct B_AlgorithmInfoType AIT_RSAKeyGen; +extern struct B_KeyInfoType KIT_PKCS_RSAPrivate; + +static int RSAKeyGenQuery PROTO_LIST + ((unsigned int *, unsigned int *, unsigned int *, struct B_KeyInfoType **, + POINTER)); +static int RSAKeyGenInit PROTO_LIST + ((POINTER, POINTER, POINTER, A_SURRENDER_CTX *)); +static int RSAKeyGen PROTO_LIST + ((POINTER, POINTER *, unsigned char *, A_SURRENDER_CTX *)); + +static A_GENERATE_ALGA A_RSA_KEY_GEN = + {RSAKeyGenQuery, RSAKeyGenInit, RSAKeyGen}; + +B_ALGORITHM_METHOD AM_RSA_KEY_GEN = + {&AIT_RSAKeyGen, 0, (struct B_KeyInfoType *)NULL_PTR, + (POINTER)&A_RSA_KEY_GEN}; + +static int RSAKeyGenQuery + (contextLen, secondContextLen, randomBlockLen, resultInfoType, params) +unsigned int *contextLen; +unsigned int *secondContextLen; +unsigned int *randomBlockLen; +struct B_KeyInfoType **resultInfoType; +POINTER params; +{ + if ((THE_GEN_PARAMS->modulusBits > MAX_RSA_MODULUS_BITS) || + (THE_GEN_PARAMS->modulusBits < MIN_RSA_MODULUS_BITS)) + /* Can't support a keypair of this size. */ + return (AE_MODULUS_LEN); + + *contextLen = sizeof (A_RSA_KEY_GEN_CTX); + *secondContextLen = 0; + *randomBlockLen = + A_RSA_KEY_GEN_RANDOM_BLOCK_LEN (THE_GEN_PARAMS->modulusBits); + *resultInfoType = &KIT_PKCS_RSAPrivate; + + return (0); +} + +static int RSAKeyGenInit (context, secondContext, params, surrenderContext) +POINTER context; +POINTER secondContext; +POINTER params; +A_SURRENDER_CTX *surrenderContext; +{ +UNUSED_ARG (secondContext) +UNUSED_ARG (surrenderContext) + + return (A_RSAKeyGenInit + ((A_RSA_KEY_GEN_CTX *)context, (A_RSA_KEY_GEN_PARAMS *)params)); +} + +static int RSAKeyGen (context, result, randomBlock, surrenderContext) +POINTER context; +POINTER *result; +unsigned char *randomBlock; +A_SURRENDER_CTX *surrenderContext; +{ + return (A_RSAKeyGen + ((A_RSA_KEY_GEN_CTX *)context, (A_PKCS_RSA_PRIVATE_KEY **)result, + randomBlock, surrenderContext)); +} + diff --git a/lib/dns/sec/dnssafe/amrsae.c b/lib/dns/sec/dnssafe/amrsae.c new file mode 100644 index 00000000..674cb253 --- /dev/null +++ b/lib/dns/sec/dnssafe/amrsae.c @@ -0,0 +1,115 @@ +/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "bsafe2.h" +#include "balgmeth.h" +#include "rsa.h" +#include "amencdec.h" + +static int RSAQuery PROTO_LIST ((unsigned int *, POINTER, POINTER)); +static int RSAInit PROTO_LIST ((POINTER, POINTER, POINTER, A_SURRENDER_CTX *)); +static int RSAUpdate PROTO_LIST + ((POINTER, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int, A_SURRENDER_CTX *)); +static int RSAFinal PROTO_LIST + ((POINTER, unsigned char *, unsigned int *, unsigned int, + A_SURRENDER_CTX *)); +static int RSAGetMaxOutputLen PROTO_LIST + ((POINTER, unsigned int *, unsigned int)); +static int RSAGetBlockLen PROTO_LIST ((POINTER, unsigned int *)); + +extern struct B_AlgorithmInfoType AIT_RSAPublic; +extern struct B_KeyInfoType KIT_RSAPublic; + +static A_ENCRYPT_DECRYPT_ALGA A_RSA_CRYPT = { + RSAQuery, RSAInit, RSAUpdate, RSAFinal, RSAGetMaxOutputLen, RSAGetBlockLen +}; + +B_ALGORITHM_METHOD AM_RSA_DECRYPT = + {&AIT_RSAPublic, 0, &KIT_RSAPublic, (POINTER)&A_RSA_CRYPT}; +B_ALGORITHM_METHOD AM_RSA_ENCRYPT = + {&AIT_RSAPublic, 1, &KIT_RSAPublic, (POINTER)&A_RSA_CRYPT}; + +static int RSAQuery (contextLen, key, params) +unsigned int *contextLen; +POINTER key; +POINTER params; +{ +UNUSED_ARG (params) + + if (A_IntegerBits + (((A_RSA_KEY *)key)->modulus.data, ((A_RSA_KEY *)key)->modulus.len) + > MAX_RSA_MODULUS_BITS) + /* Key size is too big to handle. */ + return (AE_MODULUS_LEN); + + *contextLen = sizeof (A_RSA_CTX); + return (0); +} + +static int RSAInit (context, key, params, surrenderContext) +POINTER context; +POINTER key; +POINTER params; +A_SURRENDER_CTX *surrenderContext; +{ +UNUSED_ARG (params) +UNUSED_ARG (surrenderContext) + + return (A_RSAInit ((A_RSA_CTX *)context, (A_RSA_KEY *)key)); +} + +static int RSAUpdate + (context, output, outputLen, maxOutputLen, input, inputLen, surrenderContext) +POINTER context; +unsigned char *output; +unsigned int *outputLen; +unsigned int maxOutputLen; +unsigned char *input; +unsigned int inputLen; +A_SURRENDER_CTX *surrenderContext; +{ + return (A_RSAUpdate + ((A_RSA_CTX *)context, output, outputLen, maxOutputLen, input, + inputLen, surrenderContext)); +} + +static int RSAFinal + (context, output, outputLen, maxOutputLen, surrenderContext) +POINTER context; +unsigned char *output; +unsigned int *outputLen; +unsigned int maxOutputLen; +A_SURRENDER_CTX * surrenderContext; +{ +UNUSED_ARG (output) +UNUSED_ARG (maxOutputLen) +UNUSED_ARG (surrenderContext) + + *outputLen = 0; + return (A_RSAFinal ((A_RSA_CTX *)context)); +} + +static int RSAGetMaxOutputLen (context, outputLen, inputLen) +POINTER context; +unsigned int *outputLen; +unsigned int inputLen; +{ + *outputLen = A_RSA_MAX_OUTPUT_LEN ((A_RSA_CTX *)context, inputLen); + return (0); +} + +static int RSAGetBlockLen (context, blockLen) +POINTER context; +unsigned int *blockLen; +{ + *blockLen = A_RSA_BLOCK_LEN ((A_RSA_CTX *)context); + return(0); +} diff --git a/lib/dns/sec/dnssafe/atypes.h b/lib/dns/sec/dnssafe/atypes.h new file mode 100644 index 00000000..e1af4eac --- /dev/null +++ b/lib/dns/sec/dnssafe/atypes.h @@ -0,0 +1,60 @@ +/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _ATYPES_H_ +#define _ATYPES_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ITEM_ +#define _ITEM_ 1 +typedef struct { + unsigned char *data; + unsigned int len; +} ITEM; +#endif + +typedef struct { + int (T_CALL *Surrender) PROTO_LIST ((POINTER)); + POINTER handle; + POINTER reserved; +} A_SURRENDER_CTX; + +typedef struct { + ITEM modulus; + ITEM publicExponent; + ITEM privateExponent; + ITEM prime[2]; /* prime factors */ + ITEM primeExponent[2]; /* exponents for prime factors */ + ITEM coefficient; /* CRT coefficient */ +} A_PKCS_RSA_PRIVATE_KEY; + +typedef struct { + ITEM modulus; + ITEM prime[2]; /* prime factors */ + ITEM primeExponent[2]; /* exponents for prime factors */ + ITEM coefficient; /* CRT coefficient */ +} A_RSA_CRT_KEY; + +typedef struct { + ITEM modulus; /* modulus */ + ITEM exponent; /* exponent */ +} A_RSA_KEY; + +typedef struct { + unsigned int modulusBits; + ITEM publicExponent; +} A_RSA_KEY_GEN_PARAMS; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/dnssafe/balg.c b/lib/dns/sec/dnssafe/balg.c new file mode 100644 index 00000000..b0b9bbb7 --- /dev/null +++ b/lib/dns/sec/dnssafe/balg.c @@ -0,0 +1,115 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "btypechk.h" +#include "ainfotyp.h" + +void B_AlgorithmConstructor (algorithm) +B_Algorithm *algorithm; +{ + /* Construct immediate base class. */ + B_InfoCacheConstructor (&algorithm->infoCache); + + T_memset ((POINTER)&algorithm->z, 0, sizeof (algorithm->z)); +} + +void B_AlgorithmDestructor (algorithm) +B_Algorithm *algorithm; +{ + if (algorithm->z.handler != (B_TypeCheck *)NULL_PTR) { + B_TYPE_CHECK_Destructor (algorithm->z.handler); + T_free ((POINTER)algorithm->z.handler); + } + + /* Destroy base class */ + B_INFO_CACHE_Destructor (&algorithm->infoCache); +} + +int B_AlgorithmCheckType (algorithm, Destructor) +B_Algorithm *algorithm; +B_TYPE_CHECK_DESTRUCTOR Destructor; +{ + if (algorithm->z.handler == (B_TypeCheck *)NULL_PTR) + return (BE_ALGORITHM_NOT_SET); + + if (algorithm->z.handler->_Destructor != Destructor) + return (BE_ALG_OPERATION_UNKNOWN); + + return (0); +} + +int B_AlgorithmCheckTypeAndInitFlag (algorithm, Destructor) +B_Algorithm *algorithm; +B_TYPE_CHECK_DESTRUCTOR Destructor; +{ + int status; + + /* Check the type first. */ + if ((status = B_AlgorithmCheckType (algorithm, Destructor)) != 0) + return (status); + + if (!algorithm->z.initFlag) + return (BE_ALGORITHM_NOT_INITIALIZED); + + return (0); +} + +int B_AlgorithmSetInfo (algorithm, algorithmInfoType, info) +B_Algorithm *algorithm; +B_AlgorithmInfoType *algorithmInfoType; +POINTER info; +{ + int status; + + if (algorithm->infoCache.z.infoCount > 0) + return (BE_ALGORITHM_ALREADY_SET); + + /* This will cache the encoding. */ + if ((status = (*algorithmInfoType->vTable->AddInfo) + (algorithmInfoType, algorithm, info)) != 0) + return (status); + + /* Allocate the algorithm handler. NewHandler returns NULL_PTR for error. + */ + if ((algorithm->z.handler = (*algorithmInfoType->vTable->NewHandler) + (algorithmInfoType, algorithm)) == (B_TypeCheck *)NULL_PTR) + return (BE_ALLOC); + + return (0); +} + +int B_AlgorithmGetInfo (algorithm, info, algorithmInfoType) +B_Algorithm *algorithm; +POINTER *info; +B_AlgorithmInfoType *algorithmInfoType; +{ + int status; + + if (algorithm->infoCache.z.infoCount == 0) + return (BE_ALGORITHM_NOT_SET); + + /* First check if the encoding is already in the encoding cache. + */ + if (B_InfoCacheFindInfo + (&algorithm->infoCache, info, (POINTER)algorithmInfoType) == 0) + return (0); + + /* Info is not in the cache, go ahead and encode. + */ + if ((status = (*algorithmInfoType->vTable->MakeInfo) + (algorithmInfoType, info, algorithm)) != 0) + return (status); + + return (B_InfoCacheAddInfo + (&algorithm->infoCache, (POINTER)algorithmInfoType, *info)); +} + diff --git a/lib/dns/sec/dnssafe/balg.h b/lib/dns/sec/dnssafe/balg.h new file mode 100644 index 00000000..fdbc269b --- /dev/null +++ b/lib/dns/sec/dnssafe/balg.h @@ -0,0 +1,116 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _BALG_H_ +#define _BALG_H_ 1 + +#include "binfocsh.h" +#include "btypechk.h" + +typedef struct { + B_InfoCache infoCache; /* inherited */ + + struct { + B_TypeCheck *handler; + int initFlag; + /* POINTER reserved; */ + } z; +} B_Algorithm; + +void B_AlgorithmConstructor PROTO_LIST ((B_Algorithm *)); +void B_AlgorithmDestructor PROTO_LIST ((B_Algorithm *)); + +int B_AlgorithmCheckType PROTO_LIST ((B_Algorithm *, B_TYPE_CHECK_DESTRUCTOR)); +int B_AlgorithmCheckTypeAndInitFlag PROTO_LIST + ((B_Algorithm *, B_TYPE_CHECK_DESTRUCTOR)); + +struct B_AlgorithmInfoType; +int B_AlgorithmSetInfo PROTO_LIST + ((B_Algorithm *, struct B_AlgorithmInfoType *, POINTER)); +int B_AlgorithmGetInfo PROTO_LIST + ((B_Algorithm *, POINTER *, struct B_AlgorithmInfoType *)); + +int B_AlgorithmRandomInit PROTO_LIST + ((B_Algorithm *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int B_AlgorithmRandomUpdate PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int, A_SURRENDER_CTX *)); +int B_AlgorithmGenerateRandomBytes PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int, A_SURRENDER_CTX *)); + +int B_AlgorithmDigestInit PROTO_LIST + ((B_Algorithm *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int B_AlgorithmDigestUpdate PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int, A_SURRENDER_CTX *)); +int B_AlgorithmDigestFinal PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int, + A_SURRENDER_CTX *)); + +int B_AlgorithmEncryptInit PROTO_LIST + ((B_Algorithm *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int B_AlgorithmDecryptInit PROTO_LIST + ((B_Algorithm *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int B_AlgorithmEncryptUpdate PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int, B_Algorithm *, A_SURRENDER_CTX *)); +int B_AlgorithmDecryptUpdate PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int, B_Algorithm *, A_SURRENDER_CTX *)); +int B_AlgorithmEncryptFinal PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int, + B_Algorithm *, A_SURRENDER_CTX *)); +int B_AlgorithmDecryptFinal PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int, + B_Algorithm *, A_SURRENDER_CTX *)); + +int B_AlgorithmEncodeInit PROTO_LIST ((B_Algorithm *)); +int B_AlgorithmDecodeInit PROTO_LIST ((B_Algorithm *)); +int B_AlgorithmEncodeUpdate PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int)); +int B_AlgorithmDecodeUpdate PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int)); +int B_AlgorithmEncodeFinal PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int)); +int B_AlgorithmDecodeFinal PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int)); + +int B_AlgorithmSignInit PROTO_LIST + ((B_Algorithm *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int B_AlgorithmSignUpdate PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int, A_SURRENDER_CTX *)); +int B_AlgorithmSignFinal PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int, + B_Algorithm *, A_SURRENDER_CTX *)); + +int B_AlgorithmVerifyInit PROTO_LIST + ((B_Algorithm *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int B_AlgorithmVerifyUpdate PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int, A_SURRENDER_CTX *)); +int B_AlgorithmVerifyFinal PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int, B_Algorithm *, + A_SURRENDER_CTX *)); + +int B_AlgorithmKeyAgreeInit PROTO_LIST + ((B_Algorithm *, B_Key *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int B_AlgorithmKeyAgreePhase1 PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int, + B_Algorithm *, A_SURRENDER_CTX *)); +int B_AlgorithmKeyAgreePhase2 PROTO_LIST + ((B_Algorithm *, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int, A_SURRENDER_CTX *)); + +int B_AlgorithmGenerateInit PROTO_LIST + ((B_Algorithm *, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int B_AlgorithmGenerateKeypair PROTO_LIST + ((B_Algorithm *, B_Key *, B_Key *, B_Algorithm *, + A_SURRENDER_CTX *)); +int B_AlgorithmGenerateParameters PROTO_LIST + ((B_Algorithm *, B_Algorithm *, B_Algorithm *, A_SURRENDER_CTX *)); + +#endif diff --git a/lib/dns/sec/dnssafe/balgmeth.h b/lib/dns/sec/dnssafe/balgmeth.h new file mode 100644 index 00000000..c73e3ad4 --- /dev/null +++ b/lib/dns/sec/dnssafe/balgmeth.h @@ -0,0 +1,18 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +struct B_AlgorithmInfoType; +struct B_KeyInfoType; + +struct B_ALGORITHM_METHOD { + struct B_AlgorithmInfoType *algorithmInfoType; + int encryptFlag; + struct B_KeyInfoType *keyInfoType; + POINTER alga; +}; + diff --git a/lib/dns/sec/dnssafe/bgclrbit.c b/lib/dns/sec/dnssafe/bgclrbit.c new file mode 100644 index 00000000..36565f41 --- /dev/null +++ b/lib/dns/sec/dnssafe/bgclrbit.c @@ -0,0 +1,28 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* BigClrbit (a, v) -- clears v-th bit of a, where v is nonnegative. + */ +void BigClrbit (a, v) +UINT2 *a; +unsigned int v; +{ + a[v/16] &= ~ (1 << (v % 16)); +} + +/* BigSetbit (a, v) -- sets v-th bit of a, where v is nonnegative. + */ +void BigSetbit (a, v) +UINT2 *a; +unsigned int v; +{ + a[v/16] |= (1 << (v % 16)); +} diff --git a/lib/dns/sec/dnssafe/bgmdmpyx.c b/lib/dns/sec/dnssafe/bgmdmpyx.c new file mode 100644 index 00000000..83a0a761 --- /dev/null +++ b/lib/dns/sec/dnssafe/bgmdmpyx.c @@ -0,0 +1,26 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* BigModMpyx (a, b, c, d, dInv, n) -- a = (b * c) mod d !! EXPRESS. + -- assumes a, b, c, d of length n, dInv of length n+2. + -- assumes dInv previously computed by BigInv. + */ +void BigModMpyx (a, b, c, d, dInv, n) +UINT2 *a, *b, *c, *d, *dInv; +unsigned int n; +{ + UINT2 prod[2 * MAX_RSA_MODULUS_WORDS]; + + BigPmpy (prod, b, c, n); + BigModx (a, prod, d, dInv, n); + + T_memset ((POINTER)prod, 0, sizeof (prod)); +} diff --git a/lib/dns/sec/dnssafe/bgmdsqx.c b/lib/dns/sec/dnssafe/bgmdsqx.c new file mode 100644 index 00000000..e8f0e226 --- /dev/null +++ b/lib/dns/sec/dnssafe/bgmdsqx.c @@ -0,0 +1,24 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* BigModSqx (a, b, d, dInv, n) -- a = (b * b) mod d !! EXPRESS. + */ +void BigModSqx (a, b, d, dInv, n) +UINT2 *a, *b, *d, *dInv; +unsigned int n; +{ + UINT2 prod[2 * MAX_RSA_MODULUS_WORDS]; + + BigPsq (prod, b, n); + BigModx (a, prod, d, dInv, n); + + T_memset ((POINTER)prod, 0, sizeof (prod)); +} diff --git a/lib/dns/sec/dnssafe/bgmodexp.c b/lib/dns/sec/dnssafe/bgmodexp.c new file mode 100644 index 00000000..1f1a65f4 --- /dev/null +++ b/lib/dns/sec/dnssafe/bgmodexp.c @@ -0,0 +1,132 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" +#include "surrendr.h" + +/* BigModExp (a, b, c, d, n): a = b**c (mod d) + Assumes a, b, c, d of length n. + Returns 0, AE_CANCEL. + */ +int BigModExp (a, b, c, d, n, surrenderContext) +UINT2 *a, *b, *c, *d; +unsigned int n; +A_SURRENDER_CTX *surrenderContext; +{ + struct BigModExpFrame { + UINT2 dInv[MAX_RSA_MODULUS_WORDS + 2], result[MAX_RSA_MODULUS_WORDS], + tab[16][MAX_RSA_MODULUS_WORDS]; + } *frame = (struct BigModExpFrame *)NULL_PTR; +#if !USE_ALLOCED_FRAME + struct BigModExpFrame stackFrame; +#endif + int i, didAMultiply, status; + unsigned int cLen, w, setup[64], power, mask; + + /* Initialize. + */ + do { +#if USE_ALLOCED_FRAME + if ((frame = (struct BigModExpFrame *)T_malloc (sizeof (*frame))) + == (struct BigModExpFrame *)NULL_PTR) { + status = AE_ALLOC; + break; + } +#else + /* Just use the buffers allocated on the stack. */ + frame = &stackFrame; +#endif + + /* precompute inverse of d to enable express mod-outs */ + BigInv (frame->dInv, d, n); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + + /* precompute small (size 2**w) table of powers of b */ + cLen = BigLen (c, n); + if (cLen < 4) + w = 1; + else if (cLen < 16) + w = 2; + else if (cLen < 64) + w = 3; + else + w = 4; + + /* zeroth power is one */ + BigConst (frame->tab[0], 1, n); + + /* first power is b */ + BigCopy (frame->tab[1], b, n); + setup[0] = 1; + setup[1] = 1; + for (i = 2; i < 64; i++) + setup[i] = 0; + + /* Loop over elements of exponent c in appropriate radix. + */ + power = 0; + didAMultiply = 0; + mask = 1 << ((cLen) % 16); + for (i = cLen; i >= 0; i--) { + if (didAMultiply) { + BigModSqx (frame->result, frame->result, d, frame->dInv, n); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + } + + power = power << 1; + if (setup[power] == 0) { + BigModSqx (frame->tab[power], frame->tab[power/2], d, frame->dInv, n); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + setup[power] = 1; + } + if (c[i/16] & mask) + power = power + 1; + if (mask == 1) + mask = 0x8000; + else + mask = (mask >> 1) & 0x7FFF; + if (setup[power] == 0) { + BigModMpyx + (frame->tab[power], frame->tab[power-1], b, d, frame->dInv, n); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + setup[power] = 1; + } + if ((i == 0) || (power >= (unsigned int)(1 << (w-1)))) { + if (didAMultiply) { + BigModMpyx + (frame->result, frame->result, frame->tab[power], d, frame->dInv, + n); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + } + else + BigCopy (frame->result, frame->tab[power], n); + + power = 0; + didAMultiply = 1; + } + } + if (status) + break; + + BigCopy (a, frame->result, n); + } while (0); + + if (frame != (struct BigModExpFrame *)NULL_PTR) { + T_memset ((POINTER)frame, 0, sizeof (*frame)); +#if USE_ALLOCED_FRAME + T_free ((POINTER)frame); +#endif + } + return (status); +} diff --git a/lib/dns/sec/dnssafe/bgpegcd.c b/lib/dns/sec/dnssafe/bgpegcd.c new file mode 100644 index 00000000..2201b7e9 --- /dev/null +++ b/lib/dns/sec/dnssafe/bgpegcd.c @@ -0,0 +1,78 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* BigPegcd + input + u, v bignums + k int size of u, v regs + restriction u, v positive + output + u3=GCD (u, v) (pos) + u1=inv (u)modv (pos) + u2=inv (v)modu (pos) + if GCD (u, v)!=1 then u1, u2 st + u3=u * u1mod (v) & u3=v * u2mod (u) + (see KNUTH vol 2) + */ +void BigPegcd (u3, u1, u2, u, v, k) +UINT2 *u3, *u2, *u1, *u, *v; +unsigned int k; +{ + UINT2 v1[2 * MAX_RSA_PRIME_WORDS], v2[2 * MAX_RSA_PRIME_WORDS], + v3[2 * MAX_RSA_PRIME_WORDS], q[2 * MAX_RSA_PRIME_WORDS], + r[2 * MAX_RSA_PRIME_WORDS], t1[2 * MAX_RSA_PRIME_WORDS], + t2[2 * MAX_RSA_PRIME_WORDS], t3[2 * MAX_RSA_PRIME_WORDS]; + + BigConst (u1, 1, k); + BigConst (u2, 0, k); + BigCopy (u3, u, k); + BigConst (v1, 0, k); + BigConst (v2, 1, k); + BigCopy (v3, v, k); + + /* Begin calc. + */ + do { + if (BigSign (v3, k) == 0) + break; + BigPdiv (q, r, u3, v3, k, k); + BigPmpyl (t1, v1, q, k); + BigPmpyl (t2, v2, q, k); + BigPmpyl (t3, v3, q, k); + BigSub (t1, u1, t1, k); + BigSub (t2, u2, t2, k); + BigSub (t3, u3, t3, k); + + BigCopy (u1, v1, k); + BigCopy (u2, v2, k); + BigCopy (u3, v3, k); + BigCopy (v1, t1, k); + BigCopy (v2, t2, k); + BigCopy (v3, t3, k); + } while (1); + + if (BigSign (u1, k) == -1) + /* make positive */ + BigAdd (u1, u1, v, k); + + if (BigSign (u2, k) == -1) + /* make positive */ + BigAdd (u2, u2, u, k); + + T_memset ((POINTER)v1, 0, sizeof (v1)); + T_memset ((POINTER)v2, 0, sizeof (v2)); + T_memset ((POINTER)v3, 0, sizeof (v3)); + T_memset ((POINTER)q, 0, sizeof (q)); + T_memset ((POINTER)r, 0, sizeof (r)); + T_memset ((POINTER)t1, 0, sizeof (t1)); + T_memset ((POINTER)t2, 0, sizeof (t2)); + T_memset ((POINTER)t3, 0, sizeof (t3)); +} diff --git a/lib/dns/sec/dnssafe/big2exp.c b/lib/dns/sec/dnssafe/big2exp.c new file mode 100644 index 00000000..85026db2 --- /dev/null +++ b/lib/dns/sec/dnssafe/big2exp.c @@ -0,0 +1,25 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* Big2Exp (a, v, n) -- a = 2**v, where v is nonnegative int. + Sets a to be 2**v. + */ +void Big2Exp (a, v, n) +UINT2 *a; +unsigned v; +unsigned int n; +{ + register unsigned int i; + + for (i = 0; i < n; i++) + a[i] = 0; + a[v/16] = 1 << (v % 16); +} diff --git a/lib/dns/sec/dnssafe/bigabs.c b/lib/dns/sec/dnssafe/bigabs.c new file mode 100644 index 00000000..8b4bcb70 --- /dev/null +++ b/lib/dns/sec/dnssafe/bigabs.c @@ -0,0 +1,22 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* BigAbs (a, b, n) -- a = ABS (b). + */ +void BigAbs (a, b, n) +UINT2 *a, *b; +unsigned int n; +{ + if (BigSign (b, n) >= 0) + BigCopy (a, b, n); + else + BigNeg (a, b, n); +} diff --git a/lib/dns/sec/dnssafe/bigacc.c b/lib/dns/sec/dnssafe/bigacc.c new file mode 100644 index 00000000..c4f09749 --- /dev/null +++ b/lib/dns/sec/dnssafe/bigacc.c @@ -0,0 +1,34 @@ +/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* Returns carry: vector a = b * vector c. + */ +UINT2 BigAcc (a, b, c, n) +UINT2 *a; +unsigned int b; +UINT2 *c; +unsigned int n; +{ + UINT4 bTemp, result = (UINT4)0; + register unsigned int i; + + if (!b) + return (0); + + bTemp = b; + for (i = 0; i < n; i++) { + result += bTemp * ((UINT4) c[i]); + result += ((UINT4) a[i]); + a[i] = (UINT2) result; + result >>= 16; + } + return ((UINT2)result); +} diff --git a/lib/dns/sec/dnssafe/bigarith.c b/lib/dns/sec/dnssafe/bigarith.c new file mode 100644 index 00000000..64af71c6 --- /dev/null +++ b/lib/dns/sec/dnssafe/bigarith.c @@ -0,0 +1,138 @@ +/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +void BigZero (a, n) +UINT2 *a; +unsigned int n; +{ + register unsigned int i; + + for (i = 0; i < n; i++) + a[i] = 0; +} + +void BigAdd (a, b, c, n) +UINT2 *a, *b, *c; +unsigned int n; +{ + UINT4 result = (UINT4)0; + register unsigned int i; + + for (i = 0; i < n; i++) { + result += (UINT4) b[i]; + result += (UINT4) c[i]; + a[i] = (UINT2) result; + result >>= 16; + } +} + +void BigSub (a, b, c, n) +UINT2 *a, *b, *c; +unsigned int n; +{ + UINT4 result = (UINT4)1; /* carry bit for negation of c */ + register unsigned int i; + + for (i = 0; i < n; i++) { + result += (UINT4) b[i]; + result += (((UINT4) ~c[i]) & 0x0000FFFFL); + a[i] = (UINT2)result; + result >>= 16; + } +} + +void BigNeg (a, b, n) +UINT2 *a, *b; +unsigned int n; +{ + register unsigned int i; + unsigned int carry = 1; + + for (i = 0; i < n-1; i++) { + a[i] = ~b[i] + carry; + if (a[i]) + carry = 0; + } + + a[i] = ~b[i] + carry; +} + +void BigInc (a, n) +UINT2 *a; +unsigned int n; +{ + register unsigned int i; + unsigned int carry = 1; /* carry to start */ + + for (i = 0; i < n-1 && carry; i++) { + a[i]++; + if (a[i]) + carry = 0; + } + + if (carry) + a[i]++; +} + +void BigDec (a, n) +UINT2 *a; +unsigned int n; +{ + register unsigned int i; + unsigned int borrow = 1; /* borrow to start */ + + for (i = 0; i < n-1 && borrow; i++) { + a[i]--; + if (a[i] != 0xFFFF) + borrow = 0; + } + + if (borrow) + a[i]--; +} + +int BigSign (a, n) +UINT2 *a; +unsigned int n; +{ + register int i; + + if (a[n-1] & 0x8000) + return (-1); + for (i = n-1; i >= 0; i--) + if (a[i]) + return (1); + return (0); +} + +void BigCopy (a, b, n) +UINT2 *a, *b; +unsigned int n; +{ + register unsigned int i; + + for (i = 0; i < n; i++) + a[i] = b[i]; +} + +/* Assumes a is nonnegative. + */ +unsigned int BigLenw (a, n) +UINT2 *a; +unsigned int n; +{ + register int i; + + for (i = n-1; i >= 0; i--) + if (a[i]) + return (i+1); + return (0); +} diff --git a/lib/dns/sec/dnssafe/bigcmp.c b/lib/dns/sec/dnssafe/bigcmp.c new file mode 100644 index 00000000..953be154 --- /dev/null +++ b/lib/dns/sec/dnssafe/bigcmp.c @@ -0,0 +1,34 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* Comparison operator. + BigCmp (a, b, n) -- returns sign of a-b. + */ +int BigCmp (a, b, n) +UINT2 *a, *b; +unsigned int n; +{ + register int i; + int aSign = BigSign (a, n), bSign = BigSign (b, n); + + if (aSign > bSign) + return (1); + if (aSign < bSign) + return (-1); + + for (i = n-1; i >= 0 && a[i] == b[i]; i--); + + if (i == -1) + return (0); + if (a[i] > b[i]) + return (1); + return (-1); +} diff --git a/lib/dns/sec/dnssafe/bigconst.c b/lib/dns/sec/dnssafe/bigconst.c new file mode 100644 index 00000000..6bc50009 --- /dev/null +++ b/lib/dns/sec/dnssafe/bigconst.c @@ -0,0 +1,26 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* BigConst (a, v, n) -- a = v, where v is an int. Initialize bignum a to + value v. + */ +void BigConst (a, v, n) +UINT2 *a; +unsigned int v; +unsigned int n; +{ + UINT2 signWord = (((UINT2)v & 0x8000) ? ~0 : 0); + register unsigned int i; + + a[0] = (UINT2)v; + for (i = 1; i < n; i++) + a[i] = signWord; +} diff --git a/lib/dns/sec/dnssafe/biginv.c b/lib/dns/sec/dnssafe/biginv.c new file mode 100644 index 00000000..7c69fd9f --- /dev/null +++ b/lib/dns/sec/dnssafe/biginv.c @@ -0,0 +1,103 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +static unsigned int Log2 PROTO_LIST ((unsigned int)); + +/* BigInv (a, b, n) -- compute a as an "inverse" to b, suitable for + modding out integers which are < b**2. + -- assumes a has n+2 words, b has n words. + -- assumes b is a positive integer. + */ +void BigInv (a, b, n) +UINT2 *a, *b; +unsigned int n; +{ + UINT2 p[2 * (MAX_RSA_MODULUS_WORDS + 2)], + q[2 * (MAX_RSA_MODULUS_WORDS + 3)], t1[MAX_RSA_MODULUS_WORDS + 3]; + register int i; + unsigned int bl, u, uw, sw; + + /* Do initializations. + */ + /* 2** (bl-1) <= b < 2 ** bl */ + bl = BigLen (b, n); + u = BigU (2 * bl); + + /* uw and sw are in words */ + uw = u/16; + sw = (bl - 2) / 16; + + /* since a = floor ((2**u)/b), 2**(u-bl) < a <= 2**(u-bl+1) */ + + /* Initialize a to 1+2**(u-bl) -- we will converge from below. + */ + Big2Exp (a, u - bl, n + 2); + BigInc (a, n + 2); + + /* Copy b to local register. + */ + BigZero (t1, n + 3); + BigCopy (t1, b, n); + + /* Convergence is quadratic, so iterate log (len (a)) times. + */ + for (i = 1 + Log2 (u - bl + 1); i > 0; i--) { + /* use fast squaring routine to compute p = a**2 + 2**(2 * (u-bl)) < p <= 2**(2 * (u-bl+1)) */ + BigPsq (p, a, n + 2); + + /* compute q = b * floor (p/ (2**s)) + 2**(2 * (u-bl)-s+bl-1) <= q <= 2**(2 * (u-bl+1)-s+bl + 2**(2 * u-bl-s-1) <= q <= 2**(2 * u-bl-s+2) */ + BigPmpy (q, t1, &p[sw], n + 3); + + /* double a + 2**(u-bl+1) < a <= 2**(u-bl+2) */ + BigAdd (a, a, a, n + 2); + /* a = a - floor (q/(2**(u-s))) + 2**(u-bl) < a <= 2**(u-bl+1) + epsilon */ + BigSub (a, a, &q[uw-sw], n + 2); + } + + /* now we are guaranteed that a is not too small */ + BigInc (a, n + 2); + + do { + BigPmpy (p, a, t1, n + 2); + /* makes comparison to 2**u easier */ + BigDec (p, 2 * (n + 2)); + + /* a is desired result */ + if (BigLen (p, 2 * (n + 2)) <= u) + break; + + /* a was too big, reduce and try again */ + BigDec (a, n + 2); + } while (1); + + T_memset ((POINTER)p, 0, sizeof (p)); + T_memset ((POINTER)q, 0, sizeof (q)); + T_memset ((POINTER)t1, 0, sizeof (t1)); +} + +/* Log2 (x) -- ceiling of log base 2 of x > 0. Auxiliary function. + */ +static unsigned int Log2 (x) +unsigned int x; +{ + unsigned int i; + + x = x - 1; + /* now Log2 is equal to len in bits of x */ + for (i = 0; x > 0; i++, x >>= 1); + + return (i); +} diff --git a/lib/dns/sec/dnssafe/biglen.c b/lib/dns/sec/dnssafe/biglen.c new file mode 100644 index 00000000..6b5acb9a --- /dev/null +++ b/lib/dns/sec/dnssafe/biglen.c @@ -0,0 +1,28 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +unsigned int BigLen (a, n) +UINT2 *a; +unsigned int n; +{ + UINT2 signWord = ((a[n-1] & 0x8000) ? ~0 : 0); + int i, j; + unsigned int k; + + for (i = n-1; i >= 0 && a[i] == signWord; i--); + if (i == -1) + return (1); /* len of 0 or -1 */ + + for (j = 16, k = 0x8000; + j >= 0 && 0 == (k & (signWord ^ a[i])); + j--, k >>= 1); + return (16 * i + j); +} diff --git a/lib/dns/sec/dnssafe/bigmath.h b/lib/dns/sec/dnssafe/bigmath.h new file mode 100644 index 00000000..351b55b2 --- /dev/null +++ b/lib/dns/sec/dnssafe/bigmath.h @@ -0,0 +1,71 @@ +/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _BIGMATH_H_ +#define _BIGMATH_H_ 1 + +#include "algae.h" +#include "bigmaxes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void Big2Exp PROTO_LIST ((UINT2 *, unsigned int, unsigned int)); +void BigAbs PROTO_LIST ((UINT2 *, UINT2 *, unsigned int)); +UINT2 BigAcc PROTO_LIST ((UINT2 *, unsigned int, UINT2 *, unsigned int)); +void BigZero PROTO_LIST ((UINT2 *, unsigned int)); +void BigAdd PROTO_LIST ((UINT2 *, UINT2 *, UINT2 *, unsigned int)); +void BigSub PROTO_LIST ((UINT2 *, UINT2 *, UINT2 *, unsigned int)); +void BigNeg PROTO_LIST ((UINT2 *, UINT2 *, unsigned int)); +void BigInc PROTO_LIST ((UINT2 *, unsigned int)); +void BigDec PROTO_LIST ((UINT2 *, unsigned int)); +int BigSign PROTO_LIST ((UINT2 *, unsigned int)); +void BigCopy PROTO_LIST ((UINT2 *, UINT2 *, unsigned int)); +unsigned int BigLenw PROTO_LIST ((UINT2 *, unsigned int)); +void BigClrbit PROTO_LIST ((UINT2 *, unsigned int)); +void BigSetbit PROTO_LIST ((UINT2 *, unsigned int)); +int BigCmp PROTO_LIST ((UINT2 *, UINT2 *, unsigned int)); +void BigConst PROTO_LIST ((UINT2 *, unsigned int, unsigned int)); +void BigInv PROTO_LIST ((UINT2 *, UINT2 *, unsigned int)); +unsigned int BigLen PROTO_LIST ((UINT2 *, unsigned int)); +void BigModMpyx PROTO_LIST + ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int)); +void BigModSqx PROTO_LIST + ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int)); +int BigModExp PROTO_LIST + ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int, A_SURRENDER_CTX *)); +void BigModx PROTO_LIST + ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int)); +void BigMpy PROTO_LIST ((UINT2 *, UINT2 *, UINT2 *, unsigned int)); +void BigPdiv PROTO_LIST + ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int , unsigned int)); +void BigPegcd PROTO_LIST + ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int)); +void BigPmpy PROTO_LIST ((UINT2 *, UINT2 *, UINT2 *, unsigned int)); +void BigPmpyh PROTO_LIST + ((UINT2 *, UINT2 *, UINT2 *, unsigned int, unsigned int)); +void BigPmpyl PROTO_LIST ((UINT2 *, UINT2 *, UINT2 *, unsigned int)); +void BigPsq PROTO_LIST ((UINT2 *, UINT2 *, unsigned int)); +void BigQrx PROTO_LIST + ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, unsigned int)); +UINT2 BigSmod PROTO_LIST ((UINT2 *, unsigned int, unsigned int)); +int BigToCanonical PROTO_LIST + ((unsigned char *, unsigned int, UINT2 *, unsigned int)); +unsigned int BigU PROTO_LIST ((unsigned int)); +int BigUnexp PROTO_LIST + ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, + unsigned int, A_SURRENDER_CTX *)); +int CanonicalToBig PROTO_LIST + ((UINT2 *, unsigned int, unsigned char *, unsigned int)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/dnssafe/bigmaxes.h b/lib/dns/sec/dnssafe/bigmaxes.h new file mode 100644 index 00000000..49992f67 --- /dev/null +++ b/lib/dns/sec/dnssafe/bigmaxes.h @@ -0,0 +1,47 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _BIGMAXES_H_ +#define _BIGMAXES_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_RSA_MODULUS_BITS 1024 + +#define BITS_TO_LEN(modulusBits) (((modulusBits) + 7) / 8) +#define RSA_PRIME_BITS(modulusBits) (((modulusBits) + 1) / 2) +#define RSA_PRIME_LEN(modulusBits) ((RSA_PRIME_BITS (modulusBits) + 7) / 8) +#define BITS_TO_WORDS(bits) ((bits >> 4) + 1) +#define LEN_TO_WORDS(len) ((len >> 1) + 1) + +/* MAX_RSA_PRIME_BITS -- length in bits of the maximum allowed RSA prime + MAX_RSA_MODULUS_LEN -- length in bytes of the maximum allowed RSA modulus, + in canonical format (no sign bit) + MAX_RSA_PRIME_LEN -- length in bytes of the maximum allowed RSA prime, in + canonical format (no sign bit) + */ +#define MAX_RSA_PRIME_BITS RSA_PRIME_BITS (MAX_RSA_MODULUS_BITS) +#define MAX_RSA_PRIME_LEN RSA_PRIME_LEN (MAX_RSA_MODULUS_BITS) +#define MAX_RSA_MODULUS_LEN BITS_TO_LEN (MAX_RSA_MODULUS_BITS) + +/* MAX_RSA_MODULUS_WORDS -- length in 16-bit words of the maximum allowed RSA + modulus, in bignum format (including sign bit) + MAX_RSA_PRIME_WORDS -- length in 16-bit words of the maximum allowed RSA + prime, in bignum format (including sign bit) + */ + +#define MAX_RSA_MODULUS_WORDS BITS_TO_WORDS (MAX_RSA_MODULUS_BITS) +#define MAX_RSA_PRIME_WORDS BITS_TO_WORDS (MAX_RSA_PRIME_BITS) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/dnssafe/bigmodx.c b/lib/dns/sec/dnssafe/bigmodx.c new file mode 100644 index 00000000..3559962a --- /dev/null +++ b/lib/dns/sec/dnssafe/bigmodx.c @@ -0,0 +1,25 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* BigModx (a, b, c, cInv, n) -- compute a as (b mod c). + -- assumes a and c of length n, cInv of length n + 2, b of length 2n. + -- assumes cInv computed with BigInv, and that b < c**2. + */ +void BigModx (a, b, c, cInv, n) +UINT2 *a, *b, *c, *cInv; +unsigned int n; +{ + UINT2 q[MAX_RSA_MODULUS_WORDS]; + + BigQrx (q, a, b, c, cInv, n); + + T_memset ((POINTER)q, 0, sizeof (q)); +} diff --git a/lib/dns/sec/dnssafe/bigmpy.c b/lib/dns/sec/dnssafe/bigmpy.c new file mode 100644 index 00000000..9a17b06a --- /dev/null +++ b/lib/dns/sec/dnssafe/bigmpy.c @@ -0,0 +1,36 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* BigMpy (a, b, c, n) -- a = b * c + -- assumes b and c have n words, a has 2*n words + -- inputs may be positive or negative. + */ +void BigMpy (a, b, c, n) +UINT2 *a, *b, *c; +unsigned int n; +{ + UINT2 prod[2 * MAX_RSA_PRIME_WORDS], absb[MAX_RSA_PRIME_WORDS], + absc[MAX_RSA_PRIME_WORDS]; + int bSign = BigSign (b, n), cSign = BigSign (c, n); + + BigAbs (absb, b, n); + BigAbs (absc, c, n); + BigPmpy (prod, absb, absc, n); + + if (bSign * cSign >= 0) + BigCopy (a, prod, 2 * n); + else + BigNeg (a, prod, 2 * n); + + T_memset ((POINTER)prod, 0, sizeof (prod)); + T_memset ((POINTER)absb, 0, sizeof (absb)); + T_memset ((POINTER)absc, 0, sizeof (absc)); +} diff --git a/lib/dns/sec/dnssafe/bigpdiv.c b/lib/dns/sec/dnssafe/bigpdiv.c new file mode 100644 index 00000000..23c3f8bc --- /dev/null +++ b/lib/dns/sec/dnssafe/bigpdiv.c @@ -0,0 +1,159 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* BigPdiv POSITIVE DIVIDE + uu=vv * qi+ri + uu in reg of ll cells + vv in reg of kk cells + qi assumed to be ll cells + ri assumed to be kk cells + restriction uu>=0, vv>0 + + input uu in reg of ll cells + input vv in reg of kk cells + output qi assumed to be ll cells + output ri assumed to be kk cells + restriction uu>=0, vv>0 + uu=vv * qi+ri + */ +#define UJN (u[(j+n)/2] & mk[(j+n)%2]) +#define VN (v[n/2] & mk[n%2]) +#define UT (u[t/2] & mk[t%2]) +void BigPdiv (qi, ri, uu, vv, ll, kk) +UINT2 *qi, *ri, *uu, *vv; +unsigned int ll, kk; +{ + UINT2 u[2 * MAX_RSA_PRIME_WORDS + 2], us[2 * MAX_RSA_PRIME_WORDS + 2], + v[2 * MAX_RSA_PRIME_WORDS + 2], vs[2 * MAX_RSA_PRIME_WORDS + 2], + q[2 * MAX_RSA_PRIME_WORDS + 2], r[2 * MAX_RSA_PRIME_WORDS + 2], + t1[2 * MAX_RSA_PRIME_WORDS + 2], t2[2 * MAX_RSA_PRIME_WORDS + 2], + t3[2 * MAX_RSA_PRIME_WORDS + 2], mk[2]; + int j, l, n, m, t, x; + unsigned int a, b, c, d, e, vh, qq; + + if (ll >= kk) + l = ll + 2; + else + l = kk + 2; + + mk[0] = 0x00FF; + mk[1] = 0xFF00; + b = 0x0100; + + BigConst (u, 0, l); + BigConst (v, 0, l); + BigCopy (u, uu, ll); + BigCopy (us, u, l); + BigCopy (v, vv, kk); + BigCopy (vs, v, l); + + /* zero q */ + BigConst (q, 0, l); + + /* Calculate len of v=n. + */ + for (n = (2 * l) - 1; n >= 0; n--) { + if (VN == 0) + continue; + break; + } + + /* Normalize. + */ + a = VN; + if (n % 2 == 1) + a = a >> 8; + d = b / (a+1); + BigConst (t1, d, l); + BigPmpyl (t2, t1, v, l); + BigCopy (v, t2, l); + + /* vh=high order digit of normalized v */ + vh = VN; + if (n % 2 == 1) + vh = vh >> 8; + BigPmpyl (t2, t1, u, l); + BigCopy (u, t2, l); + + /* Calculate len of u=t. + */ + for (t = (2 * l)-1; t >= 0; t--) { + if (UT == 0) + continue; + break; + } + + /* calc t = n + m */ + m = t - n; + + /* Divide u by v. + */ + for (j = m + 1 + n; j > n; j--) { + if (j % 2 == 1) + c = u[j / 2]; + else { + a = u[j/2]; + a = a << 8; + e = u[(j - 1) / 2]; + e = e >> 8; + c = a + e; + } + a = c >> 8; + if (vh == a) + qq = b - 1; + else + qq = c / vh; + + BigConst (t1, qq, l); + BigPmpyl (t2, v, t1, l); + Big2Exp (t3, (j - 1 - n) * 8, l); + BigPmpyl (t1, t3, t2, l); + BigSub (t2, u, t1, l); + + /* Adjust q. + */ + for (x = 0; ; qq --, x ++) { + if (BigSign (t2, l) != -1) + break; + BigPmpyl (t1, t3, v, l); + BigAdd (t2, t2, t1, l); + } + + BigCopy (u, t2, l); + BigConst (t3, qq, l); + Big2Exp (t2, 8, l); + BigPmpyl (t1, q, t2, l); + BigAdd (q, t3, t1, l); + } + + /* Check result. + */ + + BigPmpyl (t1, vs, q, l); + /* t2 has remainder */ + BigSub (t2, us, t1, l); + + BigSub (t3, vs, t2, l); + + /* transfer results to input registers */ + BigCopy (qi, q, ll); + BigCopy (ri, t2, kk); + + T_memset ((POINTER)u, 0, sizeof (u)); + T_memset ((POINTER)us, 0, sizeof (us)); + T_memset ((POINTER)v, 0, sizeof (v)); + T_memset ((POINTER)vs, 0, sizeof (vs)); + T_memset ((POINTER)q, 0, sizeof (q)); + T_memset ((POINTER)r, 0, sizeof (r)); + T_memset ((POINTER)t1, 0, sizeof (t1)); + T_memset ((POINTER)t2, 0, sizeof (t2)); + T_memset ((POINTER)t3, 0, sizeof (t3)); +} diff --git a/lib/dns/sec/dnssafe/bigpmpy.c b/lib/dns/sec/dnssafe/bigpmpy.c new file mode 100644 index 00000000..8ef3b4cd --- /dev/null +++ b/lib/dns/sec/dnssafe/bigpmpy.c @@ -0,0 +1,25 @@ +/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* a = b * c. + */ +void BigPmpy (a, b, c, n) +UINT2 *a, *b, *c; +unsigned int n; +{ + register unsigned int i; + unsigned int cLen; + + BigZero (a, 2*n); + cLen = BigLenw (c, n); + for (i = 0; i < n; i++) + a[cLen+i] = BigAcc (&a[i], (unsigned int)b[i], c, cLen); +} diff --git a/lib/dns/sec/dnssafe/bigpmpyh.c b/lib/dns/sec/dnssafe/bigpmpyh.c new file mode 100644 index 00000000..20bb7312 --- /dev/null +++ b/lib/dns/sec/dnssafe/bigpmpyh.c @@ -0,0 +1,30 @@ +/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* Returns high order t bytes of result. + */ +void BigPmpyh (a, b, c, t, n) +UINT2 *a, *b, *c; +unsigned int t, n; +{ + register unsigned int i; + unsigned int iStart, cLen, j; + + BigZero (a, 2*n); + cLen = BigLenw (c, n); + iStart = (t >= n-1) ? t - (n-1) : 0; + + for (i = iStart; i < n; i++) { + j = (t >= i) ? t - i : 0; + a[cLen+i] = BigAcc + (&a[i+j], (unsigned int)b[i], &c[j], (cLen >= j) ? cLen-j : 0); + } +} diff --git a/lib/dns/sec/dnssafe/bigpmpyl.c b/lib/dns/sec/dnssafe/bigpmpyl.c new file mode 100644 index 00000000..a05dfc20 --- /dev/null +++ b/lib/dns/sec/dnssafe/bigpmpyl.c @@ -0,0 +1,30 @@ +/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* Single precision multiply, a is same len as b and c. + Returns low order n bytes of result. + */ +void BigPmpyl (a, b, c, n) +UINT2 *a, *b, *c; +unsigned int n; +{ + register unsigned int i; + unsigned int cLen; + + BigZero (a, n); + cLen = BigLenw (c, n); + for (i = 0; i < n; i++) { + if (cLen < n-i) + a[cLen+i] = BigAcc (&a[i], (unsigned int)b[i], c, cLen); + else + BigAcc (&a[i], (unsigned int)b[i], c, n-i); + } +} diff --git a/lib/dns/sec/dnssafe/bigpsq.c b/lib/dns/sec/dnssafe/bigpsq.c new file mode 100644 index 00000000..87de1ab2 --- /dev/null +++ b/lib/dns/sec/dnssafe/bigpsq.c @@ -0,0 +1,42 @@ +/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* Similar to BigPmpy (a, b, b, n) but faster. + */ +void BigPsq (a, b, n) +UINT2 *a, *b; +unsigned int n; +{ + UINT4 result = (UINT4)0; + register unsigned int i; + unsigned int bLen; + + BigZero (a, 2*n); + bLen = BigLenw (b, n); + if (!bLen) + return; + + for (i = 0; i < bLen-1; i++) + a[bLen+i] = BigAcc (&a[2*i+1], (unsigned int)b[i], &b[i+1], bLen-i-1); + BigAdd (a, a, a, 2*n); + + /* add in trace b[i] * b[i] */ + for (i = 0; i < bLen; i++) { + result += ((UINT4)b[i]) * ((UINT4)b[i]); + result += (UINT4)a[2*i]; + a[2*i] = (UINT2)result; + result >>= 16; + result += (UINT4)a[2*i+1]; + a[2*i+1] = (UINT2)result; + result >>= 16; + } + a[2*i] = (UINT2)result; +} diff --git a/lib/dns/sec/dnssafe/bigqrx.c b/lib/dns/sec/dnssafe/bigqrx.c new file mode 100644 index 00000000..5bce01e8 --- /dev/null +++ b/lib/dns/sec/dnssafe/bigqrx.c @@ -0,0 +1,85 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + + +/* BigQrx (q, r, b, c, cInv, n) -- compute quotient and remainder fast. + -- computes q and r s.t. b = q * c + r with 0 <= r < c. + -- assumes b and c are positive integers. + -- assumes q, r, c have n words, cInv has n+2 words, b has 2*n words. + -- assumes cInv previously computed with BigInv. + */ +void BigQrx (q, r, b, c, cInv, n) +UINT2 *q, *r, *b, *c, *cInv; +unsigned int n; +{ + UINT2 qc[2 * (MAX_RSA_MODULUS_WORDS + 2)], /* current product of q and c */ + qsc[2 * (MAX_RSA_MODULUS_WORDS + 2)], /* temporary q scaled by 2**(u-s) */ + t1[2 * MAX_RSA_MODULUS_WORDS + 2]; + int uwsw3; + register unsigned int i; + unsigned int u, uw, cl, sw; + + /* 2**(cl-1) <= c < 2**cl + 2**(u-cl) <= cInv <= 2**(u-cl+1) */ + cl = BigLen (c, n); + + /* u is in bits, uw is in words */ + u = BigU (2 * cl); + uw = u/16; + + /* sw is in words, s is is bits */ + sw = (cl - 2) / 16; + + uwsw3 = uw - sw - 3; + + if (uwsw3 < 0) + uwsw3 = 0; + + /* Copy b to local register. + */ + BigZero (t1, 2 * n + 2); + BigCopy (t1, b, 2 * n); + + /* Compute qsc = cInv * floor (b/ (2**s)). + qsc an approximation to (b/c) * (2**(u-s)) + 2**((u-cl)+ (bl-1-s)) <= qsc 2**((u-cl+1)+ (bl-s)) + 2**(u-cl+bl-s-1) <= qsc <= 2 ** (u-cl+bl-s+1) + (Actually, we only compute a "high-order" approximation + to qsc, by using BigPmpyh.) + */ + BigPmpyh (qsc, cInv, &t1[sw], uwsw3, n + 2); + + /* Divide by 2**(u-s) to get initial estimate for quotient q + 2**(bl-cl-1) <= q <= 2**(bl-cl+1) (unless q = 0). + */ + for (i = 0; i < n; i++) + q[i] = qsc[i+ (uw - sw)]; + + /* compute qc = low-order part of q * c + 2 ** (bl - 2) <= qc <= 2 ** (bl + 1) */ + BigPmpyl (qc, q, c, n); + + /* subtract qc from b to get initial estimate for remainder r */ + BigSub (r, b, qc, n); + + /* Adjust to be exactly right by repeated subtraction. + */ + while (BigCmp (r, c, n) >= 0) { + BigSub (r, r, c, n); + BigInc (q, n); + } + + T_memset ((POINTER)qc, 0, sizeof (qc)); + T_memset ((POINTER)qsc, 0, sizeof (qsc)); + T_memset ((POINTER)t1, 0, sizeof (t1)); +} + + diff --git a/lib/dns/sec/dnssafe/bigsmod.c b/lib/dns/sec/dnssafe/bigsmod.c new file mode 100644 index 00000000..b4ae68eb --- /dev/null +++ b/lib/dns/sec/dnssafe/bigsmod.c @@ -0,0 +1,28 @@ +/* Copyright (C) RSA Data Security, Inc. created 1987, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +UINT2 BigSmod (a, v, n) +UINT2 *a; +unsigned int v; +unsigned int n; +{ + UINT4 r = (UINT4)0; + register int i; + unsigned int scale; + + scale = (unsigned int)((UINT4)65536 % (UINT4)v); + + for (i = n-1; i >= 0; i--) { + r = (r*scale) + (UINT4)a[i]; + r = r % (UINT4)v; + } + return ((UINT2)r); +} diff --git a/lib/dns/sec/dnssafe/bigtocan.c b/lib/dns/sec/dnssafe/bigtocan.c new file mode 100644 index 00000000..13e8315d --- /dev/null +++ b/lib/dns/sec/dnssafe/bigtocan.c @@ -0,0 +1,60 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "bigmath.h" + + +/* BigToCanonical () copies a word vector to a byte vector while REVERSING the + order of significance. The word vector is input LSWord first and the + byte vector is written out MSByte first. It also removes a leading zero + sign bit. (The byte vector must represent a nonnegative number.) + Returns 0, AE_DATA. + */ +int BigToCanonical (bytePointer, numBytes, wordPointer, wordCount) +unsigned char *bytePointer; +unsigned int numBytes; +UINT2 *wordPointer; +unsigned int wordCount; +{ + unsigned int copyCount; + + if (BigSign (wordPointer, wordCount) < 0 || + (BigLen (wordPointer, wordCount) + 7) / 8 > numBytes) + return (AE_DATA); + + /* start at end of byte vector */ + bytePointer += numBytes-1; + + /* copy as much as possible */ + copyCount = (wordCount < numBytes / 2) ? wordCount : numBytes / 2; + wordCount -= copyCount; + numBytes -= 2 * copyCount; + while (copyCount--) { + /* Copy two bytes.*/ + *bytePointer-- = (unsigned char)*wordPointer; + *bytePointer-- = (unsigned char)(*wordPointer >> 8); + wordPointer++; + } + + if (wordCount && numBytes & 1) { + /* The number of output bytes was odd. Copy one last byte */ + *bytePointer-- = (unsigned char)*wordPointer++; + wordCount--; + numBytes--; + } + + /* zero fill remainder of byte vector */ + while (numBytes--) + *bytePointer-- = 0; + + return (0); +} + + diff --git a/lib/dns/sec/dnssafe/bigu.c b/lib/dns/sec/dnssafe/bigu.c new file mode 100644 index 00000000..34c592a5 --- /dev/null +++ b/lib/dns/sec/dnssafe/bigu.c @@ -0,0 +1,21 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" + +/* BigU (t) -- returns length u where floor (2**u/b) is used as scaled version + of (1/b) when modding out modulo b, and where (positive) integers to be + reduced are < 2**t; i.e. they are at most t bits in length. + Result is (t+1) rounded up if necessary to next multiple of 16. +*/ +unsigned int BigU (t) +unsigned int t; +{ + return (16 * (((t+1) + 15)/16)); +} diff --git a/lib/dns/sec/dnssafe/bigunexp.c b/lib/dns/sec/dnssafe/bigunexp.c new file mode 100644 index 00000000..6bedbf51 --- /dev/null +++ b/lib/dns/sec/dnssafe/bigunexp.c @@ -0,0 +1,98 @@ +/* Copyright (C) RSA Data Security, Inc. created 1986, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bigmath.h" +#include "surrendr.h" + +/* BigUnexp - decrypt ciphertext c into message m using Chinese remainder. + Assumes m, c of length 2*pSize, pp, qq, dp, dq and cr of length pSize. + Returns 0, AE_CANCEL. + */ +int BigUnexp (m, c, pp, qq, dp, dq, cr, pSize, surrenderContext) +UINT2 *m; /* output message size 2*pSize words */ +UINT2 *c; /* input `ciphertext' size 2*pSize */ +UINT2 *pp; /* first prime size pSize */ +UINT2 *qq; /* second prime; size pSize */ +UINT2 *dp; /* decryption exponent mod p size pSize */ +UINT2 *dq; /* decryption exponent mod q size pSize */ +UINT2 *cr; /* CRT coef (inverse of q mod p) cr has len pSize */ +unsigned int pSize; /* length of p in words */ +A_SURRENDER_CTX *surrenderContext; +{ + struct BigUnexpFrame { + UINT2 t1[2 * MAX_RSA_PRIME_WORDS], t2[2 * MAX_RSA_PRIME_WORDS], + t3[2 * MAX_RSA_PRIME_WORDS], u1[2 * MAX_RSA_PRIME_WORDS], + u2[2 * MAX_RSA_PRIME_WORDS], u3[2 * MAX_RSA_PRIME_WORDS]; + } *frame = (struct BigUnexpFrame *)NULL_PTR; +#if !USE_ALLOCED_FRAME + struct BigUnexpFrame stackFrame; +#endif + int status; + + do { +#if USE_ALLOCED_FRAME + if ((frame = (struct BigUnexpFrame *)T_malloc (sizeof (*frame))) + == (struct BigUnexpFrame *)NULL_PTR) { + status = AE_ALLOC; + break; + } +#else + /* Just use the buffers allocated on the stack. */ + frame = &stackFrame; +#endif + + BigConst (frame->t1, 0, 2 * pSize); + BigConst (frame->t2, 0, 2 * pSize); + + /* u2=c mod p */ + BigPdiv (frame->u1, frame->u2, c, pp, 2 * pSize, pSize); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + + /* t1=c**dp modP */ + if ((status = BigModExp + (frame->t1, frame->u2, dp, pp, pSize, surrenderContext)) != 0) + break; + + /* u3=CmodQ */ + BigPdiv (frame->u2, frame->u3, c, qq, 2 * pSize, pSize); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + + /* t2=c**DQmodQ */ + if ((status = BigModExp + (frame->t2, frame->u3, dq, qq, pSize, surrenderContext)) != 0) + break; + + /* CRT. + */ + BigSub (frame->u1, frame->t1, frame->t2, pSize); + + while (-1 == BigSign (frame->u1, pSize)) + BigAdd (frame->u1, frame->u1, pp, pSize); + + BigMpy (frame->u2, frame->u1, cr, pSize); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + BigPdiv (frame->u3, frame->u1, frame->u2, pp, 2 * pSize, pSize); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + BigMpy (m, frame->u1, qq, pSize); + + BigAdd (m, m, frame->t2, 2 * pSize); + } while (0); + + if (frame != (struct BigUnexpFrame *)NULL_PTR) { + T_memset ((POINTER)frame, 0, sizeof (*frame)); +#if USE_ALLOCED_FRAME + T_free ((POINTER)frame); +#endif + } + return (status); +} diff --git a/lib/dns/sec/dnssafe/binfocsh.c b/lib/dns/sec/dnssafe/binfocsh.c new file mode 100644 index 00000000..f5c458e3 --- /dev/null +++ b/lib/dns/sec/dnssafe/binfocsh.c @@ -0,0 +1,63 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "binfocsh.h" + +void B_InfoCacheConstructor (infoCache) +B_InfoCache *infoCache; +{ + /* Construct immediate base class. */ + B_MemoryPoolConstructor (&infoCache->memoryPool); + + T_memset ((POINTER)&infoCache->z, 0, sizeof (infoCache->z)); +} + +/* Returns 0, BE_ALLOC. + */ +int B_InfoCacheAddInfo (infoCache, infoType, info) +B_InfoCache *infoCache; +POINTER infoType; +POINTER info; +{ + int status; + + if ((status = B_MemoryPoolRealloc + (&infoCache->memoryPool, (POINTER *)&infoCache->z.infos, + (infoCache->z.infoCount + 1) * sizeof (infoCache->z.infos[0]))) != 0) + return (status); + + infoCache->z.infos[infoCache->z.infoCount].infoType = infoType; + infoCache->z.infos[infoCache->z.infoCount].info = info; + infoCache->z.infoCount++; + + return (0); +} + +/* Set info to the entry in the cache for the given infoType. + Returns 0, or BE_NOT_SUPPORTED if infoType is not in the cache. + */ +int B_InfoCacheFindInfo (infoCache, info, infoType) +B_InfoCache *infoCache; +POINTER *info; +POINTER infoType; +{ + unsigned int i; + + for (i = 0; i < infoCache->z.infoCount; ++i) { + if (infoCache->z.infos[i].infoType == infoType) { + /* The info has already been constructed. */ + *info = infoCache->z.infos[i].info; + return (0); + } + } + + return (BE_NOT_SUPPORTED); +} + diff --git a/lib/dns/sec/dnssafe/binfocsh.h b/lib/dns/sec/dnssafe/binfocsh.h new file mode 100644 index 00000000..32778765 --- /dev/null +++ b/lib/dns/sec/dnssafe/binfocsh.h @@ -0,0 +1,33 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _BINFOCSH_H_ +#define _BINFOCSH_H_ 1 + +#include "bmempool.h" + +typedef struct B_InfoCache { + B_MemoryPool memoryPool; /* inherited */ + struct { + unsigned int infoCount; + struct { + POINTER infoType; + POINTER info; + } *infos; + /* POINTER reserved; */ + } z; /* z gives the members that are zeroized by the constructor */ +} B_InfoCache; + +void B_InfoCacheConstructor PROTO_LIST ((B_InfoCache *)); +#define B_INFO_CACHE_Destructor(infoCache) \ + B_MemoryPoolDestructor (&(infoCache)->memoryPool) + +int B_InfoCacheAddInfo PROTO_LIST ((B_InfoCache *, POINTER, POINTER)); +int B_InfoCacheFindInfo PROTO_LIST ((B_InfoCache *, POINTER *, POINTER)); + +#endif diff --git a/lib/dns/sec/dnssafe/bkey.c b/lib/dns/sec/dnssafe/bkey.c new file mode 100644 index 00000000..ddd23460 --- /dev/null +++ b/lib/dns/sec/dnssafe/bkey.c @@ -0,0 +1,101 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "kinfotyp.h" +#include "kiitem.h" + +int B_KeySetInfo (key, keyInfoType, info) +B_Key *key; +B_KeyInfoType *keyInfoType; +POINTER info; +{ + if (key == (B_Key *)NULL_PTR) + return (BE_KEY_OBJ); + + if (key->infoCache.z.infoCount > 0) + return (BE_KEY_ALREADY_SET); + + /* This will cache the encoding. */ + return ((*keyInfoType->AddInfo) (key, info)); +} + +int B_KeyGetInfo (key, info, keyInfoType) +B_Key *key; +POINTER *info; +B_KeyInfoType *keyInfoType; +{ + int status; + + if (key == (B_Key *)NULL_PTR) + return (BE_KEY_OBJ); + + if (key->infoCache.z.infoCount == 0) + return (BE_KEY_NOT_SET); + + /* First check if the encoding is already in the encoding cache. + */ + if (B_InfoCacheFindInfo (&key->infoCache, info, (POINTER)keyInfoType) == 0) + return (0); + + /* Info is not in the cache, go ahead and encode. + */ + if ((status = (*keyInfoType->MakeInfo) (info, key)) != 0) + return (status); + + return (B_InfoCacheAddInfo (&key->infoCache, (POINTER)keyInfoType, *info)); +} + +/* Create an ITEM out of the data and len and cache it as KITItem. + The data is already alloced in the info cache. + Returns 0, BE_ALLOC. + */ +int B_KeyAddItemInfo (key, data, len) +B_Key *key; +unsigned char *data; +unsigned int len; +{ + ITEM *newInfo; + int status; + + if ((status = B_MemoryPoolAlloc + (&key->infoCache.memoryPool, (POINTER *)&newInfo, sizeof (*newInfo))) + != 0) + return (status); + + newInfo->data = data; + newInfo->len = len; + + return (B_InfoCacheAddInfo + (&key->infoCache, (POINTER)&KITItem, (POINTER)newInfo)); +} + +/* Return the number of bits in the canonical, positive integer. + B_IntegerBits (0) = 0. + */ +unsigned int B_IntegerBits (integer, integerLen) +unsigned char *integer; +unsigned int integerLen; +{ + unsigned char mask, byte; + unsigned int bytes, bits; + + for (bytes = 0; bytes < integerLen && integer[bytes] == 0; bytes++); + if (bytes == integerLen) + return (0); + + /* Get byte to test and increment byte count for final calculation */ + byte = integer[bytes++]; + + /* Get number of bits in most significant byte */ + for (bits = 8, mask = 0x80; (byte & mask) == 0; bits--, mask >>= 1); + return (8 * (integerLen - bytes) + bits); +} + diff --git a/lib/dns/sec/dnssafe/bkey.h b/lib/dns/sec/dnssafe/bkey.h new file mode 100644 index 00000000..bfcaca7a --- /dev/null +++ b/lib/dns/sec/dnssafe/bkey.h @@ -0,0 +1,32 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _BKEY_H_ +#define _BKEY_H_ 1 + +#include "binfocsh.h" + +typedef struct { + B_InfoCache infoCache; /* inherited */ + + /* For now we don't need to worry about a reserved field. + struct { + POINTER reserved; + } z; + */ +} B_Key; + +#define B_KEY_Constructor(key) (B_InfoCacheConstructor (&(key)->infoCache)) +#define B_KEY_Destructor(key) (B_INFO_CACHE_Destructor (&(key)->infoCache)) + +struct B_KeyInfoType; +int B_KeySetInfo PROTO_LIST ((B_Key *, struct B_KeyInfoType *, POINTER)); +int B_KeyGetInfo PROTO_LIST ((B_Key *, POINTER *, struct B_KeyInfoType *)); +int B_KeyAddItemInfo PROTO_LIST ((B_Key *, unsigned char *, unsigned int)); + +#endif diff --git a/lib/dns/sec/dnssafe/bmempool.c b/lib/dns/sec/dnssafe/bmempool.c new file mode 100644 index 00000000..37510a46 --- /dev/null +++ b/lib/dns/sec/dnssafe/bmempool.c @@ -0,0 +1,275 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bmempool.h" + +#define ALLOCED_LIST_SLACK 10 + +void B_MemoryPoolConstructor (memoryPool) +B_MemoryPool *memoryPool; +{ + T_memset ((POINTER)&memoryPool->z, 0, sizeof (memoryPool->z)); +} + +void B_MemoryPoolDestructor (memoryPool) +B_MemoryPool *memoryPool; +{ + B_MemoryPoolReset (memoryPool); + T_free ((POINTER)memoryPool->z.allocedList); +} + +/* For each item on the alloced list, call the DeleteFuncion if + there is one, otherwise zerioze and free. + Leave the list itself allocated with all NULL entries. + */ +void B_MemoryPoolReset (memoryPool) +B_MemoryPool *memoryPool; +{ + B_ALLOCED_DATA *allocedData; + unsigned int i; + + for (i = memoryPool->z.allocedCount, + allocedData = memoryPool->z.allocedList; + i-- > 0; + ++allocedData) { + /* Only process this entry if the data is not NULL_PTR. + */ + if (allocedData->object != NULL_PTR) { + if (allocedData->DeleteFunction != + (B_MEMORY_POOL_DELETE_FUNCTION)NULL_PTR) + /* There is a destroy function, so call. */ + (*allocedData->DeleteFunction) (allocedData->object); + else { + T_memset (allocedData->object, 0, allocedData->size); + T_free (allocedData->object); + } + allocedData->object = NULL_PTR; + } + } + + memoryPool->z.allocedCount = 0; + /* Note that maxAllocedCount still indicates the size of the alloced list. */ +} + +/* On any error return, NULL_PTR is returned for the data. + Returns 0 if successful, or BE_ALLOC if cannot alloc the memory. + */ +int B_MemoryPoolAlloc (memoryPool, data, size) +B_MemoryPool *memoryPool; +POINTER *data; +unsigned int size; +{ + if ((*data = T_malloc (size)) == NULL_PTR) + return (BE_ALLOC); + return (B_MemoryPoolAdoptData (memoryPool, data, size)); +} + +/* Use alloc to allocate the newData of length size and T_memcpy data into it. + On any error return, NULL_PTR is returned for the newData. + Returns 0 if successful or BE_ALLOC if cannot alloc the memory. + */ +int B_MemoryPoolAllocAndCopy (memoryPool, newData, data, size) +B_MemoryPool *memoryPool; +POINTER *newData; +POINTER data; +unsigned int size; +{ + int status; + + if ((status = B_MemoryPoolAlloc (memoryPool, newData, size)) != 0) + return (status); + + T_memcpy (*newData, data, size); + return (0); +} + +/* Put the given data on the memory pool's alloced list. + The size of the alloced data buffer must be passed in so that it can + be zeroized when the object is reset (Pass in a size of zero if + the buffer does not need to be zeroized.) + The data is passed by reference, so that if there is an error, + the data is zeroized and freed, and the pointer to the data is set + to NULL_PTR. + This routine should be used with caution - it is meant be called + immediately after an alloc. + No check is made as to whether the data is already on the memory pool's + alloced list (which would be a problem since it will get freed twice). + Returns 0 if successful or BE_ALLOC if cannot expand the alloced list. + */ +int B_MemoryPoolAdoptData (memoryPool, data, size) +B_MemoryPool *memoryPool; +POINTER *data; +unsigned int size; +{ + int status; + + if ((status = B_MemoryPoolAdoptHelper + (memoryPool, *data, size, (B_MEMORY_POOL_DELETE_FUNCTION)NULL_PTR)) + != 0) { + T_memset (*data, 0, size); + T_free (*data); + *data = NULL_PTR; + return (status); + } + + return (0); +} + +/* Put the given object on the memory pool's alloced list. + The size of the alloced object must be passed in so that it can + be zeroized when the object is reset (Pass in a size of zero if + the buffer does not need to be zeroized, especially if it + is an object and not a data buffer.) + The object is not passed by reference. If there is an error, + the calling routine should clean up the object, such as zeroizing + and freeing. + No check is made as to whether the object is already on the memory pool's + alloced list (which would be a problem since it will get freed twice). + Returns 0 if successful or BE_ALLOC if cannot expand the alloced list. + */ +int B_MemoryPoolAdoptHelper (memoryPool, object, size, DeleteFunction) +B_MemoryPool *memoryPool; +POINTER object; +unsigned int size; +B_MEMORY_POOL_DELETE_FUNCTION DeleteFunction; +{ + POINTER newList; + unsigned int newMaxCount; + + if (memoryPool->z.allocedCount + 1 > memoryPool->z.maxAllocedCount) { + /* Make extra room on the alloced list. + */ + newMaxCount = memoryPool->z.allocedCount + ALLOCED_LIST_SLACK; + if ((newList = T_malloc (newMaxCount * sizeof (B_ALLOCED_DATA))) + == NULL_PTR) + /* alloc errorm so caller should clean up the object it passed. */ + return (BE_ALLOC); + + /* move in new list and free old list */ + T_memcpy + (newList, (POINTER)memoryPool->z.allocedList, + memoryPool->z.allocedCount * sizeof (B_ALLOCED_DATA)); + T_free ((POINTER)memoryPool->z.allocedList); + memoryPool->z.allocedList = (B_ALLOCED_DATA *)newList; + memoryPool->z.maxAllocedCount = newMaxCount; + } + + /* Put object on alloced list and increment count. + */ + memoryPool->z.allocedList[memoryPool->z.allocedCount].object = object; + memoryPool->z.allocedList[memoryPool->z.allocedCount].size = size; + memoryPool->z.allocedList[memoryPool->z.allocedCount++].DeleteFunction = + DeleteFunction; + return (0); +} + +/* 'data' points to the pointer to realloc and also is used to + return the realloced memory. + If data points to NULL_PTR, behaves like B_MemoryPoolAlloc. + Find 'data' on the allocedList and realloc it to the given size, + replacing the entry on the alloced list with the new memory. + If it is not on the allocedList, the adopt the reallocated memory. + If the buffer must be moved during the realloc, the old buffer is not + zeroized (unless T_realloc does the zeroizing). + This assumes that the (POINTER *)data is not (POINTER *)NULL_PTR. + This assumes there is no DesroyFunction for this entry. That is, + you should not try to resize an object. + On any error return, NULL_PTR is returned for the data. + Returns 0 if successful or BE_ALLOC if cannot alloc the memory. + */ +int B_MemoryPoolRealloc (memoryPool, data, size) +B_MemoryPool *memoryPool; +POINTER *data; +unsigned int size; +{ + B_ALLOCED_DATA *allocedData; + + allocedData = B_MemoryPoolFindAllocedObject (memoryPool, *data); + + if ((*data = T_realloc (*data, size)) == NULL_PTR) { + if (allocedData != (B_ALLOCED_DATA *)NULL_PTR) + /* Could not reallocate, so nullify this entry. */ + allocedData->object = NULL_PTR; + + return (BE_ALLOC); + } + + /* Realloc was successful. + */ + if (allocedData == (B_ALLOCED_DATA *)NULL_PTR) + /* The data was not in the memory pool to start with, so adopt it. + Note that this also happens when the data is initially NULL_PTR. */ + return (B_MemoryPoolAdoptData (memoryPool, data, size)); + + /* Replace the entry on the alloced list with the new memory. + */ + allocedData->object = *data; + allocedData->size = size; + return (0); +} + +/* Find the object in the alloced list, call the DeleteFunction if + there is one, zeroize it and free it, nullifying that alloced list entry. + The object to be freed is passed by pointer and is set to NULL_PTR to + enforce the fact that the address no longer points to valid memory. + This assumes that the (POINTER *)data is not (POINTER *)NULL_PTR. + If the address is not found on the alloced list, only set the address + to NULL_PTR. + */ +void B_MemoryPoolFree (memoryPool, object) +B_MemoryPool *memoryPool; +POINTER *object; +{ + B_ALLOCED_DATA *allocedData; + + if ((allocedData = B_MemoryPoolFindAllocedObject (memoryPool, *object)) + != (B_ALLOCED_DATA *)NULL_PTR) { + if (allocedData->DeleteFunction != + (B_MEMORY_POOL_DELETE_FUNCTION)NULL_PTR) + /* There is a destroy function, so call. */ + (*allocedData->DeleteFunction) (allocedData->object); + else { + T_memset (*object, 0, allocedData->size); + T_free (*object); + } + + /* Set this entry to NULL_PTR so that reset will not process it. */ + allocedData->object = NULL_PTR; + } + + *object = NULL_PTR; +} + +/* Return a pointer to the alloced object entry in the memoryPool. + Return (ALLOCED_DATA *)NULL_PTR if object is NULL_PTR or object is not + in the memoryPool. + */ +B_ALLOCED_DATA *B_MemoryPoolFindAllocedObject (memoryPool, object) +B_MemoryPool *memoryPool; +POINTER object; +{ + B_ALLOCED_DATA *allocedData; + unsigned int i; + + if (object == NULL_PTR) + return ((B_ALLOCED_DATA *)NULL_PTR); + + for (i = memoryPool->z.allocedCount, + allocedData = memoryPool->z.allocedList; + i-- > 0; + ++allocedData) { + if (allocedData->object == object) + return (allocedData); + } + + /* data not found. */ + return ((B_ALLOCED_DATA *)NULL_PTR); +} + diff --git a/lib/dns/sec/dnssafe/bmempool.h b/lib/dns/sec/dnssafe/bmempool.h new file mode 100644 index 00000000..b5216dd2 --- /dev/null +++ b/lib/dns/sec/dnssafe/bmempool.h @@ -0,0 +1,53 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _BMEMPOOL_H_ +#define _BMEMPOOL_H_ 1 + +typedef void (*B_MEMORY_POOL_DELETE_FUNCTION) PROTO_LIST ((POINTER)); + +typedef struct { + POINTER object; + unsigned int size; + B_MEMORY_POOL_DELETE_FUNCTION DeleteFunction; +} B_ALLOCED_DATA; + +typedef struct { + struct { + unsigned int allocedCount; + unsigned int maxAllocedCount; /* Size of the actuall allocated list */ + B_ALLOCED_DATA *allocedList; + /* POINTER reserved; */ + } z; /* z gives the members that are zeroized by the constructor */ +} B_MemoryPool; + +void B_MemoryPoolConstructor PROTO_LIST ((B_MemoryPool *)); +void B_MemoryPoolDestructor PROTO_LIST ((B_MemoryPool *)); + +void B_MemoryPoolReset PROTO_LIST ((B_MemoryPool *)); +int B_MemoryPoolAlloc PROTO_LIST ((B_MemoryPool *, POINTER *, unsigned int)); +int B_MemoryPoolAllocAndCopy PROTO_LIST + ((B_MemoryPool *, POINTER *, POINTER, unsigned int)); +int B_MemoryPoolAdoptData PROTO_LIST + ((B_MemoryPool *, POINTER *, unsigned int)); +int B_MemoryPoolAdoptObject PROTO_LIST + ((B_MemoryPool *, POINTER *, B_MEMORY_POOL_DELETE_FUNCTION)); +int B_MemoryPoolRealloc PROTO_LIST ((B_MemoryPool *, POINTER *, unsigned int)); +int B_MemoryPoolSafeRealloc PROTO_LIST + ((B_MemoryPool *, POINTER *, unsigned int)); +void B_MemoryPoolFree PROTO_LIST ((B_MemoryPool *, POINTER *)); +void B_MemoryPoolResetExceptObject PROTO_LIST ((B_MemoryPool *, POINTER)); + +/* These are "private member functions ". + */ +B_ALLOCED_DATA *B_MemoryPoolFindAllocedObject PROTO_LIST + ((B_MemoryPool *, POINTER)); +int B_MemoryPoolAdoptHelper PROTO_LIST + ((B_MemoryPool *, POINTER, unsigned int, B_MEMORY_POOL_DELETE_FUNCTION)); + +#endif diff --git a/lib/dns/sec/dnssafe/bsafe2.h b/lib/dns/sec/dnssafe/bsafe2.h new file mode 100644 index 00000000..4eb4ef55 --- /dev/null +++ b/lib/dns/sec/dnssafe/bsafe2.h @@ -0,0 +1,194 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _BSAFE_H_ +#define _BSAFE_H_ 1 + +#ifndef T_CALL +#define T_CALL +#endif + +#include "atypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BE_ALGORITHM_ALREADY_SET 0x0200 +#define BE_ALGORITHM_INFO 0x0201 +#define BE_ALGORITHM_NOT_INITIALIZED 0x0202 +#define BE_ALGORITHM_NOT_SET 0x0203 +#define BE_ALGORITHM_OBJ 0x0204 +#define BE_ALG_OPERATION_UNKNOWN 0x0205 +#define BE_ALLOC 0x0206 +#define BE_CANCEL 0x0207 +#define BE_DATA 0x0208 +#define BE_EXPONENT_EVEN 0x0209 +#define BE_EXPONENT_LEN 0x020a +#define BE_HARDWARE 0x020b +#define BE_INPUT_DATA 0x020c +#define BE_INPUT_LEN 0x020d +#define BE_KEY_ALREADY_SET 0x020e +#define BE_KEY_INFO 0x020f +#define BE_KEY_LEN 0x0210 +#define BE_KEY_NOT_SET 0x0211 +#define BE_KEY_OBJ 0x0212 +#define BE_KEY_OPERATION_UNKNOWN 0x0213 +#define BE_MEMORY_OBJ 0x0214 +#define BE_MODULUS_LEN 0x0215 +#define BE_NOT_INITIALIZED 0x0216 +#define BE_NOT_SUPPORTED 0x0217 +#define BE_OUTPUT_LEN 0x0218 +#define BE_OVER_32K 0x0219 +#define BE_RANDOM_NOT_INITIALIZED 0x021a +#define BE_RANDOM_OBJ 0x021b +#define BE_SIGNATURE 0x021c +#define BE_WRONG_ALGORITHM_INFO 0x021d +#define BE_WRONG_KEY_INFO 0x021e +#define BE_INPUT_COUNT 0x021f +#define BE_OUTPUT_COUNT 0x0220 +#define BE_METHOD_NOT_IN_CHOOSER 0x221 + +typedef POINTER B_KEY_OBJ; +typedef POINTER B_ALGORITHM_OBJ; + +typedef int (T_CALL *B_INFO_TYPE) PROTO_LIST ((POINTER *)); + +typedef struct B_ALGORITHM_METHOD B_ALGORITHM_METHOD; +typedef B_ALGORITHM_METHOD **B_ALGORITHM_CHOOSER; + +/* Routines supplied by the implementor. + */ +void T_CALL T_memset PROTO_LIST ((POINTER, int, unsigned int)); +void T_CALL T_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); +void T_CALL T_memmove PROTO_LIST ((POINTER, POINTER, unsigned int)); +int T_CALL T_memcmp PROTO_LIST ((POINTER, POINTER, unsigned int)); +POINTER T_CALL T_malloc PROTO_LIST ((unsigned int)); +POINTER T_CALL T_realloc PROTO_LIST ((POINTER, unsigned int)); +void T_CALL T_free PROTO_LIST ((POINTER)); + +/* The key object. + */ +int T_CALL B_CreateKeyObject PROTO_LIST ((B_KEY_OBJ *)); +void T_CALL B_DestroyKeyObject PROTO_LIST ((B_KEY_OBJ *)); +int T_CALL B_SetKeyInfo PROTO_LIST ((B_KEY_OBJ, B_INFO_TYPE, POINTER)); +int T_CALL B_GetKeyInfo PROTO_LIST ((POINTER *, B_KEY_OBJ, B_INFO_TYPE)); + +/* The algorithm object. + */ +int T_CALL B_CreateAlgorithmObject PROTO_LIST ((B_ALGORITHM_OBJ *)); +void T_CALL B_DestroyAlgorithmObject PROTO_LIST ((B_ALGORITHM_OBJ *)); +int T_CALL B_SetAlgorithmInfo PROTO_LIST + ((B_ALGORITHM_OBJ, B_INFO_TYPE, POINTER)); +int T_CALL B_GetAlgorithmInfo PROTO_LIST + ((POINTER *, B_ALGORITHM_OBJ, B_INFO_TYPE)); + +unsigned int B_IntegerBits PROTO_LIST ((unsigned char *, unsigned int)); + +/* Algorithm operations. + */ +int T_CALL B_RandomInit PROTO_LIST + ((B_ALGORITHM_OBJ, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int T_CALL B_RandomUpdate PROTO_LIST + ((B_ALGORITHM_OBJ, unsigned char *, unsigned int, A_SURRENDER_CTX *)); +int T_CALL B_GenerateRandomBytes PROTO_LIST + ((B_ALGORITHM_OBJ, unsigned char *, unsigned int, A_SURRENDER_CTX *)); + +int T_CALL B_DigestInit PROTO_LIST + ((B_ALGORITHM_OBJ, B_KEY_OBJ, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int T_CALL B_DigestUpdate PROTO_LIST + ((B_ALGORITHM_OBJ, unsigned char *, unsigned int, A_SURRENDER_CTX *)); +int T_CALL B_DigestFinal PROTO_LIST + ((B_ALGORITHM_OBJ, unsigned char *, unsigned int *, unsigned int, + A_SURRENDER_CTX *)); + +int T_CALL B_EncryptInit PROTO_LIST + ((B_ALGORITHM_OBJ, B_KEY_OBJ, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int T_CALL B_EncryptUpdate PROTO_LIST + ((B_ALGORITHM_OBJ, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int, B_ALGORITHM_OBJ, A_SURRENDER_CTX *)); +int T_CALL B_EncryptFinal PROTO_LIST + ((B_ALGORITHM_OBJ, unsigned char *, unsigned int *, unsigned int, + B_ALGORITHM_OBJ, A_SURRENDER_CTX *)); + +int T_CALL B_DecryptInit PROTO_LIST + ((B_ALGORITHM_OBJ, B_KEY_OBJ, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int T_CALL B_DecryptUpdate PROTO_LIST + ((B_ALGORITHM_OBJ, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int, B_ALGORITHM_OBJ, A_SURRENDER_CTX *)); +int T_CALL B_DecryptFinal PROTO_LIST + ((B_ALGORITHM_OBJ, unsigned char *, unsigned int *, unsigned int, + B_ALGORITHM_OBJ, A_SURRENDER_CTX *)); + + + +int T_CALL B_GenerateInit PROTO_LIST + ((B_ALGORITHM_OBJ, B_ALGORITHM_CHOOSER, A_SURRENDER_CTX *)); +int T_CALL B_GenerateKeypair PROTO_LIST + ((B_ALGORITHM_OBJ, B_KEY_OBJ, B_KEY_OBJ, B_ALGORITHM_OBJ, + A_SURRENDER_CTX *)); +int T_CALL B_GenerateParameters PROTO_LIST + ((B_ALGORITHM_OBJ, B_ALGORITHM_OBJ, B_ALGORITHM_OBJ, A_SURRENDER_CTX *)); + + +/* Information for password-based encryption (PBE) algorithms. + */ +typedef struct { + unsigned char *salt; /* salt value */ + unsigned int iterationCount; /* iteration count */ +} B_PBE_PARAMS; + +/* Information for MAC algorithm. + */ +typedef struct { + unsigned int macLen; /* length of MAC value */ +} B_MAC_PARAMS; + + +/* Information for BSAFE 1.x compatible encryption algorithms. + */ + + +typedef struct { + unsigned int threshold; /* share threshold */ +} B_SECRET_SHARING_PARAMS; + +/* Key Info Types. + */ +int T_CALL KI_8Byte PROTO_LIST ((POINTER *)); +int T_CALL KI_Item PROTO_LIST ((POINTER *)); +int T_CALL KI_PKCS_RSAPrivate PROTO_LIST ((POINTER *)); +int T_CALL KI_RSAPublic PROTO_LIST ((POINTER *)); +int T_CALL KI_RSA_CRT PROTO_LIST ((POINTER *)); + +/* Algorithm Info Types. + */ +int T_CALL AI_MD5 PROTO_LIST ((POINTER *)); +int T_CALL AI_MD5Random PROTO_LIST ((POINTER *)); +int T_CALL AI_PKCS_RSAPrivate PROTO_LIST ((POINTER *)); +int T_CALL AI_PKCS_RSAPublic PROTO_LIST ((POINTER *)); +int T_CALL AI_RSAKeyGen PROTO_LIST ((POINTER *)); +int T_CALL AI_RSAPrivate PROTO_LIST ((POINTER *)); +int T_CALL AI_RSAPublic PROTO_LIST ((POINTER *)); + + +/* Algorithm methods for use int the algorithm chooser. + */ +extern B_ALGORITHM_METHOD T_CALL AM_MD5; +extern B_ALGORITHM_METHOD T_CALL AM_MD5_RANDOM; +extern B_ALGORITHM_METHOD T_CALL AM_RSA_CRT_DECRYPT; +extern B_ALGORITHM_METHOD T_CALL AM_RSA_CRT_ENCRYPT; +extern B_ALGORITHM_METHOD T_CALL AM_RSA_DECRYPT; +extern B_ALGORITHM_METHOD T_CALL AM_RSA_ENCRYPT; +extern B_ALGORITHM_METHOD T_CALL AM_RSA_KEY_GEN; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/dnssafe/btypechk.h b/lib/dns/sec/dnssafe/btypechk.h new file mode 100644 index 00000000..93f5a97b --- /dev/null +++ b/lib/dns/sec/dnssafe/btypechk.h @@ -0,0 +1,25 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _BTYPECHK_H_ +#define _BTYPECHK_H_ 1 + +struct B_TypeCheck; + +typedef void (*B_TYPE_CHECK_DESTRUCTOR) PROTO_LIST ((struct B_TypeCheck *)); + +typedef struct B_TypeCheck { + B_TYPE_CHECK_DESTRUCTOR _Destructor; +} B_TypeCheck; + +#define B_TYPE_CHECK_Constructor(typeCheck, Destructor)\ + (typeCheck)->_Destructor = (Destructor) +#define B_TYPE_CHECK_Destructor(typeCheck)\ + (*(typeCheck)->_Destructor) (typeCheck) + +#endif diff --git a/lib/dns/sec/dnssafe/cantobig.c b/lib/dns/sec/dnssafe/cantobig.c new file mode 100644 index 00000000..79b760f7 --- /dev/null +++ b/lib/dns/sec/dnssafe/cantobig.c @@ -0,0 +1,57 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "bigmath.h" + +/* CanonicalToBig () copies a byte vector into a word vector while REVERSING + the order of significance. The byte vector is input MSByte first while + the word vector is written out LSWord first. It also adds a leading zero + sign bit if necessary. + Returns 0, AE_DATA. + */ +int CanonicalToBig (wordPointer, wordCount, bytePointer, numBytes) +UINT2 *wordPointer; +unsigned int wordCount; +unsigned char *bytePointer; +unsigned int numBytes; +{ + unsigned int copyCount; + + if (A_IntegerBits (bytePointer, numBytes) / 16 + 1 > wordCount) + return (AE_DATA); + + /* start at end of byte vector */ + bytePointer += numBytes-1; + + /* copy as much as possible */ + copyCount = (wordCount < numBytes / 2) ? wordCount : numBytes / 2; + wordCount -= copyCount; + numBytes -= 2 * copyCount; + while (copyCount--) { + /* Copy two bytes.*/ + *wordPointer++ = (UINT2)*bytePointer + (*(bytePointer - 1) << 8); + bytePointer -= 2; + } + + if (wordCount && numBytes & 1) { + /* If the number of input bytes was odd. Copy one last byte.*/ + *wordPointer++ = (UINT2)*bytePointer--; + wordCount--; + numBytes--; + } + + /* zero fill remainder of word vector */ + while (wordCount--) + *wordPointer++ = 0; + + return (0); +} + + diff --git a/lib/dns/sec/dnssafe/crt2.c b/lib/dns/sec/dnssafe/crt2.c new file mode 100644 index 00000000..36b9d01f --- /dev/null +++ b/lib/dns/sec/dnssafe/crt2.c @@ -0,0 +1,228 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "crt2.h" +#include "bigmath.h" + +/* RSA encryption/decryption with Chinese Remainder Theorem. + */ + +#define GENERATE_BREAK(type) { \ + status = type; \ + break; \ + } + +static int RSA_CRT2 PROTO_LIST + ((A_RSA_CRT2_CTX *, unsigned char *, unsigned int *, unsigned int, + unsigned char *, A_SURRENDER_CTX *)); + +int A_RSA_CRT2Init (context, key) +A_RSA_CRT2_CTX *context; +A_RSA_CRT_KEY *key; +{ + if (A_IntegerBits (key->modulus.data, key->modulus.len) + > MAX_RSA_MODULUS_BITS) + /* Key len is too big to handle. */ + return (AE_MODULUS_LEN); + + /* Set the block update blockLen to be big enough to hold the modulus. + */ + context->blockLen = + BITS_TO_LEN (A_IntegerBits (key->modulus.data, key->modulus.len)); + + context->inputLen = 0; + + /* convert first prime to bignum format */ + if (CanonicalToBig + (context->primeP, MAX_RSA_PRIME_WORDS, key->prime[0].data, + key->prime[0].len)) + return (AE_KEY_INFO); + + /* compute significant length of first prime */ + context->primeWords = BITS_TO_WORDS + (BigLen (context->primeP, MAX_RSA_PRIME_WORDS)); + + /* convert other private key parameters to bignum format */ + if (CanonicalToBig + (context->primeQ, context->primeWords, key->prime[1].data, + key->prime[1].len) || + CanonicalToBig + (context->exponentP, context->primeWords, + key->primeExponent[0].data, key->primeExponent[0].len) || + CanonicalToBig + (context->exponentQ, context->primeWords, + key->primeExponent[1].data, key->primeExponent[1].len) || + CanonicalToBig + (context->coefficient, context->primeWords, + key->coefficient.data, key->coefficient.len)) + return (AE_KEY_INFO); + + /* convert modulus to bignum format */ + if (CanonicalToBig + (context->modulus, 2 * context->primeWords, + key->modulus.data, key->modulus.len)) + return (AE_KEY_INFO); + + return (0); +} + +int A_RSA_CRT2Update + (context, partOut, partOutLen, maxPartOutLen, partIn, partInLen, + surrenderContext) +A_RSA_CRT2_CTX *context; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +unsigned char *partIn; +unsigned int partInLen; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + unsigned int partialLen, localPartOutLen; + + /* Initialize partOutLen to zero. */ + *partOutLen = 0; + + if (context->inputLen + partInLen < context->blockLen) { + /* Not enough to encrypt - just accumulate. + */ + T_memcpy + ((POINTER)(context->input + context->inputLen), (POINTER)partIn, + partInLen); + context->inputLen += partInLen; + return (0); + } + + if (context->inputLen > 0) { + /* Need to accumulate the rest of the block bytes into the input and + encrypt from there (otherwise it's OK to encrypt straight from + the partIn). + */ + partialLen = context->blockLen - context->inputLen; + T_memcpy + ((POINTER)(context->input + context->inputLen), (POINTER)partIn, + partialLen); + partIn += partialLen; + partInLen -= partialLen; + + if ((status = RSA_CRT2 + (context, partOut, &localPartOutLen, maxPartOutLen, context->input, + surrenderContext)) != 0) + return (status); + (*partOutLen) += localPartOutLen; + partOut += localPartOutLen; + maxPartOutLen -= localPartOutLen; + } + + /* Encrypt as many blocks of input as provided. + */ + while (partInLen >= context->blockLen) { + if ((status = RSA_CRT2 + (context, partOut, &localPartOutLen, maxPartOutLen, partIn, + surrenderContext)) != 0) + return (status); + + partIn += context->blockLen; + partInLen -= context->blockLen; + (*partOutLen) += localPartOutLen; + partOut += localPartOutLen; + maxPartOutLen -= localPartOutLen; + } + + /* Copy remaining input bytes to the context's input buffer. + */ + T_memcpy + ((POINTER)context->input, partIn, partInLen); + context->inputLen = partInLen; + return (0); +} + +int A_RSA_CRT2Final (context) +A_RSA_CRT2_CTX *context; +{ + if (context->inputLen != 0) + return (AE_INPUT_LEN); + + /* Restart context to accumulate a new block. + */ + context->inputLen = 0; + return (0); +} + +/* Assume input length is context->blockLen. + */ +static int RSA_CRT2 + (context, output, outputLen, maxOutputLen, input, surrenderContext) +A_RSA_CRT2_CTX *context; +unsigned char *output; +unsigned int *outputLen; +unsigned int maxOutputLen; +unsigned char *input; +A_SURRENDER_CTX *surrenderContext; +{ + struct ModExpCRTFrame { + UINT2 bigInBuf[2 * MAX_RSA_PRIME_WORDS], + bigOutBuf[2 * MAX_RSA_PRIME_WORDS]; + } *frame = (struct ModExpCRTFrame *)NULL_PTR; +#if !USE_ALLOCED_FRAME + struct ModExpCRTFrame stackFrame; +#endif + int status; + + status = 0; + do { + if ((*outputLen = context->blockLen) > maxOutputLen) + return (AE_OUTPUT_LEN); + +#if USE_ALLOCED_FRAME + if ((frame = (struct ModExpCRTFrame *)T_malloc (sizeof (*frame))) + == (struct ModExpCRTFrame *)NULL_PTR) { + status = AE_ALLOC; + break; + } +#else + /* Just use the buffers allocated on the stack. */ + frame = &stackFrame; +#endif + + /* Convert input to bignum representation. + This won't return AE_DATA since input length was checked at Update. + */ + CanonicalToBig + (frame->bigInBuf, 2 * context->primeWords, input, context->blockLen); + + /* Check for overflow. */ + if (BigCmp + (frame->bigInBuf, context->modulus, 2 * context->primeWords) >= 0) + GENERATE_BREAK (AE_INPUT_DATA); + + /* Chinese remainder exponentiation. */ + if ((status = BigUnexp + (frame->bigOutBuf, frame->bigInBuf, context->primeP, context->primeQ, + context->exponentP, context->exponentQ, context->coefficient, + context->primeWords, surrenderContext)) != 0) + break; + + /* Convert output to canonical representation. + This won't return AE_DATA since outputLen was set above. + */ + BigToCanonical + (output, *outputLen, frame->bigOutBuf, 2 * context->primeWords); + } while (0); + + if (frame != (struct ModExpCRTFrame *)NULL_PTR) { + T_memset ((POINTER)frame, 0, sizeof (*frame)); +#if USE_ALLOCED_FRAME + T_free ((POINTER)frame); +#endif + } + return (status); +} + diff --git a/lib/dns/sec/dnssafe/crt2.h b/lib/dns/sec/dnssafe/crt2.h new file mode 100644 index 00000000..4c5c0f7d --- /dev/null +++ b/lib/dns/sec/dnssafe/crt2.h @@ -0,0 +1,50 @@ +/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _RSA_H_ +#define _RSA_H_ 1 + +#include "bigmaxes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Note, these are only valid after a call to A_RSA_CRT2Init. + */ +#define A_RSA_CRT2_BLOCK_LEN(context) ((context)->blockLen) +#define A_RSA_CRT2_MAX_OUTPUT_LEN(context, inputLen)\ + (inputLen) + (((inputLen) % (context)->blockLen) ?\ + (context)->blockLen - ((inputLen) % (context)->blockLen) : 0) + +typedef struct { + unsigned int blockLen; /* total size of the block to be computed */ + unsigned char input[MAX_RSA_MODULUS_LEN]; + unsigned int inputLen; + unsigned int primeWords; + UINT2 modulus[2 * MAX_RSA_PRIME_WORDS]; + UINT2 primeP[MAX_RSA_PRIME_WORDS]; + UINT2 primeQ[MAX_RSA_PRIME_WORDS]; + UINT2 exponentP[MAX_RSA_PRIME_WORDS]; + UINT2 exponentQ[MAX_RSA_PRIME_WORDS]; + UINT2 coefficient[MAX_RSA_PRIME_WORDS]; +} A_RSA_CRT2_CTX; + +int A_RSA_CRT2Init PROTO_LIST ((A_RSA_CRT2_CTX *, A_RSA_CRT_KEY *)); +int A_RSA_CRT2Update PROTO_LIST + ((A_RSA_CRT2_CTX *, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int, A_SURRENDER_CTX *)); +int A_RSA_CRT2Final PROTO_LIST ((A_RSA_CRT2_CTX *)); +void A_RSA_CRT2GetMaxOutputLen PROTO_LIST + ((A_RSA_CRT2_CTX *, unsigned int *, unsigned int)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/dnssafe/digest.c b/lib/dns/sec/dnssafe/digest.c new file mode 100644 index 00000000..823fbc65 --- /dev/null +++ b/lib/dns/sec/dnssafe/digest.c @@ -0,0 +1,67 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "keyobj.h" +#include "algobj.h" + +int B_DigestInit + (algorithmObject, keyObject, algorithmChooser, surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +B_KEY_OBJ keyObject; +B_ALGORITHM_CHOOSER algorithmChooser; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + if ((status = KeyWrapCheck ((KeyWrap *)keyObject)) != 0) + return (status); + + return (B_AlgorithmDigestInit + (&THE_ALG_WRAP->algorithm, &((KeyWrap *)keyObject)->key, + algorithmChooser, surrenderContext)); +} + +int B_DigestUpdate (algorithmObject, partIn, partInLen, surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +unsigned char *partIn; +unsigned int partInLen; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + + return (B_AlgorithmDigestUpdate + (&THE_ALG_WRAP->algorithm, partIn, partInLen, surrenderContext)); +} + +int B_DigestFinal + (algorithmObject, digest, digestLen, maxDigestLen, surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +unsigned char *digest; +unsigned int *digestLen; +unsigned int maxDigestLen; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + + return (B_AlgorithmDigestFinal + (&THE_ALG_WRAP->algorithm, digest, digestLen, maxDigestLen, + surrenderContext)); +} + diff --git a/lib/dns/sec/dnssafe/digrand.c b/lib/dns/sec/dnssafe/digrand.c new file mode 100644 index 00000000..e6f9016e --- /dev/null +++ b/lib/dns/sec/dnssafe/digrand.c @@ -0,0 +1,88 @@ +/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "digrand.h" + +/* Calling routine must initialize the digest algorithm and set + digestRandom->vTable. + digestLen is the length of the output of the digest algorithm (i.e. 16). + state must point to an unsigned char * array of 3 * digestLen. + */ +void A_DigestRandomInit (digestRandom, digestLen, state) +A_DigestRandom *digestRandom; +unsigned int digestLen; +unsigned char *state; +{ + digestRandom->_state = state; + digestRandom->_output = state + digestLen; + digestRandom->_digest = digestRandom->_output + digestLen; + + digestRandom->_outputAvailable = 0; + digestRandom->_digestLen = digestLen; + + T_memset ((POINTER)digestRandom->_state, 0, digestLen); +} + +void A_DigestRandomUpdate (digestRandom, input, inputLen) +A_DigestRandom *digestRandom; +unsigned char *input; +unsigned int inputLen; +{ + unsigned int i, j, x; + + (*digestRandom->vTable->DigestUpdate) (digestRandom, input, inputLen); + (*digestRandom->vTable->DigestFinal) (digestRandom, digestRandom->_digest); + + /* add digest to state */ + x = 0; + for (i = 0; i < digestRandom->_digestLen; i++) { + j = digestRandom->_digestLen-1-i; + x += digestRandom->_state[j] + digestRandom->_digest[j]; + digestRandom->_state[j] = (unsigned char)x; + x >>= 8; + } +} + +void A_DigestRandomGenerateBytes (digestRandom, output, outputLen) +A_DigestRandom *digestRandom; +unsigned char *output; +unsigned int outputLen; +{ + unsigned int available, i; + + available = digestRandom->_outputAvailable; + + while (outputLen > available) { + T_memcpy + ((POINTER)output, + (POINTER)&digestRandom->_output[digestRandom->_digestLen-available], + available); + output += available; + outputLen -= available; + + /* generate new output */ + (*digestRandom->vTable->DigestUpdate) + (digestRandom, digestRandom->_state, digestRandom->_digestLen); + (*digestRandom->vTable->DigestFinal) (digestRandom, digestRandom->_output); + available = digestRandom->_digestLen; + + /* increment state */ + for (i = 0; i < digestRandom->_digestLen; i++) + if (digestRandom->_state[digestRandom->_digestLen-1-i]++) + break; + } + + T_memcpy + ((POINTER)output, + (POINTER)&digestRandom->_output[digestRandom->_digestLen-available], + outputLen); + digestRandom->_outputAvailable = available - outputLen; +} + diff --git a/lib/dns/sec/dnssafe/digrand.h b/lib/dns/sec/dnssafe/digrand.h new file mode 100644 index 00000000..6753c9cf --- /dev/null +++ b/lib/dns/sec/dnssafe/digrand.h @@ -0,0 +1,53 @@ +/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _DIGRAND_H_ +#define _DIGRAND_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Use the THIS_DIGEST_RANDOM macro to define the type of object in the + virtual function prototype. It defaults to the most base class, but + derived modules may define the macro to a more derived class before + including this header file. + */ +#ifndef THIS_DIGEST_RANDOM +#define THIS_DIGEST_RANDOM struct A_DigestRandom +#endif + +struct A_DigestRandom; + +typedef struct { + void (*DigestUpdate) PROTO_LIST + ((THIS_DIGEST_RANDOM *, unsigned char *, unsigned int)); + void (*DigestFinal) PROTO_LIST ((THIS_DIGEST_RANDOM *, unsigned char *)); +} A_DigestRandomVTable; + +typedef struct A_DigestRandom { + unsigned char *_state; /* input to digest */ + unsigned char *_output; /* current output of digest */ + unsigned int _outputAvailable; + unsigned char *_digest; + unsigned int _digestLen; + A_DigestRandomVTable *vTable; +} A_DigestRandom; + +void A_DigestRandomInit PROTO_LIST + ((A_DigestRandom *, unsigned int, unsigned char *)); +void A_DigestRandomUpdate PROTO_LIST + ((A_DigestRandom *, unsigned char *, unsigned int)); +void A_DigestRandomGenerateBytes PROTO_LIST + ((A_DigestRandom *, unsigned char *, unsigned int)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/dnssafe/encrypt.c b/lib/dns/sec/dnssafe/encrypt.c new file mode 100644 index 00000000..e7995b4d --- /dev/null +++ b/lib/dns/sec/dnssafe/encrypt.c @@ -0,0 +1,147 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "keyobj.h" +#include "algobj.h" + +int B_EncryptInit + (algorithmObject, keyObject, algorithmChooser, surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +B_KEY_OBJ keyObject; +B_ALGORITHM_CHOOSER algorithmChooser; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + if ((status = KeyWrapCheck ((KeyWrap *)keyObject)) != 0) + return (status); + + return (B_AlgorithmEncryptInit + (&THE_ALG_WRAP->algorithm, &((KeyWrap *)keyObject)->key, + algorithmChooser, surrenderContext)); +} + +int B_EncryptUpdate + (algorithmObject, partOut, partOutLen, maxPartOutLen, partIn, partInLen, + randomAlgorithm, surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +unsigned char *partIn; +unsigned int partInLen; +B_ALGORITHM_OBJ randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + if ((status = RandomAlgorithmCheck (randomAlgorithm)) != 0) + return (status); + + return (B_AlgorithmEncryptUpdate + (&THE_ALG_WRAP->algorithm, partOut, partOutLen, maxPartOutLen, + partIn, partInLen, + &((AlgorithmWrap *)randomAlgorithm)->algorithm, surrenderContext)); +} + +int B_EncryptFinal + (algorithmObject, partOut, partOutLen, maxPartOutLen, randomAlgorithm, + surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +B_ALGORITHM_OBJ randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + if ((status = RandomAlgorithmCheck (randomAlgorithm)) != 0) + return (status); + + return (B_AlgorithmEncryptFinal + (&THE_ALG_WRAP->algorithm, partOut, partOutLen, maxPartOutLen, + &((AlgorithmWrap *)randomAlgorithm)->algorithm, surrenderContext)); +} + +int B_DecryptInit + (algorithmObject, keyObject, algorithmChooser, surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +B_KEY_OBJ keyObject; +B_ALGORITHM_CHOOSER algorithmChooser; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + if ((status = KeyWrapCheck ((KeyWrap *)keyObject)) != 0) + return (status); + + return (B_AlgorithmDecryptInit + (&THE_ALG_WRAP->algorithm, &((KeyWrap *)keyObject)->key, + algorithmChooser, surrenderContext)); +} + +int B_DecryptUpdate + (algorithmObject, partOut, partOutLen, maxPartOutLen, partIn, partInLen, + randomAlgorithm, surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +unsigned char *partIn; +unsigned int partInLen; +B_ALGORITHM_OBJ randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + if ((status = RandomAlgorithmCheck (randomAlgorithm)) != 0) + return (status); + + return (B_AlgorithmDecryptUpdate + (&THE_ALG_WRAP->algorithm, partOut, partOutLen, maxPartOutLen, + partIn, partInLen, + &((AlgorithmWrap *)randomAlgorithm)->algorithm, surrenderContext)); +} + +int B_DecryptFinal + (algorithmObject, partOut, partOutLen, maxPartOutLen, randomAlgorithm, + surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +B_ALGORITHM_OBJ randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + if ((status = RandomAlgorithmCheck (randomAlgorithm)) != 0) + return (status); + + return (B_AlgorithmDecryptFinal + (&THE_ALG_WRAP->algorithm, partOut, partOutLen, maxPartOutLen, + &((AlgorithmWrap *)randomAlgorithm)->algorithm, surrenderContext)); +} + diff --git a/lib/dns/sec/dnssafe/generate.c b/lib/dns/sec/dnssafe/generate.c new file mode 100644 index 00000000..76069370 --- /dev/null +++ b/lib/dns/sec/dnssafe/generate.c @@ -0,0 +1,78 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ainfotyp.h" +#include "keyobj.h" +#include "algobj.h" + +int B_GenerateInit (algorithmObject, algorithmChooser, surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +B_ALGORITHM_CHOOSER algorithmChooser; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + + return (B_AlgorithmGenerateInit + (&THE_ALG_WRAP->algorithm, algorithmChooser, surrenderContext)); +} + +int B_GenerateKeypair + (algorithmObject, publicKey, privateKey, randomAlgorithm, surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +B_KEY_OBJ publicKey; +B_KEY_OBJ privateKey; +B_ALGORITHM_OBJ randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + if ((status = KeyWrapCheck ((KeyWrap *)publicKey)) != 0) + return (status); + if ((status = KeyWrapCheck ((KeyWrap *)privateKey)) != 0) + return (status); + if ((status = RandomAlgorithmCheck (randomAlgorithm)) != 0) + return (status); + + return (B_AlgorithmGenerateKeypair + (&THE_ALG_WRAP->algorithm, &((KeyWrap *)publicKey)->key, + &((KeyWrap *)privateKey)->key, + &((AlgorithmWrap *)randomAlgorithm)->algorithm, surrenderContext)); +} + +int B_GenerateParameters + (algorithmObject, resultAlgorithmObject, randomAlgorithm, surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +B_ALGORITHM_OBJ resultAlgorithmObject; +B_ALGORITHM_OBJ randomAlgorithm; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + + if ((status = AlgorithmWrapCheck (THE_ALG_WRAP)) != 0) + return (status); + if ((status = AlgorithmWrapCheck ((AlgorithmWrap *)resultAlgorithmObject)) + != 0) + return (status); + if ((status = RandomAlgorithmCheck (randomAlgorithm)) != 0) + return (status); + + return (B_AlgorithmGenerateParameters + (&THE_ALG_WRAP->algorithm, + &((AlgorithmWrap *)resultAlgorithmObject)->algorithm, + &((AlgorithmWrap *)randomAlgorithm)->algorithm, surrenderContext)); +} + diff --git a/lib/dns/sec/dnssafe/global.h b/lib/dns/sec/dnssafe/global.h new file mode 100644 index 00000000..e95ac180 --- /dev/null +++ b/lib/dns/sec/dnssafe/global.h @@ -0,0 +1,60 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _GLOBAL_H_ +#define _GLOBAL_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* PROTOTYPES should be set to one if and only if the compiler supports + function argument prototyping. + The following makes PROTOTYPES default to 1 if it has not already been + defined as 0 with C compiler flags. + */ +#ifndef PROTOTYPES +#define PROTOTYPES 1 +#endif + +#include <config.h> +#include <isc/int.h> +#include <sys/types.h> + +/* POINTER defines a generic pointer type */ +typedef unsigned char *POINTER; + +/* UINT2 defines a two byte word */ +typedef isc_uint16_t UINT2; + +/* UINT4 defines a four byte word */ +typedef isc_uint32_t UINT4; + +#ifndef NULL_PTR +#define NULL_PTR ((POINTER)0) +#endif + +#ifndef UNUSED_ARG +#define UNUSED_ARG(x) x = *(&x); +#endif + +/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. + If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it + returns an empty list. + */ +#if PROTOTYPES +#define PROTO_LIST(list) list +#else +#define PROTO_LIST(list) () +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* end _GLOBAL_H_ */ diff --git a/lib/dns/sec/dnssafe/intbits.c b/lib/dns/sec/dnssafe/intbits.c new file mode 100644 index 00000000..6a60e22a --- /dev/null +++ b/lib/dns/sec/dnssafe/intbits.c @@ -0,0 +1,32 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" + +/* Return the number of bits in the canonical, positive integer. + IntgerBits (0) = 0. + */ +unsigned int A_IntegerBits (integer, integerLen) +unsigned char *integer; +unsigned int integerLen; +{ + unsigned char mask, byte; + unsigned int bytes, bits; + + for (bytes = 0; bytes < integerLen && integer[bytes] == 0; bytes++); + if (bytes == integerLen) + return (0); + + /* Get byte to test and increment byte count for final calculation */ + byte = integer[bytes++]; + + /* Get number of bits in most significant byte */ + for (bits = 8, mask = 0x80; (byte & mask) == 0; bits--, mask >>= 1); + return (8 * (integerLen - bytes) + bits); +} diff --git a/lib/dns/sec/dnssafe/intitem.c b/lib/dns/sec/dnssafe/intitem.c new file mode 100644 index 00000000..a9bcc7e8 --- /dev/null +++ b/lib/dns/sec/dnssafe/intitem.c @@ -0,0 +1,54 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bmempool.h" +#include "intitem.h" + +/* Copy itemCount ITEMs from source to destination, allocating new + memory in the memoryPool. + Each ITEM is a canonical integer, and is stripped of leading zeros. + Use the list of staticItems as a template. Each of the staticItems + points to the ITEM within the staticStruct, which is a structure + of the same format as destination and source. + Returns 0, BE_ALLOC. + */ +int AllocAndCopyIntegerItems + (destination, source, staticStruct, staticItems, itemCount, memoryPool) +POINTER destination; +POINTER source; +POINTER staticStruct; +ITEM **staticItems; +unsigned int itemCount; +B_MemoryPool *memoryPool; +{ + ITEM sourceItem, *destinationItem; + int status; + unsigned int i, offset; + + for (i = 0; i < itemCount; i++) { + offset = (unsigned int)((char *)staticItems[i] - (char *)staticStruct); + sourceItem = *(ITEM *)((char *)source + offset); + destinationItem = (ITEM *)((char *)destination + offset); + + while (sourceItem.len > 0 && *sourceItem.data == 0) { + sourceItem.len--; + sourceItem.data++; + } + + if ((status = B_MemoryPoolAllocAndCopy + (memoryPool, (POINTER *)&destinationItem->data, + (POINTER)sourceItem.data, destinationItem->len = sourceItem.len)) + != 0) + return (status); + } + + return (0); +} + diff --git a/lib/dns/sec/dnssafe/intitem.h b/lib/dns/sec/dnssafe/intitem.h new file mode 100644 index 00000000..05cb2fc1 --- /dev/null +++ b/lib/dns/sec/dnssafe/intitem.h @@ -0,0 +1,11 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +int AllocAndCopyIntegerItems PROTO_LIST + ((POINTER, POINTER, POINTER, ITEM **, unsigned int, B_MemoryPool *)); + diff --git a/lib/dns/sec/dnssafe/keyobj.c b/lib/dns/sec/dnssafe/keyobj.c new file mode 100644 index 00000000..4dd5d77c --- /dev/null +++ b/lib/dns/sec/dnssafe/keyobj.c @@ -0,0 +1,113 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "kinfotyp.h" +#include "keyobj.h" + +#define THE_KEY_WRAP ((KeyWrap *)keyObject) + +static char KEY_TYPE_TAG = 0; + +int B_CreateKeyObject (keyObject) +B_KEY_OBJ *keyObject; +{ + KeyWrap *keyWrap; + + if ((*keyObject = T_malloc (sizeof (*keyWrap))) == NULL_PTR) + return (BE_ALLOC); + + keyWrap = (KeyWrap *)*keyObject; + + /* First construct base class */ + B_KEY_Constructor (&keyWrap->key); + + keyWrap->typeTag = &KEY_TYPE_TAG; + keyWrap->selfCheck = keyWrap; + return (0); +} + +void B_DestroyKeyObject (keyObject) +B_KEY_OBJ *keyObject; +{ + KeyWrap *keyWrap = (KeyWrap *)*keyObject; + + /* Need to explicitly check for NULL_PTR since KeyWrapCheck does not. + */ + if (*keyObject == NULL_PTR) + return; + + if (KeyWrapCheck (keyWrap) == 0) { + /* zeroize self check to invalidate memory. */ + keyWrap->selfCheck = (KeyWrap *)NULL_PTR; + + /* Call base class descructor */ + B_KEY_Destructor (&keyWrap->key); + + T_free ((POINTER)keyWrap); + } + + *keyObject = NULL_PTR; +} + +int B_SetKeyInfo (keyObject, infoType, info) +B_KEY_OBJ keyObject; +B_INFO_TYPE infoType; +POINTER info; +{ + B_KeyInfoType *keyInfoType; + int status; + + if ((status = KeyWrapCheck (THE_KEY_WRAP)) != 0) + return (status); + + /* Get the KeyInfoType from the B_INFO_TYPE, which returns + zero for an AlgorithmInfoType, non-zero for KeyInfoType + */ + if ((*infoType) ((POINTER *)&keyInfoType) == 0) + return (BE_ALG_OPERATION_UNKNOWN); + + return (B_KeySetInfo (&THE_KEY_WRAP->key, keyInfoType, info)); +} + +int B_GetKeyInfo (info, keyObject, infoType) +POINTER *info; +B_KEY_OBJ keyObject; +B_INFO_TYPE infoType; +{ + B_KeyInfoType *keyInfoType; + int status; + + if ((status = KeyWrapCheck (THE_KEY_WRAP)) != 0) + return (status); + + /* Get the KeyInfoType from the B_INFO_TYPE, which returns + zero for an AlgorithmInfoType, non-zero for KeyInfoType + */ + if ((*infoType) ((POINTER *)&keyInfoType) == 0) + return (BE_ALG_OPERATION_UNKNOWN); + + return (B_KeyGetInfo (&THE_KEY_WRAP->key, info, keyInfoType)); +} + +/* Return 0 if this is a valid KeyWrap object, else BE_KEY_OBJ. + If keyWrap is NULL_PTR, return 0 and expect the lower routines + to check for NULL. + */ +int KeyWrapCheck (keyWrap) +KeyWrap *keyWrap; +{ + if (keyWrap == (KeyWrap *)NULL_PTR) + return (0); + + return ((keyWrap->selfCheck == keyWrap && keyWrap->typeTag == &KEY_TYPE_TAG) + ? 0 : BE_KEY_OBJ); +} + diff --git a/lib/dns/sec/dnssafe/keyobj.h b/lib/dns/sec/dnssafe/keyobj.h new file mode 100644 index 00000000..b7f582f8 --- /dev/null +++ b/lib/dns/sec/dnssafe/keyobj.h @@ -0,0 +1,16 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +typedef struct KeyWrap { + B_Key key; + char *typeTag; + struct KeyWrap *selfCheck; +} KeyWrap; + +int KeyWrapCheck PROTO_LIST ((KeyWrap *)); + diff --git a/lib/dns/sec/dnssafe/ki8byte.c b/lib/dns/sec/dnssafe/ki8byte.c new file mode 100644 index 00000000..306cc7b1 --- /dev/null +++ b/lib/dns/sec/dnssafe/ki8byte.c @@ -0,0 +1,70 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "kinfotyp.h" +#include "kiitem.h" +#include "ki8byte.h" + +int KIT_8ByteAddInfo PROTO_LIST ((B_Key *, POINTER)); +int KIT_8ByteMakeInfo PROTO_LIST ((POINTER *, B_Key *)); + +B_KeyInfoType KIT_8Byte = {KIT_8ByteAddInfo, KIT_8ByteMakeInfo}; + +int KI_8Byte (keyInfoType) +POINTER *keyInfoType; +{ + *keyInfoType = (POINTER)&KIT_8Byte; + + /* Return 1 to indicate a KeyInfoType, not an AlgorithmInfoType */ + return (1); +} + +/* info points to 8 byte key. + Cache as a KITItem and a KIT_8Byte. + */ +int KIT_8ByteAddInfo (key, info) +B_Key *key; +POINTER info; +{ + POINTER newData; + int status; + + /* Copy the 8 byte key. */ + if ((status = B_MemoryPoolAllocAndCopy + (&key->infoCache.memoryPool, &newData, info, 8)) != 0) + return (status); + + /* Cache as a KITItem as well as KIT_8Byte. + */ + if ((status = B_KeyAddItemInfo (key, (unsigned char *)newData, 8)) != 0) + return (status); + return (B_InfoCacheAddInfo (&key->infoCache, (POINTER)&KIT_8Byte, newData)); +} + +int KIT_8ByteMakeInfo (info, key) +POINTER *info; +B_Key *key; +{ + ITEM *item; + int status; + + /* Try to make one from a KI_Item. Since KI_Item doesn't + call KI_8Byte, this should not cause an endless loop. + */ + if ((status = B_KeyGetInfo (key, (POINTER *)&item, &KITItem)) != 0) + return (status); + if (item->len != 8) + return (BE_WRONG_KEY_INFO); + + *(unsigned char **)info = item->data; + return (0); +} + diff --git a/lib/dns/sec/dnssafe/ki8byte.h b/lib/dns/sec/dnssafe/ki8byte.h new file mode 100644 index 00000000..1c78bb12 --- /dev/null +++ b/lib/dns/sec/dnssafe/ki8byte.h @@ -0,0 +1,9 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +extern B_KeyInfoType KIT_8Byte; diff --git a/lib/dns/sec/dnssafe/kifulprv.c b/lib/dns/sec/dnssafe/kifulprv.c new file mode 100644 index 00000000..be358352 --- /dev/null +++ b/lib/dns/sec/dnssafe/kifulprv.c @@ -0,0 +1,151 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "kinfotyp.h" +#include "kifulprv.h" + +typedef struct { + ITEM modulus; /* modulus */ + ITEM publicExponent; /* exponent for the public key */ + ITEM privateExponent; /* exponent for the private key */ + ITEM prime[2]; /* prime factors */ + ITEM primeExponent[2]; /* exponents for prime factors */ + ITEM coefficient; /* CRT coefficient */ +} FULL_PRIVATE_KEY; + +static int KITFullPrivateKeyAddInfo PROTO_LIST ((B_Key *, POINTER)); + +static B_KeyInfoType KITFullPrivate = + {KITFullPrivateKeyAddInfo, B_KeyInfoTypeMakeError}; + +/* Create a FULL_PRIVATE_KEY value and only copy inthe entries + that are not (ITEM *)NULL_PTR. + primes and primeExponents point to a 2 entry ITEM array. + */ +int CacheFullPrivateKey + (key, modulus, publicExponent, privateExponent, primes, + primeExponents, coefficient) +B_Key *key; +ITEM *modulus; +ITEM *publicExponent; +ITEM *privateExponent; +ITEM *primes; +ITEM *primeExponents; +ITEM *coefficient; +{ + FULL_PRIVATE_KEY *fullKey; + int status; + + /* Allocate memory for FULL_PRIVATE_KEY value. + */ + if ((status = B_MemoryPoolAlloc + (&key->infoCache.memoryPool, (POINTER *)&fullKey, + sizeof (FULL_PRIVATE_KEY))) != 0) + return (status); + + /* Pre-zeroize and only copy in values that are not NULL. + */ + T_memset ((POINTER)fullKey, 0, sizeof (*fullKey)); + if (modulus != (ITEM *)NULL_PTR) + fullKey->modulus = *modulus; + if (publicExponent != (ITEM *)NULL_PTR) + fullKey->publicExponent = *publicExponent; + if (privateExponent != (ITEM *)NULL_PTR) + fullKey->privateExponent = *privateExponent; + if (primes != (ITEM *)NULL_PTR) { + fullKey->prime[0] = primes[0]; + fullKey->prime[1] = primes[1]; + } + if (primeExponents != (ITEM *)NULL_PTR) { + fullKey->primeExponent[0] = primeExponents[0]; + fullKey->primeExponent[1] = primeExponents[1]; + } + if (coefficient != (ITEM *)NULL_PTR) + fullKey->coefficient = *coefficient; + + return (B_InfoCacheAddInfo + (&key->infoCache, (POINTER)&KITFullPrivate, (POINTER)fullKey)); +} + +/* Select the key object's full private key and set all of the supplied + fields which are not (ITEM *)NULL_PTR. + primes and primeExponents point to a 2 entry ITEM array. + If one of the fields is not (ITEM *)NULL_PTR, but the full key's + field is null, return BE_WRONG_KEY_INFO. + */ +int GetFullPrivateKeyInfo + (modulus, publicExponent, privateExponent, primes, primeExponents, + coefficient, key) +ITEM *modulus; +ITEM *publicExponent; +ITEM *privateExponent; +ITEM *primes; +ITEM *primeExponents; +ITEM *coefficient; +B_Key *key; +{ + FULL_PRIVATE_KEY *fullKey; + int status; + + if ((status = B_KeyGetInfo + (key, (POINTER *)&fullKey, &KITFullPrivate)) != 0) + return (status); + + if (modulus != (ITEM *)NULL_PTR) { + if (fullKey->modulus.data == (unsigned char *)NULL_PTR) + return (BE_WRONG_KEY_INFO); + *modulus = fullKey->modulus; + } + if (publicExponent != (ITEM *)NULL_PTR) { + if (fullKey->publicExponent.data == (unsigned char *)NULL_PTR) + return (BE_WRONG_KEY_INFO); + *publicExponent = fullKey->publicExponent; + } + if (privateExponent != (ITEM *)NULL_PTR) { + if (fullKey->privateExponent.data == (unsigned char *)NULL_PTR) + return (BE_WRONG_KEY_INFO); + *privateExponent = fullKey->privateExponent; + } + if (primes != (ITEM *)NULL_PTR) { + if (fullKey->prime[0].data == (unsigned char *)NULL_PTR || + fullKey->prime[1].data == (unsigned char *)NULL_PTR) + return (BE_WRONG_KEY_INFO); + primes[0] = fullKey->prime[0]; + primes[1] = fullKey->prime[1]; + } + if (primeExponents != (ITEM *)NULL_PTR) { + if (fullKey->primeExponent[0].data == (unsigned char *)NULL_PTR || + fullKey->primeExponent[1].data == (unsigned char *)NULL_PTR) + return (BE_WRONG_KEY_INFO); + primeExponents[0] = fullKey->primeExponent[0]; + primeExponents[1] = fullKey->primeExponent[1]; + } + if (coefficient != (ITEM *)NULL_PTR) { + if (fullKey->coefficient.data == (unsigned char *)NULL_PTR) + return (BE_WRONG_KEY_INFO); + *coefficient = fullKey->coefficient; + } + + return (0); +} + +/* This is not intended to be called from B_SetKeyInfo. + Get returns BE_WRONG_KEY_INFO. + */ +static int KITFullPrivateKeyAddInfo (key, info) +B_Key *key; +POINTER info; +{ +UNUSED_ARG (key) +UNUSED_ARG (info) + return (BE_ALG_OPERATION_UNKNOWN); +} + diff --git a/lib/dns/sec/dnssafe/kifulprv.h b/lib/dns/sec/dnssafe/kifulprv.h new file mode 100644 index 00000000..8e469ce9 --- /dev/null +++ b/lib/dns/sec/dnssafe/kifulprv.h @@ -0,0 +1,12 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +int CacheFullPrivateKey PROTO_LIST + ((B_Key *, ITEM *, ITEM *, ITEM *, ITEM *, ITEM *, ITEM *)); +int GetFullPrivateKeyInfo PROTO_LIST + ((ITEM *, ITEM *, ITEM *, ITEM *, ITEM *, ITEM *, B_Key *)); diff --git a/lib/dns/sec/dnssafe/kiitem.c b/lib/dns/sec/dnssafe/kiitem.c new file mode 100644 index 00000000..9c44d8f1 --- /dev/null +++ b/lib/dns/sec/dnssafe/kiitem.c @@ -0,0 +1,44 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "kinfotyp.h" +#include "kiitem.h" + +int KITItemAddInfo PROTO_LIST ((B_Key *, POINTER)); + +B_KeyInfoType KITItem = {KITItemAddInfo, B_KeyInfoTypeMakeError}; + +int KI_Item (keyInfoType) +POINTER *keyInfoType; +{ + *keyInfoType = (POINTER)&KITItem; + + /* Return 1 to indicate a KeyInfoType, not an AlgorithmInfoType */ + return (1); +} + +/* info is an ITEM. The ITEM's data is copied into the object. + */ +int KITItemAddInfo (key, info) +B_Key *key; +POINTER info; +{ + unsigned char *newData; + int status; + + if ((status = B_MemoryPoolAllocAndCopy + (&key->infoCache.memoryPool, (POINTER *)&newData, + (POINTER)((ITEM *)info)->data, ((ITEM *)info)->len)) != 0) + return (status); + + return (B_KeyAddItemInfo (key, newData, ((ITEM *)info)->len)); +} + diff --git a/lib/dns/sec/dnssafe/kiitem.h b/lib/dns/sec/dnssafe/kiitem.h new file mode 100644 index 00000000..ab80ceee --- /dev/null +++ b/lib/dns/sec/dnssafe/kiitem.h @@ -0,0 +1,9 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +extern B_KeyInfoType KITItem; diff --git a/lib/dns/sec/dnssafe/kinfotyp.c b/lib/dns/sec/dnssafe/kinfotyp.c new file mode 100644 index 00000000..fdb3338f --- /dev/null +++ b/lib/dns/sec/dnssafe/kinfotyp.c @@ -0,0 +1,26 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "kinfotyp.h" + +/* This is the default routine which key info types can point MakeInfo to. + */ +int B_KeyInfoTypeMakeError (info, key) +POINTER *info; +B_Key *key; +{ +UNUSED_ARG (info) +UNUSED_ARG (key) + + /* Should already have been found in the cache. */ + return (BE_WRONG_KEY_INFO); +} + diff --git a/lib/dns/sec/dnssafe/kinfotyp.h b/lib/dns/sec/dnssafe/kinfotyp.h new file mode 100644 index 00000000..3f6ce7c1 --- /dev/null +++ b/lib/dns/sec/dnssafe/kinfotyp.h @@ -0,0 +1,57 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +typedef int (*KIT_ADD_INFO) PROTO_LIST ((B_Key *, POINTER)); +typedef int (*KIT_MAKE_INFO) PROTO_LIST ((POINTER *, B_Key *)); + +/* The definition in C++ is: + class B_KeyInfoType { + public: + B_KeyInfoType (KIT_ADD_INFO AddInfo) { + _AddInfo = AddInfo; + _MakeInfo = KeyInfoType::makeError;} + B_KeyInfoType (KIT_ADD_INFO AddInfo, KIT_MAKE_INFO MakeInfo) { + _AddInfo = AddInfo; + _MakeInfo = MakeInfo;} + + int addInfo (B_Key *key, POINTER info) {return (*_AddInfo) (key, info);} + int makeInfo (POINTER *info, B_Key *key) {return (*_MakeInfo) (info, key);} + + static int makeError (POINTER *info, B_Key *key); + + private: + KIT_ADD_INFO _AddInfo; + KIT_MAKE_INFO _MakeInfo; + }; + + Note that a derived class simply calls one of the B_KeyInfoType constructors + which set the addInfo or both the addInfo and makeInfo callbacks. + There is no need for an extra level involving virtual functions because + each key class only has one instance, making a V table a waste of space. + An example of a derived class is: + + class KITItem : public B_KeyInfoType { + public: + // Set addInfo and leave makeInfo as B_KeyInfoType::makeError + KITItem () : B_KeyInfoType (KITItem::addInfo) {}; + + static int addInfo (B_Key *key, POINTER info); + }; + + + There is one global instance which is used by B_Key::setInfo, etc.: + + KITItem KITItem; + */ + +typedef struct B_KeyInfoType { + KIT_ADD_INFO AddInfo; + KIT_MAKE_INFO MakeInfo; +} B_KeyInfoType; + +int B_KeyInfoTypeMakeError PROTO_LIST ((POINTER *, B_Key *)); diff --git a/lib/dns/sec/dnssafe/kipkcrpr.c b/lib/dns/sec/dnssafe/kipkcrpr.c new file mode 100644 index 00000000..50c08edb --- /dev/null +++ b/lib/dns/sec/dnssafe/kipkcrpr.c @@ -0,0 +1,100 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "kinfotyp.h" +#include "intitem.h" +#include "kifulprv.h" +#include "kipkcrpr.h" + +B_KeyInfoType KIT_PKCS_RSAPrivate = + {KIT_PKCS_RSAPrivateAddInfo, KIT_PKCS_RSAPrivateMakeInfo}; + +static A_PKCS_RSA_PRIVATE_KEY STATIC_PKCS_RSA_PRIVATE_KEY; +static ITEM *PKCS_RSA_PRIVATE_KEY_ITEMS[] = { + &STATIC_PKCS_RSA_PRIVATE_KEY.modulus, + &STATIC_PKCS_RSA_PRIVATE_KEY.publicExponent, + &STATIC_PKCS_RSA_PRIVATE_KEY.privateExponent, + &STATIC_PKCS_RSA_PRIVATE_KEY.prime[0], + &STATIC_PKCS_RSA_PRIVATE_KEY.prime[1], + &STATIC_PKCS_RSA_PRIVATE_KEY.primeExponent[0], + &STATIC_PKCS_RSA_PRIVATE_KEY.primeExponent[1], + &STATIC_PKCS_RSA_PRIVATE_KEY.coefficient +}; + +int KI_PKCS_RSAPrivate (keyInfoType) +POINTER *keyInfoType; +{ + *keyInfoType = (POINTER)&KIT_PKCS_RSAPrivate; + + /* Return 1 to indicate a KeyInfoType, not an AlgorithmInfoType */ + return (1); +} + +int KIT_PKCS_RSAPrivateAddInfo (key, info) +B_Key *key; +POINTER info; +{ + A_PKCS_RSA_PRIVATE_KEY *newValue; + int status; + + /* Allocate memory for A_PKCS_RSA_PRIVATE_KEY struct and copy integers + from supplied value. + */ + if ((status = B_MemoryPoolAlloc + (&key->infoCache.memoryPool, (POINTER *)&newValue, + sizeof (A_PKCS_RSA_PRIVATE_KEY))) != 0) + return (status); + if ((status = AllocAndCopyIntegerItems + ((POINTER)newValue, info, (POINTER)&STATIC_PKCS_RSA_PRIVATE_KEY, + PKCS_RSA_PRIVATE_KEY_ITEMS, sizeof (PKCS_RSA_PRIVATE_KEY_ITEMS) / + sizeof (PKCS_RSA_PRIVATE_KEY_ITEMS[0]), &key->infoCache.memoryPool)) + != 0) + return (status); + + /* Cache the full private key info. + */ + if ((status = CacheFullPrivateKey + (key, &newValue->modulus, &newValue->publicExponent, + &newValue->privateExponent, newValue->prime, newValue->primeExponent, + &newValue->coefficient)) != 0) + return (status); + return (B_InfoCacheAddInfo + (&key->infoCache, (POINTER)&KIT_PKCS_RSAPrivate, (POINTER)newValue)); +} + +int KIT_PKCS_RSAPrivateMakeInfo (info, key) +POINTER *info; +B_Key *key; +{ + A_PKCS_RSA_PRIVATE_KEY keyValue; + int status; + + /* If not already found in the cache, try to get values from + a full private key info. + */ + if ((status = GetFullPrivateKeyInfo + (&keyValue.modulus, &keyValue.publicExponent, + &keyValue.privateExponent, keyValue.prime, keyValue.primeExponent, + &keyValue.coefficient, key)) != 0) + return (status); + + /* Got all the needed fields, so allocate memory for a new + A_PKCS_RSA_PRIVATE_KEY struct and copy the key value. + */ + if ((status = B_MemoryPoolAlloc + (&key->infoCache.memoryPool, info, sizeof (A_PKCS_RSA_PRIVATE_KEY))) + != 0) + return (status); + + **(A_PKCS_RSA_PRIVATE_KEY **)info = keyValue; + return (0); +} + diff --git a/lib/dns/sec/dnssafe/kipkcrpr.h b/lib/dns/sec/dnssafe/kipkcrpr.h new file mode 100644 index 00000000..9bcfc02d --- /dev/null +++ b/lib/dns/sec/dnssafe/kipkcrpr.h @@ -0,0 +1,13 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +extern B_KeyInfoType KIT_PKCS_RSAPrivate; + +int KIT_PKCS_RSAPrivateAddInfo PROTO_LIST ((B_Key *, POINTER)); +int KIT_PKCS_RSAPrivateMakeInfo PROTO_LIST ((POINTER *, B_Key *)); + diff --git a/lib/dns/sec/dnssafe/kirsacrt.c b/lib/dns/sec/dnssafe/kirsacrt.c new file mode 100644 index 00000000..fe1ecb93 --- /dev/null +++ b/lib/dns/sec/dnssafe/kirsacrt.c @@ -0,0 +1,101 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "kinfotyp.h" +#include "intitem.h" +#include "kifulprv.h" + +#define NULL_UCHAR_PTR ((unsigned char *)NULL_PTR) + +int KIT_RSA_CRTAddInfo PROTO_LIST ((B_Key *, POINTER)); +int KIT_RSA_CRTMakeInfo PROTO_LIST ((POINTER *, B_Key *)); + +B_KeyInfoType KIT_RSA_CRT = {KIT_RSA_CRTAddInfo, KIT_RSA_CRTMakeInfo}; + +static A_RSA_CRT_KEY STATIC_RSA_CRT_KEY; +static ITEM *RSA_CRT_KEY_ITEMS[] = { + &STATIC_RSA_CRT_KEY.modulus, &STATIC_RSA_CRT_KEY.prime[0], + &STATIC_RSA_CRT_KEY.prime[1], + &STATIC_RSA_CRT_KEY.primeExponent[0], + &STATIC_RSA_CRT_KEY.primeExponent[1], + &STATIC_RSA_CRT_KEY.coefficient +}; + +/* args points to A_RSA_CRT_KEY. + */ +int KI_RSA_CRT (keyInfoType) +POINTER *keyInfoType; +{ + *keyInfoType = (POINTER)&KIT_RSA_CRT; + + /* Return 1 to indicate a KeyInfoType, not an AlgorithmInfoType */ + return (1); +} + +int KIT_RSA_CRTAddInfo (key, info) +B_Key *key; +POINTER info; +{ + A_RSA_CRT_KEY *newValue; + int status; + + /* Allocate memory for A_RSA_CRT_KEY struct and copy integers + from supplied value. + */ + if ((status = B_MemoryPoolAlloc + (&key->infoCache.memoryPool, (POINTER *)&newValue, + sizeof (A_RSA_CRT_KEY))) != 0) + return (status); + if ((status = AllocAndCopyIntegerItems + ((POINTER)newValue, info, (POINTER)&STATIC_RSA_CRT_KEY, + RSA_CRT_KEY_ITEMS, + sizeof (RSA_CRT_KEY_ITEMS) / sizeof (RSA_CRT_KEY_ITEMS[0]), + &key->infoCache.memoryPool)) != 0) + return (status); + + /* Cache the full private key info, setting unused fields to NULL. + */ + if ((status = CacheFullPrivateKey + (key, &newValue->modulus, (ITEM *)NULL_PTR, (ITEM *)NULL_PTR, + newValue->prime, newValue->primeExponent, &newValue->coefficient)) + != 0) + return (status); + return (B_InfoCacheAddInfo + (&key->infoCache, (POINTER)&KIT_RSA_CRT, (POINTER)newValue)); +} + +int KIT_RSA_CRTMakeInfo (info, key) +POINTER *info; +B_Key *key; +{ + A_RSA_CRT_KEY keyValue; + int status; + + /* If not already found in the cache, try to get values from + a full private key info, setting unneeded entries to NULL. + */ + if ((status = GetFullPrivateKeyInfo + (&keyValue.modulus, (ITEM *)NULL_PTR, (ITEM *)NULL_PTR, + keyValue.prime, keyValue.primeExponent, &keyValue.coefficient, + key)) != 0) + return (status); + + /* Got all the needed fields, so allocate memory for a new + A_RSA_CRT_KEY struct and copy the key value. + */ + if ((status = B_MemoryPoolAlloc + (&key->infoCache.memoryPool, info, sizeof (A_RSA_CRT_KEY))) != 0) + return (status); + + **(A_RSA_CRT_KEY **)info = keyValue; + return (0); +} + diff --git a/lib/dns/sec/dnssafe/kirsapub.c b/lib/dns/sec/dnssafe/kirsapub.c new file mode 100644 index 00000000..a588ec88 --- /dev/null +++ b/lib/dns/sec/dnssafe/kirsapub.c @@ -0,0 +1,80 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "kinfotyp.h" +#include "intitem.h" +#include "kifulprv.h" +#include "kirsapub.h" + +B_KeyInfoType KIT_RSAPublic = + {KIT_RSAPublicAddInfo, KIT_RSAPublicMakeInfo}; + +static A_RSA_KEY STATIC_RSA_KEY; +static ITEM *RSA_KEY_ITEMS[] = + {&STATIC_RSA_KEY.modulus, &STATIC_RSA_KEY.exponent}; + +int KI_RSAPublic (keyInfoType) +POINTER *keyInfoType; +{ + *keyInfoType = (POINTER)&KIT_RSAPublic; + + /* Return 1 to indicate a KeyInfoType, not an AlgorithmInfoType */ + return (1); +} + +int KIT_RSAPublicAddInfo (key, info) +B_Key *key; +POINTER info; +{ + POINTER newValue; + int status; + + /* Allocate memory for A_RSA_KEY struct and copy integers + from supplied value. + */ + if ((status = B_MemoryPoolAlloc + (&key->infoCache.memoryPool, &newValue, sizeof (A_RSA_KEY))) != 0) + return (status); + if ((status = AllocAndCopyIntegerItems + (newValue, info, (POINTER)&STATIC_RSA_KEY, RSA_KEY_ITEMS, + sizeof (RSA_KEY_ITEMS) / sizeof (RSA_KEY_ITEMS[0]), + &key->infoCache.memoryPool)) != 0) + return (status); + + return (B_InfoCacheAddInfo + (&key->infoCache, (POINTER)&KIT_RSAPublic, newValue)); +} + +int KIT_RSAPublicMakeInfo (info, key) +POINTER *info; +B_Key *key; +{ + A_RSA_KEY keyValue; + int status; + + /* If not already found in the cache, try to get values from + a full private key info, setting unneeded entries to NULL. + */ + if ((status = GetFullPrivateKeyInfo + (&keyValue.modulus, &keyValue.exponent, (ITEM *)NULL_PTR, + (ITEM *)NULL_PTR, (ITEM *)NULL_PTR, (ITEM *)NULL_PTR, key)) != 0) + return (status); + + /* Got all the needed fields, so allocate memory for a new + A_RSA_KEY struct and copy the key value. + */ + if ((status = B_MemoryPoolAlloc + (&key->infoCache.memoryPool, info, sizeof (A_RSA_KEY))) != 0) + return (status); + + **(A_RSA_KEY **)info = keyValue; + return (0); +} diff --git a/lib/dns/sec/dnssafe/kirsapub.h b/lib/dns/sec/dnssafe/kirsapub.h new file mode 100644 index 00000000..485fd79a --- /dev/null +++ b/lib/dns/sec/dnssafe/kirsapub.h @@ -0,0 +1,13 @@ +/* Copyright (C) RSA Data Security, Inc. created 1993, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +extern B_KeyInfoType KIT_RSAPublic; + +int KIT_RSAPublicAddInfo PROTO_LIST ((B_Key *, POINTER)); +int KIT_RSAPublicMakeInfo PROTO_LIST ((POINTER *, B_Key *)); + diff --git a/lib/dns/sec/dnssafe/md5.c b/lib/dns/sec/dnssafe/md5.c new file mode 100644 index 00000000..a5865d9e --- /dev/null +++ b/lib/dns/sec/dnssafe/md5.c @@ -0,0 +1,281 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "md5.h" + +/* Constants for MD5Transform routine. + */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); +static void Encode PROTO_LIST ((unsigned char *, UINT4 *, unsigned int)); +static void Decode PROTO_LIST ((UINT4 *, unsigned char *, unsigned int)); + +/* F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. + Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +/* MD5 initialization. Begins an MD5 operation, writing a new context. + */ +void A_MD5Init (context) +A_MD5_CTX *context; +{ + context->count[0] = context->count[1] = 0; + + /* Load magic initialization constants. + */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest + operation, processing another message block, and updating the + context. + */ +void A_MD5Update (context, input, inputLen) +A_MD5_CTX *context; +unsigned char *input; /* input block */ +unsigned int inputLen; /* length of input block */ +{ + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3)) + context->count[1]++; + context->count[1] += ((UINT4)inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible. + */ + if (inputLen >= partLen) { + T_memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen); + MD5Transform (context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform (context->state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + T_memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i); +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + the message digest and zeroizing the context. + Assume digest buffer is at least A_MD5_DIGEST_LEN. + */ +void A_MD5Final (context, digest) +A_MD5_CTX *context; +unsigned char *digest; +{ + unsigned char bits[8], pad[64]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. + */ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + T_memset ((POINTER)pad, 0, padLen); + pad[0] = 0x80; + A_MD5Update (context, pad, padLen); + + /* Append length (before padding) */ + A_MD5Update (context, bits, 8); + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Restart the context. */ + A_MD5Init (context); +} + +/* MD5 basic transformation. Transforms state based on block. + */ +static void MD5Transform (state, block) +UINT4 state[4]; +unsigned char block[64]; +{ + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. + */ + T_memset ((POINTER)x, 0, sizeof (x)); +} + +/* Encodes input (UINT4) into output (unsigned char). Assumes len is + a multiple of 4. + */ +static void Encode (output, input, len) +unsigned char *output; +UINT4 *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (unsigned char) into output (UINT4). Assumes len is + a multiple of 4. + */ +static void Decode (output, input, len) +UINT4 *output; +unsigned char *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | + (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); +} + diff --git a/lib/dns/sec/dnssafe/md5.h b/lib/dns/sec/dnssafe/md5.h new file mode 100644 index 00000000..f770a073 --- /dev/null +++ b/lib/dns/sec/dnssafe/md5.h @@ -0,0 +1,32 @@ +/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _MD5_H_ +#define _MD5_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#define A_MD5_DIGEST_LEN 16 + +typedef struct { + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} A_MD5_CTX; + +void A_MD5Init PROTO_LIST ((A_MD5_CTX *)); +void A_MD5Update PROTO_LIST ((A_MD5_CTX *, unsigned char *, unsigned int)); +void A_MD5Final PROTO_LIST ((A_MD5_CTX *, unsigned char *)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/dnssafe/md5rand.c b/lib/dns/sec/dnssafe/md5rand.c new file mode 100644 index 00000000..b5013d95 --- /dev/null +++ b/lib/dns/sec/dnssafe/md5rand.c @@ -0,0 +1,69 @@ +/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +/* Define this so that the type of the 'this' pointer in the + virtual functions will be correct for this derived class. + */ +struct A_MD5_RANDOM_CTX; +#define THIS_DIGEST_RANDOM struct A_MD5_RANDOM_CTX + +#include "global.h" +#include "algae.h" +#include "md5rand.h" + +static void A_MD5RandomDigestUpdate PROTO_LIST + ((A_MD5_RANDOM_CTX *, unsigned char *, unsigned int)); +static void A_MD5RandomDigestFinal PROTO_LIST + ((A_MD5_RANDOM_CTX *, unsigned char *)); + +static A_DigestRandomVTable V_TABLE = + {A_MD5RandomDigestUpdate, A_MD5RandomDigestFinal}; + +void A_MD5RandomInit (context) +A_MD5_RANDOM_CTX *context; +{ + /* Initialize "base class" */ + A_DigestRandomInit + (&context->digestRandom, A_MD5_DIGEST_LEN, context->state); + + /* Initialize digest algorithm and set vTable. + */ + A_MD5Init (&context->md5Context); + context->digestRandom.vTable = &V_TABLE; +} + +void A_MD5RandomUpdate (context, input, inputLen) +A_MD5_RANDOM_CTX *context; +unsigned char *input; +unsigned int inputLen; +{ + A_DigestRandomUpdate (&context->digestRandom, input, inputLen); +} + +void A_MD5RandomGenerateBytes (context, output, outputLen) +A_MD5_RANDOM_CTX *context; +unsigned char *output; +unsigned int outputLen; +{ + A_DigestRandomGenerateBytes (&context->digestRandom, output, outputLen); +} + +static void A_MD5RandomDigestUpdate (context, input, inputLen) +A_MD5_RANDOM_CTX *context; +unsigned char *input; +unsigned int inputLen; +{ + A_MD5Update (&context->md5Context, input, inputLen); +} + +static void A_MD5RandomDigestFinal (context, digest) +A_MD5_RANDOM_CTX *context; +unsigned char *digest; +{ + A_MD5Final (&context->md5Context, digest); +} diff --git a/lib/dns/sec/dnssafe/md5rand.h b/lib/dns/sec/dnssafe/md5rand.h new file mode 100644 index 00000000..f1974106 --- /dev/null +++ b/lib/dns/sec/dnssafe/md5rand.h @@ -0,0 +1,36 @@ +/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _MD5RAND_H_ +#define _MD5RAND_H_ 1 + +#include "digrand.h" +#include "md5.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct A_MD5_RANDOM_CTX { + A_DigestRandom digestRandom; /* "base class" */ + + unsigned char state[3 * A_MD5_DIGEST_LEN]; + A_MD5_CTX md5Context; +} A_MD5_RANDOM_CTX; + +void A_MD5RandomInit PROTO_LIST ((A_MD5_RANDOM_CTX *)); +void A_MD5RandomUpdate PROTO_LIST + ((A_MD5_RANDOM_CTX *, unsigned char *, unsigned int)); +void A_MD5RandomGenerateBytes PROTO_LIST + ((A_MD5_RANDOM_CTX *, unsigned char *, unsigned int)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/dnssafe/prime.c b/lib/dns/sec/dnssafe/prime.c new file mode 100644 index 00000000..f2832ea1 --- /dev/null +++ b/lib/dns/sec/dnssafe/prime.c @@ -0,0 +1,163 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ +#include "global.h" +#include "algae.h" +#include "bigmath.h" +#include "prime.h" + +static unsigned char SMALL_PRIME[]= {3, 5, 7, 11, 13, 17, 19, 23, 29, 31}; + +/* Prime finding routine. + Returns 0, AE_CANCEL, AE_NEED_RANDOM. + */ +int PrimeFind + (prime, primeSizeBits, primeWords, ee, modulusWords, randomBlock, + surrenderContext) +UINT2 *prime; +unsigned int primeSizeBits; +unsigned int primeWords; +UINT2 *ee; +unsigned int modulusWords; +unsigned char *randomBlock; +A_SURRENDER_CTX *surrenderContext; +{ + UINT2 t1[MAX_RSA_MODULUS_WORDS], u1[MAX_RSA_MODULUS_WORDS], + u2[MAX_RSA_MODULUS_WORDS], u3[MAX_RSA_MODULUS_WORDS], + u4[MAX_RSA_MODULUS_WORDS]; + char sieve[1000]; + int status = 0; + unsigned int i, r, s, testResult; + + do { + /* Create a starting point for the prime from the random block */ + for (i = 0; i < primeWords; i++) { + prime[i] = (UINT2)((UINT2)randomBlock[0] << 8) + randomBlock[1]; + randomBlock += 2; + } + + /* set high order two bits */ + BigSetbit (prime, primeSizeBits-2); + BigSetbit (prime, primeSizeBits-1); + for (i = primeSizeBits; i < (unsigned int)(16 * primeWords); i++) + BigClrbit (prime, i); + + /* force p to be even */ + BigClrbit (prime, 0); + + /* clear sieve and mark even positions */ + for (i = 0; i < 1000; i += 2) { + sieve[i] = 1; + sieve[i+1] = 0; + } + + /* sieve by all odd numbers (don't bother with primality checking) */ + for (s = 3; s < 9000; s += 2) { + /* increase likelihood that s is prime */ + for (i = 0; i < 5; i++) + if (s > SMALL_PRIME[i] && !(s % SMALL_PRIME[i])) + continue; + + /* sieve based on s */ + r = BigSmod (prime, s, primeWords); + + /* returns prime modulo s */ + if (r == 0) + r = s; + + for (i = s - r; i < 1000; i += s) + sieve[i] = 1; + } + + /* t1 = 1 */ + BigConst (t1, 1, modulusWords); + + /* now check for primality of values with unmarked sieve */ + testResult = 0; + for (i = 0; i < 1000; i++, BigInc (prime, primeWords)) { + if (sieve[i]) + continue; + + /* copy prime into big variable */ + BigZero (u4, modulusWords); + BigCopy (u4, prime, primeWords); + + /* set u4 = p - 1 */ + BigDec (u4, modulusWords); + BigPegcd (u1, u2, u3, ee, u4, modulusWords); + + /* Now u1 = gcd (E, t1). + Test (E, t1)==1 */ + if (BigCmp (t1, u1, modulusWords)) + continue; + + /* check for pseudo primality */ + if ((status = PseudoPrime + (&testResult, prime, primeWords, surrenderContext)) != 0) + break; + if (testResult) + /* testResult is set and will cause a break out of while (1) loop */ + break; + } + if (status) + break; + + if (!testResult) + /* Couldn't find a prime with the supplied random block, so ask + caller to generate another random block and try again. */ + status = AE_NEED_RANDOM; + } while (0); + + T_memset ((POINTER)u1, 0, sizeof (u1)); + T_memset ((POINTER)u2, 0, sizeof (u2)); + T_memset ((POINTER)u3, 0, sizeof (u3)); + T_memset ((POINTER)u4, 0, sizeof (u4)); + return (status); +} + +/* Pseudo-primality test. + If pseudo prime, *testResult = 1, else *testResult = 0. + Returns 0, AE_CANCEL. + */ +int PseudoPrime (testResult, prime, primeWords, surrenderContext) +unsigned int *testResult; +UINT2 *prime; +unsigned int primeWords; +A_SURRENDER_CTX *surrenderContext; +{ + UINT2 base[MAX_RSA_MODULUS_WORDS], remainder[MAX_RSA_MODULUS_WORDS]; + int status; + unsigned int i; + + /* Default testResult to false. */ + *testResult = 0; + + /* Prepare for setting base vector to the small prime. */ + T_memset ((POINTER)base, 0, sizeof (base)); + + for (i = 0; i < 4; i++) { + /* check to see if target is multiple of SMALL_PRIME */ + if (BigSmod (prime, (unsigned int)SMALL_PRIME[i], primeWords) == 0) + /* fail... */ + return (0); + + /* Fermat test. Compute remainder = base ^ prime mod prime + and compare the base to the remainder. + */ + base[0] = (UINT2)SMALL_PRIME[i]; + if ((status = BigModExp + (remainder, base, prime, prime, primeWords, surrenderContext)) != 0) + return (status); + if (BigCmp (remainder, base, primeWords) != 0) + /* fail... */ + return (0); + } + + *testResult = 1; + return (0); +} + diff --git a/lib/dns/sec/dnssafe/prime.h b/lib/dns/sec/dnssafe/prime.h new file mode 100644 index 00000000..e922f36a --- /dev/null +++ b/lib/dns/sec/dnssafe/prime.h @@ -0,0 +1,26 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _PRIME_H_ +#define _PRIME_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +int PrimeFind PROTO_LIST + ((UINT2 *, unsigned int, unsigned int, UINT2 *, unsigned int, + unsigned char *, A_SURRENDER_CTX *)); +int PseudoPrime PROTO_LIST + ((unsigned int *, UINT2 *, unsigned int, A_SURRENDER_CTX *)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/dnssafe/random.c b/lib/dns/sec/dnssafe/random.c new file mode 100644 index 00000000..44732d47 --- /dev/null +++ b/lib/dns/sec/dnssafe/random.c @@ -0,0 +1,58 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "bsafe2.h" +#include "bkey.h" +#include "balg.h" +#include "ainfotyp.h" +#include "algobj.h" + +int B_RandomInit + (algorithmObject, algorithmChooser, surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +B_ALGORITHM_CHOOSER algorithmChooser; +A_SURRENDER_CTX *surrenderContext; +{ + if (AlgorithmWrapCheck (THE_ALG_WRAP) != 0) + /* Assume error is B_ALGORITHM_OBJ */ + return (BE_RANDOM_OBJ); + + return (B_AlgorithmRandomInit + (&THE_ALG_WRAP->algorithm, algorithmChooser, surrenderContext)); +} + +int B_RandomUpdate (algorithmObject, input, inputLen, surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +unsigned char *input; +unsigned int inputLen; +A_SURRENDER_CTX *surrenderContext; +{ + if (AlgorithmWrapCheck (THE_ALG_WRAP) != 0) + /* Assume error is B_ALGORITHM_OBJ */ + return (BE_RANDOM_OBJ); + + return (B_AlgorithmRandomUpdate + (&THE_ALG_WRAP->algorithm, input, inputLen, surrenderContext)); +} + +int B_GenerateRandomBytes + (algorithmObject, output, outputLen, surrenderContext) +B_ALGORITHM_OBJ algorithmObject; +unsigned char *output; +unsigned int outputLen; +A_SURRENDER_CTX *surrenderContext; +{ + if (AlgorithmWrapCheck (THE_ALG_WRAP) != 0) + /* Assume error is B_ALGORITHM_OBJ */ + return (BE_RANDOM_OBJ); + + return (B_AlgorithmGenerateRandomBytes + (&THE_ALG_WRAP->algorithm, output, outputLen, surrenderContext)); +} + diff --git a/lib/dns/sec/dnssafe/rsa.c b/lib/dns/sec/dnssafe/rsa.c new file mode 100644 index 00000000..8cf24b32 --- /dev/null +++ b/lib/dns/sec/dnssafe/rsa.c @@ -0,0 +1,209 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "rsa.h" +#include "bigmath.h" + +/* RSA encryption/decryption with full exponent. + */ + +#define GENERATE_BREAK(type) { \ + status = type; \ + break; \ + } + +static int RSA PROTO_LIST + ((A_RSA_CTX *, unsigned char *, unsigned int *, unsigned int, + unsigned char *, A_SURRENDER_CTX *)); + +/* Returns 0, AE_MODULUS_LEN, AE_KEY_INFO. + */ +int A_RSAInit (context, key) +A_RSA_CTX *context; +A_RSA_KEY *key; +{ + if (A_IntegerBits (key->modulus.data, key->modulus.len) + > MAX_RSA_MODULUS_BITS) + /* Key size is too big to handle. */ + return (AE_MODULUS_LEN); + + /* Set the block update blockLen to be big enough to hold the modulus. */ + context->blockLen = + (A_IntegerBits (key->modulus.data, key->modulus.len) + 7) / 8; + + context->inputLen = 0; + + /* convert modulus to bignum representation */ + if (CanonicalToBig + (context->modulus, MAX_RSA_MODULUS_WORDS, key->modulus.data, + key->modulus.len)) + return (AE_KEY_INFO); + + /* compute significant length of modulus */ + context->modulusWords = BigLen + (context->modulus, MAX_RSA_MODULUS_WORDS) / 16 + 1; + + /* convert exponent to bignum representation */ + if (CanonicalToBig + (context->exponent, context->modulusWords, + key->exponent.data, key->exponent.len)) + return (AE_KEY_INFO); + + return (0); +} + +int A_RSAUpdate + (context, partOut, partOutLen, maxPartOutLen, partIn, partInLen, + surrenderContext) +A_RSA_CTX *context; +unsigned char *partOut; +unsigned int *partOutLen; +unsigned int maxPartOutLen; +unsigned char *partIn; +unsigned int partInLen; +A_SURRENDER_CTX *surrenderContext; +{ + int status; + unsigned int partialLen, localPartOutLen; + + /* Initialize partOutLen to zero. */ + *partOutLen = 0; + + if (context->inputLen + partInLen < context->blockLen) { + /* Not enough to encrypt - just accumulate. + */ + T_memcpy + ((POINTER)(context->input + context->inputLen), (POINTER)partIn, + partInLen); + context->inputLen += partInLen; + return (0); + } + + if (context->inputLen > 0) { + /* Need to accumulate the rest of the block bytes into the input and + encrypt from there (otherwise it's OK to encrypt straight from + the partIn). + */ + partialLen = context->blockLen - context->inputLen; + T_memcpy + ((POINTER)(context->input + context->inputLen), (POINTER)partIn, + partialLen); + partIn += partialLen; + partInLen -= partialLen; + + if ((status = RSA + (context, partOut, &localPartOutLen, maxPartOutLen, context->input, + surrenderContext)) != 0) + return (status); + (*partOutLen) += localPartOutLen; + partOut += localPartOutLen; + maxPartOutLen -= localPartOutLen; + } + + /* Encrypt as many blocks of input as provided. + */ + while (partInLen >= context->blockLen) { + if ((status = RSA + (context, partOut, &localPartOutLen, maxPartOutLen, partIn, + surrenderContext)) != 0) + return (status); + + partIn += context->blockLen; + partInLen -= context->blockLen; + (*partOutLen) += localPartOutLen; + partOut += localPartOutLen; + maxPartOutLen -= localPartOutLen; + } + + /* Copy remaining input bytes to the context's input buffer. + */ + T_memcpy + ((POINTER)context->input, partIn, context->inputLen = partInLen); + return (0); +} + +int A_RSAFinal (context) +A_RSA_CTX *context; +{ + if (context->inputLen != 0) + return (AE_INPUT_LEN); + + /* Restart context to accumulate a new block. */ + context->inputLen = 0; + return (0); +} + +/* Assume input length is context->blockLen. + */ +static int RSA + (context, output, outputLen, maxOutputLen, input, surrenderContext) +A_RSA_CTX *context; +unsigned char *output; +unsigned int *outputLen; +unsigned int maxOutputLen; +unsigned char *input; +A_SURRENDER_CTX *surrenderContext; +{ + struct ModExpFrame { + UINT2 bigInBuf[MAX_RSA_MODULUS_WORDS], bigOutBuf[MAX_RSA_MODULUS_WORDS]; + } *frame = (struct ModExpFrame *)NULL_PTR; +#if !USE_ALLOCED_FRAME + struct ModExpFrame stackFrame; +#endif + int status; + + status = 0; + do { + if ((*outputLen = context->blockLen) > maxOutputLen) + return (AE_OUTPUT_LEN); + +#if USE_ALLOCED_FRAME + if ((frame = (struct ModExpFrame *)T_malloc (sizeof (*frame))) + == (struct ModExpFrame *)NULL_PTR) { + status = AE_ALLOC; + break; + } +#else + /* Just use the buffers allocated on the stack. */ + frame = &stackFrame; +#endif + + /* Convert input to bignum representation. + This won't return AE_DATA since input length was checked at Update. + */ + CanonicalToBig + (frame->bigInBuf, context->modulusWords, input, context->blockLen); + + /* Check for overflow. */ + if (BigCmp (frame->bigInBuf, context->modulus, context->modulusWords) >= 0) + GENERATE_BREAK (AE_INPUT_DATA); + + /* Exponentiate. */ + if ((status = BigModExp + (frame->bigOutBuf, frame->bigInBuf, context->exponent, + context->modulus, context->modulusWords, surrenderContext)) != 0) + break; + + /* Convert output to canonical representation. + This won't return AE_DATA since outputLen was set above. + */ + BigToCanonical + (output, *outputLen, frame->bigOutBuf, context->modulusWords); + } while (0); + + if (frame != (struct ModExpFrame *)NULL_PTR) { + T_memset ((POINTER)frame, 0, sizeof (*frame)); +#if USE_ALLOCED_FRAME + T_free ((POINTER)frame); +#endif + } + + return (status); +} diff --git a/lib/dns/sec/dnssafe/rsa.h b/lib/dns/sec/dnssafe/rsa.h new file mode 100644 index 00000000..2d86099a --- /dev/null +++ b/lib/dns/sec/dnssafe/rsa.h @@ -0,0 +1,44 @@ +/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _RSA_H_ +#define _RSA_H_ 1 + +#include "bigmaxes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Note, these are only valid after a call to A_RSAInit. + */ +#define A_RSA_BLOCK_LEN(context) ((context)->blockLen) +#define A_RSA_MAX_OUTPUT_LEN(context, inputLen)\ + (inputLen) + (((inputLen) % (context)->blockLen) ?\ + (context)->blockLen - ((inputLen) % (context)->blockLen) : 0) + +typedef struct { + unsigned int blockLen; /* total size for the block to be computed */ + unsigned char input[MAX_RSA_MODULUS_LEN]; + unsigned int inputLen; + unsigned int modulusWords; + UINT2 modulus[MAX_RSA_MODULUS_WORDS]; + UINT2 exponent[MAX_RSA_MODULUS_WORDS]; +} A_RSA_CTX; + +int A_RSAInit PROTO_LIST ((A_RSA_CTX *, A_RSA_KEY *)); +int A_RSAUpdate PROTO_LIST + ((A_RSA_CTX *, unsigned char *, unsigned int *, unsigned int, + unsigned char *, unsigned int, A_SURRENDER_CTX *)); +int A_RSAFinal PROTO_LIST ((A_RSA_CTX *)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/dnssafe/rsakeygn.c b/lib/dns/sec/dnssafe/rsakeygn.c new file mode 100644 index 00000000..685fb71c --- /dev/null +++ b/lib/dns/sec/dnssafe/rsakeygn.c @@ -0,0 +1,242 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "bigmath.h" +#include "surrendr.h" +#include "prime.h" +#include "rsakeygn.h" + +#define GENERATE_BREAK(type) { \ + status = type; \ + break; \ + } + +static int RSAParameters PROTO_LIST + ((UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, UINT2 *, + unsigned int, unsigned int, A_SURRENDER_CTX *)); +static void SetRSAKeyGenResult PROTO_LIST + ((A_PKCS_RSA_PRIVATE_KEY *, A_RSA_KEY_GEN_CTX *, UINT2 *, UINT2 *)); + +int A_RSAKeyGenInit (context, params) +A_RSA_KEY_GEN_CTX *context; +A_RSA_KEY_GEN_PARAMS *params; +{ + context->modulusBits = params->modulusBits; + + /* Prezeroize big public exponent vector. */ + T_memset + ((POINTER)context->bigPublicExponent, 0, + sizeof (context->bigPublicExponent)); + + /* Copy public exponent into big vector */ + if (CanonicalToBig + (context->bigPublicExponent, MAX_RSA_MODULUS_WORDS, + params->publicExponent.data, params->publicExponent.len) != 0) + /* could not copy exponent into MAX_RSA_MODULUS_WORDS */ + return (AE_EXPONENT_LEN); + + /* Check that public exponent is in bounds and odd. + */ + if (BigLen (context->bigPublicExponent, MAX_RSA_MODULUS_WORDS) >= + context->modulusBits) + return (AE_EXPONENT_LEN); + if (!(context->bigPublicExponent[0] & 1)) + return (AE_EXPONENT_EVEN); + + return (0); +} + +/* This generates an RSA keypair of size modulusBits with the fixed + publicExponent, pointing result to the resulting integers. The + resulting integer data is in the context, so that the values must be + copied before the context is zeroized. + All integers are unsigned canonical bytes arrays with the most significant + byte first. + The randomBlock is of length randomBlockLen returned by RSAKeyGenQuery. + This assumes that the modulusBits size was checked by RSAKeyGenQuery. + */ +int A_RSAKeyGen (context, result, randomBlock, surrenderContext) +A_RSA_KEY_GEN_CTX *context; +A_PKCS_RSA_PRIVATE_KEY **result; +unsigned char *randomBlock; +A_SURRENDER_CTX *surrenderContext; +{ + UINT2 *bigPrimeP, *bigPrimeQ; + int status; + unsigned int modulusWords, primeSizeBits, primeWords; + + /* Prezeroize all big word vectors. */ + T_memset ((POINTER)context->bigModulus, 0, sizeof (context->bigModulus)); + T_memset + ((POINTER)context->bigPrivateExponent, 0, + sizeof (context->bigPrivateExponent)); + T_memset ((POINTER)context->bigPrime1, 0, sizeof (context->bigPrime1)); + T_memset ((POINTER)context->bigPrime2, 0, sizeof (context->bigPrime2)); + T_memset ((POINTER)context->bigExponentP, 0, sizeof (context->bigExponentP)); + T_memset ((POINTER)context->bigExponentQ, 0, sizeof (context->bigExponentQ)); + T_memset + ((POINTER)context->bigCoefficient, 0, sizeof (context->bigCoefficient)); + + /* prime size is half modulus size */ + modulusWords = BITS_TO_WORDS (context->modulusBits); + primeSizeBits = RSA_PRIME_BITS (context->modulusBits); + primeWords = BITS_TO_WORDS (RSA_PRIME_BITS (context->modulusBits)); + + /* Fish for bigPrime1 and bigPrime2 that are compatible with supplied + publicExponent. + The randomBlock holds random bytes for two primes. + */ + if ((status = PrimeFind + (context->bigPrime1, primeSizeBits, primeWords, + context->bigPublicExponent, modulusWords, randomBlock, + surrenderContext)) != 0) + return (status); + if ((status = PrimeFind + (context->bigPrime2, context->modulusBits - primeSizeBits, + primeWords, context->bigPublicExponent, modulusWords, + randomBlock + (2 * primeWords), surrenderContext)) != 0) + return (status); + + /* Set bigPrimeP to the larger of bigPrime1 and bigPrime2 and set + bigPrimeQ to the smaller. + */ + if (BigCmp (context->bigPrime1, context->bigPrime2, primeWords) == 1) { + bigPrimeP = context->bigPrime1; + bigPrimeQ = context->bigPrime2; + } + else { + bigPrimeP = context->bigPrime2; + bigPrimeQ = context->bigPrime1; + } + + /* Calculate the rest of the key components */ + if ((status = RSAParameters + (context->bigModulus, context->bigCoefficient, + context->bigExponentP, context->bigExponentQ, + context->bigPrivateExponent, context->bigPublicExponent, + bigPrimeP, bigPrimeQ, primeWords, modulusWords, surrenderContext)) != 0) + return (status); + + /* Copy key components into canonical buffers which are at the + end of the context. */ + *result = &context->result; + SetRSAKeyGenResult (*result, context, bigPrimeP, bigPrimeQ); + + return (0); +} + +/* Assumes ee, pp, qq are given, calculates other parameters. + Returns 0, AE_CANCEL. + */ +static int RSAParameters + (nn, cr, dp, dq, dd, ee, pp, qq, primeWords, modulusWords, surrenderContext) +UINT2 *nn, *cr, *dp, *dq, *dd, *ee, *pp, *qq; +unsigned int primeWords, modulusWords; +A_SURRENDER_CTX *surrenderContext; +{ + UINT2 t1[2 * MAX_RSA_PRIME_WORDS], t2[MAX_RSA_PRIME_WORDS], + t3[MAX_RSA_MODULUS_WORDS], u1[MAX_RSA_MODULUS_WORDS], + u3[MAX_RSA_MODULUS_WORDS], pm1[MAX_RSA_PRIME_WORDS], + qm1[MAX_RSA_PRIME_WORDS]; + int status; + + do { + /* N=P*Q */ + BigMpy (t1, pp, qq, primeWords); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + BigCopy (nn, t1, modulusWords); + + /* qm1=q-1 & pm1=p-1 */ + BigConst (t1, 1, primeWords); + BigSub (qm1, qq, t1, primeWords); + BigSub (pm1, pp, t1, primeWords); + + /* t3=1 */ + BigConst (t3, 1, modulusWords); + + /*t1=phi (N) */ + BigMpy (t1, pm1, qm1, primeWords); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + + /* compute decryption exponent */ + BigPegcd (u1, dd, u3, ee, t1, modulusWords); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + + /* calc DP=inv (E)[mod (P-1)] & DQ=inv (e)[mod (Q-1)] */ + BigPdiv (t1, dp, dd, pm1, modulusWords, primeWords); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + BigPdiv (t1, dq, dd, qm1, modulusWords, primeWords); + if ((status = CheckSurrender (surrenderContext)) != 0) + break; + + /* calc CR = (inv (Q)[modP]) */ + BigPegcd (t1, t2, cr, pp, qq, primeWords); + } while (0); + + T_memset ((POINTER)t1, 0, sizeof (t1)); + T_memset ((POINTER)t2, 0, sizeof (t2)); + T_memset ((POINTER)t3, 0, sizeof (t3)); + T_memset ((POINTER)u1, 0, sizeof (u1)); + T_memset ((POINTER)u3, 0, sizeof (u3)); + T_memset ((POINTER)pm1, 0, sizeof (pm1)); + T_memset ((POINTER)qm1, 0, sizeof (qm1)); + return (status); +} + +static void SetRSAKeyGenResult (result, context, bigPrimeP, bigPrimeQ) +A_PKCS_RSA_PRIVATE_KEY *result; +A_RSA_KEY_GEN_CTX *context; +UINT2 *bigPrimeP; +UINT2 *bigPrimeQ; +{ + unsigned int primeLen, modulusLen; + + modulusLen = result->modulus.len = result->publicExponent.len = + result->privateExponent.len = BITS_TO_LEN (context->modulusBits); + primeLen = result->prime[0].len = result->prime[1].len = + result->primeExponent[0].len = result->primeExponent[1].len = + result->coefficient.len = RSA_PRIME_LEN (context->modulusBits); + + result->modulus.data = context->resultBuffer; + result->publicExponent.data = result->modulus.data + modulusLen; + result->privateExponent.data = result->publicExponent.data + modulusLen; + result->prime[0].data = result->privateExponent.data + modulusLen; + result->prime[1].data = result->prime[0].data + primeLen; + result->primeExponent[0].data = result->prime[1].data + primeLen; + result->primeExponent[1].data = result->primeExponent[0].data + primeLen; + result->coefficient.data = result->primeExponent[1].data + primeLen; + + BigToCanonical + (result->modulus.data, modulusLen, context->bigModulus, + MAX_RSA_MODULUS_WORDS); + BigToCanonical + (result->publicExponent.data, modulusLen, + context->bigPublicExponent, MAX_RSA_MODULUS_WORDS); + BigToCanonical + (result->privateExponent.data, modulusLen, + context->bigPrivateExponent, MAX_RSA_MODULUS_WORDS); + BigToCanonical + (result->prime[0].data, primeLen, bigPrimeP, MAX_RSA_PRIME_WORDS); + BigToCanonical + (result->prime[1].data, primeLen, bigPrimeQ, MAX_RSA_PRIME_WORDS); + BigToCanonical + (result->primeExponent[0].data, primeLen, context->bigExponentP, + MAX_RSA_PRIME_WORDS); + BigToCanonical + (result->primeExponent[1].data, primeLen, context->bigExponentQ, + MAX_RSA_PRIME_WORDS); + BigToCanonical + (result->coefficient.data, primeLen, context->bigCoefficient, + MAX_RSA_PRIME_WORDS); +} diff --git a/lib/dns/sec/dnssafe/rsakeygn.h b/lib/dns/sec/dnssafe/rsakeygn.h new file mode 100644 index 00000000..ba40b864 --- /dev/null +++ b/lib/dns/sec/dnssafe/rsakeygn.h @@ -0,0 +1,54 @@ +/* Copyright (C) RSA Data Security, Inc. created 1994, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _RSAKEYGN_H_ +#define _RSAKEYGN_H_ 1 + +#include "bigmaxes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MIN_RSA_MODULUS_BITS 256 + +/* Need randomBlock to hold bytes for two UINT2 prime number arrays each, + of length primeWords = BITS_TO_WORDS (RSA_PRIME_BITS (modulusBits)). */ +#define A_RSA_KEY_GEN_RANDOM_BLOCK_LEN(modulusBits) \ + (4 * BITS_TO_WORDS (RSA_PRIME_BITS (modulusBits))) + +/* Note that the scratch area for the output integers is allocated + in the context after the RSA_KEY_GEN_CTX. + */ +typedef struct { + unsigned int modulusBits; + UINT2 bigModulus[MAX_RSA_MODULUS_WORDS]; + UINT2 bigPublicExponent[MAX_RSA_MODULUS_WORDS]; + UINT2 bigPrivateExponent[MAX_RSA_MODULUS_WORDS]; + UINT2 bigPrime1[MAX_RSA_PRIME_WORDS]; + UINT2 bigPrime2[MAX_RSA_PRIME_WORDS]; + UINT2 bigExponentP[MAX_RSA_PRIME_WORDS]; + UINT2 bigExponentQ[MAX_RSA_PRIME_WORDS]; + UINT2 bigCoefficient[MAX_RSA_PRIME_WORDS]; + A_PKCS_RSA_PRIVATE_KEY result; + unsigned char resultBuffer + [3 * BITS_TO_LEN (MAX_RSA_MODULUS_BITS) + + 5 * RSA_PRIME_LEN (MAX_RSA_MODULUS_BITS)]; +} A_RSA_KEY_GEN_CTX; + +int A_RSAKeyGenInit PROTO_LIST ((A_RSA_KEY_GEN_CTX *, A_RSA_KEY_GEN_PARAMS *)); +int A_RSAKeyGen PROTO_LIST + ((A_RSA_KEY_GEN_CTX *, A_PKCS_RSA_PRIVATE_KEY **, unsigned char *, + A_SURRENDER_CTX *)); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/lib/dns/sec/dnssafe/seccbcd.c b/lib/dns/sec/dnssafe/seccbcd.c new file mode 100644 index 00000000..52dafd69 --- /dev/null +++ b/lib/dns/sec/dnssafe/seccbcd.c @@ -0,0 +1,146 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "secrcbc.h" + +static void SecretCBCDecryptBlock PROTO_LIST + ((POINTER, unsigned char *, SECRET_CRYPT, unsigned char *, + unsigned char *)); + +/* On first call, it is assumed that *remainderLen is zero. + This assumes remainder buffer is at least 16 bytes is size. + Returns AE_OUTPUT_LEN, 0. + */ +int SecretCBCDecryptUpdate + (context, xorBlock, remainder, remainderLen, SecretDecrypt, output, + outputLen, maxOutputLen, input, inputLen) +POINTER context; +unsigned char *xorBlock; +unsigned char *remainder; +unsigned int *remainderLen; +SECRET_CRYPT SecretDecrypt; +unsigned char *output; +unsigned int *outputLen; +unsigned int maxOutputLen; +unsigned char *input; +unsigned int inputLen; +{ + unsigned int partialLen; + + if (*remainderLen + inputLen <= 16) { + /* Not enough to decrypt, just accumulate into remainder. + */ + *outputLen = 0; + T_memcpy ((POINTER)remainder + *remainderLen, (POINTER)input, inputLen); + *remainderLen += inputLen; + return (0); + } + + /* Fill up the rest of the remainder with bytes from input. + */ + T_memcpy + ((POINTER)remainder + *remainderLen, (POINTER)input, + partialLen = 16 - *remainderLen); + input += partialLen; + inputLen -= partialLen; + + /* remainder is full and inputLen is at least 1. Compute outputLen + as the size needed to keep remainder as full as possible. + */ + if ((*outputLen = 8 * ((inputLen + 7) / 8)) > maxOutputLen) + return (AE_OUTPUT_LEN); + + SecretCBCDecryptBlock + (context, xorBlock, SecretDecrypt, output, remainder); + output += 8; + + if (inputLen <= 8) { + /* Shift remaining input bytes into remainder */ + T_memmove ((POINTER)remainder, (POINTER)(remainder + 8), 8); + T_memcpy ((POINTER)(remainder + 8), (POINTER)input, inputLen); + *remainderLen = 8 + inputLen; + return (0); + } + + /* Decrypt the rest of the remainder. + */ + SecretCBCDecryptBlock + (context, xorBlock, SecretDecrypt, output, remainder + 8); + output += 8; + + /* Now decrypt the bulk of the input. + */ + while (inputLen > 16) { + SecretCBCDecryptBlock (context, xorBlock, SecretDecrypt, output, input); + output += 8; + input += 8; + inputLen -= 8; + } + + /* inputLen is now <= 16, so copy input to remainder. + */ + T_memcpy ((POINTER)remainder, (POINTER)input, inputLen); + *remainderLen = inputLen; + return (0); +} + +/* The caller must restart the context (setting remainderLen to zero). + Returns AE_INPUT_LEN, AE_OUTPUT_LEN, 0. + */ +int SecretCBCDecryptFinal + (context, xorBlock, remainder, remainderLen, SecretDecrypt, output, + outputLen, maxOutputLen) +POINTER context; +unsigned char *xorBlock; +unsigned char *remainder; +unsigned int remainderLen; +SECRET_CRYPT SecretDecrypt; +unsigned char *output; +unsigned int *outputLen; +unsigned int maxOutputLen; +{ + if ((*outputLen = remainderLen) == 0) + /* There was never any data. */ + return (0); + + if (remainderLen != 8 && remainderLen != 16) + return (AE_INPUT_LEN); + + if (*outputLen > maxOutputLen) + return (AE_OUTPUT_LEN); + + SecretCBCDecryptBlock + (context, xorBlock, SecretDecrypt, output, remainder); + output += 8; + if (remainderLen == 16) + SecretCBCDecryptBlock + (context, xorBlock, SecretDecrypt, output, remainder + 8); + return (0); +} + +static void SecretCBCDecryptBlock (context, xorBlock, SecretDecrypt, out, in) +POINTER context; +unsigned char *xorBlock; +SECRET_CRYPT SecretDecrypt; +unsigned char *out; +unsigned char *in; +{ + unsigned char tempBuffer[8]; + unsigned int i; + + /* Save input to be copied to the xor block. */ + T_memcpy ((POINTER)tempBuffer, (POINTER)in, 8); + (*SecretDecrypt) (context, out, in); + for (i = 0; i < 8; i++) + out[i] ^= xorBlock[i]; + T_memcpy ((POINTER)xorBlock, (POINTER)tempBuffer, 8); + + T_memset ((POINTER)tempBuffer, 0, sizeof (tempBuffer)); +} diff --git a/lib/dns/sec/dnssafe/seccbce.c b/lib/dns/sec/dnssafe/seccbce.c new file mode 100644 index 00000000..6fe5c863 --- /dev/null +++ b/lib/dns/sec/dnssafe/seccbce.c @@ -0,0 +1,97 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "secrcbc.h" + +/* On first call, it is assumed that *remainderLen is zero. + Returns AE_OUTPUT_LEN, 0. + */ +int SecretCBCEncryptUpdate + (context, xorBlock, remainder, remainderLen, SecretEncrypt, output, + outputLen, maxOutputLen, input, inputLen) +POINTER context; +unsigned char *xorBlock; +unsigned char *remainder; +unsigned int *remainderLen; +SECRET_CRYPT SecretEncrypt; +unsigned char *output; +unsigned int *outputLen; +unsigned int maxOutputLen; +unsigned char *input; +unsigned int inputLen; +{ + unsigned int partialLen, totalLen, i; + + totalLen = *remainderLen + inputLen; + + /* Output length will be all available 8-byte blocks. + */ + if ((*outputLen = 8 * (totalLen / 8)) > maxOutputLen) + return (AE_OUTPUT_LEN); + + if (totalLen < 8) { + /* Not enough to encrypt, just accumulate into remainder. + */ + T_memcpy + ((POINTER)remainder + *remainderLen, (POINTER)input, inputLen); + *remainderLen = totalLen; + + return (0); + } + + /* Accumulate enough bytes from input into remainder to encrypt the + remainder. + */ + T_memcpy + ((POINTER)remainder + *remainderLen, (POINTER)input, + partialLen = 8 - *remainderLen); + + for (i = 0; i < 8; i++) + output[i] = remainder[i] ^ xorBlock[i]; + /* Encrypt in place */ + (*SecretEncrypt) (context, output, output); + + T_memcpy ((POINTER)xorBlock, (POINTER)output, 8); + input += partialLen; + inputLen -= partialLen; + output += 8; + + /* Now encrypt the bulk of the input. + */ + while (inputLen >= 8) { + for (i = 0; i < 8; i++) + output[i] = *(input++) ^ xorBlock[i]; + /* Encrypt in place */ + (*SecretEncrypt) (context, output, output); + T_memcpy ((POINTER)xorBlock, (POINTER)output, 8); + output += 8; + inputLen -= 8; + } + + /* inputLen is now < 8, so copy input to remainder. + */ + T_memcpy ((POINTER)remainder, (POINTER)input, inputLen); + *remainderLen = inputLen; + + return (0); +} + +/* This just ensures that *remainderLen is zero. + The caller must restart the context (setting remainderLen to zero). + Returns AE_INPUT_LEN, 0. + */ +int SecretCBCEncryptFinal (remainderLen) +unsigned int remainderLen; +{ + if (remainderLen != 0) + return (AE_INPUT_LEN); + + return (0); +} diff --git a/lib/dns/sec/dnssafe/secrcbc.h b/lib/dns/sec/dnssafe/secrcbc.h new file mode 100644 index 00000000..122f83f5 --- /dev/null +++ b/lib/dns/sec/dnssafe/secrcbc.h @@ -0,0 +1,36 @@ +/* Copyright (C) RSA Data Security, Inc. created 1990, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _SECRCBC_H_ +#define _SECRCBC_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*SECRET_CRYPT) PROTO_LIST + ((POINTER, unsigned char *, unsigned char *)); + +int SecretCBCEncryptUpdate PROTO_LIST + ((POINTER, unsigned char *, unsigned char *, unsigned int *, SECRET_CRYPT, + unsigned char *, unsigned int *, unsigned int, unsigned char *, + unsigned int)); +int SecretCBCEncryptFinal PROTO_LIST ((unsigned int)); +int SecretCBCDecryptUpdate PROTO_LIST + ((POINTER, unsigned char *, unsigned char *, unsigned int *, SECRET_CRYPT, + unsigned char *, unsigned int *, unsigned int, unsigned char *, + unsigned int)); +int SecretCBCDecryptFinal PROTO_LIST + ((POINTER, unsigned char *, unsigned char *, unsigned int, SECRET_CRYPT, + unsigned char *, unsigned int *, unsigned int)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/dnssafe/surrendr.c b/lib/dns/sec/dnssafe/surrendr.c new file mode 100644 index 00000000..c9aa460e --- /dev/null +++ b/lib/dns/sec/dnssafe/surrendr.c @@ -0,0 +1,24 @@ +/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#include "global.h" +#include "algae.h" +#include "surrendr.h" + +/* Returns 0, AE_CANCEL. + */ +int CheckSurrender (surrenderContext) +A_SURRENDER_CTX *surrenderContext; +{ + if (surrenderContext == (A_SURRENDER_CTX *)NULL_PTR) + return (0); + + if ((*surrenderContext->Surrender) (surrenderContext->handle)) + return (AE_CANCEL); + return (0); +} diff --git a/lib/dns/sec/dnssafe/surrendr.h b/lib/dns/sec/dnssafe/surrendr.h new file mode 100644 index 00000000..dc929046 --- /dev/null +++ b/lib/dns/sec/dnssafe/surrendr.h @@ -0,0 +1,22 @@ +/* Copyright (C) RSA Data Security, Inc. created 1992, 1996. This is an + unpublished work protected as such under copyright law. This work + contains proprietary, confidential, and trade secret information of + RSA Data Security, Inc. Use, disclosure or reproduction without the + express written authorization of RSA Data Security, Inc. is + prohibited. + */ + +#ifndef _SURRENDR_H_ +#define _SURRENDR_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +int CheckSurrender PROTO_LIST ((A_SURRENDER_CTX *)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/dst/.cvsignore b/lib/dns/sec/dst/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/lib/dns/sec/dst/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/lib/dns/sec/dst/Makefile.in b/lib/dns/sec/dst/Makefile.in new file mode 100644 index 00000000..b881b2bc --- /dev/null +++ b/lib/dns/sec/dst/Makefile.in @@ -0,0 +1,44 @@ +# Copyright (C) 1998, 1999, 2000 Internet Software Consortium. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS +# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE +# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +# SOFTWARE. + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_INCLUDES@ + +CINCLUDES = -I${srcdir} \ + -I${srcdir}/../dnssafe \ + -I${srcdir}/../openssl/include \ + ${DNS_INCLUDES} ${ISC_INCLUDES} + +CDEFINES = -DUSE_MD5 -DDNSSAFE -DOPENSSL +CWARNINGS = + +LIBS = @LIBS@ + +# Alphabetically +OBJS = bsafe_link.@O@ dst_api.@O@ dst_parse.@O@ hmac_link.@O@ \ + openssl_link.@O@ openssldh_link.@O@ opensslmd5_link.@O@ \ + dst_result.@O@ dst_support.@O@ dst_lib.@O@ + +SRCS = bsafe_link.c dst_api.c dst_parse.c hmac_link.c \ + openssl_link.c openssldh_link.c opensslmd5_link.c \ + dst_result.c dst_support.c dst_lib.c + +SUBDIRS = include +TARGETS = ${OBJS} + +@BIND9_MAKE_RULES@ diff --git a/lib/dns/sec/dst/bsafe_link.c b/lib/dns/sec/dst/bsafe_link.c new file mode 100644 index 00000000..05fc9d96 --- /dev/null +++ b/lib/dns/sec/dst/bsafe_link.c @@ -0,0 +1,1093 @@ +#if defined(BSAFE) || defined(DNSSAFE) + +/* + * Portions Copyright (c) 1995-1999 by Network Associates, Inc. + * + * Permission to use, copy modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. + */ + +/* + * Principal Author: Brian Wellington + * $Id: bsafe_link.c,v 1.11 1999/10/29 12:56:56 marka Exp $ + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <memory.h> + +#include <isc/assertions.h> +#include <isc/buffer.h> +#include <isc/int.h> +#include <isc/region.h> + +#include <dns/keyvalues.h> + +#include "dst_internal.h" +#include "dst_parse.h" + +# ifdef BSAFE +# include <aglobal.h> +# include <bsafe.h> +# else +# include <global.h> +# include <bsafe2.h> +# endif + +typedef struct bsafekey { + B_KEY_OBJ rk_Private_Key; + B_KEY_OBJ rk_Public_Key; +} RSA_Key; + +#define MAX_RSA_MODULUS_BITS 2048 +#define MAX_RSA_MODULUS_LEN (MAX_RSA_MODULUS_BITS/8) +#define MAX_RSA_PRIME_LEN (MAX_RSA_MODULUS_LEN/2) + +#define NULL_SURRENDER (A_SURRENDER_CTX *)NULL_PTR +#define NULL_RANDOM (B_ALGORITHM_OBJ)NULL_PTR + +static struct dst_func bsafe_functions; + +static B_ALGORITHM_METHOD *CHOOSER[] = +{ + &AM_MD5, + &AM_MD5_RANDOM, + &AM_RSA_KEY_GEN, + &AM_RSA_ENCRYPT, + &AM_RSA_DECRYPT, + &AM_RSA_CRT_ENCRYPT, + &AM_RSA_CRT_DECRYPT, + (B_ALGORITHM_METHOD *) NULL_PTR +}; + +static unsigned char pkcs1[] = +{ + 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, + 0x04, 0x10 +}; + +static dst_result_t dst_bsafe_md5digest(const unsigned int mode, + B_ALGORITHM_OBJ *digest_obj, + isc_region_t *data, + isc_buffer_t *digest); + +static int dst_bsafe_key_size(RSA_Key *r_key); +static isc_boolean_t dst_s_bsafe_itemcmp(ITEM i1, ITEM i2); + +static dst_result_t dst_bsafe_sign(const unsigned int mode, dst_key_t *key, + void **context, isc_region_t *data, + isc_buffer_t *sig, isc_mem_t *mctx); +static dst_result_t dst_bsafe_verify(const unsigned int mode, + dst_key_t *key, + void **context, isc_region_t *data, + isc_region_t *sig, isc_mem_t *mctx); +static isc_boolean_t dst_bsafe_compare(const dst_key_t *key1, + const dst_key_t *key2); +static dst_result_t dst_bsafe_generate(dst_key_t *key, int exp, + isc_mem_t *mctx); +static isc_boolean_t dst_bsafe_isprivate(const dst_key_t *key); +static void dst_bsafe_destroy(void *key, isc_mem_t *mctx); +static dst_result_t dst_bsafe_to_dns(const dst_key_t *in_key, + isc_buffer_t *data); +static dst_result_t dst_bsafe_from_dns(dst_key_t *key, isc_buffer_t *data, + isc_mem_t *mctx); +static dst_result_t dst_bsafe_to_file(const dst_key_t *key); +static dst_result_t dst_bsafe_from_file(dst_key_t *key, + const isc_uint16_t id, + isc_mem_t *mctx); + +/* + * dst_s_bsafersa_init() + * Sets up function pointers for BSAFE/DNSSAFE related functions + */ +void +dst_s_bsafersa_init() { + REQUIRE(dst_t_func[DST_ALG_RSA] == NULL); + dst_t_func[DST_ALG_RSA] = &bsafe_functions; + memset(&bsafe_functions, 0, sizeof(struct dst_func)); + bsafe_functions.sign = dst_bsafe_sign; + bsafe_functions.verify = dst_bsafe_verify; + bsafe_functions.computesecret = NULL; + bsafe_functions.compare = dst_bsafe_compare; + bsafe_functions.paramcompare = NULL; + bsafe_functions.generate = dst_bsafe_generate; + bsafe_functions.isprivate = dst_bsafe_isprivate; + bsafe_functions.destroy = dst_bsafe_destroy; + bsafe_functions.to_dns = dst_bsafe_to_dns; + bsafe_functions.from_dns = dst_bsafe_from_dns; + bsafe_functions.to_file = dst_bsafe_to_file; + bsafe_functions.from_file = dst_bsafe_from_file; +} + +/* + * dst_bsafe_sign + * Call BSAFE signing functions to sign a block of data. + * There are three steps to signing, INIT (initialize structures), + * UPDATE (hash (more) data), FINAL (generate a signature). This + * routine performs one or more of these steps. + * Parameters + * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL} + * key key to use for signing + * context the context to use for this computation + * data data to be signed + * signature buffer to store signature + * mctx memory context for temporary allocations + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_bsafe_sign(const unsigned int mode, dst_key_t *key, void **context, + isc_region_t *data, isc_buffer_t *sig, isc_mem_t *mctx) +{ + int status = 0; + B_ALGORITHM_OBJ *md5_ctx = NULL; + unsigned char digest_array[DNS_SIG_RSAMAXSIZE]; + isc_buffer_t digest; + isc_region_t sig_region, digest_region; + dst_result_t ret; + + if (mode & DST_SIGMODE_INIT) { + md5_ctx = (B_ALGORITHM_OBJ *) isc_mem_get(mctx, + sizeof(*md5_ctx)); + if (md5_ctx == NULL) + return (ISC_R_NOMEMORY); + if ((status = B_CreateAlgorithmObject(md5_ctx)) != 0) + return (ISC_R_NOMEMORY); + if ((status = B_SetAlgorithmInfo(*md5_ctx, AI_MD5, NULL)) != 0) + return (ISC_R_NOMEMORY); + } + else if (context != NULL) + md5_ctx = (B_ALGORITHM_OBJ *) *context; + REQUIRE (md5_ctx != NULL); + + isc_buffer_init(&digest, digest_array, sizeof(digest_array), + ISC_BUFFERTYPE_BINARY); + ret = dst_bsafe_md5digest(mode, md5_ctx, data, &digest); + if (ret != ISC_R_SUCCESS || (mode & DST_SIGMODE_FINAL)) { + B_DestroyAlgorithmObject(md5_ctx); + memset(md5_ctx, 0, sizeof(*md5_ctx)); + isc_mem_put(mctx, md5_ctx, sizeof(*md5_ctx)); + if (ret != ISC_R_SUCCESS) + return (ret); + } + + if (mode & DST_SIGMODE_FINAL) { + RSA_Key *rkey; + B_ALGORITHM_OBJ rsaEncryptor = (B_ALGORITHM_OBJ) NULL_PTR; + unsigned int written = 0; + + isc_buffer_available(sig, &sig_region); + isc_buffer_remaining(&digest, &digest_region); + + if (sig_region.length * 8 < (unsigned int) key->key_size) + return (ISC_R_NOSPACE); + + rkey = (RSA_Key *) key->opaque; + if (rkey == NULL) + return (DST_R_NULLKEY); + if (rkey->rk_Private_Key == NULL) + return (DST_R_NOTPRIVATEKEY); + + if ((status = B_CreateAlgorithmObject(&rsaEncryptor)) != 0) + return (ISC_R_NOMEMORY); + if ((status = B_SetAlgorithmInfo(rsaEncryptor, + AI_PKCS_RSAPrivate, + NULL_PTR)) != 0) + + goto finalfail; + if ((status = B_EncryptInit(rsaEncryptor, + rkey->rk_Private_Key, + CHOOSER, NULL_SURRENDER)) != 0) + goto finalfail; + if ((status = B_EncryptUpdate(rsaEncryptor, sig_region.base, + &written, sig_region.length, + pkcs1, sizeof(pkcs1), + NULL_PTR, NULL_SURRENDER)) != 0) + goto finalfail; + + if (written > 0) { + isc_buffer_add(sig, written); + isc_buffer_available(sig, &sig_region); + written = 0; + } + + if ((status = B_EncryptUpdate(rsaEncryptor, sig_region.base, + &written, sig_region.length, + digest_region.base, + digest_region.length, + NULL_PTR, NULL_SURRENDER)) != 0) + goto finalfail; + + if (written > 0) { + isc_buffer_add(sig, written); + isc_buffer_available(sig, &sig_region); + written = 0; + } + + isc_buffer_forward(&digest, digest_region.length); + + if ((status = B_EncryptFinal(rsaEncryptor, sig_region.base, + &written, sig_region.length, + NULL_PTR, NULL_SURRENDER)) != 0) + goto finalfail; + isc_buffer_add(sig, written); + + B_DestroyAlgorithmObject(&rsaEncryptor); + return (ISC_R_SUCCESS); + finalfail: + B_DestroyAlgorithmObject(&rsaEncryptor); + return (DST_R_SIGNFINALFAILURE); + } + else + *context = md5_ctx; + + return (ISC_R_SUCCESS); +} + + +/* + * dst_bsafe_verify + * Calls BSAFE verification routines. There are three steps to + * verification, INIT (initialize structures), UPDATE (hash (more) data), + * FINAL (generate a signature). This routine performs one or more of + * these steps. + * Parameters + * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL} + * key key to use for verifying + * context the context to use for this computation + * data signed data + * signature signature + * mctx memory context for temporary allocations + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_bsafe_verify(const unsigned int mode, dst_key_t *key, void **context, + isc_region_t *data, isc_region_t *sig, isc_mem_t *mctx) +{ + B_ALGORITHM_OBJ *md5_ctx = NULL; + unsigned char digest_array[DST_HASH_SIZE]; + unsigned char work_area[DST_HASH_SIZE + sizeof(pkcs1)]; + isc_buffer_t work, digest; + isc_region_t work_region, digest_region; + dst_result_t ret; + int status = 0; + + if (mode & DST_SIGMODE_INIT) { + md5_ctx = (B_ALGORITHM_OBJ *) isc_mem_get(mctx, + sizeof(*md5_ctx)); + if (md5_ctx == NULL) + return (ISC_R_NOMEMORY); + if ((status = B_CreateAlgorithmObject(md5_ctx)) != 0) + return (ISC_R_NOMEMORY); + if ((status = B_SetAlgorithmInfo(*md5_ctx, AI_MD5, NULL)) != 0) + return (ISC_R_NOMEMORY); + } + else if (context != NULL) + md5_ctx = (B_ALGORITHM_OBJ *) *context; + REQUIRE (md5_ctx != NULL); + + isc_buffer_init(&digest, digest_array, sizeof(digest_array), + ISC_BUFFERTYPE_BINARY); + ret = dst_bsafe_md5digest(mode, md5_ctx, data, &digest); + if (ret != ISC_R_SUCCESS || (mode & DST_SIGMODE_FINAL)) { + B_DestroyAlgorithmObject(md5_ctx); + memset(md5_ctx, 0, sizeof(*md5_ctx)); + isc_mem_put(mctx, md5_ctx, sizeof(*md5_ctx)); + if (ret != ISC_R_SUCCESS) + return (ret); + } + + if (mode & DST_SIGMODE_FINAL) { + RSA_Key *rkey; + B_ALGORITHM_OBJ rsaEncryptor = (B_ALGORITHM_OBJ) NULL_PTR; + unsigned int written = 0; + + isc_buffer_init(&work, work_area, sizeof(work_area), + ISC_BUFFERTYPE_BINARY); + + isc_buffer_available(&work, &work_region); + + rkey = (RSA_Key *) key->opaque; + if (rkey == NULL) + return (DST_R_NULLKEY); + if (rkey->rk_Public_Key == NULL) + return (DST_R_NOTPUBLICKEY); + if ((status = B_CreateAlgorithmObject(&rsaEncryptor)) != 0) + return (ISC_R_NOMEMORY); + if ((status = B_SetAlgorithmInfo(rsaEncryptor, + AI_PKCS_RSAPublic, + NULL_PTR)) != 0) + goto finalfail; + if ((status = B_DecryptInit(rsaEncryptor, rkey->rk_Public_Key, + CHOOSER, NULL_SURRENDER)) != 0) + goto finalfail; + + if ((status = B_DecryptUpdate(rsaEncryptor, work_region.base, + &written, work_region.length, + sig->base, sig->length, + NULL_PTR, NULL_SURRENDER)) != 0) + goto finalfail; + + if (written > 0) { + isc_buffer_add(&work, written); + isc_buffer_available(&work, &work_region); + written = 0; + } + + if ((status = B_DecryptFinal(rsaEncryptor, work_region.base, + &written, work_region.length, + NULL_PTR, NULL_SURRENDER)) != 0) + goto finalfail; + + if (written > 0) + isc_buffer_add(&work, written); + + isc_buffer_used(&work, &work_region); + isc_buffer_used(&digest, &digest_region); + + B_DestroyAlgorithmObject(&rsaEncryptor); + /* skip PKCS#1 header in output from Decrypt function */ + if (memcmp(digest_region.base, work_region.base + sizeof(pkcs1), + digest_region.length) == 0) + return (ISC_R_SUCCESS); + else + return (DST_R_VERIFYFINALFAILURE); + finalfail: + B_DestroyAlgorithmObject(&rsaEncryptor); + return (DST_R_VERIFYFINALFAILURE); + } + else + *context = md5_ctx; + + return (ISC_R_SUCCESS); +} + + +/* + * dst_bsafe_isprivate + * Is this a private key? + * Parameters + * key DST KEY structure + * Returns + * ISC_TRUE + * ISC_FALSE + */ +static isc_boolean_t +dst_bsafe_isprivate(const dst_key_t *key) { + RSA_Key *rkey = (RSA_Key *) key->opaque; + return (ISC_TF(rkey != NULL && rkey->rk_Private_Key != NULL)); +} + + +/* + * dst_bsafe_to_dns + * Converts key from RSA to DNS distribution format + * Parameters + * key DST KEY structure + * data output data + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +dst_bsafe_to_dns(const dst_key_t *key, isc_buffer_t *data) { + B_KEY_OBJ public; + A_RSA_KEY *pub = NULL; + isc_region_t r; + int status; + + REQUIRE(key->opaque != NULL); + + public = (B_KEY_OBJ)((RSA_Key *)key->opaque)->rk_Public_Key; + + if ((status = B_GetKeyInfo((POINTER *)&pub, public, KI_RSAPublic)) != 0) + return (DST_R_INVALIDPUBLICKEY); + isc_buffer_available(data, &r); + if (pub->exponent.len < 256) { /* key exponent is <= 2040 bits */ + if (r.length < 1 + pub->exponent.len + pub->modulus.len) + return (ISC_R_NOSPACE); + isc_buffer_putuint8(data, (isc_uint8_t)pub->exponent.len); + } else { /* key exponent is > 2040 bits */ + if (r.length < 3 + pub->exponent.len + pub->modulus.len) + return (ISC_R_NOSPACE); + isc_buffer_putuint8(data, 0); + isc_buffer_putuint16(data, (isc_uint16_t)pub->exponent.len); + } + + isc_buffer_available(data, &r); + memcpy(r.base, pub->exponent.data, pub->exponent.len); + r.base += pub->exponent.len; + memcpy(r.base, pub->modulus.data, pub->modulus.len); + isc_buffer_add(data, pub->exponent.len + pub->modulus.len); + + return (ISC_R_SUCCESS); +} + + +/* + * dst_bsafe_from_dns + * Converts from a DNS KEY RR format to an RSA KEY. + * Parameters + * key Partially filled key structure + * data Buffer containing key in DNS format + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_bsafe_from_dns(dst_key_t *key, isc_buffer_t *data, isc_mem_t *mctx) { + unsigned int bytes; + RSA_Key *rkey; + A_RSA_KEY *public; + isc_region_t r; + isc_buffer_t b; + int status; + + isc_buffer_remaining(data, &r); + if (r.length == 0) + return (ISC_R_SUCCESS); + + rkey = (RSA_Key *) isc_mem_get(mctx, sizeof(RSA_Key)); + if (rkey == NULL) + return (ISC_R_NOMEMORY); + + memset(rkey, 0, sizeof(RSA_Key)); + + if (B_CreateKeyObject(&rkey->rk_Public_Key) != 0) { + isc_mem_put(mctx, rkey, sizeof(RSA_Key)); + return (ISC_R_NOMEMORY); + } + + /* length of exponent in bytes */ + bytes = isc_buffer_getuint8(data); + if (bytes == 0) /* special case for long exponents */ + bytes = isc_buffer_getuint16(data); + + if (bytes > MAX_RSA_MODULUS_LEN) { + dst_bsafe_destroy(rkey, mctx); + return (DST_R_INVALIDPUBLICKEY); + } + + public = (A_RSA_KEY *) isc_mem_get(mctx, sizeof(A_RSA_KEY)); + if (public == NULL) + return (ISC_R_NOMEMORY); + memset(public, 0, sizeof(*public)); + public->exponent.len = bytes; + public->exponent.data = (unsigned char *) isc_mem_get(mctx, bytes); + if (public->exponent.data == NULL) { + isc_mem_put(mctx, public, sizeof(*public)); + return (ISC_R_NOMEMORY); + } + + isc_buffer_remaining(data, &r); + if (r.length < bytes) { + isc_mem_put(mctx, public, sizeof(*public)); + return (ISC_R_NOMEMORY); + } + memcpy(public->exponent.data, r.base, bytes); + isc_buffer_forward(data, bytes); + + isc_buffer_remaining(data, &r); + + if (r.length > MAX_RSA_MODULUS_LEN) { + dst_bsafe_destroy(rkey, mctx); + memset(public->exponent.data, 0, bytes); + isc_mem_put(mctx, public->exponent.data, bytes); + isc_mem_put(mctx, public, sizeof(*public)); + return (ISC_R_NOMEMORY); + } + public->modulus.len = r.length; + public->modulus.data = (unsigned char *) isc_mem_get(mctx, r.length); + if (public->modulus.data == NULL) { + dst_bsafe_destroy(rkey, mctx); + memset(public->exponent.data, 0, bytes); + isc_mem_put(mctx, public->exponent.data, bytes); + isc_mem_put(mctx, public, sizeof(*public)); + return (ISC_R_NOMEMORY); + } + memcpy(public->modulus.data, r.base, r.length); + isc_buffer_forward(data, r.length); + + status = B_SetKeyInfo(rkey->rk_Public_Key, KI_RSAPublic, + (POINTER) public); + if (status != 0) + return (DST_R_INVALIDPUBLICKEY); + + isc_buffer_init(&b, public->modulus.data + public->modulus.len - 3, + 2, ISC_BUFFERTYPE_BINARY); + isc_buffer_add(&b, 2); + key->key_id = isc_buffer_getuint16(&b); + key->key_size = dst_bsafe_key_size(rkey); + + memset(public->exponent.data, 0, public->exponent.len); + isc_mem_put(mctx, public->exponent.data, public->exponent.len); + memset(public->modulus.data, 0, public->modulus.len); + isc_mem_put(mctx, public->modulus.data, public->modulus.len); + isc_mem_put(mctx, public, sizeof(*public)); + + key->opaque = (void *) rkey; + + return (ISC_R_SUCCESS); +} + + +/* + * dst_bsafe_to_file + * Encodes an RSA Key into the portable file format. + * Parameters + * key DST KEY structure + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_bsafe_to_file(const dst_key_t *key) { + int cnt = 0; + B_KEY_OBJ rkey; + A_PKCS_RSA_PRIVATE_KEY *private = NULL; + dst_private_t priv; + + if (key->opaque == NULL) + return (DST_R_NULLKEY); + + rkey = (B_KEY_OBJ)((RSA_Key *) key->opaque)->rk_Private_Key; + + B_GetKeyInfo((POINTER *) &private, rkey, KI_PKCS_RSAPrivate); + + priv.elements[cnt].tag = TAG_RSA_MODULUS; + priv.elements[cnt].data = private->modulus.data; + priv.elements[cnt++].length = private->modulus.len; + + priv.elements[cnt].tag = TAG_RSA_PUBLICEXPONENT; + priv.elements[cnt].data = private->publicExponent.data; + priv.elements[cnt++].length = private->publicExponent.len; + + priv.elements[cnt].tag = TAG_RSA_PRIVATEEXPONENT; + priv.elements[cnt].data = private->privateExponent.data; + priv.elements[cnt++].length = private->privateExponent.len; + + priv.elements[cnt].tag = TAG_RSA_PRIME1; + priv.elements[cnt].data = private->prime[0].data; + priv.elements[cnt++].length = private->prime[0].len; + + priv.elements[cnt].tag = TAG_RSA_PRIME2; + priv.elements[cnt].data = private->prime[1].data; + priv.elements[cnt++].length = private->prime[1].len; + + priv.elements[cnt].tag = TAG_RSA_EXPONENT1; + priv.elements[cnt].data = private->primeExponent[0].data; + priv.elements[cnt++].length = private->primeExponent[0].len; + + priv.elements[cnt].tag = TAG_RSA_EXPONENT2; + priv.elements[cnt].data = private->primeExponent[1].data; + priv.elements[cnt++].length = private->primeExponent[1].len; + + priv.elements[cnt].tag = TAG_RSA_COEFFICIENT; + priv.elements[cnt].data = private->coefficient.data; + priv.elements[cnt++].length = private->coefficient.len; + + priv.nelements = cnt; + return (dst_s_write_private_key_file(key->key_name, key->key_alg, + key->key_id, &priv)); +} + + +/* + * dst_bsafe_from_file + * Converts contents of a private key file into a private RSA key. + * Parameters + * key Partially filled RSA KEY structure + * id The key id + * path The directory that the file will be read from + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +dst_bsafe_from_file(dst_key_t *key, const isc_uint16_t id, isc_mem_t *mctx) { + dst_private_t priv; + dst_result_t ret; + isc_buffer_t b; + int i; + RSA_Key *rkey = NULL; + A_RSA_KEY *public = NULL; + A_PKCS_RSA_PRIVATE_KEY *private = NULL; + int status = 0; +#define DST_RET(a) {ret = a; goto err;} + + /* read private key file */ + ret = dst_s_parse_private_key_file(key->key_name, key->key_alg, + id, &priv, mctx); + if (ret != ISC_R_SUCCESS) + return (ret); + /* allocate key*/ + private = (A_PKCS_RSA_PRIVATE_KEY *) + isc_mem_get(mctx, sizeof(A_PKCS_RSA_PRIVATE_KEY)); + if (private == NULL) + DST_RET(ISC_R_NOMEMORY); + memset(private, 0, sizeof(*private)); + + public = (A_RSA_KEY *) isc_mem_get(mctx, sizeof(A_RSA_KEY)); + if (public == NULL) + DST_RET(ISC_R_NOMEMORY); + memset(public, 0, sizeof(*public)); + + for (i=0; i < priv.nelements; i++) { + int len = priv.elements[i].length; + unsigned char *data = priv.elements[i].data; + + switch (priv.elements[i].tag){ + case TAG_RSA_MODULUS: + public->modulus.len = len; + private->modulus.len = len; + public->modulus.data = data; + private->modulus.data = data; + break; + case TAG_RSA_PUBLICEXPONENT: + public->exponent.len = len; + private->publicExponent.len = len; + public->exponent.data = data; + private->publicExponent.data = data; + break; + case TAG_RSA_PRIVATEEXPONENT: + private->privateExponent.len = len; + private->privateExponent.data = data; + break; + case TAG_RSA_PRIME1: + private->prime[0].len = len; + private->prime[0].data = data; + break; + case TAG_RSA_PRIME2: + private->prime[1].len = len; + private->prime[1].data = data; + break; + case TAG_RSA_EXPONENT1: + private->primeExponent[0].len = len; + private->primeExponent[0].data = data; + break; + case TAG_RSA_EXPONENT2: + private->primeExponent[1].len = len; + private->primeExponent[1].data = data; + break; + case TAG_RSA_COEFFICIENT: + private->coefficient.len = len; + private->coefficient.data = data; + break; + } + } + + isc_buffer_init(&b, public->modulus.data + public->modulus.len - 3, + 2, ISC_BUFFERTYPE_BINARY); + isc_buffer_add(&b, 2); + key->key_id = isc_buffer_getuint16(&b); + if (key->key_id != id) + DST_RET(DST_R_INVALIDPRIVATEKEY); + + rkey = (RSA_Key *) isc_mem_get(mctx, sizeof(RSA_Key)); + if (rkey == NULL) + DST_RET(ISC_R_NOMEMORY); + memset(rkey, 0, sizeof(*rkey)); + if ((status = B_CreateKeyObject(&(rkey->rk_Public_Key))) != 0) + DST_RET(ISC_R_NOMEMORY); + if ((status = B_SetKeyInfo(rkey->rk_Public_Key, KI_RSAPublic, + (POINTER) public)) != 0) + DST_RET(DST_R_INVALIDPUBLICKEY); + + if ((status = B_CreateKeyObject(&rkey->rk_Private_Key)) != 0) + DST_RET(ISC_R_NOMEMORY); + + if ((status = B_SetKeyInfo(rkey->rk_Private_Key, KI_PKCS_RSAPrivate, + (POINTER) private)) != 0) + DST_RET(DST_R_INVALIDPRIVATEKEY); + + key->key_size = dst_bsafe_key_size(rkey); + key->opaque = rkey; + rkey = NULL; + err: + if (private != NULL) { + memset(private, 0, sizeof(*private)); + isc_mem_put(mctx, private, sizeof(*private)); + } + if (public != NULL) { + memset(public, 0, sizeof(*public)); + isc_mem_put(mctx, public, sizeof(*public)); + } + if (rkey != NULL) { + memset(rkey, 0, sizeof(*rkey)); + isc_mem_put(mctx, rkey, sizeof(*rkey)); + } + dst_s_free_private_structure_fields(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (ret); +} + +/* + * dst_bsafe_destroy + * Frees all dynamically allocated structures in key. + */ +static void +dst_bsafe_destroy(void *key, isc_mem_t *mctx) +{ + RSA_Key *rkey = (RSA_Key *) key; + if (rkey == NULL) + return; + if (rkey->rk_Private_Key != NULL) + B_DestroyKeyObject(&rkey->rk_Private_Key); + if (rkey->rk_Public_Key != NULL) + B_DestroyKeyObject(&rkey->rk_Public_Key); + memset(rkey, 0, sizeof(*rkey)); + isc_mem_put(mctx, rkey, sizeof(*rkey)); +} + + +/* + * dst_bsafe_generate + * Generates unique keys that are hard to predict. + * Parameters + * key DST Key structure + * exp the public exponent + * mctx memory context to allocate key + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +dst_bsafe_generate(dst_key_t *key, int exp, isc_mem_t *mctx) { + int status; + B_KEY_OBJ private; + B_KEY_OBJ public; + B_ALGORITHM_OBJ keypairGenerator = NULL; + B_ALGORITHM_OBJ randomAlgorithm = NULL; + A_RSA_KEY_GEN_PARAMS keygenParams; + char exponent[4]; + int exponent_len = 0; + RSA_Key *rsa; + unsigned char randomSeed[256]; + isc_buffer_t b, rand; + A_RSA_KEY *pub = NULL; + dst_result_t ret; + + rsa = (RSA_Key *) isc_mem_get(mctx, sizeof(RSA_Key)); + if (rsa == NULL) + return (ISC_R_NOMEMORY); + + memset(rsa, 0, sizeof(*rsa)); + keygenParams.publicExponent.data = NULL; + +#define do_fail(code) {ret = code; goto fail;} + if ((status = B_CreateAlgorithmObject(&keypairGenerator)) != 0) + do_fail(ISC_R_NOMEMORY); + + keygenParams.modulusBits = key->key_size; + + /* exp = 0 or 1 are special (mean 3 or F4) */ + if (exp == 0) + exp = 3; + else if (exp == 1) + exp = 65537; + + /* Now encode the exponent and its length */ + if (exp < 256) { + exponent_len = 1; + exponent[0] = exp; + } else if (exp < (1 << 16)) { + exponent_len = 2; + exponent[0] = exp >> 8; + exponent[1] = exp; + } else if (exp < (1 << 24)) { + exponent_len = 3; + exponent[0] = exp >> 16; + exponent[1] = exp >> 8; + exponent[2] = exp; + } else { + exponent_len = 4; + exponent[0] = exp >> 24; + exponent[1] = exp >> 16; + exponent[2] = exp >> 8; + exponent[3] = exp; + } + + keygenParams.publicExponent.data = (unsigned char *) isc_mem_get(mctx, + exponent_len); + if (keygenParams.publicExponent.data == NULL) + do_fail(ISC_R_NOMEMORY); + + memcpy(keygenParams.publicExponent.data, exponent, exponent_len); + keygenParams.publicExponent.len = exponent_len; + if ((status = B_SetAlgorithmInfo + (keypairGenerator, AI_RSAKeyGen, (POINTER) &keygenParams)) != 0) + do_fail(DST_R_INVALIDPARAM); + + isc_mem_put(mctx, keygenParams.publicExponent.data, exponent_len); + keygenParams.publicExponent.data = NULL; + + if ((status = B_GenerateInit(keypairGenerator, CHOOSER, + NULL_SURRENDER)) != 0) + do_fail(ISC_R_NOMEMORY); + + if ((status = B_CreateKeyObject(&public)) != 0) + do_fail(ISC_R_NOMEMORY); + + if ((status = B_CreateKeyObject(&private)) != 0) + do_fail(ISC_R_NOMEMORY); + + if ((status = B_CreateAlgorithmObject(&randomAlgorithm)) != 0) + do_fail(ISC_R_NOMEMORY); + + if ((status = B_SetAlgorithmInfo(randomAlgorithm, AI_MD5Random, + NULL_PTR)) != 0) + do_fail(ISC_R_NOMEMORY); + + if ((status = B_RandomInit(randomAlgorithm, CHOOSER, + NULL_SURRENDER)) != 0) + do_fail(ISC_R_NOMEMORY); + + isc_buffer_init(&rand, randomSeed, sizeof(randomSeed), + ISC_BUFFERTYPE_BINARY); + ret = dst_random_get(sizeof(randomSeed), &rand); + if (ret != ISC_R_SUCCESS) + goto fail; + + if ((status = B_RandomUpdate(randomAlgorithm, randomSeed, + sizeof(randomSeed), NULL_SURRENDER)) != 0) + do_fail(ISC_R_NOMEMORY); + + memset(randomSeed, 0, sizeof(randomSeed)); + + if ((status = B_GenerateKeypair(keypairGenerator, public, private, + randomAlgorithm, NULL_SURRENDER)) != 0) + do_fail(DST_R_INVALIDPARAM); + + rsa->rk_Private_Key = private; + rsa->rk_Public_Key = public; + key->opaque = (void *) rsa; + + B_DestroyAlgorithmObject(&keypairGenerator); + B_DestroyAlgorithmObject(&randomAlgorithm); + + /* fill in the footprint in generate key */ + B_GetKeyInfo((POINTER *) &pub, public, KI_RSAPublic); + + isc_buffer_init(&b, pub->modulus.data + pub->modulus.len - 3, + 2, ISC_BUFFERTYPE_BINARY); + isc_buffer_add(&b, 2); + key->key_id = isc_buffer_getuint16(&b); + return (ISC_R_SUCCESS); + + fail: + if (rsa != NULL) { + memset(rsa, 0, sizeof(*rsa)); + isc_mem_put(mctx, rsa, sizeof(*rsa)); + } + if (keygenParams.publicExponent.data != NULL) { + memset(keygenParams.publicExponent.data, 0, exponent_len); + isc_mem_put(mctx, keygenParams.publicExponent.data, + exponent_len); + } + if (keypairGenerator != NULL) + B_DestroyAlgorithmObject(&keypairGenerator); + if (randomAlgorithm != NULL) + B_DestroyAlgorithmObject(&randomAlgorithm); + return (ret); +} + + +static isc_boolean_t +dst_s_bsafe_itemcmp(ITEM i1, ITEM i2) { + if (i1.len != i2.len || memcmp (i1.data, i2.data, i1.len) != 0) + return (ISC_FALSE); + else + return (ISC_TRUE); +} + +/************************************************************************** + * dst_bsafe_compare + * Compare two keys for equality. + * Return + * ISC_TRUE The keys are equal + * ISC_FALSE The keys are not equal + */ +static isc_boolean_t +dst_bsafe_compare(const dst_key_t *key1, const dst_key_t *key2) { + int status, s1 = 0, s2 = 0; + RSA_Key *rkey1, *rkey2; + A_RSA_KEY *public1 = NULL, *public2 = NULL; + A_PKCS_RSA_PRIVATE_KEY *p1 = NULL, *p2 = NULL; + + rkey1 = (RSA_Key *) key1->opaque; + rkey2 = (RSA_Key *) key2->opaque; + + if (rkey1 == NULL && rkey2 == NULL) + return (ISC_TRUE); + else if (rkey1 == NULL || rkey2 == NULL) + return (ISC_FALSE); + + if (rkey1->rk_Public_Key) + B_GetKeyInfo((POINTER *) &public1, rkey1->rk_Public_Key, + KI_RSAPublic); + if (rkey2->rk_Public_Key) + B_GetKeyInfo((POINTER *) &public2, rkey2->rk_Public_Key, + KI_RSAPublic); + if (public1 == NULL && public2 == NULL) + return (ISC_TRUE); + else if (public1 == NULL || public2 == NULL) + return (ISC_FALSE); + + status = dst_s_bsafe_itemcmp(public1->modulus, public2->modulus) || + dst_s_bsafe_itemcmp(public1->exponent, public2->exponent); + + if (status == ISC_FALSE) + return (ISC_FALSE); + + if (rkey1->rk_Private_Key != NULL || rkey2->rk_Private_Key != NULL) { + if (rkey1->rk_Private_Key == NULL || + rkey2->rk_Private_Key == NULL) + return (ISC_FALSE); + + s1 = B_GetKeyInfo((POINTER *) &p1, rkey1->rk_Private_Key, + KI_PKCS_RSAPrivate); + s2 = B_GetKeyInfo((POINTER *) &p2, rkey2->rk_Private_Key, + KI_PKCS_RSAPrivate); + if (p1 == NULL || p2 == NULL) + return (ISC_FALSE); + + status = dst_s_bsafe_itemcmp(p1->modulus, p2->modulus) && + dst_s_bsafe_itemcmp(p1->publicExponent, + p2->publicExponent) && + dst_s_bsafe_itemcmp(p1->privateExponent, + p2->privateExponent) && + dst_s_bsafe_itemcmp(p1->prime[0], p2->prime[0]) && + dst_s_bsafe_itemcmp(p1->prime[1], p2->prime[1]) && + dst_s_bsafe_itemcmp(p1->primeExponent[0], + p2->primeExponent[0]) && + dst_s_bsafe_itemcmp(p1->primeExponent[1], + p2->primeExponent[1]) && + dst_s_bsafe_itemcmp(p1->coefficient, p2->coefficient); + if (status == ISC_FALSE) + return (ISC_FALSE); + } + return (ISC_TRUE); +} + + +/* + * dst_bsafe_key_size() + * Function to calculate the size of the key in bits + */ +static int +dst_bsafe_key_size(RSA_Key *key) +{ + int size; + A_PKCS_RSA_PRIVATE_KEY *private = NULL; + + REQUIRE(key != NULL); + REQUIRE(key->rk_Private_Key != NULL || key->rk_Public_Key != NULL); + + if (key->rk_Private_Key != NULL) + B_GetKeyInfo((POINTER *) &private, key->rk_Private_Key, + KI_PKCS_RSAPrivate); + else + B_GetKeyInfo((POINTER *) &private, key->rk_Public_Key, + KI_RSAPublic); + + size = dst_s_calculate_bits(private->modulus.data, + private->modulus.len * 8); + return (size); +} + +/* + * dst_bsafe_md5digest(): function to digest data using MD5 digest function + * if needed + */ +static dst_result_t +dst_bsafe_md5digest(const unsigned int mode, B_ALGORITHM_OBJ *digest_obj, + isc_region_t *data, isc_buffer_t *digest) +{ + int status = 0; + unsigned int written = 0; + isc_region_t r; + + REQUIRE(digest != NULL); + REQUIRE(digest_obj != NULL); + + if ((mode & DST_SIGMODE_INIT) && + (status = B_DigestInit(*digest_obj, (B_KEY_OBJ) NULL, + CHOOSER, NULL_SURRENDER)) != 0) + return (DST_R_SIGNINITFAILURE); + + if ((mode & DST_SIGMODE_UPDATE) && + (status = B_DigestUpdate(*digest_obj, data->base, data->length, + NULL_SURRENDER)) != 0) + return (DST_R_SIGNUPDATEFAILURE); + + isc_buffer_available(digest, &r); + if (mode & DST_SIGMODE_FINAL) { + if (digest == NULL || + (status = B_DigestFinal(*digest_obj, r.base, &written, + r.length, NULL_SURRENDER)) != 0) + return (DST_R_SIGNFINALFAILURE); + isc_buffer_add(digest, written); + } + return (ISC_R_SUCCESS); +} + + +/* + * define memory functions for bsafe that use the isc_mem functions and a + * static context. + */ +void +T_free(POINTER block) { + dst_mem_free(block); +} + +POINTER +T_malloc(unsigned int len) { + return (dst_mem_alloc(len)); +} + +int +T_memcmp(POINTER firstBlock, POINTER secondBlock, unsigned int len) { + return (memcmp(firstBlock, secondBlock, len)); +} + +void +T_memcpy(POINTER output, POINTER input, unsigned int len) { + memcpy(output, input, len); +} + +void +T_memmove(POINTER output, POINTER input, unsigned int len) { + memmove(output, input, len); +} + +void +T_memset(POINTER output, int value, unsigned int len) { + memset(output, value, len); +} + +POINTER +T_realloc(POINTER block, unsigned int len) { + return (dst_mem_realloc(block, len)); +} +#endif /* BSAFE || DNSSAFE */ diff --git a/lib/dns/sec/dst/dst_api.c b/lib/dns/sec/dst/dst_api.c new file mode 100644 index 00000000..5cdfedc4 --- /dev/null +++ b/lib/dns/sec/dst/dst_api.c @@ -0,0 +1,1092 @@ +/* + * Portions Copyright (c) 1995-1999 by Network Associates, Inc. + * + * Permission to use, copy modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. + */ + +/* + * Principal Author: Brian Wellington + * $Id: dst_api.c,v 1.20 1999/12/23 00:09:04 explorer Exp $ + */ + +#include <config.h> + +#include <ctype.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <isc/assertions.h> +#include <isc/buffer.h> +#include <isc/dir.h> +#include <isc/error.h> +#include <isc/int.h> +#include <isc/lex.h> +#include <isc/mem.h> +#include <isc/mutex.h> +#include <isc/once.h> +#include <isc/region.h> +#include <dns/rdata.h> +#include <dns/keyvalues.h> + +#include <openssl/rand.h> + +#include "dst_internal.h" +#include "dst/result.h" + +#define KEY_MAGIC 0x44535421U /* DST! */ + +#define VALID_KEY(key) (key != NULL && key->magic == KEY_MAGIC) + +dst_func *dst_t_func[DST_MAX_ALGS]; + +static isc_mem_t *dst_memory_pool = NULL; +static isc_once_t once = ISC_ONCE_INIT; +static isc_mutex_t random_lock; + +/* Static functions */ +static void initialize(void); +static dst_key_t * get_key_struct(const char *name, const int alg, + const int flags, const int protocol, + const int bits, isc_mem_t *mctx); +static dst_result_t read_public_key(const char *name, + const isc_uint16_t id, int in_alg, + isc_mem_t *mctx, dst_key_t **keyp); +static dst_result_t write_public_key(const dst_key_t *key); + +/* + * dst_supported_algorithm + * This function determines if the crypto system for the specified + * algorithm is present. + * Parameters + * alg The algorithm to test + * Returns + * ISC_TRUE The algorithm is available. + * ISC_FALSE The algorithm is not available. + */ +isc_boolean_t +dst_supported_algorithm(const int alg) { + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + if (alg >= DST_MAX_ALGS || dst_t_func[alg] == NULL) + return (ISC_FALSE); + return (ISC_TRUE); +} + +/* + * dst_sign + * An incremental signing function. Data is signed in steps. + * First the context must be initialized (DST_SIGMODE_INIT). + * Then data is hashed (DST_SIGMODE_UPDATE). Finally the signature + * itself is created (DST_SIGMODE_FINAL). This function can be called + * once with DST_SIGMODE_ALL set, or it can be called separately + * for each step. The UPDATE step may be repeated. + * Parameters + * mode A bit mask specifying operation(s) to be performed. + * DST_SIGMODE_INIT Initialize digest + * DST_SIGMODE_UPDATE Add data to digest + * DST_SIGMODE_FINAL Generate signature + * DST_SIGMODE_ALL Perform all operations + * key The private key used to sign the data + * context The state of the operation + * data The data to be signed. + * sig The buffer to which the signature will be written. + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +dst_result_t +dst_sign(const unsigned int mode, dst_key_t *key, dst_context_t *context, + isc_region_t *data, isc_buffer_t *sig) +{ + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(VALID_KEY(key)); + REQUIRE((mode & DST_SIGMODE_ALL) != 0); + + if ((mode & DST_SIGMODE_UPDATE) != 0) + REQUIRE(data != NULL && data->base != NULL); + + if ((mode & DST_SIGMODE_FINAL) != 0) + REQUIRE(sig != NULL); + + if (dst_supported_algorithm(key->key_alg) == ISC_FALSE) + return (DST_R_UNSUPPORTEDALG); + if (key->opaque == NULL) + return (DST_R_NULLKEY); + if (key->func->sign == NULL) + return (DST_R_NOTPRIVATEKEY); + + return (key->func->sign(mode, key, (void **)context, data, sig, + key->mctx)); +} + + +/* + * dst_verify + * An incremental verify function. Data is verified in steps. + * First the context must be initialized (DST_SIGMODE_INIT). + * Then data is hashed (DST_SIGMODE_UPDATE). Finally the signature + * is verified (DST_SIGMODE_FINAL). This function can be called + * once with DST_SIGMODE_ALL set, or it can be called separately + * for each step. The UPDATE step may be repeated. + * Parameters + * mode A bit mask specifying operation(s) to be performed. + * DST_SIGMODE_INIT Initialize digest + * DST_SIGMODE_UPDATE Add data to digest + * DST_SIGMODE_FINAL Verify signature + * DST_SIGMODE_ALL Perform all operations + * key The public key used to verify the signature. + * context The state of the operation + * data The data to be digested. + * sig The signature. + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +dst_result_t +dst_verify(const unsigned int mode, dst_key_t *key, dst_context_t *context, + isc_region_t *data, isc_region_t *sig) +{ + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(VALID_KEY(key)); + REQUIRE((mode & DST_SIGMODE_ALL) != 0); + + if ((mode & DST_SIGMODE_UPDATE) != 0) + REQUIRE(data != NULL && data->base != NULL); + + if ((mode & DST_SIGMODE_FINAL) != 0) + REQUIRE(sig != NULL && sig->base != NULL); + + if (dst_supported_algorithm(key->key_alg) == ISC_FALSE) + return (DST_R_UNSUPPORTEDALG); + if (key->opaque == NULL) + return (DST_R_NULLKEY); + if (key->func->verify == NULL) + return (DST_R_NOTPUBLICKEY); + + return (key->func->verify(mode, key, (void **)context, data, sig, + key->mctx)); +} + +/* + * dst_digest + * An incremental digest function. Data is digested in steps. + * First the context must be initialized (DST_SIGMODE_INIT). + * Then data is hashed (DST_SIGMODE_UPDATE). Finally the digest + * is generated (DST_SIGMODE_FINAL). This function can be called + * once with DST_SIGMODE_ALL set, or it can be called separately + * for each step. The UPDATE step may be repeated. + * Parameters + * mode A bit mask specifying operation(s) to be performed. + * DST_SIGMODE_INIT Initialize digest + * DST_SIGMODE_UPDATE Add data to digest + * DST_SIGMODE_FINAL Complete digest + * DST_SIGMODE_ALL Perform all operations + * alg The digest algorithm to use + * context The state of the operation + * data The data to be digested. + * sig The sdigest. + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +dst_result_t +dst_digest(const unsigned int mode, const unsigned int alg, + dst_context_t *context, isc_region_t *data, isc_buffer_t *digest) +{ + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE((mode & DST_SIGMODE_ALL) != 0); + + if ((mode & DST_SIGMODE_UPDATE) != 0) + REQUIRE(data != NULL && data->base != NULL); + + if ((mode & DST_SIGMODE_FINAL) != 0) + REQUIRE(digest != NULL); + + if (alg != DST_DIGEST_MD5) + return (DST_R_UNSUPPORTEDALG); + + return (dst_s_md5(mode, context, data, digest, dst_memory_pool)); +} + + +/* + * dst_computesecret + * A function to compute a shared secret from two (Diffie-Hellman) keys. + * Parameters + * pub The public key + * priv The private key + * secret A buffer into which the secret is written + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +dst_result_t +dst_computesecret(const dst_key_t *pub, const dst_key_t *priv, + isc_buffer_t *secret) +{ + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(VALID_KEY(pub) && VALID_KEY(priv)); + REQUIRE(secret != NULL); + + if (dst_supported_algorithm(pub->key_alg) == ISC_FALSE || + dst_supported_algorithm(priv->key_alg) == ISC_FALSE) + return (DST_R_UNSUPPORTEDALG); + + if (pub->opaque == NULL || priv->opaque == NULL) + return (DST_R_NULLKEY); + + if (pub->key_alg != priv->key_alg || + pub->func->computesecret == NULL || + priv->func->computesecret == NULL) + return (DST_R_KEYCANNOTCOMPUTESECRET); + + if (dst_key_isprivate(priv) == ISC_FALSE) + return (DST_R_NOTPRIVATEKEY); + + return (pub->func->computesecret(pub, priv, secret)); +} + +/* + * dst_key_tofile + * Writes a key to disk. The key can either be a public or private key. + * The public key is written in DNS format and the private key is + * written as a set of base64 encoded values. + * Parameters + * key The key to be written. + * type Either DST_PUBLIC or DST_PRIVATE, or both + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +dst_result_t +dst_key_tofile(const dst_key_t *key, const int type) { + int ret = ISC_R_SUCCESS; + + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(VALID_KEY(key)); + + if (dst_supported_algorithm(key->key_alg) == ISC_FALSE) + return (DST_R_UNSUPPORTEDALG); + + if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == 0) + return (DST_R_UNSUPPORTEDTYPE); + + if (type & DST_TYPE_PUBLIC) + if ((ret = write_public_key(key)) != ISC_R_SUCCESS) + return (ret); + + if ((type & DST_TYPE_PRIVATE) && + (key->key_flags & DNS_KEYFLAG_TYPEMASK) != DNS_KEYTYPE_NOKEY) + { + ret = key->func->to_file(key); + if (ret != ISC_R_SUCCESS) + return (ret); + } + + return (ret); +} + +/* + * dst_key_fromfile + * Reads a key from disk. The key can either be a public or private + * key, and is specified by name, algorithm, and id. + * Parameters + * name The key name. + * id The id of the key. + * alg The algorithm of the key. + * type Either DST_PUBLIC or DST_PRIVATE + * mctx Memory context used to allocate key structure + * keyp Returns the new key + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +dst_result_t +dst_key_fromfile(const char *name, const isc_uint16_t id, const int alg, + const int type, isc_mem_t *mctx, dst_key_t **keyp) +{ + dst_key_t *key = NULL, *pubkey = NULL; + dst_result_t ret; + + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(name != NULL); + REQUIRE(mctx != NULL); + REQUIRE(keyp != NULL); + + *keyp = NULL; + if (dst_supported_algorithm(alg) == ISC_FALSE) + return (DST_R_UNSUPPORTEDALG); + + if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == 0) + return (DST_R_UNSUPPORTEDTYPE); + + ret = read_public_key(name, id, alg, mctx, &pubkey); + if (ret == ISC_R_NOTFOUND && (type & DST_TYPE_PUBLIC) == 0) + key = get_key_struct(name, alg, 0, 0, 0, mctx); + else if (ret != ISC_R_SUCCESS) + return (ret); + else { + if (type == DST_TYPE_PUBLIC || + (pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == + DNS_KEYTYPE_NOKEY) + { + *keyp = pubkey; + return (ISC_R_SUCCESS); + } + + key = get_key_struct(name, pubkey->key_alg, pubkey->key_flags, + pubkey->key_proto, 0, mctx); + dst_key_free(pubkey); + } + + if (key == NULL) + return (ISC_R_NOMEMORY); + + /* Fill in private key and some fields in the general key structure */ + ret = key->func->from_file(key, id, mctx); + if (ret != ISC_R_SUCCESS) { + dst_key_free(key); + return (ret); + } + + *keyp = key; + return (ISC_R_SUCCESS); +} + +/* + * dst_key_todns + * Function to encode a public key into DNS KEY format + * Parameters + * key Key structure to encode. + * target Buffer to write the encoded key into. + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +dst_result_t +dst_key_todns(const dst_key_t *key, isc_buffer_t *target) { + isc_region_t r; + + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(VALID_KEY(key)); + REQUIRE(target != NULL); + + if (dst_supported_algorithm(key->key_alg) == ISC_FALSE) + return (DST_R_UNSUPPORTEDALG); + + isc_buffer_available(target, &r); + if (r.length < 4) + return (ISC_R_NOSPACE); + isc_buffer_putuint16(target, (isc_uint16_t)(key->key_flags & 0xffff)); + isc_buffer_putuint8(target, (isc_uint8_t)key->key_proto); + isc_buffer_putuint8(target, (isc_uint8_t)key->key_alg); + + if (key->key_flags & DNS_KEYFLAG_EXTENDED) { + isc_buffer_available(target, &r); + if (r.length < 2) + return (ISC_R_NOSPACE); + isc_buffer_putuint16(target, + (isc_uint16_t)((key->key_flags >> 16) + & 0xffff)); + } + + if (key->opaque == NULL) /* NULL KEY */ + return (ISC_R_SUCCESS); + + return (key->func->to_dns(key, target)); +} + +/* + * dst_key_fromdns + * This function converts the contents of a DNS KEY RR into a key + * Paramters + * name Name of the new key + * source A buffer containing the KEY RR + * mctx The memory context used to allocate the key + * keyp Returns the new key + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +dst_result_t +dst_key_fromdns(const char *name, isc_buffer_t *source, isc_mem_t *mctx, + dst_key_t **keyp) +{ + isc_region_t r; + isc_uint8_t alg, proto; + isc_uint32_t flags, extflags; + dst_result_t ret; + + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE (name != NULL); + REQUIRE (source != NULL); + REQUIRE (mctx != NULL); + REQUIRE (keyp != NULL); + + isc_buffer_remaining(source, &r); + if (r.length < 4) /* 2 bytes of flags, 1 proto, 1 alg */ + return (DST_R_INVALIDPUBLICKEY); + flags = isc_buffer_getuint16(source); + proto = isc_buffer_getuint8(source); + alg = isc_buffer_getuint8(source); + + if (!dst_supported_algorithm(alg)) + return (DST_R_UNSUPPORTEDALG); + + if (flags & DNS_KEYFLAG_EXTENDED) { + isc_buffer_remaining(source, &r); + if (r.length < 2) + return (DST_R_INVALIDPUBLICKEY); + extflags = isc_buffer_getuint16(source); + flags |= (extflags << 16); + } + + *keyp = get_key_struct(name, alg, flags, proto, 0, mctx); + if (*keyp == NULL) + return (ISC_R_NOMEMORY); + + ret = (*keyp)->func->from_dns(*keyp, source, mctx); + if (ret != ISC_R_SUCCESS) + dst_key_free((*keyp)); + return (ret); +} + + +/* + * dst_key_frombuffer + * Function to convert raw data into a public key. The raw data format + * is basically DNS KEY rdata format. + * Parameters + * name The key name + * alg The algorithm + * flags The key's flags + * protocol The key's protocol + * source A buffer containing the key + * mctx The memory context used to allocate the key + * keyp Returns the new key + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +dst_result_t +dst_key_frombuffer(const char *name, const int alg, const int flags, + const int protocol, isc_buffer_t *source, isc_mem_t *mctx, + dst_key_t **keyp) +{ + dst_result_t ret; + + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(name != NULL); + REQUIRE(source != NULL); + REQUIRE(mctx != NULL); + + if (dst_supported_algorithm(alg) == ISC_FALSE) + return (DST_R_UNSUPPORTEDALG); + + *keyp = get_key_struct(name, alg, flags, protocol, 0, mctx); + + if (*keyp == NULL) + return (ISC_R_NOMEMORY); + + ret = (*keyp)->func->from_dns((*keyp), source, mctx); + if (ret != ISC_R_SUCCESS) { + dst_key_free((*keyp)); + return (ret); + } + return (ISC_R_SUCCESS); +} + +/* + * dst_key_tobuffer + * Function to convert a public key into raw data. The raw data format + * is basically DNS KEY rdata format. + * Parameters + * key The key + * target The buffer to be written into. + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +dst_result_t +dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target) { + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(VALID_KEY(key)); + REQUIRE(target != NULL); + + if (dst_supported_algorithm(key->key_alg) == ISC_FALSE) + return (DST_R_UNSUPPORTEDALG); + + return (key->func->to_dns(key, target)); +} + +/* + * dst_key_generate + * Generate a public/private keypair. + * Parameters + * name Name of the new key. Used to create key files + * K<name>+<alg>+<id>.public + * K<name>+<alg>+<id>.private + * alg The algorithm to use + * bits Size of the new key in bits + * param Algorithm specific + * RSA: exponent + * 0 use exponent 3 + * !0 use Fermat4 (2^16 + 1) + * DH: generator + * 0 default - use well-known prime if bits == 768 + * or 1024, otherwise use generator 2 + * !0 use this value as the generator + * DSA/HMACMD5: unused + * flags The default value of the DNS Key flags. + * protocol Default value of the DNS Key protocol field. + * mctx The memory context used to allocate the key + * keyp Returns the new key + * + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +dst_result_t +dst_key_generate(const char *name, const int alg, const int bits, + const int exp, const int flags, const int protocol, + isc_mem_t *mctx, dst_key_t **keyp) +{ + dst_result_t ret; + + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(name != NULL); + REQUIRE(mctx != NULL); + REQUIRE(keyp != NULL); + + if (dst_supported_algorithm(alg) == ISC_FALSE) + return (DST_R_UNSUPPORTEDALG); + + *keyp = get_key_struct(name, alg, flags, protocol, bits, mctx); + if (*keyp == NULL) + return (ISC_R_NOMEMORY); + + if (bits == 0) { /* NULL KEY */ + (*keyp)->key_flags |= DNS_KEYTYPE_NOKEY; + return (ISC_R_SUCCESS); + } + + ret = (*keyp)->func->generate(*keyp, exp, mctx); + if (ret != ISC_R_SUCCESS) { + dst_key_free(*keyp); + return (ret); + } + + return (ISC_R_SUCCESS); +} + +/* + * dst_key_compare + * Compares two keys for equality. + * Parameters + * key1, key2 Two keys to be compared. + * Returns + * ISC_TRUE The keys are equal. + * ISC_FALSE The keys are not equal. + */ +isc_boolean_t +dst_key_compare(const dst_key_t *key1, const dst_key_t *key2) { + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(VALID_KEY(key1)); + REQUIRE(VALID_KEY(key2)); + + if (key1 == key2) + return (ISC_TRUE); + if (key1 == NULL || key2 == NULL) + return (ISC_FALSE); + if (key1->key_alg == key2->key_alg && + key1->key_id == key2->key_id && + key1->func->compare(key1, key2) == ISC_TRUE) + return (ISC_TRUE); + else + return (ISC_FALSE); +} +/* + * dst_key_paramcompare + * Compares two keys' parameters for equality. This is designed to + * determine if two (Diffie-Hellman) keys can be used to derive a shared + * secret. + * Parameters + * key1, key2 Two keys whose parameters are to be compared. + * Returns + * ISC_TRUE The keys' parameters are equal. + * ISC_FALSE The keys' parameters are not equal. + */ +isc_boolean_t +dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(VALID_KEY(key1)); + REQUIRE(VALID_KEY(key2)); + + if (key1 == key2) + return (ISC_TRUE); + if (key1 == NULL || key2 == NULL) + return (ISC_FALSE); + if (key1->key_alg == key2->key_alg && + key1->func->paramcompare != NULL && + key1->func->paramcompare(key1, key2) == ISC_TRUE) + return (ISC_TRUE); + else + return (ISC_FALSE); +} + +/* + * dst_key_free + * Release all data structures pointed to by a key structure. + * Parameters + * key Key structure to be freed. + */ +void +dst_key_free(dst_key_t *key) { + isc_mem_t *mctx; + + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(VALID_KEY(key)); + + mctx = key->mctx; + + if (key->opaque != NULL) + key->func->destroy(key->opaque, mctx); + + isc_mem_free(mctx, key->key_name); + memset(key, 0, sizeof(dst_key_t)); + isc_mem_put(mctx, key, sizeof(dst_key_t)); +} + +char * +dst_key_name(const dst_key_t *key) { + REQUIRE(VALID_KEY(key)); + return (key->key_name); +} + +int +dst_key_size(const dst_key_t *key) { + REQUIRE(VALID_KEY(key)); + return (key->key_size); +} + +int +dst_key_proto(const dst_key_t *key) { + REQUIRE(VALID_KEY(key)); + return (key->key_proto); +} + +int +dst_key_alg(const dst_key_t *key) { + REQUIRE(VALID_KEY(key)); + return (key->key_alg); +} + +isc_uint32_t +dst_key_flags(const dst_key_t *key) { + REQUIRE(VALID_KEY(key)); + return (key->key_flags); +} + +isc_uint16_t +dst_key_id(const dst_key_t *key) { + REQUIRE(VALID_KEY(key)); + return (key->key_id); +} + +isc_boolean_t +dst_key_isprivate(const dst_key_t *key) { + REQUIRE(VALID_KEY(key)); + return (key->func->isprivate(key)); +} + +/* + * dst_sig_size + * Computes the maximum size of a signature generated by the given key + * Parameters + * key The DST key + * n Stores the number of bytes necessary to hold a signature + * with the key. + * Returns + * ISC_R_SUCCESS + * DST_R_UNSUPPORTEDALG + */ +isc_result_t +dst_sig_size(const dst_key_t *key, unsigned int *n) { + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(VALID_KEY(key)); + REQUIRE(n != NULL); + + switch (key->key_alg) { + case DST_ALG_RSA: + *n = (key->key_size + 7) / 8; + break; + case DST_ALG_DSA: + *n = DNS_SIG_DSASIGSIZE; + break; + case DST_ALG_HMACMD5: + *n = 16; + break; + case DST_ALG_HMACSHA1: + *n = 20; + break; + case DST_ALG_DH: + default: + return (DST_R_UNSUPPORTEDALG); + } + return (ISC_R_SUCCESS); +} + +/* + * dst_secret_size + * Computes the maximum size of a shared secret generated by the given key + * Parameters + * key The DST key + * n Stores the number of bytes necessary to hold a shared secret + * generated by the key. + * Returns + * ISC_R_SUCCESS + * DST_R_UNSUPPORTEDALG + */ +isc_result_t +dst_secret_size(const dst_key_t *key, unsigned int *n) { + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(VALID_KEY(key)); + REQUIRE(n != NULL); + + switch (key->key_alg) { + case DST_ALG_DH: + *n = (key->key_size + 7) / 8; + break; + case DST_ALG_RSA: + case DST_ALG_DSA: + case DST_ALG_HMACMD5: + case DST_ALG_HMACSHA1: + default: + return (DST_R_UNSUPPORTEDALG); + } + return (ISC_R_SUCCESS); +} + +/* + * dst_random_get + * a random number generator that can generate different levels of + * randomness + * Parameters + * mode selects the random number generator + * wanted the number of random bytes requested + * target the buffer to store the random data + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +dst_result_t +dst_random_get(const unsigned int wanted, isc_buffer_t *target) { + isc_region_t r; + + RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); + REQUIRE(target != NULL); + + isc_buffer_available(target, &r); + if (r.length < wanted) + return (ISC_R_NOSPACE); + + RUNTIME_CHECK(isc_mutex_lock((&random_lock)) == ISC_R_SUCCESS); + RAND_bytes(r.base, wanted); + RUNTIME_CHECK(isc_mutex_unlock((&random_lock)) == ISC_R_SUCCESS); + isc_buffer_add(target, wanted); + return (ISC_R_SUCCESS); +} + +/*** + *** Static methods + ***/ + +/* + * initialize + * This function initializes the Digital Signature Toolkit. + * Parameters + * none + * Returns + * none + */ +static void +initialize() { + memset(dst_t_func, 0, sizeof(dst_t_func)); + + RUNTIME_CHECK(isc_mem_create(0, 0, &dst_memory_pool) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_mutex_init(&random_lock) == ISC_R_SUCCESS); + + dst_result_register(); + + dst_s_hmacmd5_init(); +#if defined(BSAFE) || defined(DNSSAFE) + dst_s_bsafersa_init(); +#endif +#ifdef OPENSSL + dst_s_openssldsa_init(); + dst_s_openssldh_init(); +#endif +} + +/* + * get_key_struct + * This function allocates key structure and fills in some of the + * fields of the structure. + * Parameters: + * name the name of the key + * alg the algorithm number + * flags the dns flags of the key + * protocol the dns protocol of the key + * bits the size of the key + * mctx the memory context to allocate from + * Returns: + * NULL error + * valid pointer otherwise + */ +static dst_key_t * +get_key_struct(const char *name, const int alg, const int flags, + const int protocol, const int bits, isc_mem_t *mctx) +{ + dst_key_t *key; + + REQUIRE(dst_supported_algorithm(alg) != ISC_FALSE); + + key = (dst_key_t *) isc_mem_get(mctx, sizeof(dst_key_t)); + if (key == NULL) + return (NULL); + + memset(key, 0, sizeof(dst_key_t)); + key->magic = KEY_MAGIC; + if (name[strlen(name) - 1] == '.') { + key->key_name = isc_mem_strdup(mctx, name); + if (key->key_name == NULL) { + isc_mem_free(mctx, key); + return (NULL); + } + } + else { + key->key_name = isc_mem_allocate(mctx, strlen(name) + 2); + if (key->key_name == NULL) { + isc_mem_free(mctx, key); + return (NULL); + } + sprintf(key->key_name, "%s.", name); + } + key->key_alg = alg; + key->key_flags = flags; + key->key_proto = protocol; + key->mctx = mctx; + key->opaque = NULL; + key->key_size = bits; + key->func = dst_t_func[alg]; + return (key); +} + +/* + * dst_read_public_key + * Read a public key from disk + * Parameters + * name The name + * id The id + * alg The algorithm + * mctx The memory context used to allocate the key + * keyp Returns the new key + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +read_public_key(const char *name, const isc_uint16_t id, int alg, + isc_mem_t *mctx, dst_key_t **keyp) +{ + char filename[ISC_DIR_NAMEMAX]; + u_char rdatabuf[DST_KEY_MAXSIZE]; + isc_buffer_t b; + isc_lex_t *lex = NULL; + isc_token_t token; + isc_result_t ret; + dns_rdata_t rdata; + unsigned int opt = ISC_LEXOPT_DNSMULTILINE; + + if (dst_s_build_filename(filename, name, id, alg, PUBLIC_KEY, + sizeof(filename)) != ISC_R_SUCCESS) + return (DST_R_NAMETOOLONG); + + /* + * Open the file and read its formatted contents + * File format: + * domain.name [ttl] [IN] KEY <flags> <protocol> <algorithm> <key> + */ + + /* 1500 should be large enough for any key */ + ret = isc_lex_create(mctx, 1500, &lex); + if (ret != ISC_R_SUCCESS) + return (ISC_R_NOMEMORY); + + ret = isc_lex_openfile(lex, filename); + if (ret != ISC_R_SUCCESS) { + if (ret == ISC_R_FAILURE) + ret = ISC_R_NOTFOUND; + goto cleanup; + } + +#define NEXTTOKEN(lex, opt, token) { \ + ret = isc_lex_gettoken(lex, opt, token); \ + if (ret != ISC_R_SUCCESS) \ + goto cleanup; \ + } + + /* Read the domain name */ + NEXTTOKEN(lex, opt, &token); + + /* Read the next word: either TTL, 'IN', or 'KEY' */ + NEXTTOKEN(lex, opt, &token); + + /* If it's a TTL, read the next one */ + if (token.type == isc_tokentype_number) + NEXTTOKEN(lex, opt, &token); + + if (token.type != isc_tokentype_string) + goto cleanup; + + if (strcasecmp(token.value.as_pointer, "IN") == 0) + NEXTTOKEN(lex, opt, &token); + + if (token.type != isc_tokentype_string) + goto cleanup; + + if (strcasecmp(token.value.as_pointer, "KEY") != 0) + goto cleanup; + + isc_buffer_init(&b, rdatabuf, sizeof(rdatabuf), ISC_BUFFERTYPE_BINARY); + ret = dns_rdata_fromtext(&rdata, dns_rdataclass_in, dns_rdatatype_key, + lex, NULL, ISC_FALSE, &b, NULL); + if (ret != ISC_R_SUCCESS) + goto cleanup; + + ret = dst_key_fromdns(name, &b, mctx, keyp); + if (ret != ISC_R_SUCCESS || (*keyp)->key_alg != alg) + goto cleanup; + + isc_lex_close(lex); + isc_lex_destroy(&lex); + + return (ISC_R_SUCCESS); + +cleanup: + if (lex != NULL) { + isc_lex_close(lex); + isc_lex_destroy(&lex); + } + return (ret); +} + + +/* + * write_public_key + * Write a key to disk in DNS format. + * Parameters + * key A DST key + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +write_public_key(const dst_key_t *key) { + FILE *fp; + isc_buffer_t keyb, textb; + isc_region_t r; + char filename[ISC_DIR_NAMEMAX]; + unsigned char key_array[DST_KEY_MAXSIZE]; + char text_array[DST_KEY_MAXSIZE]; + dst_result_t ret; + isc_result_t dnsret; + dns_rdata_t rdata; + + REQUIRE(VALID_KEY(key)); + + isc_buffer_init(&keyb, key_array, sizeof(key_array), + ISC_BUFFERTYPE_BINARY); + isc_buffer_init(&textb, text_array, sizeof(text_array), + ISC_BUFFERTYPE_TEXT); + + ret = dst_key_todns(key, &keyb); + if (ret != ISC_R_SUCCESS) + return (ret); + + isc_buffer_used(&keyb, &r); + dns_rdata_fromregion(&rdata, dns_rdataclass_in, dns_rdatatype_key, &r); + + dnsret = dns_rdata_totext(&rdata, (dns_name_t *) NULL, &textb); + if (dnsret != ISC_R_SUCCESS) + return (DST_R_INVALIDPUBLICKEY); + + dns_rdata_freestruct(&rdata); + + isc_buffer_used(&textb, &r); + + /* + * Make the filename. + */ + if (dst_s_build_filename(filename, + key->key_name, key->key_id, key->key_alg, + PUBLIC_KEY, sizeof(filename)) < 0) + return (DST_R_NAMETOOLONG); + + /* + * Create public key file. + */ + if ((fp = fopen(filename, "w")) == NULL) + return (DST_R_WRITEERROR); + + fprintf(fp, "%s IN KEY ", key->key_name); + fwrite(r.base, 1, r.length, fp); + fputc('\n', fp); + fclose(fp); + return (ISC_R_SUCCESS); +} + +void * +dst_mem_alloc(size_t size) { + INSIST(dst_memory_pool != NULL); + return (isc_mem_allocate(dst_memory_pool, size)); +} + +void +dst_mem_free(void *ptr) { + INSIST(dst_memory_pool != NULL); + if (ptr != NULL) + isc_mem_free(dst_memory_pool, ptr); +} + +void * +dst_mem_realloc(void *ptr, size_t size) { + void *p; + + INSIST(dst_memory_pool != NULL); + p = NULL; + if (size > 0) { + p = dst_mem_alloc(size); + if (p != NULL && ptr != NULL) + memcpy(p, ptr, size); + } + if (ptr != NULL) + dst_mem_free(ptr); + return (p); +} diff --git a/lib/dns/sec/dst/dst_internal.h b/lib/dns/sec/dst/dst_internal.h new file mode 100644 index 00000000..7689fb03 --- /dev/null +++ b/lib/dns/sec/dst/dst_internal.h @@ -0,0 +1,123 @@ +#ifndef DST_INTERNAL_H +#define DST_INTERNAL_H + +/* + * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. + * + * Permission to use, copy modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND TRUSTED INFORMATION SYSTEMS + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. + */ +#include <isc/lang.h> +#include <isc/buffer.h> +#include <isc/int.h> +#include <isc/region.h> + +#include <dst/dst.h> +#include <dst/result.h> + +ISC_LANG_BEGINDECLS + +/* + * define what crypto systems are supported. + * BSAFE, DNSSAFE for RSA + * OPENSSL for DSA + * Only one package per algorithm can be defined. + */ +#if defined(BSAFE) && defined(DNSSAFE) +# error "Cannot have both BSAFE and DNSSAFE defined" +#endif + +/*** + *** Types + ***/ + +typedef struct dst_func dst_func; + +struct dst_key { + unsigned int magic; + char * key_name; /* name of the key */ + int key_size; /* size of the key in bits */ + int key_proto; /* protocols this key is used for */ + int key_alg; /* algorithm of the key */ + isc_uint32_t key_flags; /* flags of the public key */ + isc_uint16_t key_id; /* identifier of the key */ + isc_mem_t *mctx; /* memory context */ + void * opaque; /* pointer to key in crypto pkg fmt */ + dst_func * func; /* crypto package specific functions */ +}; + +struct dst_func { + dst_result_t (*sign)(const unsigned int mode, dst_key_t *key, + void **context, isc_region_t *data, + isc_buffer_t *sig, isc_mem_t *mctx); + dst_result_t (*verify)(const unsigned int mode, dst_key_t *key, + void **context, isc_region_t *data, + isc_region_t *sig, isc_mem_t *mctx); + dst_result_t (*computesecret)(const dst_key_t *pub, + const dst_key_t *priv, + isc_buffer_t *secret); + isc_boolean_t (*compare)(const dst_key_t *key1, const dst_key_t *key2); + isc_boolean_t (*paramcompare)(const dst_key_t *key1, + const dst_key_t *key2); + dst_result_t (*generate)(dst_key_t *key, int parms, isc_mem_t *mctx); + isc_boolean_t (*isprivate)(const dst_key_t *key); + void (*destroy)(void *key, isc_mem_t *mctx); + /* conversion functions */ + dst_result_t (*to_dns)(const dst_key_t *key, isc_buffer_t *data); + dst_result_t (*from_dns)(dst_key_t *key, isc_buffer_t *data, + isc_mem_t *mctx); + dst_result_t (*to_file)(const dst_key_t *key); + dst_result_t (*from_file)(dst_key_t *key, const isc_uint16_t id, + isc_mem_t *mctx); +}; + +extern dst_func *dst_t_func[DST_MAX_ALGS]; + +/* suffixes for key file names */ +#define PRIVATE_KEY "private" +#define PUBLIC_KEY "key" + +#ifndef DST_HASH_SIZE +#define DST_HASH_SIZE 20 /* RIPEMD160 & SHA-1 are 20 bytes, MD5 is 16 */ +#endif + +void dst_s_hmacmd5_init(void); +void dst_s_bsafersa_init(void); +void dst_s_openssldsa_init(void); +void dst_s_openssldh_init(void); + +/* support functions */ + +int dst_s_calculate_bits(const unsigned char *str, const int max_bits); +isc_uint16_t dst_s_id_calc(const unsigned char *key, const int keysize); +int dst_s_build_filename(char *filename, const char *name, + isc_uint16_t id, int alg, + const char *suffix, + size_t filename_length); + + +/* digest functions */ +dst_result_t dst_s_md5(const unsigned int mode, void **context, + isc_region_t *data, isc_buffer_t *digest, + isc_mem_t *mctx); + + +/* memory allocators using the DST memory pool */ +void * dst_mem_alloc(size_t size); +void dst_mem_free(void *ptr); +void * dst_mem_realloc(void *ptr, size_t size); + + +ISC_LANG_ENDDECLS + +#endif /* DST_INTERNAL_H */ diff --git a/lib/dns/sec/dst/dst_lib.c b/lib/dns/sec/dst/dst_lib.c new file mode 100644 index 00000000..d4702194 --- /dev/null +++ b/lib/dns/sec/dst/dst_lib.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Principal Author: Brian Wellington + * $Id: dst_lib.c,v 1.1 1999/07/12 20:08:28 bwelling Exp $ + */ + +#include <config.h> + +#include <stddef.h> + +#include <isc/once.h> +#include <isc/error.h> +#include <isc/msgcat.h> + +#include <dst/lib.h> + +/*** + *** Globals + ***/ + +isc_msgcat_t * dst_msgcat = NULL; + + +/*** + *** Private + ***/ + +static isc_once_t msgcat_once = ISC_ONCE_INIT; + + +/*** + *** Functions + ***/ + +static void +open_msgcat(void) { + isc_msgcat_open("libdst.cat", &dst_msgcat); +} + +void +dst_lib_initmsgcat(void) { + + /* + * Initialize the DST library's message catalog, dst_msgcat, if it + * has not already been initialized. + */ + + RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS); +} diff --git a/lib/dns/sec/dst/dst_parse.c b/lib/dns/sec/dst/dst_parse.c new file mode 100644 index 00000000..e2dae73a --- /dev/null +++ b/lib/dns/sec/dst/dst_parse.c @@ -0,0 +1,391 @@ +/* + * Portions Copyright (c) 1995-1999 by Network Associates, Inc. + * + * Permission to use, copy modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. + */ + +/* + * Principal Author: Brian Wellington + * $Id: dst_parse.c,v 1.9 1999/10/20 22:14:14 bwelling Exp $ + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <limits.h> + +#include <isc/assertions.h> +#include <isc/base64.h> +#include <isc/buffer.h> +#include <isc/dir.h> +#include <isc/int.h> +#include <isc/lex.h> +#include <isc/mem.h> +#include <isc/region.h> +#include <dns/rdata.h> + +/* XXXBEW For chmod. This should be removed. */ +#include <sys/stat.h> + +#include "dst_internal.h" +#include "dst_parse.h" +#include "dst/result.h" + + +#define PRIVATE_KEY_STR "Private-key-format:" +#define ALGORITHM_STR "Algorithm:" +#define RSA_STR "RSA" +#define DH_STR "DH" +#define DSA_STR "DSA" +#define HMACMD5_STR "HMAC_MD5" + +struct parse_map { + int value; + char *tag; +}; + +static struct parse_map map[] = { + {TAG_RSA_MODULUS, "Modulus:"}, + {TAG_RSA_PUBLICEXPONENT, "PublicExponent:"}, + {TAG_RSA_PRIVATEEXPONENT, "PrivateExponent:"}, + {TAG_RSA_PRIME1, "Prime1:"}, + {TAG_RSA_PRIME2, "Prime2:"}, + {TAG_RSA_EXPONENT1, "Exponent1:"}, + {TAG_RSA_EXPONENT2, "Exponent2:"}, + {TAG_RSA_COEFFICIENT, "Coefficient:"}, + + {TAG_DH_PRIME, "Prime(p):"}, + {TAG_DH_GENERATOR, "Generator(g):"}, + {TAG_DH_PRIVATE, "Private_value(x):"}, + {TAG_DH_PUBLIC, "Public_value(y):"}, + + {TAG_DSA_PRIME, "Prime(p):"}, + {TAG_DSA_SUBPRIME, "Subprime(q):"}, + {TAG_DSA_BASE, "Base(g):"}, + {TAG_DSA_PRIVATE, "Private_value(x):"}, + {TAG_DSA_PUBLIC, "Public_value(y):"}, + + {TAG_HMACMD5_KEY, "Key:"}, + {0, NULL} +}; + +static int +find_value(const char *s, const int alg) { + int i; + + for (i = 0; ; i++) { + if (map[i].tag == NULL) + return (-1); + else if (strcasecmp(s, map[i].tag) == 0 && + TAG_ALG(map[i].value) == alg) + return (map[i].value); + } +} + +static char * +find_tag(const int value) { + int i; + + for (i = 0; ; i++) { + if (map[i].tag == NULL) + return (NULL); + else if (value == map[i].value) + return (map[i].tag); + } +} + +static int +check_rsa(const dst_private_t *priv) { + int i, j; + if (priv->nelements != RSA_NTAGS) + return (-1); + for (i = 0; i < RSA_NTAGS; i++) { + for (j = 0; j < priv->nelements; j++) + if (priv->elements[j].tag == TAG(DST_ALG_RSA, i)) + break; + if (j == priv->nelements) + return (-1); + } + return (0); +} + +static int +check_dh(const dst_private_t *priv) { + int i, j; + if (priv->nelements != DH_NTAGS) + return (-1); + for (i = 0; i < DH_NTAGS; i++) { + for (j = 0; j < priv->nelements; j++) + if (priv->elements[j].tag == TAG(DST_ALG_DH, i)) + break; + if (j == priv->nelements) + return (-1); + } + return (0); +} + +static int +check_dsa(const dst_private_t *priv) { + int i, j; + if (priv->nelements != DSA_NTAGS) + return (-1); + for (i = 0; i < DSA_NTAGS; i++) { + for (j = 0; j < priv->nelements; j++) + if (priv->elements[j].tag == TAG(DST_ALG_DSA, i)) + break; + if (j == priv->nelements) + return (-1); + } + return (0); +} + +static int +check_hmac_md5(const dst_private_t *priv) { + if (priv->nelements != HMACMD5_NTAGS) + return (-1); + if (priv->elements[0].tag != TAG_HMACMD5_KEY) + return (-1); + return (0); +} + +static int +check_data(const dst_private_t *priv, const int alg) { + switch (alg) { + case DST_ALG_RSA: + return (check_rsa(priv)); + case DST_ALG_DH: + return (check_dh(priv)); + case DST_ALG_DSA: + return (check_dsa(priv)); + case DST_ALG_HMACMD5: + return (check_hmac_md5(priv)); + default: + return (DST_R_UNSUPPORTEDALG); + } +} + +void +dst_s_free_private_structure_fields(dst_private_t *priv, isc_mem_t *mctx) { + int i; + + if (priv == NULL) + return; + for (i = 0; i < priv->nelements; i++) { + if (priv->elements[i].data == NULL) + continue; + memset(priv->elements[i].data, 0, MAXFIELDSIZE); + isc_mem_put(mctx, priv->elements[i].data, MAXFIELDSIZE); + } + priv->nelements = 0; +} + +int +dst_s_parse_private_key_file(const char *name, const int alg, + const isc_uint16_t id, dst_private_t *priv, + isc_mem_t *mctx) +{ + char filename[ISC_DIR_NAMEMAX]; + int n = 0, ret, major, minor; + isc_buffer_t b; + isc_lex_t *lex = NULL; + isc_token_t token; + unsigned int opt = ISC_LEXOPT_EOL; + isc_result_t iret; + isc_result_t error = DST_R_INVALIDPRIVATEKEY; + + REQUIRE(priv != NULL); + + priv->nelements = 0; + + ret = dst_s_build_filename(filename, name, id, alg, PRIVATE_KEY, + sizeof(filename)); + if (ret < 0) + return (DST_R_NAMETOOLONG); + + iret = isc_lex_create(mctx, 1024, &lex); + if (iret != ISC_R_SUCCESS) + return (ISC_R_NOMEMORY); + + iret = isc_lex_openfile(lex, filename); + if (iret != ISC_R_SUCCESS) + goto fail; + +#define NEXTTOKEN(lex, opt, token) \ + { \ + iret = isc_lex_gettoken(lex, opt, token); \ + if (iret != ISC_R_SUCCESS) \ + goto fail; \ + } + +#define READLINE(lex, opt, token) \ + do { \ + NEXTTOKEN(lex, opt, token) \ + } while ((*token).type != isc_tokentype_eol) \ + + /* Read the description line */ + NEXTTOKEN(lex, opt, &token); + if (token.type != isc_tokentype_string || + strcmp(token.value.as_pointer, PRIVATE_KEY_STR) != 0) + goto fail; + + NEXTTOKEN(lex, opt, &token); + if (token.type != isc_tokentype_string || + ((char *)token.value.as_pointer)[0] != 'v') + goto fail; + if (sscanf(token.value.as_pointer, "v%d.%d", &major, &minor) != 2) + goto fail; + + if (major > MAJOR_VERSION || + (major == MAJOR_VERSION && minor > MINOR_VERSION)) + goto fail; + + READLINE(lex, opt, &token); + + /* Read the algorithm line */ + NEXTTOKEN(lex, opt, &token); + if (token.type != isc_tokentype_string || + strcmp(token.value.as_pointer, ALGORITHM_STR) != 0) + goto fail; + + NEXTTOKEN(lex, opt | ISC_LEXOPT_NUMBER, &token); + if (token.type != isc_tokentype_number || + token.value.as_ulong != (unsigned long) alg) + goto fail; + + READLINE(lex, opt, &token); + + /* Read the key data */ + for (n = 0; n < MAXFIELDS; n++) { + int tag; + unsigned char *data; + isc_region_t r; + + iret = isc_lex_gettoken(lex, opt, &token); + if (iret == ISC_R_EOF) + break; + if (iret != ISC_R_SUCCESS) + goto fail; + if (token.type != isc_tokentype_string) + goto fail; + + memset(&priv->elements[n], 0, sizeof(dst_private_element_t)); + tag = find_value(token.value.as_pointer, alg); + if (tag < 0 || TAG_ALG(tag) != alg) + goto fail; + priv->elements[n].tag = tag; + + data = (unsigned char *) isc_mem_get(mctx, MAXFIELDSIZE); + if (data == NULL) { + error = DST_R_INVALIDPRIVATEKEY; + goto fail; + } + isc_buffer_init(&b, data, MAXFIELDSIZE, ISC_BUFFERTYPE_BINARY); + ret = isc_base64_tobuffer(lex, &b, -1); + if (ret != ISC_R_SUCCESS) + goto fail; + isc_buffer_used(&b, &r); + priv->elements[n].length = r.length; + priv->elements[n].data = r.base; + + READLINE(lex, opt, &token); + } + + priv->nelements = n; + + if (check_data(priv, alg) < 0) + goto fail; + + isc_lex_close(lex); + isc_lex_destroy(&lex); + + return (ISC_R_SUCCESS); + +fail: + if (lex != NULL) { + isc_lex_close(lex); + isc_lex_destroy(&lex); + } + + priv->nelements = n; + dst_s_free_private_structure_fields(priv, mctx); + return (DST_R_INVALIDPRIVATEKEY); +} + +int +dst_s_write_private_key_file(const char *name, const int alg, + const isc_uint16_t id, const dst_private_t *priv) +{ + FILE *fp; + int ret, i; + isc_result_t iret; + char filename[ISC_DIR_NAMEMAX]; + char buffer[MAXFIELDSIZE * 2]; + + REQUIRE(priv != NULL); + + if (check_data(priv, alg) < 0) + return (DST_R_INVALIDPRIVATEKEY); + + ret = dst_s_build_filename(filename, name, id, alg, PRIVATE_KEY, + sizeof(filename)); + if (ret < 0) + return (DST_R_NAMETOOLONG); + + if ((fp = fopen(filename, "w")) == NULL) + return (DST_R_WRITEERROR); + + /* XXXBEW This won't exist on non-unix systems. Hmmm.... */ + chmod(filename, 0600); + + fprintf(fp, "%s v%d.%d\n", PRIVATE_KEY_STR, MAJOR_VERSION, + MINOR_VERSION); + + fprintf(fp, "%s %d ", ALGORITHM_STR, alg); + switch (alg) { + case DST_ALG_RSA: fprintf(fp, "(RSA)\n"); break; + case DST_ALG_DH: fprintf(fp, "(DH)\n"); break; + case DST_ALG_DSA: fprintf(fp, "(DSA)\n"); break; + case DST_ALG_HMACMD5: fprintf(fp, "(HMAC_MD5)\n"); break; + default : fprintf(fp, "(?)\n"); break; + } + + for (i = 0; i < priv->nelements; i++) { + isc_buffer_t b; + isc_region_t r; + char *s; + + s = find_tag(priv->elements[i].tag); + + r.base = priv->elements[i].data; + r.length = priv->elements[i].length; + isc_buffer_init(&b, buffer, sizeof(buffer), + ISC_BUFFERTYPE_TEXT); + iret = isc_base64_totext(&r, sizeof(buffer), "", &b); + if (iret != ISC_R_SUCCESS) { + fclose(fp); + return (DST_R_INVALIDPRIVATEKEY); + } + isc_buffer_used(&b, &r); + + fprintf(fp, "%s ", s); + fwrite(r.base, 1, r.length, fp); + fprintf(fp, "\n"); + } + + fclose(fp); + return (ISC_R_SUCCESS); +} diff --git a/lib/dns/sec/dst/dst_parse.h b/lib/dns/sec/dst/dst_parse.h new file mode 100644 index 00000000..a431fc98 --- /dev/null +++ b/lib/dns/sec/dst/dst_parse.h @@ -0,0 +1,88 @@ +#ifndef DST_PARSE_H +#define DST_PARSE_H + +/* + * Portions Copyright (c) 1995-1998 by Trusted Information Systems, Inc. + * + * Permission to use, copy modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND TRUSTED INFORMATION SYSTEMS + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * TRUSTED INFORMATION SYSTEMS BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. + */ +#include <isc/lang.h> +#include <isc/mem.h> +#include <dst/dst.h> + +ISC_LANG_BEGINDECLS + +#define MAJOR_VERSION 1 +#define MINOR_VERSION 2 + +#define MAXFIELDSIZE 512 +#define MAXFIELDS 12 + +#define TAG_SHIFT 4 +#define TAG_ALG(tag) (tag >> TAG_SHIFT) +#define TAG(alg, off) ((alg << TAG_SHIFT) + off) + +#define RSA_NTAGS 8 +#define TAG_RSA_MODULUS ((DST_ALG_RSA << TAG_SHIFT) + 0) +#define TAG_RSA_PUBLICEXPONENT ((DST_ALG_RSA << TAG_SHIFT) + 1) +#define TAG_RSA_PRIVATEEXPONENT ((DST_ALG_RSA << TAG_SHIFT) + 2) +#define TAG_RSA_PRIME1 ((DST_ALG_RSA << TAG_SHIFT) + 3) +#define TAG_RSA_PRIME2 ((DST_ALG_RSA << TAG_SHIFT) + 4) +#define TAG_RSA_EXPONENT1 ((DST_ALG_RSA << TAG_SHIFT) + 5) +#define TAG_RSA_EXPONENT2 ((DST_ALG_RSA << TAG_SHIFT) + 6) +#define TAG_RSA_COEFFICIENT ((DST_ALG_RSA << TAG_SHIFT) + 7) + +#define DH_NTAGS 4 +#define TAG_DH_PRIME ((DST_ALG_DH << TAG_SHIFT) + 0) +#define TAG_DH_GENERATOR ((DST_ALG_DH << TAG_SHIFT) + 1) +#define TAG_DH_PRIVATE ((DST_ALG_DH << TAG_SHIFT) + 2) +#define TAG_DH_PUBLIC ((DST_ALG_DH << TAG_SHIFT) + 3) + +#define DSA_NTAGS 5 +#define TAG_DSA_PRIME ((DST_ALG_DSA << TAG_SHIFT) + 0) +#define TAG_DSA_SUBPRIME ((DST_ALG_DSA << TAG_SHIFT) + 1) +#define TAG_DSA_BASE ((DST_ALG_DSA << TAG_SHIFT) + 2) +#define TAG_DSA_PRIVATE ((DST_ALG_DSA << TAG_SHIFT) + 3) +#define TAG_DSA_PUBLIC ((DST_ALG_DSA << TAG_SHIFT) + 4) + +#define HMACMD5_NTAGS 1 +#define TAG_HMACMD5_KEY ((DST_ALG_HMACMD5 << TAG_SHIFT) + 0) + +struct dst_private_element { + unsigned short tag; + unsigned short length; + unsigned char *data; +}; + +typedef struct dst_private_element dst_private_element_t; + +struct dst_private { + unsigned short nelements; + dst_private_element_t elements[MAXFIELDS]; +}; + +typedef struct dst_private dst_private_t; + +void dst_s_free_private_structure_fields(dst_private_t *priv, + isc_mem_t *mctx); +int dst_s_parse_private_key_file(const char *name, const int alg, + const isc_uint16_t id, dst_private_t *priv, + isc_mem_t *mctx); +int dst_s_write_private_key_file(const char *name, const int alg, + const isc_uint16_t id, + const dst_private_t *priv); + +ISC_LANG_ENDDECLS + +#endif /* DST_PARSE_H */ diff --git a/lib/dns/sec/dst/dst_result.c b/lib/dns/sec/dst/dst_result.c new file mode 100644 index 00000000..16cc3d5a --- /dev/null +++ b/lib/dns/sec/dst/dst_result.c @@ -0,0 +1,87 @@ +/* + * Copyright (C) 1998, 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Principal Author: Brian Wellington + * $Id: dst_result.c,v 1.3 1999/09/27 16:55:44 bwelling Exp $ + */ + +#include <config.h> + +#include <stddef.h> + +#include <isc/resultclass.h> +#include <isc/once.h> +#include <isc/error.h> + +#include <dst/result.h> +#include <dst/lib.h> + +static char *text[DST_R_NRESULTS] = { + "algorithm is unsupported", /* 0 */ + "key type is unsupported", /* 1 */ + "signature mode is unsupported", /* 2 */ + "illegal operation for a null key", /* 3 */ + "public key is invalid", /* 4 */ + "private key is invalid", /* 5 */ + "key name is too long", /* 6 */ + "error occurred writing key to disk", /* 7 */ + "invalid algorithm specific parameter", /* 8 */ + "sign init failure", /* 9 */ + "sign update failure", /* 10 */ + "sign final failure", /* 11 */ + "verify init failure", /* 12 */ + "verify update failure", /* 13 */ + "verify final failure", /* 14 */ + "not a public key", /* 15 */ + "not a private key", /* 16 */ + "not a key that can compute a secret", /* 17 */ + "failure computing a shared secret", /* 18 */ +}; + +#define DST_RESULT_RESULTSET 2 + +static isc_once_t once = ISC_ONCE_INIT; + +static void +initialize_action(void) { + isc_result_t result; + + result = isc_result_register(ISC_RESULTCLASS_DST, DST_R_NRESULTS, + text, dst_msgcat, DST_RESULT_RESULTSET); + if (result != ISC_R_SUCCESS) + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_result_register() failed: %u", result); +} + +static void +initialize(void) { + dst_lib_initmsgcat(); + RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); +} + +char * +dst_result_totext(dst_result_t result) { + initialize(); + + return (isc_result_totext(result)); +} + +void +dst_result_register(void) { + initialize(); +} diff --git a/lib/dns/sec/dst/dst_support.c b/lib/dns/sec/dst/dst_support.c new file mode 100644 index 00000000..a2d42a9d --- /dev/null +++ b/lib/dns/sec/dst/dst_support.c @@ -0,0 +1,129 @@ +/* + * Portions Copyright (c) 1995-1999 by Network Associates, Inc. + * + * Permission to use, copy modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. + */ + +/* + * Principal Author: Brian Wellington + * $Id: dst_support.c,v 1.3 1999/11/02 19:52:29 bwelling Exp $ + */ + +#include <config.h> + +#include <stdio.h> +#include <unistd.h> +#include <memory.h> +#include <string.h> +#include <isc/int.h> + +#include "dst_internal.h" + +/* + * dst_s_calculate_bits + * Given a binary number represented by a u_char[], determine + * the number of significant bits used. + * Parameters + * str An input character string containing a binary number. + * max_bits The maximum possible significant bits. + * Return + * N The number of significant bits in str. + */ + +int +dst_s_calculate_bits(const unsigned char *str, const int max_bits) +{ + const unsigned char *p = str; + unsigned char i, j = 0x80; + int bits; + for (bits = max_bits; *p == 0x00 && bits > 0; p++) + bits -= 8; + for (i = *p; (i & j) != j; j >>= 1) + bits--; + return (bits); +} + + +/* + * dst_s_id_calc + * Calculates the checksum used by DNS as a key id. + * Parameters + * key The key in DNS format + * length The length of the array + * Return + * N the 16 bit checksum. + */ +isc_uint16_t +dst_s_id_calc(const unsigned char *key, const int keysize) +{ + isc_uint32_t ac; + const unsigned char *kp = key; + int size = keysize; + + if (key == NULL || (keysize <= 0)) + return (-1); + + for (ac = 0; size > 1; size -= 2, kp += 2) + ac += ((*kp) << 8) + *(kp + 1); + + if (size > 0) + ac += ((*kp) << 8); + ac += (ac >> 16) & 0xffff; + + return ((isc_uint16_t)(ac & 0xffff)); +} + +/* + * dst_s_build_filename + * Builds a key filename from the key name, its id, and a + * suffix. '\', '/' and ':' are not allowed. fA filename is of the + * form: K<keyname><id>.<suffix> + * form: K<keyname>+<alg>+<id>.<suffix> + * + * Returns -1 if the conversion fails: + * if the filename would be too long for space allotted + * if the filename would contain a '\', '/' or ':' + * Returns 0 on success + */ + +int +dst_s_build_filename(char *filename, const char *name, isc_uint16_t id, + int alg, const char *suffix, size_t filename_length) +{ + isc_uint32_t my_id; + char *dot; + if (filename == NULL) + return (-1); + memset(filename, 0, filename_length); + if (name == NULL) + return (-1); + if (suffix == NULL) + return (-1); + if (filename_length < 1 + strlen(name) + 1 + 4 + 6 + 1 + strlen(suffix)) + return (-1); + my_id = id; + if (name[strlen(name) - 1] == '.') + dot = ""; + else + dot = "."; + sprintf(filename, "K%s%s+%03d+%05d.%s", name, dot, alg, my_id, + (char *) suffix); + if (strrchr(filename, '/')) + return (-1); + if (strrchr(filename, '\\')) + return (-1); + if (strrchr(filename, ':')) + return (-1); + return (0); +} diff --git a/lib/dns/sec/dst/hmac_link.c b/lib/dns/sec/dst/hmac_link.c new file mode 100644 index 00000000..6cc2c0b8 --- /dev/null +++ b/lib/dns/sec/dst/hmac_link.c @@ -0,0 +1,504 @@ +/* + * Portions Copyright (c) 1995-1998 by Network Associates, Inc. + * + * Permission to use, copy modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. + */ + +/* + * Principal Author: Brian Wellington + * $Id: hmac_link.c,v 1.15 1999/10/29 05:25:57 marka Exp $ + */ + +#include <config.h> + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <memory.h> + +#include <isc/assertions.h> +#include <isc/buffer.h> +#include <isc/int.h> +#include <isc/region.h> + +#include <openssl/md5.h> + +#include "dst_internal.h" +#include "dst_parse.h" + +#define HMAC_LEN 64 +#define HMAC_IPAD 0x36 +#define HMAC_OPAD 0x5c + +#define MD5Init MD5_Init +#define MD5Update MD5_Update +#define MD5Final MD5_Final + +#define RETERR(x) do { \ + ret = (x); \ + if (ret != ISC_R_SUCCESS) \ + return (ret); \ + } while (0) + +typedef struct hmackey { + unsigned char ipad[64], opad[64]; +} HMAC_Key; + +static struct dst_func hmacmd5_functions; + +static dst_result_t dst_hmacmd5_sign(const unsigned int mode, + dst_key_t *key, + void **context, isc_region_t *data, + isc_buffer_t *sig, isc_mem_t *mctx); +static dst_result_t dst_hmacmd5_verify(const unsigned int mode, + dst_key_t *key, + void **context, isc_region_t *data, + isc_region_t *sig, isc_mem_t *mctx); +static isc_boolean_t dst_hmacmd5_compare(const dst_key_t *key1, + const dst_key_t *key2); +static dst_result_t dst_hmacmd5_generate(dst_key_t *key, int exp, + isc_mem_t *mctx); +static isc_boolean_t dst_hmacmd5_isprivate(const dst_key_t *key); +static void dst_hmacmd5_destroy(void *key, isc_mem_t *mctx); +static dst_result_t dst_hmacmd5_to_dns(const dst_key_t *in_key, + isc_buffer_t *data); +static dst_result_t dst_hmacmd5_from_dns(dst_key_t *key, isc_buffer_t *data, + isc_mem_t *mctx); +static dst_result_t dst_hmacmd5_to_file(const dst_key_t *key); +static dst_result_t dst_hmacmd5_from_file(dst_key_t *key, + const isc_uint16_t id, + isc_mem_t *mctx); + +/* + * dst_s_hmacmd5_init() + * Sets up function pointers for HMAC-MD5 related functions + */ +void +dst_s_hmacmd5_init() +{ + REQUIRE(dst_t_func[DST_ALG_HMACMD5] == NULL); + dst_t_func[DST_ALG_HMACMD5] = &hmacmd5_functions; + memset(&hmacmd5_functions, 0, sizeof(struct dst_func)); + hmacmd5_functions.sign = dst_hmacmd5_sign; + hmacmd5_functions.verify = dst_hmacmd5_verify; + hmacmd5_functions.computesecret = NULL; + hmacmd5_functions.compare = dst_hmacmd5_compare; + hmacmd5_functions.paramcompare = NULL; + hmacmd5_functions.generate = dst_hmacmd5_generate; + hmacmd5_functions.isprivate = dst_hmacmd5_isprivate; + hmacmd5_functions.destroy = dst_hmacmd5_destroy; + hmacmd5_functions.to_dns = dst_hmacmd5_to_dns; + hmacmd5_functions.from_dns = dst_hmacmd5_from_dns; + hmacmd5_functions.to_file = dst_hmacmd5_to_file; + hmacmd5_functions.from_file = dst_hmacmd5_from_file; +} + +/* + * dst_hmacmd5_sign + * Call HMAC-MD5 signing functions to sign a block of data. + * There are three steps to signing, INIT (initialize structures), + * UPDATE (hash (more) data), FINAL (generate a signature). This + * routine performs one or more of these steps. + * Parameters + * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL} + * key key to use for signing + * context the context to use for this computation + * data data to be signed + * signature buffer to store signature + * mctx memory context for temporary allocations + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_hmacmd5_sign(const unsigned int mode, dst_key_t *key, void **context, + isc_region_t *data, isc_buffer_t *sig, isc_mem_t *mctx) +{ + isc_region_t r; + isc_result_t ret; + void *ctx; + + if ((mode & DST_SIGMODE_ALL) != DST_SIGMODE_ALL) + REQUIRE(context != NULL); + else + context = &ctx; + + if (mode & DST_SIGMODE_INIT) { + HMAC_Key *hkey = key->opaque; + + r.base = hkey->ipad; + r.length = HMAC_LEN; + RETERR(dst_s_md5(DST_SIGMODE_INIT, context, NULL, NULL, mctx)); + RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx)); + } + if (mode & DST_SIGMODE_UPDATE) { + RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, data, NULL, + mctx)); + } + if (mode & DST_SIGMODE_FINAL) { + HMAC_Key *hkey = key->opaque; + unsigned char digest[MD5_DIGEST_LENGTH]; + isc_buffer_t b; + + isc_buffer_init(&b, digest, sizeof(digest), + ISC_BUFFERTYPE_BINARY); + + RETERR(dst_s_md5(DST_SIGMODE_FINAL, context, NULL, &b, mctx)); + + RETERR(dst_s_md5(DST_SIGMODE_INIT, context, NULL, NULL, mctx)); + r.base = hkey->opad; + r.length = HMAC_LEN; + RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx)); + isc_buffer_used(&b, &r); + RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx)); + RETERR(dst_s_md5(DST_SIGMODE_FINAL, context, NULL, sig, mctx)); + } + + return (ISC_R_SUCCESS); +} + + +/* + * dst_hmacmd5_verify + * Calls HMAC-MD5 verification routines. There are three steps to + * verification, INIT (initialize structures), UPDATE (hash (more) data), + * FINAL (generate a signature). This routine performs one or more of + * these steps. + * Parameters + * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL} + * key key to use for verifying + * context the context to use for this computation + * data signed data + * signature signature + * mctx memory context for temporary allocations + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_hmacmd5_verify(const unsigned int mode, dst_key_t *key, void **context, + isc_region_t *data, isc_region_t *sig, isc_mem_t *mctx) +{ + isc_region_t r; + isc_result_t ret; + void *ctx; + + if ((mode & DST_SIGMODE_ALL) != DST_SIGMODE_ALL) + REQUIRE(context != NULL); + else + context = &ctx; + + if (mode & DST_SIGMODE_INIT) { + HMAC_Key *hkey = key->opaque; + + r.base = hkey->ipad; + r.length = HMAC_LEN; + RETERR(dst_s_md5(DST_SIGMODE_INIT, context, NULL, NULL, mctx)); + RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx)); + } + if (mode & DST_SIGMODE_UPDATE) { + RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, data, NULL, + mctx)); + } + if (mode & DST_SIGMODE_FINAL) { + HMAC_Key *hkey = key->opaque; + unsigned char digest[MD5_DIGEST_LENGTH]; + isc_buffer_t b; + + isc_buffer_init(&b, digest, sizeof(digest), + ISC_BUFFERTYPE_BINARY); + + RETERR(dst_s_md5(DST_SIGMODE_FINAL, context, NULL, &b, mctx)); + + RETERR(dst_s_md5(DST_SIGMODE_INIT, context, NULL, NULL, mctx)); + r.base = hkey->opad; + r.length = HMAC_LEN; + RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx)); + isc_buffer_used(&b, &r); + RETERR(dst_s_md5(DST_SIGMODE_UPDATE, context, &r, NULL, mctx)); + isc_buffer_clear(&b); + RETERR(dst_s_md5(DST_SIGMODE_FINAL, context, NULL, &b, mctx)); + + if (memcmp(digest, sig->base, MD5_DIGEST_LENGTH) != 0) + return (DST_R_VERIFYFINALFAILURE); + } + + return (ISC_R_SUCCESS); +} + +/* + * dst_hmacmd5_isprivate + * Is this a private key? Yes + * Parameters + * key DST KEY structure + * Returns + * ISC_TRUE + */ +static isc_boolean_t +dst_hmacmd5_isprivate(const dst_key_t *key) { + key = key; /* suppress warning */ + + return (ISC_TRUE); +} + + +/* + * dst_hmacmd5_to_dns + * Converts key from HMAC to DNS rdata (raw bytes) + * Parameters + * key DST KEY structure + * data output data + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +dst_hmacmd5_to_dns(const dst_key_t *key, isc_buffer_t *data) { + HMAC_Key *hkey; + isc_region_t r; + unsigned int bytes, i; + + REQUIRE(key->opaque != NULL); + + hkey = (HMAC_Key *) key->opaque; + + isc_buffer_available(data, &r); + + bytes = (key->key_size + 7) / 8; + if (r.length < bytes) + return (ISC_R_NOSPACE); + + for (i = 0; i < bytes; i++) + *r.base++ = hkey->ipad[i] ^ HMAC_IPAD; + + isc_buffer_add(data, bytes); + + return (ISC_R_SUCCESS); +} + + +/* + * dst_hmacmd5_from_dns + * Converts from a DNS KEY RR format to an HMAC-MD5 KEY. + * Parameters + * key Partially filled key structure + * data Buffer containing key in DNS format + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_hmacmd5_from_dns(dst_key_t *key, isc_buffer_t *data, isc_mem_t *mctx) { + HMAC_Key *hkey; + isc_region_t r; + int i, keylen; + + isc_buffer_remaining(data, &r); + if (r.length == 0) + return (ISC_R_SUCCESS); + + hkey = (HMAC_Key *) isc_mem_get(mctx, sizeof(HMAC_Key)); + if (hkey == NULL) + return (ISC_R_NOMEMORY); + + memset(hkey->ipad, 0, sizeof(hkey->ipad)); + memset(hkey->opad, 0, sizeof(hkey->opad)); + + if (r.length > HMAC_LEN) { + MD5_CTX ctx; + unsigned char digest[MD5_DIGEST_LENGTH]; + + MD5Init(&ctx); + MD5Update(&ctx, r.base, r.length); + MD5Final(digest, &ctx); + memcpy(hkey->ipad, digest, MD5_DIGEST_LENGTH); + memcpy(hkey->opad, digest, MD5_DIGEST_LENGTH); + keylen = MD5_DIGEST_LENGTH; + } + else { + memcpy(hkey->ipad, r.base, r.length); + memcpy(hkey->opad, r.base, r.length); + keylen = r.length; + } + + /* XOR key with ipad and opad values */ + for (i = 0; i < HMAC_LEN; i++) { + hkey->ipad[i] ^= HMAC_IPAD; + hkey->opad[i] ^= HMAC_OPAD; + } + key->key_size = keylen * 8; + key->opaque = hkey; + + return (ISC_R_SUCCESS); +} + + +/* + * dst_hmacmd5_to_file + * Encodes an HMAC-MD5 Key into the portable file format. + * Parameters + * key DST KEY structure + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_hmacmd5_to_file(const dst_key_t *key) { + int i, cnt = 0; + HMAC_Key *hkey; + dst_private_t priv; + unsigned char keydata[HMAC_LEN]; + + if (key->opaque == NULL) + return (DST_R_NULLKEY); + + hkey = (HMAC_Key *) key->opaque; + for (i = 0; i < HMAC_LEN; i++) + keydata[i] = hkey->ipad[i] ^ HMAC_IPAD; + + priv.elements[cnt].tag = TAG_HMACMD5_KEY; + priv.elements[cnt].length = HMAC_LEN; + priv.elements[cnt++].data = keydata; + + priv.nelements = cnt; + return (dst_s_write_private_key_file(key->key_name, key->key_alg, + key->key_id, &priv)); +} + + +/* + * dst_hmacmd5_from_file + * Converts contents of a private key file into a private HMAC-MD5 key. + * Parameters + * key Partially filled HMAC-MD5 KEY structure + * id The key id + * path The directory that the file will be read from + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +dst_hmacmd5_from_file(dst_key_t *key, const isc_uint16_t id, isc_mem_t *mctx) { + dst_private_t priv; + dst_result_t ret; + isc_buffer_t b; + HMAC_Key *hkey = NULL; +#define DST_RET(a) {ret = a; goto err;} + + /* read private key file */ + ret = dst_s_parse_private_key_file(key->key_name, key->key_alg, + id, &priv, mctx); + if (ret != ISC_R_SUCCESS) + return (ret); + + hkey = (HMAC_Key *) isc_mem_get(mctx, sizeof(HMAC_Key *)); + if (hkey == NULL) + DST_RET(ISC_R_NOMEMORY); + + key->opaque = hkey; + isc_buffer_init(&b, priv.elements[0].data, priv.elements[0].length, + ISC_BUFFERTYPE_BINARY); + ret = dst_hmacmd5_from_dns(key, &b, mctx); + if (ret != ISC_R_SUCCESS) + DST_RET(ret); + + return (ISC_R_SUCCESS); + + err: + dst_hmacmd5_destroy(hkey, mctx); + dst_s_free_private_structure_fields(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (ret); +} + +/* + * dst_hmacmd5_destroy + * Frees all dynamically allocated structures in key. + */ +static void +dst_hmacmd5_destroy(void *key, isc_mem_t *mctx) { + HMAC_Key *hkey = (HMAC_Key *) key; + memset(hkey, 0, sizeof(HMAC_Key)); + isc_mem_put(mctx, hkey, sizeof(HMAC_Key)); +} + + +/* + * dst_hmacmd5_generate + * Creates an HMAC-MD5 key. If the specified size is more than 512 + * bits, a key of size 512 is generated. + * Parameters + * key DST Key structure + * unused algorithm specific data, unused for HMAC-MD5. + * mctx memory context to allocate key + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +dst_hmacmd5_generate(dst_key_t *key, int unused, isc_mem_t *mctx) { + isc_buffer_t b; + dst_result_t ret; + int bytes; + unsigned char data[HMAC_LEN]; + + unused = unused; /* make the compiler happy */ + + bytes = (key->key_size + 7) / 8; + if (bytes > 64) { + bytes = 64; + key->key_size = 512; + } + + memset(data, 0, HMAC_LEN); + isc_buffer_init(&b, data, sizeof(data), ISC_BUFFERTYPE_BINARY); + ret = dst_random_get(bytes, &b); + if (ret != ISC_R_SUCCESS) + return (ret); + + ret = dst_hmacmd5_from_dns(key, &b, mctx); + memset(data, 0, HMAC_LEN); + + return (ret); +} + + +/************************************************************************** + * dst_hmacmd5_compare + * Compare two keys for equality. + * Return + * ISC_TRUE The keys are equal + * ISC_FALSE The keys are not equal + */ +static isc_boolean_t +dst_hmacmd5_compare(const dst_key_t *key1, const dst_key_t *key2) { + HMAC_Key *hkey1, *hkey2; + + hkey1 = (HMAC_Key *) key1->opaque; + hkey2 = (HMAC_Key *) key2->opaque; + + if (hkey1 == NULL && hkey2 == NULL) + return (ISC_TRUE); + else if (hkey1 == NULL || hkey2 == NULL) + return (ISC_FALSE); + + if (memcmp(hkey1->ipad, hkey2->ipad, HMAC_LEN) == 0) + return (ISC_TRUE); + else + return (ISC_FALSE); +} diff --git a/lib/dns/sec/dst/include/.cvsignore b/lib/dns/sec/dst/include/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/lib/dns/sec/dst/include/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/lib/dns/sec/dst/include/Makefile.in b/lib/dns/sec/dst/include/Makefile.in new file mode 100644 index 00000000..a0a07886 --- /dev/null +++ b/lib/dns/sec/dst/include/Makefile.in @@ -0,0 +1,23 @@ +# Copyright (C) 1998, 1999, 2000 Internet Software Consortium. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS +# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE +# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +# SOFTWARE. + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +SUBDIRS = dst +TARGETS = + +@BIND9_MAKE_RULES@ diff --git a/lib/dns/sec/dst/include/dst/.cvsignore b/lib/dns/sec/dst/include/dst/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/lib/dns/sec/dst/include/dst/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/lib/dns/sec/dst/include/dst/Makefile.in b/lib/dns/sec/dst/include/dst/Makefile.in new file mode 100644 index 00000000..89cb459f --- /dev/null +++ b/lib/dns/sec/dst/include/dst/Makefile.in @@ -0,0 +1,40 @@ +# Copyright (C) 1998, 1999, 2000 Internet Software Consortium. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS +# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE +# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +# SOFTWARE. + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_VERSION@ + +HEADERS = dst.h lib.h result.h + +SUBDIRS = +TARGETS = + +@BIND9_MAKE_RULES@ + +installdirs: + if [ ! -d ${includedir} ]; then \ + mkdir ${includedir} ; \ + fi + if [ ! -d ${includedir}/dst ]; then \ + mkdir ${includedir}/dst ; \ + fi + +install:: installdirs + for i in ${HEADERS}; do \ + ${INSTALL_DATA} ${srcdir}/$$i ${includedir}/dst ; \ + done diff --git a/lib/dns/sec/dst/include/dst/dst.h b/lib/dns/sec/dst/include/dst/dst.h new file mode 100644 index 00000000..bc013cb6 --- /dev/null +++ b/lib/dns/sec/dst/include/dst/dst.h @@ -0,0 +1,332 @@ +#ifndef DST_DST_H +#define DST_DST_H 1 + +#include <isc/boolean.h> +#include <isc/buffer.h> +#include <isc/int.h> +#include <isc/lang.h> +#include <isc/mem.h> +#include <isc/region.h> + +#include <dst/result.h> + +ISC_LANG_BEGINDECLS + +/*** + *** Types + ***/ + +/* + * The dst_key structure is opaque. Applications should use the accessor + * functions provided to retrieve key attributes. If an application needs + * to set attributes, new accessor functions will be written. + */ + +typedef struct dst_key dst_key_t; +typedef void * dst_context_t; + +/* DST algorithm codes */ +#define DST_ALG_UNKNOWN 0 +#define DST_ALG_RSA 1 +#define DST_ALG_DH 2 +#define DST_ALG_DSA 3 +#define DST_ALG_HMACMD5 157 +#define DST_ALG_HMACSHA1 158 /* not implemented */ +#define DST_ALG_PRIVATE 254 +#define DST_ALG_EXPAND 255 +#define DST_MAX_ALGS DST_ALG_HMACSHA1 + +/* DST algorithm codes */ +#define DST_DIGEST_MD5 258 +#define DST_DIGEST_SHA1 259 + +/* 'Mode' passed into dst_sign() and dst_verify() */ +#define DST_SIGMODE_INIT 1 /* initialize digest */ +#define DST_SIGMODE_UPDATE 2 /* add data to digest */ +#define DST_SIGMODE_FINAL 4 /* generate/verify signature */ +#define DST_SIGMODE_ALL (DST_SIGMODE_INIT | \ + DST_SIGMODE_UPDATE | \ + DST_SIGMODE_FINAL) + +/* A buffer of this size is large enough to hold any key */ +#define DST_KEY_MAXSIZE 1024 + +/* 'Type' for dst_read_key() */ +#define DST_TYPE_PRIVATE 0x2000000 +#define DST_TYPE_PUBLIC 0x4000000 + +/*** + *** Functions + ***/ + +/* + * Check that a given algorithm is supported + */ +isc_boolean_t +dst_supported_algorithm(const int alg); + +/* Sign a block of data. + * + * Requires: + * "mode" is some combination of DST_SIGMODE_INIT, DST_SIGMODE_UPDATE, + * and DST_SIGMODE_FINAL. + * "key" is a valid key. + * "context" contains a value appropriate for the value of "mode". + * "data" is a valid region. + * "sig" is a valid buffer. + * + * Ensures: + * All allocated memory will be freed after the FINAL call. "sig" + * will contain a signature if all operations completed successfully. + */ +dst_result_t +dst_sign(const unsigned int mode, dst_key_t *key, dst_context_t *context, + isc_region_t *data, isc_buffer_t *sig); + +/* Verify a signature on a block of data. + * + * Requires: + * "mode" is some combination of DST_SIGMODE_INIT, DST_SIGMODE_UPDATE, + * and DST_SIGMODE_FINAL. + * "key" is a valid key. + * "context" contains a value appropriate for the value of "mode". + * "data" is a valid region. + * "sig" is a valid region. + * + * Ensures: + * All allocated memory will be freed after the FINAL call. + */ +dst_result_t +dst_verify(const unsigned int mode, dst_key_t *key, dst_context_t *context, + isc_region_t *data, isc_region_t *sig); + +/* Digest a block of data. + * + * Requires: + * "mode" is some combination of DST_SIGMODE_INIT, DST_SIGMODE_UPDATE, + * and DST_SIGMODE_FINAL. + * "alg" is a valid digest algorithm + * "context" contains a value appropriate for the value of "mode". + * "data" is a valid region. + * "digest" is a valid buffer. + * + * Ensures: + * All allocated memory will be freed after the FINAL call. "digest" + * will contain a digest if all operations completed successfully. + */ +dst_result_t +dst_digest(const unsigned int mode, const unsigned int alg, + dst_context_t *context, isc_region_t *data, isc_buffer_t *digest); + +/* + * dst_computesecret + * A function to compute a shared secret from two (Diffie-Hellman) keys. + * + * Requires: + * "pub" is a valid key that can be used to derive a shared secret + * "priv" is a valid private key that can be used to derive a shared secret + * "secret" is a valid buffer + * + * Ensures: + * If successful, secret will contain the derived shared secret. + */ +dst_result_t +dst_computesecret(const dst_key_t *pub, const dst_key_t *priv, + isc_buffer_t *secret); + +/* Reads a key from permanent storage. + * + * Requires: + * "name" is not NULL. + * "id" is a valid key tag identifier. + * "alg" is a supported key algorithm. + * "type" is either DST_TYPE_PUBLIC or DST_TYPE_PRIVATE. + * "mctx" is a valid memory context. + * "keyp" is not NULL. + * + * Ensures: + * If successful, *keyp will contain a valid key. + */ +dst_result_t +dst_key_fromfile(const char *name, const isc_uint16_t id, const int alg, + const int type, isc_mem_t *mctx, dst_key_t **keyp); + +/* Writes a key to permanent storage. + * + * Requires: + * "key" is a valid key. + * "type" is either DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or both. + */ +dst_result_t +dst_key_tofile(const dst_key_t *key, const int type); + +/* Converts a DNS KEY record into a DST key. + * + * Requires: + * "name" is not NULL. + * "source" is a valid buffer. There must be at least 4 bytes available. + * "mctx" is a valid memory context. + * "keyp" is not NULL. + * + * Ensures: + * If successful, *keyp will contain a valid key, and the consumed + * pointer in data will be advanced. + */ +dst_result_t +dst_key_fromdns(const char *name, isc_buffer_t *source, isc_mem_t *mctx, + dst_key_t **keyp); + +/* Converts a DST key into a DNS KEY record. + * + * Requires: + * "key" is a valid key. + * "target" is a valid buffer. There must be at least 4 bytes unused. + * + * Ensures: + * If successful, the used pointer in 'target' is advanced by at least 4. + */ +dst_result_t +dst_key_todns(const dst_key_t *key, isc_buffer_t *target); + +/* Converts a buffer containing DNS KEY RDATA into a DST key. + * + * Requires: + * "name" is not NULL. + * "alg" is a supported key algorithm. + * "source" is a valid buffer. + * "mctx" is a valid memory context. + * "keyp" is not NULL. + * + * Ensures: + * If successful, *keyp will contain a valid key, and the consumed + * pointer in source will be advanced. + */ +dst_result_t +dst_key_frombuffer(const char *name, const int alg, const int flags, + const int protocol, isc_buffer_t *source, isc_mem_t *mctx, + dst_key_t **keyp); + +/* Converts a DST key into DNS KEY RDATA format. + * + * Requires: + * "key" is a valid key. + * "target" is a valid buffer. + * + * Ensures: + * If successful, the used pointer in 'target' is advanced. + */ +dst_result_t +dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target); + +/* Generate a DST key (or keypair) + * + * Requires: + * "name" is not NULL + * "alg" is a supported algorithm + * "bits" is a valid key size for the given algorithm + * "keyp" is not NULL. + * + * Ensures: + * If successful, *keyp will contain a valid key. + */ +dst_result_t +dst_key_generate(const char *name, const int alg, const int bits, + const int param, const int flags, const int protocol, + isc_mem_t *mctx, dst_key_t **keyp); + +/* Compares two DST keys. + * + * Requires: + * "key1" is a valid key. + * "key2" is a valid key. + */ +isc_boolean_t +dst_key_compare(const dst_key_t *key1, const dst_key_t *key2); + +/* Compares the parameters of two DST keys. + * + * Requires: + * "key1" is a valid key. + * "key2" is a valid key. + */ +isc_boolean_t +dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2); + +/* Free a DST key. + * + * Requires: + * "key" is a valid key. + * + * Ensures: + * All memory associated with "key" will be freed. + */ +void +dst_key_free(dst_key_t *key); + +/* Accessor functions to obtain key fields. + * + * Require: + * "key" is a valid key. + */ +char * +dst_key_name(const dst_key_t *key); + +int +dst_key_size(const dst_key_t *key); + +int +dst_key_proto(const dst_key_t *key); + +int +dst_key_alg(const dst_key_t *key); + +isc_uint32_t +dst_key_flags(const dst_key_t *key); + +isc_uint16_t +dst_key_id(const dst_key_t *key); + +isc_boolean_t +dst_key_isprivate(const dst_key_t *key); + +/* Computes the size of a signature generated by the given key. + * + * Requires: + * "key" is a valid key. + * "n" is not NULL + * + * Returns: + * ISC_R_SUCCESS + * DST_R_UNSUPPORTEDALG + */ +isc_result_t +dst_sig_size(const dst_key_t *key, unsigned int *n); + +/* Computes the size of a shared secret generated by the given key. + * + * Requires: + * "key" is a valid key. + * "n" is not NULL + * + * Returns: + * ISC_R_SUCCESS + * DST_R_UNSUPPORTEDALG + */ +isc_result_t +dst_secret_size(const dst_key_t *key, unsigned int *n); + +/* Generate random data. + * + * Requires: + * "data" is a valid buffer, with at least "wanted" bytes available. + * + * Ensures: + * <= wanted bytes will be written to "data", and the used pointer will + * be advanced. + */ +dst_result_t +dst_random_get(const unsigned int wanted, isc_buffer_t *data); + +ISC_LANG_ENDDECLS + +#endif /* DST_DST_H */ diff --git a/lib/dns/sec/dst/include/dst/lib.h b/lib/dns/sec/dst/include/dst/lib.h new file mode 100644 index 00000000..309c67fd --- /dev/null +++ b/lib/dns/sec/dst/include/dst/lib.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifndef DST_LIB_H +#define DST_LIB_H 1 + +#include <isc/types.h> +#include <isc/lang.h> + +ISC_LANG_BEGINDECLS + +extern isc_msgcat_t *dst_msgcat; + +void +dst_lib_initmsgcat(void); +/* + * Initialize the DST library's message catalog, dst_msgcat, if it + * has not already been initialized. + */ + +ISC_LANG_ENDDECLS + +#endif /* DST_LIB_H */ diff --git a/lib/dns/sec/dst/include/dst/result.h b/lib/dns/sec/dst/include/dst/result.h new file mode 100644 index 00000000..38a58aad --- /dev/null +++ b/lib/dns/sec/dst/include/dst/result.h @@ -0,0 +1,40 @@ +#ifndef DST_RESULT_H +#define DST_RESULT_H 1 + +#include <isc/lang.h> +#include <isc/result.h> +#include <isc/resultclass.h> + +ISC_LANG_BEGINDECLS + +typedef unsigned int dst_result_t; + +#define DST_R_UNSUPPORTEDALG (ISC_RESULTCLASS_DST + 0) +#define DST_R_UNSUPPORTEDTYPE (ISC_RESULTCLASS_DST + 1) +#define DST_R_UNSUPPORTEDMODE (ISC_RESULTCLASS_DST + 2) +#define DST_R_NULLKEY (ISC_RESULTCLASS_DST + 3) +#define DST_R_INVALIDPUBLICKEY (ISC_RESULTCLASS_DST + 4) +#define DST_R_INVALIDPRIVATEKEY (ISC_RESULTCLASS_DST + 5) +#define DST_R_NAMETOOLONG (ISC_RESULTCLASS_DST + 6) +#define DST_R_WRITEERROR (ISC_RESULTCLASS_DST + 7) +#define DST_R_INVALIDPARAM (ISC_RESULTCLASS_DST + 8) +#define DST_R_SIGNINITFAILURE (ISC_RESULTCLASS_DST + 9) +#define DST_R_SIGNUPDATEFAILURE (ISC_RESULTCLASS_DST + 10) +#define DST_R_SIGNFINALFAILURE (ISC_RESULTCLASS_DST + 11) +#define DST_R_VERIFYINITFAILURE (ISC_RESULTCLASS_DST + 12) +#define DST_R_VERIFYUPDATEFAILURE (ISC_RESULTCLASS_DST + 13) +#define DST_R_VERIFYFINALFAILURE (ISC_RESULTCLASS_DST + 14) +#define DST_R_NOTPUBLICKEY (ISC_RESULTCLASS_DST + 15) +#define DST_R_NOTPRIVATEKEY (ISC_RESULTCLASS_DST + 16) +#define DST_R_KEYCANNOTCOMPUTESECRET (ISC_RESULTCLASS_DST + 17) +#define DST_R_COMPUTESECRETFAILURE (ISC_RESULTCLASS_DST + 18) + +#define DST_R_NRESULTS 19 /* Number of results */ + + +char * dst_result_totext(dst_result_t); +void dst_result_register(void); + +ISC_LANG_ENDDECLS + +#endif /* DST_RESULT_H */ diff --git a/lib/dns/sec/dst/openssl_link.c b/lib/dns/sec/dst/openssl_link.c new file mode 100644 index 00000000..b718aec1 --- /dev/null +++ b/lib/dns/sec/dst/openssl_link.c @@ -0,0 +1,628 @@ +#if defined(OPENSSL) + +/* + * Portions Copyright (c) 1995-1998 by Network Associates, Inc. + * + * Permission to use, copy modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. + */ + +/* + * Principal Author: Brian Wellington + * $Id: openssl_link.c,v 1.12 1999/10/29 12:56:57 marka Exp $ + */ + +#include <config.h> + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <memory.h> + +#include <isc/assertions.h> +#include <isc/buffer.h> +#include <isc/int.h> +#include <isc/region.h> + +#include "dst_internal.h" +#include "dst_parse.h" + +#include <openssl/crypto.h> +#include <openssl/bn.h> +#include <openssl/dsa.h> +#include <openssl/sha.h> + +static struct dst_func openssl_functions; + +static dst_result_t dst_openssl_sign(const unsigned int mode, + dst_key_t *key, + void **context, isc_region_t *data, + isc_buffer_t *sig, isc_mem_t *mctx); +static dst_result_t dst_openssl_verify(const unsigned int mode, + dst_key_t *key, + void **context, isc_region_t *data, + isc_region_t *sig, isc_mem_t *mctx); +static isc_boolean_t dst_openssl_compare(const dst_key_t *key1, + const dst_key_t *key2); +static dst_result_t dst_openssl_generate(dst_key_t *key, int unused, + isc_mem_t *mctx); +static isc_boolean_t dst_openssl_isprivate(const dst_key_t *key); +static void dst_openssl_destroy(void *key, isc_mem_t *mctx); +static dst_result_t dst_openssl_to_dns(const dst_key_t *in_key, + isc_buffer_t *data); +static dst_result_t dst_openssl_from_dns(dst_key_t *key, isc_buffer_t *data, + isc_mem_t *mctx); +static dst_result_t dst_openssl_to_file(const dst_key_t *key); +static dst_result_t dst_openssl_from_file(dst_key_t *key, + const isc_uint16_t id, + isc_mem_t *mctx); + +static int BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, + int size); + + +/* + * dst_s_openssldsa_init() + * Sets up function pointers for OpenSSL related functions + */ +void +dst_s_openssldsa_init() { + REQUIRE(dst_t_func[DST_ALG_DSA] == NULL); + dst_t_func[DST_ALG_DSA] = &openssl_functions; + memset(&openssl_functions, 0, sizeof(struct dst_func)); + openssl_functions.sign = dst_openssl_sign; + openssl_functions.verify = dst_openssl_verify; + openssl_functions.computesecret = NULL; + openssl_functions.compare = dst_openssl_compare; + openssl_functions.paramcompare = NULL; /* is this useful for DSA? */ + openssl_functions.generate = dst_openssl_generate; + openssl_functions.isprivate = dst_openssl_isprivate; + openssl_functions.destroy = dst_openssl_destroy; + openssl_functions.to_dns = dst_openssl_to_dns; + openssl_functions.from_dns = dst_openssl_from_dns; + openssl_functions.to_file = dst_openssl_to_file; + openssl_functions.from_file = dst_openssl_from_file; + CRYPTO_set_mem_functions(dst_mem_alloc, dst_mem_realloc, dst_mem_free); +} + +/* + * dst_openssl_sign + * Call OpenSSL signing functions to sign a block of data. + * There are three steps to signing, INIT (initialize structures), + * UPDATE (hash (more) data), FINAL (generate a signature). This + * routine performs one or more of these steps. + * Parameters + * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL} + * key key to use for signing + * context the context to use for this computation + * data data to be signed + * signature buffer to store signature + * mctx memory context for temporary allocations + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_openssl_sign(const unsigned int mode, dst_key_t *key, void **context, + isc_region_t *data, isc_buffer_t *sig, isc_mem_t *mctx) +{ + isc_region_t r; + SHA_CTX *ctx = NULL; + + if (mode & DST_SIGMODE_INIT) { + ctx = (SHA_CTX *) isc_mem_get(mctx, sizeof(SHA_CTX)); + if (ctx == NULL) + return (ISC_R_NOMEMORY); + } + else if (context != NULL) + ctx = (SHA_CTX *) *context; + REQUIRE (ctx != NULL); + + if (mode & DST_SIGMODE_INIT) + SHA1_Init(ctx); + + if ((mode & DST_SIGMODE_UPDATE)) + SHA1_Update(ctx, data->base, data->length); + + if (mode & DST_SIGMODE_FINAL) { + DSA *dsa; + DSA_SIG *dsasig; + unsigned char digest[SHA_DIGEST_LENGTH]; + + isc_buffer_available(sig, &r); + if (r.length < SHA_DIGEST_LENGTH * 2 + 1) + return (ISC_R_NOSPACE); + + dsa = key->opaque; + + SHA1_Final(digest, ctx); + isc_mem_put(mctx, ctx, sizeof(SHA_CTX)); + + dsasig = DSA_do_sign(digest, SHA_DIGEST_LENGTH, dsa); + if (dsasig == NULL) + return (DST_R_SIGNFINALFAILURE); + + *r.base++ = (key->key_size - 512)/64; + BN_bn2bin_fixed(dsasig->r, r.base, SHA_DIGEST_LENGTH); + r.base += SHA_DIGEST_LENGTH; + BN_bn2bin_fixed(dsasig->s, r.base, SHA_DIGEST_LENGTH); + r.base += SHA_DIGEST_LENGTH; + DSA_SIG_free(dsasig); + isc_buffer_add(sig, SHA_DIGEST_LENGTH * 2 + 1); + } + else + *context = ctx; + + return (ISC_R_SUCCESS); +} + + +/* + * dst_openssl_verify + * Calls OpenSSL verification routines. There are three steps to + * verification, INIT (initialize structures), UPDATE (hash (more) data), + * FINAL (generate a signature). This routine performs one or more of + * these steps. + * Parameters + * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL} + * key key to use for verifying + * context the context to use for this computation + * data signed data + * signature signature + * mctx memory context for temporary allocations + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_openssl_verify(const unsigned int mode, dst_key_t *key, void **context, + isc_region_t *data, isc_region_t *sig, isc_mem_t *mctx) +{ + int status = 0; + SHA_CTX *ctx = NULL; + + if (mode & DST_SIGMODE_INIT) { + ctx = (SHA_CTX *) isc_mem_get(mctx, sizeof(SHA_CTX)); + if (ctx == NULL) + return (ISC_R_NOMEMORY); + } + else if (context != NULL) + ctx = (SHA_CTX *) *context; + REQUIRE (ctx != NULL); + + if (mode & DST_SIGMODE_INIT) + SHA1_Init(ctx); + + if ((mode & DST_SIGMODE_UPDATE)) + SHA1_Update(ctx, data->base, data->length); + + if (mode & DST_SIGMODE_FINAL) { + DSA *dsa; + DSA_SIG *dsasig; + unsigned char digest[SHA_DIGEST_LENGTH]; + unsigned char *cp = sig->base; + + dsa = key->opaque; + + SHA1_Final(digest, ctx); + isc_mem_put(mctx, ctx, sizeof(SHA_CTX)); + + if (sig->length < 2 * SHA_DIGEST_LENGTH + 1) + return (DST_R_VERIFYFINALFAILURE); + + cp++; /* Skip T */ + dsasig = DSA_SIG_new(); + dsasig->r = BN_bin2bn(cp, SHA_DIGEST_LENGTH, NULL); + cp += SHA_DIGEST_LENGTH; + dsasig->s = BN_bin2bn(cp, SHA_DIGEST_LENGTH, NULL); + cp += SHA_DIGEST_LENGTH; + + status = DSA_do_verify(digest, SHA_DIGEST_LENGTH, dsasig, dsa); + DSA_SIG_free(dsasig); + if (status == 0) + return (DST_R_VERIFYFINALFAILURE); + } + else + *context = ctx; + + return (ISC_R_SUCCESS); +} + + +/* + * dst_openssl_isprivate + * Is this a private key? + * Parameters + * key DST KEY structure + * Returns + * ISC_TRUE + * ISC_FALSE + */ +static isc_boolean_t +dst_openssl_isprivate(const dst_key_t *key) { + DSA *dsa = (DSA *) key->opaque; + return (ISC_TF(dsa != NULL && dsa->priv_key != NULL)); +} + + +/* + * dst_openssl_to_dns + * Converts key from DSA to DNS distribution format + * Parameters + * key DST KEY structure + * data output data + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +dst_openssl_to_dns(const dst_key_t *key, isc_buffer_t *data) { + DSA *dsa; + isc_region_t r; + int dnslen; + unsigned int t; + + REQUIRE(key->opaque != NULL); + + dsa = (DSA *) key->opaque; + + isc_buffer_available(data, &r); + + t = (BN_num_bytes(dsa->p) - 64) / 8; + if (t > 8) + return (DST_R_INVALIDPUBLICKEY); + + dnslen = 1 + (key->key_size * 3)/8 + SHA_DIGEST_LENGTH; + if (r.length < (unsigned int) dnslen) + return (ISC_R_NOSPACE); + + *r.base++ = t; + BN_bn2bin_fixed(dsa->q, r.base, SHA_DIGEST_LENGTH); + r.base += SHA_DIGEST_LENGTH; + BN_bn2bin_fixed(dsa->p, r.base, key->key_size/8); + r.base += key->key_size/8; + BN_bn2bin_fixed(dsa->g, r.base, key->key_size/8); + r.base += key->key_size/8; + BN_bn2bin_fixed(dsa->pub_key, r.base, key->key_size/8); + r.base += key->key_size/8; + + isc_buffer_add(data, dnslen); + + return (ISC_R_SUCCESS); +} + + +/* + * dst_openssl_from_dns + * Converts from a DNS KEY RR format to a DSA KEY. + * Parameters + * key Partially filled key structure + * data Buffer containing key in DNS format + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_openssl_from_dns(dst_key_t *key, isc_buffer_t *data, isc_mem_t *mctx) { + DSA *dsa; + isc_region_t r; + unsigned int t, p_bytes; + + mctx = mctx; /* make the compiler happy */ + + isc_buffer_remaining(data, &r); + if (r.length == 0) + return (ISC_R_SUCCESS); + + dsa = DSA_new(); +/* dsa = (DSA *) isc_mem_get(mctx, sizeof(DSA));*/ + if (dsa == NULL) + return (ISC_R_NOMEMORY); + + memset(dsa, 0, sizeof(DSA)); + + t = (unsigned int) *r.base++; + if (t > 8) { + DSA_free(dsa); + return (DST_R_INVALIDPUBLICKEY); + } + p_bytes = 64 + 8 * t; + + if (r.length < 1 + SHA_DIGEST_LENGTH + 3 * p_bytes) { + DSA_free(dsa); + return (DST_R_INVALIDPUBLICKEY); + } + + dsa->q = BN_bin2bn(r.base, SHA_DIGEST_LENGTH, NULL); + r.base += SHA_DIGEST_LENGTH; + + dsa->p = BN_bin2bn(r.base, p_bytes, NULL); + r.base += SHA_DIGEST_LENGTH; + + dsa->g = BN_bin2bn(r.base, p_bytes, NULL); + r.base += SHA_DIGEST_LENGTH; + + dsa->pub_key = BN_bin2bn(r.base, p_bytes, NULL); + r.base += SHA_DIGEST_LENGTH; + + isc_buffer_remaining(data, &r); + key->key_id = dst_s_id_calc(r.base, + 1 + SHA_DIGEST_LENGTH + 3 * p_bytes); + key->key_size = p_bytes * 8; + + isc_buffer_forward(data, SHA_DIGEST_LENGTH + 3 * p_bytes); + + key->opaque = (void *) dsa; + + return (ISC_R_SUCCESS); +} + + +/* + * dst_openssl_to_file + * Encodes a DSA Key into the portable file format. + * Parameters + * key DST KEY structure + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_openssl_to_file(const dst_key_t *key) { + int cnt = 0; + DSA *dsa; + dst_private_t priv; + unsigned char bufs[5][128]; + + if (key->opaque == NULL) + return (DST_R_NULLKEY); + + dsa = (DSA *) key->opaque; + + priv.elements[cnt].tag = TAG_DSA_PRIME; + priv.elements[cnt].length = BN_num_bytes(dsa->p); + BN_bn2bin(dsa->p, bufs[cnt]); + priv.elements[cnt].data = bufs[cnt]; + cnt++; + + priv.elements[cnt].tag = TAG_DSA_SUBPRIME; + priv.elements[cnt].length = BN_num_bytes(dsa->q); + BN_bn2bin(dsa->q, bufs[cnt]); + priv.elements[cnt].data = bufs[cnt]; + cnt++; + + priv.elements[cnt].tag = TAG_DSA_BASE; + priv.elements[cnt].length = BN_num_bytes(dsa->g); + BN_bn2bin(dsa->g, bufs[cnt]); + priv.elements[cnt].data = bufs[cnt]; + cnt++; + + priv.elements[cnt].tag = TAG_DSA_PRIVATE; + priv.elements[cnt].length = BN_num_bytes(dsa->priv_key); + BN_bn2bin(dsa->priv_key, bufs[cnt]); + priv.elements[cnt].data = bufs[cnt]; + cnt++; + + priv.elements[cnt].tag = TAG_DSA_PUBLIC; + priv.elements[cnt].length = BN_num_bytes(dsa->pub_key); + BN_bn2bin(dsa->pub_key, bufs[cnt]); + priv.elements[cnt].data = bufs[cnt]; + cnt++; + + priv.nelements = cnt; + return (dst_s_write_private_key_file(key->key_name, key->key_alg, + key->key_id, &priv)); +} + + +/* + * dst_openssl_from_file + * Converts contents of a private key file into a private DSA key. + * Parameters + * key Partially filled DSA KEY structure + * id The key id + * path The directory that the file will be read from + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +dst_openssl_from_file(dst_key_t *key, const isc_uint16_t id, isc_mem_t *mctx) { + dst_private_t priv; + dst_result_t ret; + isc_buffer_t dns; + isc_region_t r; + unsigned char dns_array[1024]; + int i; + DSA *dsa = NULL; +#define DST_RET(a) {ret = a; goto err;} + + /* read private key file */ + ret = dst_s_parse_private_key_file(key->key_name, key->key_alg, + id, &priv, mctx); + if (ret != ISC_R_SUCCESS) + return (ret); + + dsa = DSA_new(); + if (dsa == NULL) + DST_RET(ISC_R_NOMEMORY); + memset(dsa, 0, sizeof(DSA)); + key->opaque = dsa; + + for (i=0; i < priv.nelements; i++) { + BIGNUM *bn; + bn = BN_bin2bn(priv.elements[i].data, + priv.elements[i].length, NULL); + if (bn == NULL) + DST_RET(ISC_R_NOMEMORY); + + switch (priv.elements[i].tag) { + case TAG_DSA_PRIME: + dsa->p = bn; + break; + case TAG_DSA_SUBPRIME: + dsa->q = bn; + break; + case TAG_DSA_BASE: + dsa->g = bn; + break; + case TAG_DSA_PRIVATE: + dsa->priv_key = bn; + break; + case TAG_DSA_PUBLIC: + dsa->pub_key = bn; + break; + } + } + dst_s_free_private_structure_fields(&priv, mctx); + + key->key_size = BN_num_bits(dsa->p); + isc_buffer_init(&dns, dns_array, sizeof(dns_array), + ISC_BUFFERTYPE_BINARY); + ret = dst_openssl_to_dns(key, &dns); + if (ret != ISC_R_SUCCESS) + DST_RET(ret); + isc_buffer_used(&dns, &r); + key->key_id = dst_s_id_calc(r.base, r.length); + + if (key->key_id != id) + DST_RET(DST_R_INVALIDPRIVATEKEY); + + return (ISC_R_SUCCESS); + + err: + key->opaque = NULL; + dst_openssl_destroy(dsa, mctx); + dst_s_free_private_structure_fields(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (ret); +} + +/* + * dst_openssl_destroy + * Frees all dynamically allocated structures in key. + */ +static void +dst_openssl_destroy(void *key, isc_mem_t *mctx) { + DSA *dsa = (DSA *) key; + if (dsa == NULL) + return; + + mctx = mctx; /* make the compiler happy */ + + DSA_free(dsa); +} + + +/* + * dst_openssl_generate + * Generates unique keys that are hard to predict. + * Parameters + * key DST Key structure + * unused algorithm specific data, unused for DSA. + * mctx memory context to allocate key + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +dst_openssl_generate(dst_key_t *key, int unused, isc_mem_t *mctx) { + DSA *dsa; + unsigned char dns_array[1024]; + unsigned char rand_array[SHA_DIGEST_LENGTH]; + isc_buffer_t dns, rand; + dst_result_t ret; + isc_region_t r; + + unused = unused; /* make the compiler happy */ + mctx = mctx; /* make the compiler happy */ + + isc_buffer_init(&rand, rand_array, sizeof(rand_array), + ISC_BUFFERTYPE_BINARY); + ret = dst_random_get(SHA_DIGEST_LENGTH, &rand); + if (ret != ISC_R_SUCCESS) + return (ret); + + dsa = DSA_generate_parameters(key->key_size, rand_array, + SHA_DIGEST_LENGTH, NULL, NULL, + NULL, NULL); + + if (dsa == NULL) + return (ISC_R_NOMEMORY); + + if (DSA_generate_key(dsa) == 0) + return (ISC_R_NOMEMORY); + + key->opaque = dsa; + + isc_buffer_init(&dns, dns_array, sizeof(dns_array), + ISC_BUFFERTYPE_BINARY); + dst_openssl_to_dns(key, &dns); + isc_buffer_used(&dns, &r); + key->key_id = dst_s_id_calc(r.base, r.length); + + return (ISC_R_SUCCESS); +} + + +/************************************************************************** + * dst_openssl_compare + * Compare two keys for equality. + * Return + * ISC_TRUE The keys are equal + * ISC_FALSE The keys are not equal + */ +static isc_boolean_t +dst_openssl_compare(const dst_key_t *key1, const dst_key_t *key2) { + int status; + DSA *dsa1, *dsa2; + + dsa1 = (DSA *) key1->opaque; + dsa2 = (DSA *) key2->opaque; + + if (dsa1 == NULL && dsa2 == NULL) + return (ISC_TRUE); + else if (dsa1 == NULL || dsa2 == NULL) + return (ISC_FALSE); + + status = BN_cmp(dsa1->p, dsa2->p) || + BN_cmp(dsa1->q, dsa2->q) || + BN_cmp(dsa1->g, dsa2->g) || + BN_cmp(dsa1->pub_key, dsa2->pub_key); + + if (status != 0) + return (ISC_FALSE); + + if (dsa1->priv_key != NULL || dsa2->priv_key != NULL) { + if (dsa1->priv_key == NULL || dsa2->priv_key == NULL) + return (ISC_FALSE); + if (BN_cmp(dsa1->priv_key, dsa2->priv_key)) + return (ISC_FALSE); + } + return (ISC_TRUE); +} + +static int +BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) { + int bytes = size - BN_num_bytes(bn); + while (bytes-- > 0) + *buf++ = 0; + BN_bn2bin(bn, buf); + return (size); +} + +#endif diff --git a/lib/dns/sec/dst/openssldh_link.c b/lib/dns/sec/dst/openssldh_link.c new file mode 100644 index 00000000..37bebfcd --- /dev/null +++ b/lib/dns/sec/dst/openssldh_link.c @@ -0,0 +1,694 @@ +#if defined(OPENSSL) + +/* + * Portions Copyright (c) 1995-1998 by Network Associates, Inc. + * + * Permission to use, copy modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. + */ + +/* + * Principal Author: Brian Wellington + * $Id: openssldh_link.c,v 1.6 1999/10/29 12:56:57 marka Exp $ + */ + +#include <config.h> + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <memory.h> +#include <ctype.h> + +#include <isc/assertions.h> +#include <isc/buffer.h> +#include <isc/error.h> +#include <isc/int.h> +#include <isc/region.h> + +#include "dst_internal.h" +#include "dst_parse.h" + +#include <openssl/crypto.h> +#include <openssl/bn.h> +#include <openssl/dh.h> + +#define PRIME768 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF" + +#define PRIME1024 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF" + +static struct dst_func openssldh_functions; + +static dst_result_t dst_openssldh_computesecret(const dst_key_t *pub, + const dst_key_t *priv, + isc_buffer_t *secret); +static isc_boolean_t dst_openssldh_compare(const dst_key_t *key1, + const dst_key_t *key2); +static isc_boolean_t dst_openssldh_paramcompare(const dst_key_t *key1, + const dst_key_t *key2); +static dst_result_t dst_openssldh_generate(dst_key_t *key, int generator, + isc_mem_t *mctx); +static isc_boolean_t dst_openssldh_isprivate(const dst_key_t *key); +static void dst_openssldh_destroy(void *key, isc_mem_t *mctx); +static dst_result_t dst_openssldh_to_dns(const dst_key_t *in_key, + isc_buffer_t *data); +static dst_result_t dst_openssldh_from_dns(dst_key_t *key, + isc_buffer_t *data, + isc_mem_t *mctx); +static dst_result_t dst_openssldh_to_file(const dst_key_t *key); +static dst_result_t dst_openssldh_from_file(dst_key_t *key, + const isc_uint16_t id, + isc_mem_t *mctx); + +static void uint16_toregion(isc_uint16_t val, isc_region_t *region); +static isc_uint16_t uint16_fromregion(isc_region_t *region); +static void BN_fromhex(BIGNUM *b, const char *str); + +static BIGNUM bn2, bn768, bn1024; + +/* + * dst_s_openssldh_init() + * Sets up function pointers for OpenSSL related functions + */ +void +dst_s_openssldh_init() +{ + REQUIRE(dst_t_func[DST_ALG_DH] == NULL); + dst_t_func[DST_ALG_DH] = &openssldh_functions; + memset(&openssldh_functions, 0, sizeof(struct dst_func)); + openssldh_functions.sign = NULL; + openssldh_functions.verify = NULL; + openssldh_functions.computesecret = dst_openssldh_computesecret; + openssldh_functions.compare = dst_openssldh_compare; + openssldh_functions.paramcompare = dst_openssldh_paramcompare; + openssldh_functions.generate = dst_openssldh_generate; + openssldh_functions.isprivate = dst_openssldh_isprivate; + openssldh_functions.destroy = dst_openssldh_destroy; + openssldh_functions.to_dns = dst_openssldh_to_dns; + openssldh_functions.from_dns = dst_openssldh_from_dns; + openssldh_functions.to_file = dst_openssldh_to_file; + openssldh_functions.from_file = dst_openssldh_from_file; + CRYPTO_set_mem_functions(dst_mem_alloc, dst_mem_realloc, dst_mem_free); + + BN_init(&bn2); + BN_init(&bn768); + BN_init(&bn1024); + BN_set_word(&bn2, 2); + BN_fromhex(&bn768, PRIME768); + BN_fromhex(&bn1024, PRIME1024); +} + +/* + * dst_openssldh_computesecret + * Compute a shared secret from this public and private key + * Parameters + * pub The public key + * priv The private key + * secret A buffer into which the secret is written + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv, + isc_buffer_t *secret) +{ + DH *dhpub, *dhpriv; + int ret; + isc_region_t r; + unsigned int len; + + REQUIRE(pub->opaque != NULL); + REQUIRE(priv->opaque != NULL); + + dhpub = (DH *) pub->opaque; + dhpriv = (DH *) priv->opaque; + + len = DH_size(dhpriv); + isc_buffer_available(secret, &r); + if (r.length < len) + return (ISC_R_NOSPACE); + ret = DH_compute_key(r.base, dhpub->pub_key, dhpriv); + if (ret == 0) + return (DST_R_COMPUTESECRETFAILURE); + isc_buffer_add(secret, len); + return (ISC_R_SUCCESS); +} + +/* + * dst_openssldh_isprivate + * Is this a private key? + * Parameters + * key DST KEY structure + * Returns + * ISC_TRUE + * ISC_FALSE + */ +static isc_boolean_t +dst_openssldh_isprivate(const dst_key_t *key) { + DH *dh = (DH *) key->opaque; + return (ISC_TF(dh != NULL && dh->priv_key != NULL)); +} + + +/* + * dst_openssldh_to_dns + * Converts key from DH to DNS distribution format + * Parameters + * key DST KEY structure + * data output data + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +dst_openssldh_to_dns(const dst_key_t *key, isc_buffer_t *data) { + DH *dh; + isc_region_t r; + isc_uint16_t dnslen, plen, glen, publen; + + REQUIRE(key->opaque != NULL); + + dh = (DH *) key->opaque; + + isc_buffer_available(data, &r); + + if (dh->g == &bn2 && (dh->p == &bn768 || dh->p == &bn1024)) { + plen = 1; + glen = 0; + } + else { + plen = BN_num_bytes(dh->p); + glen = BN_num_bytes(dh->g); + } + publen = BN_num_bytes(dh->pub_key); + dnslen = plen + glen + publen + 6; + if (r.length < (unsigned int) dnslen) + return (ISC_R_NOSPACE); + + uint16_toregion(plen, &r); + if (plen == 1) { + if (dh->p == &bn768) + *r.base = 1; + else + *r.base = 2; + } + else + BN_bn2bin(dh->p, r.base); + r.base += plen; + + uint16_toregion(glen, &r); + if (glen > 0) + BN_bn2bin(dh->g, r.base); + r.base += glen; + + uint16_toregion(publen, &r); + BN_bn2bin(dh->pub_key, r.base); + r.base += publen; + + isc_buffer_add(data, dnslen); + + return (ISC_R_SUCCESS); +} + + +/* + * dst_openssldh_from_dns + * Converts from a DNS KEY RR format to a DH KEY. + * Parameters + * key Partially filled key structure + * data Buffer containing key in DNS format + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_openssldh_from_dns(dst_key_t *key, isc_buffer_t *data, isc_mem_t *mctx) { + DH *dh; + isc_region_t r; + isc_uint16_t plen, glen, publen; + int special = 0; + + mctx = mctx; /* make the compiler happy */ + + isc_buffer_remaining(data, &r); + if (r.length == 0) + return (ISC_R_SUCCESS); + + dh = DH_new(); + if (dh == NULL) + return (ISC_R_NOMEMORY); + + memset(dh, 0, sizeof(DH)); + + /* + * Read the prime length. 1 & 2 are table entries, > 16 means a + * prime follows, otherwise an error. + */ + if (r.length < 2) { + DH_free(dh); + return (DST_R_INVALIDPUBLICKEY); + } + plen = uint16_fromregion(&r); + if (plen < 16 && plen != 1 && plen != 2) { + DH_free(dh); + return (DST_R_INVALIDPUBLICKEY); + } + if (r.length < plen) { + DH_free(dh); + return (DST_R_INVALIDPUBLICKEY); + } + if (plen == 1 || plen == 2) { + if (plen == 1) + special = *r.base++; + else + special = uint16_fromregion(&r); + switch (special) { + case 1: + dh->p = &bn768; + break; + case 2: + dh->p = &bn1024; + break; + default: + DH_free(dh); + return (DST_R_INVALIDPUBLICKEY); + } + } + else { + dh->p = BN_bin2bn(r.base, plen, NULL); + r.base += plen; + } + + /* + * Read the generator length. This should be 0 if the prime was + * special, but it might not be. If it's 0 and the prime is not + * special, we have a problem. + */ + if (r.length < 2) { + DH_free(dh); + return (DST_R_INVALIDPUBLICKEY); + } + glen = uint16_fromregion(&r); + if (r.length < glen) { + DH_free(dh); + return (DST_R_INVALIDPUBLICKEY); + } + if (special != 0) { + if (glen == 0) + dh->g = &bn2; + else { + dh->g = BN_bin2bn(r.base, glen, NULL); + if (BN_cmp(dh->g, &bn2) == 0) { + BN_free(dh->g); + dh->g = &bn2; + } + else { + DH_free(dh); + return (DST_R_INVALIDPUBLICKEY); + } + } + } + else { + if (glen == 0) { + DH_free(dh); + return (DST_R_INVALIDPUBLICKEY); + } + dh->g = BN_bin2bn(r.base, glen, NULL); + } + r.base += glen; + + if (r.length < 2) { + DH_free(dh); + return (DST_R_INVALIDPUBLICKEY); + } + publen = uint16_fromregion(&r); + if (r.length < publen) { + DH_free(dh); + return (DST_R_INVALIDPUBLICKEY); + } + dh->pub_key = BN_bin2bn(r.base, publen, NULL); + r.base += publen; + + isc_buffer_remaining(data, &r); + key->key_id = dst_s_id_calc(r.base, plen + glen + publen + 6); + key->key_size = BN_num_bits(dh->p); + + isc_buffer_forward(data, plen + glen + publen + 6); + + key->opaque = (void *) dh; + + return (ISC_R_SUCCESS); +} + + +/* + * dst_openssldh_to_file + * Encodes a DH Key into the portable file format. + * Parameters + * key DST KEY structure + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +static dst_result_t +dst_openssldh_to_file(const dst_key_t *key) { + int cnt = 0; + DH *dh; + dst_private_t priv; + unsigned char bufs[4][128]; + + if (key->opaque == NULL) + return (DST_R_NULLKEY); + + dh = (DH *) key->opaque; + + priv.elements[cnt].tag = TAG_DH_PRIME; + priv.elements[cnt].length = BN_num_bytes(dh->p); + BN_bn2bin(dh->p, bufs[cnt]); + priv.elements[cnt].data = bufs[cnt]; + cnt++; + + priv.elements[cnt].tag = TAG_DH_GENERATOR; + priv.elements[cnt].length = BN_num_bytes(dh->g); + BN_bn2bin(dh->g, bufs[cnt]); + priv.elements[cnt].data = bufs[cnt]; + cnt++; + + priv.elements[cnt].tag = TAG_DH_PRIVATE; + priv.elements[cnt].length = BN_num_bytes(dh->priv_key); + BN_bn2bin(dh->priv_key, bufs[cnt]); + priv.elements[cnt].data = bufs[cnt]; + cnt++; + + priv.elements[cnt].tag = TAG_DH_PUBLIC; + priv.elements[cnt].length = BN_num_bytes(dh->pub_key); + BN_bn2bin(dh->pub_key, bufs[cnt]); + priv.elements[cnt].data = bufs[cnt]; + cnt++; + + priv.nelements = cnt; + return (dst_s_write_private_key_file(key->key_name, key->key_alg, + key->key_id, &priv)); +} + + +/* + * dst_openssldh_from_file + * Converts contents of a private key file into a private DH key. + * Parameters + * key Partially filled DH KEY structure + * id The key id + * path The directory that the file will be read from + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +dst_openssldh_from_file(dst_key_t *key, const isc_uint16_t id, isc_mem_t *mctx) { + dst_private_t priv; + dst_result_t ret; + isc_buffer_t dns; + isc_region_t r; + unsigned char dns_array[1024]; + int i; + DH *dh = NULL; +#define DST_RET(a) {ret = a; goto err;} + + /* read private key file */ + ret = dst_s_parse_private_key_file(key->key_name, key->key_alg, + id, &priv, mctx); + if (ret != ISC_R_SUCCESS) + return (ret); + + dh = DH_new(); + if (dh == NULL) + DST_RET(ISC_R_NOMEMORY); + memset(dh, 0, sizeof(DH)); + key->opaque = dh; + + for (i=0; i < priv.nelements; i++) { + BIGNUM *bn; + bn = BN_bin2bn(priv.elements[i].data, + priv.elements[i].length, NULL); + if (bn == NULL) + DST_RET(ISC_R_NOMEMORY); + + switch (priv.elements[i].tag) { + case TAG_DH_PRIME: + dh->p = bn; + break; + case TAG_DH_GENERATOR: + dh->g = bn; + break; + case TAG_DH_PRIVATE: + dh->priv_key = bn; + break; + case TAG_DH_PUBLIC: + dh->pub_key = bn; + break; + } + } + dst_s_free_private_structure_fields(&priv, mctx); + + key->key_size = BN_num_bits(dh->p); + + if ((key->key_size == 768 || key->key_size == 1024) && + BN_cmp(dh->g, &bn2) == 0) + { + if (key->key_size == 768 && BN_cmp(dh->p, &bn768) == 0) { + BN_free(dh->p); + BN_free(dh->g); + dh->p = &bn768; + dh->g = &bn2; + } + else if (key->key_size == 1024 && BN_cmp(dh->p, &bn1024) == 0) { + BN_free(dh->p); + BN_free(dh->g); + dh->p = &bn1024; + dh->g = &bn2; + } + } + isc_buffer_init(&dns, dns_array, sizeof(dns_array), + ISC_BUFFERTYPE_BINARY); + ret = dst_openssldh_to_dns(key, &dns); + if (ret != ISC_R_SUCCESS) + DST_RET(ret); + isc_buffer_used(&dns, &r); + key->key_id = dst_s_id_calc(r.base, r.length); + + if (key->key_id != id) + DST_RET(DST_R_INVALIDPRIVATEKEY); + + return (ISC_R_SUCCESS); + + err: + key->opaque = NULL; + dst_openssldh_destroy(dh, mctx); + dst_s_free_private_structure_fields(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (ret); +} + +/* + * dst_openssldh_destroy + * Frees all dynamically allocated structures in key. + */ +static void +dst_openssldh_destroy(void *key, isc_mem_t *mctx) { + DH *dh = (DH *) key; + if (dh == NULL) + return; + + mctx = mctx; /* make the compiler happy */ + + if (dh->p == &bn768 || dh->p == &bn1024) + dh->p = NULL; + if (dh->g == &bn2) + dh->g = NULL; + DH_free(dh); +} + + +/* + * dst_openssldh_generate + * Generates unique keys that are hard to predict. + * Parameters + * key DST Key structure + * generator generator + * mctx memory context to allocate key + * Return + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ + +static dst_result_t +dst_openssldh_generate(dst_key_t *key, int generator, isc_mem_t *mctx) { + DH *dh = NULL; + unsigned char dns_array[1024]; + isc_buffer_t dns; + isc_region_t r; + + mctx = mctx; /* make the compiler happy */ + + if (generator == 0) { + if (key->key_size == 768 || key->key_size == 1024) { + dh = DH_new(); + if (dh == NULL) + return (ISC_R_NOMEMORY); + if (key->key_size == 768) + dh->p = &bn768; + else + dh->p = &bn1024; + dh->g = &bn2; + } + else + generator = 2; + } + + if (generator != 0) + dh = DH_generate_parameters(key->key_size, generator, + NULL, NULL); + + if (dh == NULL) + return (DST_R_INVALIDPARAM); + + if (DH_generate_key(dh) == 0) { + DH_free(dh); + return (ISC_R_NOMEMORY); + } + + key->opaque = dh; + + isc_buffer_init(&dns, dns_array, sizeof(dns_array), + ISC_BUFFERTYPE_BINARY); + dst_openssldh_to_dns(key, &dns); + isc_buffer_used(&dns, &r); + key->key_id = dst_s_id_calc(r.base, r.length); + + return (ISC_R_SUCCESS); +} + + +/************************************************************************** + * dst_openssldh_compare + * Compare two keys for equality. + * Return + * ISC_TRUE The keys are equal + * ISC_FALSE The keys are not equal + */ +static isc_boolean_t +dst_openssldh_compare(const dst_key_t *key1, const dst_key_t *key2) { + int status; + DH *dh1, *dh2; + + dh1 = (DH *) key1->opaque; + dh2 = (DH *) key2->opaque; + + if (dh1 == NULL && dh2 == NULL) + return (ISC_TRUE); + else if (dh1 == NULL || dh2 == NULL) + return (ISC_FALSE); + + status = BN_cmp(dh1->p, dh2->p) || + BN_cmp(dh1->g, dh2->g) || + BN_cmp(dh1->pub_key, dh2->pub_key); + + if (status != 0) + return (ISC_FALSE); + + if (dh1->priv_key != NULL || dh2->priv_key != NULL) { + if (dh1->priv_key == NULL || dh2->priv_key == NULL) + return (ISC_FALSE); + if (BN_cmp(dh1->priv_key, dh2->priv_key) != 0) + return (ISC_FALSE); + } + return (ISC_TRUE); +} + +/************************************************************************** + * dst_openssldh_paramcompare + * Compare two keys' parameters for equality. + * Return + * ISC_TRUE The keys are equal + * ISC_FALSE The keys are not equal + */ +static isc_boolean_t +dst_openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { + int status; + DH *dh1, *dh2; + + dh1 = (DH *) key1->opaque; + dh2 = (DH *) key2->opaque; + + if (dh1 == NULL && dh2 == NULL) + return (ISC_TRUE); + else if (dh1 == NULL || dh2 == NULL) + return (ISC_FALSE); + + status = BN_cmp(dh1->p, dh2->p) || + BN_cmp(dh1->g, dh2->g); + + if (status != 0) + return (ISC_FALSE); + return (ISC_TRUE); +} + +static void +uint16_toregion(isc_uint16_t val, isc_region_t *region) { + *region->base++ = (val & 0xff00) >> 8; + *region->base++ = (val & 0x00ff); +} + +static isc_uint16_t +uint16_fromregion(isc_region_t *region) { + isc_uint16_t val; + unsigned char *cp = region->base; + + val = ((unsigned int)(cp[0])) << 8; + val |= ((unsigned int)(cp[1])); + + region->base += 2; + return (val); +} + +static void +BN_fromhex(BIGNUM *b, const char *str) { + static const char hexdigits[] = "0123456789abcdef"; + unsigned char data[512]; + unsigned int i; + BIGNUM *out; + + RUNTIME_CHECK(strlen(str) < 1024 && strlen(str) % 2 == 0); + for (i = 0; i < strlen(str); i += 2) { + char *s; + unsigned int high, low; + + s = strchr(hexdigits, tolower(str[i])); + RUNTIME_CHECK(s != NULL); + high = s - hexdigits; + + s = strchr(hexdigits, tolower(str[i + 1])); + RUNTIME_CHECK(s != NULL); + low = s - hexdigits; + + data[i/2] = (unsigned char)((high << 4) + low); + } + out = BN_bin2bn(data, strlen(str)/2, b); + RUNTIME_CHECK(out != NULL); +} + +#endif diff --git a/lib/dns/sec/dst/opensslmd5_link.c b/lib/dns/sec/dst/opensslmd5_link.c new file mode 100644 index 00000000..86493409 --- /dev/null +++ b/lib/dns/sec/dst/opensslmd5_link.c @@ -0,0 +1,102 @@ +#if defined(OPENSSL) + +/* + * Portions Copyright (c) 1995-1998 by Network Associates, Inc. + * + * Permission to use, copy modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND NETWORK ASSOCIATES + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * NETWORK ASSOCIATES BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THE SOFTWARE. + */ + +/* + * Principal Author: Brian Wellington + * $Id: opensslmd5_link.c,v 1.2 1999/10/20 22:14:15 bwelling Exp $ + */ + +#include <config.h> + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <memory.h> + +#include <isc/assertions.h> +#include <isc/buffer.h> +#include <isc/int.h> +#include <isc/region.h> + +#include "dst_internal.h" +#include "dst_parse.h" + +#include <openssl/crypto.h> +#include <openssl/bn.h> +#include <openssl/md5.h> + +#define MD5Init MD5_Init +#define MD5Update MD5_Update +#define MD5Final MD5_Final + +/* + * dst_s_md5 + * Call MD5 functions to digest a block of data. + * There are three steps to signing, INIT (initialize structures), + * UPDATE (hash (more) data), FINAL (generate a digest). This + * routine performs one or more of these steps. + * Parameters + * mode DST_SIGMODE_{INIT_UPDATE_FINAL|ALL} + * context the context to use for this computation + * data data to be signed + * digest buffer to store digest + * mctx memory context for temporary allocations + * Returns + * ISC_R_SUCCESS Success + * !ISC_R_SUCCESS Failure + */ +dst_result_t +dst_s_md5(const unsigned int mode, void **context, isc_region_t *data, + isc_buffer_t *digest, isc_mem_t *mctx) +{ + isc_region_t r; + MD5_CTX *ctx = NULL; + + if (mode & DST_SIGMODE_INIT) { + ctx = (MD5_CTX *) isc_mem_get(mctx, sizeof(MD5_CTX)); + if (ctx == NULL) + return (ISC_R_NOMEMORY); + } + else if (context != NULL) + ctx = (MD5_CTX *) *context; + REQUIRE (ctx != NULL); + + if (mode & DST_SIGMODE_INIT) + MD5Init(ctx); + + if (mode & DST_SIGMODE_UPDATE) + MD5Update(ctx, data->base, data->length); + + if (mode & DST_SIGMODE_FINAL) { + isc_buffer_available(digest, &r); + if (r.length < MD5_DIGEST_LENGTH) + return (ISC_R_NOSPACE); + + MD5Final(r.base, ctx); + isc_buffer_add(digest, MD5_DIGEST_LENGTH); + isc_mem_put(mctx, ctx, sizeof(MD5_CTX)); + } + else + *context = ctx; + + return (ISC_R_SUCCESS); +} + +#endif diff --git a/lib/dns/sec/openssl/.cvsignore b/lib/dns/sec/openssl/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/lib/dns/sec/openssl/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/lib/dns/sec/openssl/Makefile.in b/lib/dns/sec/openssl/Makefile.in new file mode 100644 index 00000000..8a77c44c --- /dev/null +++ b/lib/dns/sec/openssl/Makefile.in @@ -0,0 +1,55 @@ +# Copyright (C) 1998, 1999, 2000 Internet Software Consortium. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS +# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE +# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +# SOFTWARE. + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +CINCLUDES = -I${srcdir}/include + +CDEFINES = -DMFUNC +CWARNINGS = + +LIBS = @LIBS@ + +# Alphabetically +OBJS = bn_add.@O@ bn_asm.@O@ bn_comba.@O@ bn_div.@O@ \ + bn_err.@O@ bn_exp.@O@ bn_exp2.@O@ bn_gcd.@O@ \ + bn_lib.@O@ bn_mont.@O@ bn_mul.@O@ \ + bn_prime.@O@ bn_print.@O@ bn_rand.@O@ bn_recp.@O@ \ + bn_shift.@O@ bn_sqr.@O@ bn_word.@O@ buffer.@O@ \ + cryptlib.@O@ dh_err.@O@ dh_gen.@O@ dh_key.@O@ \ + dh_lib.@O@ dsa_asn1.@O@ dsa_err.@O@ dsa_gen.@O@ \ + dsa_key.@O@ dsa_lib.@O@ dsa_sign.@O@ dsa_vrf.@O@ \ + err.@O@ lhash.@O@ md_rand.@O@ md5_dgst.@O@ mem.@O@ \ + rand_lib.@O@ sha1_one.@O@ sha1dgst.@O@ stack.@O@ \ + th-lock.@O@ + +SRCS = bn_add.c bn_asm.c bn_comba.c bn_div.c \ + bn_err.c bn_exp.c bn_exp2.c bn_gcd.c \ + bn_lib.c bn_mont.c bn_mul.c \ + bn_prime.c bn_print.c bn_rand.c bn_recp.c \ + bn_shift.c bn_sqr.c bn_word.c buffer.c \ + cryptlib.c dh_err.c dh_gen.c dh_key.c dh_lib.c \ + dsa_asn1.c dsa_err.c dsa_gen.c \ + dsa_key.c dsa_lib.c dsa_sign.c dsa_vrf.c \ + err.c lhash.c md_rand.c md5_dgst.c mem.c \ + rand_lib.c sha1_one.c sha1dgst.c stack.c \ + th-lock.c + +SUBDIRS = include +TARGETS = ${OBJS} + +@BIND9_MAKE_RULES@ diff --git a/lib/dns/sec/openssl/bn_add.c b/lib/dns/sec/openssl/bn_add.c new file mode 100644 index 00000000..c5ab066c --- /dev/null +++ b/lib/dns/sec/openssl/bn_add.c @@ -0,0 +1,307 @@ +/* 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, BIGNUM *a, BIGNUM *b) + { + BIGNUM *tmp; + + 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); + } + + if (a->neg) /* both are neg */ + r->neg=1; + else + r->neg=0; + + if (!BN_uadd(r,a,b)) return(0); + return(1); + } + +/* unsigned add of b to a, r must be large enough */ +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) + { + register int i; + int max,min; + BN_ULONG *ap,*bp,*rp,carry,t1; + 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; + + if (bn_wexpand(r,max+1) == NULL) + return(0); + + r->top=max; + + + ap=a->d; + bp=b->d; + rp=r->d; + carry=0; + + carry=bn_add_words(rp,ap,bp,min); + rp+=min; + ap+=min; + bp+=min; + i=min; + + if (carry) + { + while (i < max) + { + i++; + t1= *(ap++); + if ((*(rp++)=(t1+1)&BN_MASK2) >= t1) + { + carry=0; + break; + } + } + if ((i >= max) && carry) + { + *(rp++)=1; + r->top++; + } + } + if (rp != ap) + { + for (; i<max; i++) + *(rp++)= *(ap++); + } + /* memcpy(rp,ap,sizeof(*ap)*(max-i));*/ + 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; + 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); + + if (a->top < b->top) /* hmm... should not be happening */ + { + BNerr(BN_F_BN_USUB,BN_R_ARG2_LT_ARG3); + return(0); + } + + max=a->top; + min=b->top; + if (bn_wexpand(r,max) == NULL) return(0); + + ap=a->d; + bp=b->d; + rp=r->d; + +#if 1 + carry=0; + for (i=0; i<min; 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; + i=min; +#endif + if (carry) /* subtracted */ + { + while (i < max) + { + i++; + t1= *(ap++); + t2=(t1-1)&BN_MASK2; + *(rp++)=t2; + if (t1 > t2) break; + } + } +#if 0 + memcpy(rp,ap,sizeof(*rp)*(max-i)); +#else + if (rp != ap) + { + for (;;) + { + if (i++ >= max) break; + rp[0]=ap[0]; + if (i++ >= max) break; + rp[1]=ap[1]; + if (i++ >= max) break; + rp[2]=ap[2]; + if (i++ >= max) break; + rp[3]=ap[3]; + rp+=4; + ap+=4; + } + } +#endif + + r->top=max; + bn_fix_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; + } + return(1); + } + diff --git a/lib/dns/sec/openssl/bn_asm.c b/lib/dns/sec/openssl/bn_asm.c new file mode 100644 index 00000000..4d3da16a --- /dev/null +++ b/lib/dns/sec/openssl/bn_asm.c @@ -0,0 +1,802 @@ +/* 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.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +#ifdef BN_LLONG + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) + { + BN_ULONG c1=0; + + bn_check_num(num); + if (num <= 0) return(c1); + + for (;;) + { + mul_add(rp[0],ap[0],w,c1); + if (--num == 0) break; + mul_add(rp[1],ap[1],w,c1); + if (--num == 0) break; + mul_add(rp[2],ap[2],w,c1); + if (--num == 0) break; + mul_add(rp[3],ap[3],w,c1); + if (--num == 0) break; + ap+=4; + rp+=4; + } + + return(c1); + } + +BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) + { + BN_ULONG c1=0; + + bn_check_num(num); + if (num <= 0) return(c1); + + /* for (;;) */ + while (1) /* circumvent egcs-1.1.2 bug */ + { + mul(rp[0],ap[0],w,c1); + if (--num == 0) break; + mul(rp[1],ap[1],w,c1); + if (--num == 0) break; + mul(rp[2],ap[2],w,c1); + if (--num == 0) break; + mul(rp[3],ap[3],w,c1); + if (--num == 0) break; + ap+=4; + rp+=4; + } + return(c1); + } + +void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n) + { + bn_check_num(n); + if (n <= 0) return; + for (;;) + { + BN_ULLONG t; + + t=(BN_ULLONG)(a[0])*(a[0]); + r[0]=Lw(t); r[1]=Hw(t); + if (--n == 0) break; + + t=(BN_ULLONG)(a[1])*(a[1]); + r[2]=Lw(t); r[3]=Hw(t); + if (--n == 0) break; + + t=(BN_ULLONG)(a[2])*(a[2]); + r[4]=Lw(t); r[5]=Hw(t); + if (--n == 0) break; + + t=(BN_ULLONG)(a[3])*(a[3]); + r[6]=Lw(t); r[7]=Hw(t); + if (--n == 0) break; + + a+=4; + r+=8; + } + } + +#else + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) + { + BN_ULONG c=0; + BN_ULONG bl,bh; + + bn_check_num(num); + if (num <= 0) return((BN_ULONG)0); + + bl=LBITS(w); + bh=HBITS(w); + + for (;;) + { + mul_add(rp[0],ap[0],bl,bh,c); + if (--num == 0) break; + mul_add(rp[1],ap[1],bl,bh,c); + if (--num == 0) break; + mul_add(rp[2],ap[2],bl,bh,c); + if (--num == 0) break; + mul_add(rp[3],ap[3],bl,bh,c); + if (--num == 0) break; + ap+=4; + rp+=4; + } + return(c); + } + +BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) + { + BN_ULONG carry=0; + BN_ULONG bl,bh; + + bn_check_num(num); + if (num <= 0) return((BN_ULONG)0); + + bl=LBITS(w); + bh=HBITS(w); + + for (;;) + { + mul(rp[0],ap[0],bl,bh,carry); + if (--num == 0) break; + mul(rp[1],ap[1],bl,bh,carry); + if (--num == 0) break; + mul(rp[2],ap[2],bl,bh,carry); + if (--num == 0) break; + mul(rp[3],ap[3],bl,bh,carry); + if (--num == 0) break; + ap+=4; + rp+=4; + } + return(carry); + } + +void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n) + { + bn_check_num(n); + if (n <= 0) return; + for (;;) + { + sqr64(r[0],r[1],a[0]); + if (--n == 0) break; + + sqr64(r[2],r[3],a[1]); + if (--n == 0) break; + + sqr64(r[4],r[5],a[2]); + if (--n == 0) break; + + sqr64(r[6],r[7],a[3]); + if (--n == 0) break; + + a+=4; + r+=8; + } + } + +#endif + +#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); + if ((i != BN_BITS2) && (h > (BN_ULONG)1<<i)) + { +#if !defined(NO_STDIO) && !defined(WIN16) + fprintf(stderr,"Division would overflow (%d)\n",i); +#endif + abort(); + } + 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 + +#ifdef BN_LLONG +BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) + { + BN_ULLONG ll=0; + + bn_check_num(n); + if (n <= 0) return((BN_ULONG)0); + + for (;;) + { + ll+=(BN_ULLONG)a[0]+b[0]; + r[0]=(BN_ULONG)ll&BN_MASK2; + ll>>=BN_BITS2; + if (--n <= 0) break; + + ll+=(BN_ULLONG)a[1]+b[1]; + r[1]=(BN_ULONG)ll&BN_MASK2; + ll>>=BN_BITS2; + if (--n <= 0) break; + + ll+=(BN_ULLONG)a[2]+b[2]; + r[2]=(BN_ULONG)ll&BN_MASK2; + ll>>=BN_BITS2; + if (--n <= 0) break; + + ll+=(BN_ULLONG)a[3]+b[3]; + r[3]=(BN_ULONG)ll&BN_MASK2; + ll>>=BN_BITS2; + if (--n <= 0) break; + + a+=4; + b+=4; + r+=4; + } + return((BN_ULONG)ll); + } +#else +BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) + { + BN_ULONG c,l,t; + + bn_check_num(n); + if (n <= 0) return((BN_ULONG)0); + + c=0; + for (;;) + { + t=a[0]; + t=(t+c)&BN_MASK2; + c=(t < c); + l=(t+b[0])&BN_MASK2; + c+=(l < t); + r[0]=l; + if (--n <= 0) break; + + t=a[1]; + t=(t+c)&BN_MASK2; + c=(t < c); + l=(t+b[1])&BN_MASK2; + c+=(l < t); + r[1]=l; + if (--n <= 0) break; + + t=a[2]; + t=(t+c)&BN_MASK2; + c=(t < c); + l=(t+b[2])&BN_MASK2; + c+=(l < t); + r[2]=l; + if (--n <= 0) break; + + t=a[3]; + t=(t+c)&BN_MASK2; + c=(t < c); + l=(t+b[3])&BN_MASK2; + c+=(l < t); + r[3]=l; + if (--n <= 0) break; + + a+=4; + b+=4; + r+=4; + } + return((BN_ULONG)c); + } +#endif + +BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) + { + BN_ULONG t1,t2; + int c=0; + + bn_check_num(n); + if (n <= 0) return((BN_ULONG)0); + + for (;;) + { + t1=a[0]; t2=b[0]; + r[0]=(t1-t2-c)&BN_MASK2; + if (t1 != t2) c=(t1 < t2); + if (--n <= 0) break; + + t1=a[1]; t2=b[1]; + r[1]=(t1-t2-c)&BN_MASK2; + if (t1 != t2) c=(t1 < t2); + if (--n <= 0) break; + + t1=a[2]; t2=b[2]; + r[2]=(t1-t2-c)&BN_MASK2; + if (t1 != t2) c=(t1 < t2); + if (--n <= 0) break; + + t1=a[3]; t2=b[3]; + r[3]=(t1-t2-c)&BN_MASK2; + if (t1 != t2) c=(t1 < t2); + if (--n <= 0) break; + + a+=4; + b+=4; + r+=4; + } + return(c); + } + +#ifdef BN_MUL_COMBA + +#undef bn_mul_comba8 +#undef bn_mul_comba4 +#undef bn_sqr_comba8 +#undef bn_sqr_comba4 + +#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) +#else +#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 + +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, 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, 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; + } +#else + +/* hmm... is it faster just to do a multiply? */ +#undef bn_sqr_comba4 +void bn_sqr_comba4(BN_ULONG *r, 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, 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]); + } + +#endif /* BN_COMBA */ diff --git a/lib/dns/sec/openssl/bn_comba.c b/lib/dns/sec/openssl/bn_comba.c new file mode 100644 index 00000000..7ad09b4a --- /dev/null +++ b/lib/dns/sec/openssl/bn_comba.c @@ -0,0 +1,345 @@ +/* crypto/bn/bn_comba.c */ +#include <stdio.h> +#include "bn_lcl.h" +/* Auto generated from crypto/bn/comba.pl + */ + +#undef bn_mul_comba8 +#undef bn_mul_comba4 +#undef bn_sqr_comba8 +#undef bn_sqr_comba4 + +#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) +#else +#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 + +void bn_mul_comba88(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b); +void bn_mul_comba44(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b); +void bn_sqr_comba88(BN_ULONG *r,BN_ULONG *a); +void bn_sqr_comba44(BN_ULONG *r,BN_ULONG *a); + +void bn_mul_comba88(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_comba44(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_comba88(BN_ULONG *r, 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_comba44(BN_ULONG *r, 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; + } diff --git a/lib/dns/sec/openssl/bn_div.c b/lib/dns/sec/openssl/bn_div.c new file mode 100644 index 00000000..150dd289 --- /dev/null +++ b/lib/dns/sec/openssl/bn_div.c @@ -0,0 +1,358 @@ +/* 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, BIGNUM *m, BIGNUM *d, BN_CTX *ctx) + { + int i,nm,nd; + 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); + } + + D= &(ctx->bn[ctx->tos]); + if (dv == NULL) dv= &(ctx->bn[ctx->tos+1]); + if (rem == NULL) rem= &(ctx->bn[ctx->tos+2]); + + nd=BN_num_bits(d); + nm=BN_num_bits(m); + if (BN_copy(D,d) == NULL) return(0); + if (BN_copy(rem,m) == NULL) return(0); + + /* 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); + bn_wexpand(dv,1); + dv->top=1; + + if (!BN_lshift(D,D,nm-nd)) return(0); + for (i=nm-nd; i>=0; i--) + { + if (!BN_lshift1(dv,dv)) return(0); + if (BN_ucmp(rem,D) >= 0) + { + dv->d[0]|=1; + if (!BN_usub(rem,rem,D)) return(0); + } +/* CAN IMPROVE (and have now :=) */ + if (!BN_rshift1(D,D)) return(0); + } + rem->neg=BN_is_zero(rem)?0:m->neg; + dv->neg=m->neg^d->neg; + return(1); + } + +#else + +int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, + BN_CTX *ctx) + { + int norm_shift,i,j,loop; + BIGNUM *tmp,wnum,*snum,*sdiv,*res; + BN_ULONG *resp,*wnump; + BN_ULONG d0,d1; + int num_n,div_n; + + bn_check_top(num); + bn_check_top(divisor); + + if (BN_is_zero(divisor)) + { + BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO); + return(0); + } + + if (BN_ucmp(num,divisor) < 0) + { + if (rm != NULL) + { if (BN_copy(rm,num) == NULL) return(0); } + if (dv != NULL) BN_zero(dv); + return(1); + } + + tmp= &(ctx->bn[ctx->tos]); + tmp->neg=0; + snum= &(ctx->bn[ctx->tos+1]); + sdiv= &(ctx->bn[ctx->tos+2]); + if (dv == NULL) + res= &(ctx->bn[ctx->tos+3]); + else res=dv; + + /* First we normalise the numbers */ + norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2); + BN_lshift(sdiv,divisor,norm_shift); + sdiv->neg=0; + norm_shift+=BN_BITS2; + BN_lshift(snum,num,norm_shift); + snum->neg=0; + 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 */ + BN_init(&wnum); + wnum.d= &(snum->d[loop]); + wnum.top= div_n; + wnum.max= snum->max+1; /* a bit of a lie */ + + /* Get the top 2 words of sdiv */ + /* i=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; + resp= &(res->d[loop-1]); + + /* space for temp */ + if (!bn_wexpand(tmp,(div_n+1))) goto err; + + if (BN_ucmp(&wnum,sdiv) >= 0) + { + if (!BN_usub(&wnum,&wnum,sdiv)) goto err; + *resp=1; + res->d[res->top-1]=1; + } + else + res->top--; + resp--; + + for (i=0; i<loop-1; i++) + { + BN_ULONG q,l0; +#ifdef BN_DIV3W + q=bn_div_3_words(wnump,d0,d1); +#else + +#if !defined(NO_ASM) && !defined(PEDANTIC) +# if defined(__GNUC__) && __GNUC__>=2 +# if 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> + */ +# define bn_div_words(n0,n1,d0) \ + ({ asm volatile ( \ + "divl %4" \ + : "=a"(q), "=d"(rem) \ + : "a"(n1), "d"(n0), "g"(d0) \ + : "cc"); \ + q; \ + }) +# define REMINDER_IS_ALREADY_CALCULATED +# endif /* __<cpu> */ +# endif /* __GNUC__ */ +#endif /* NO_ASM */ + BN_ULONG n0,n1,rem=0; + + n0=wnump[0]; + n1=wnump[-1]; + if (n0 == d0) + q=BN_MASK2; + else +#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words) + q=((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0; +#else + q=bn_div_words(n0,n1,d0); +#endif + { +#ifdef BN_LLONG + BN_ULLONG t2; + +#ifndef REMINDER_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_ULONG t2l,t2h,ql,qh; + +#ifndef REMINDER_IS_ALREADY_CALCULATED + /* + * It's more than enough with the only multiplication. + * See the comment above in BN_LLONG section... + */ + rem=(n1-q*d0)&BN_MASK2; +#endif + t2l=LBITS(d1); t2h=HBITS(d1); + ql =LBITS(q); qh =HBITS(q); + mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */ + + 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 + } +#endif /* !BN_DIV3W */ + wnum.d--; wnum.top++; + l0=bn_mul_words(tmp->d,sdiv->d,div_n,q); + tmp->d[div_n]=l0; + for (j=div_n+1; j>0; j--) + if (tmp->d[j-1]) break; + tmp->top=j; + + j=wnum.top; + BN_sub(&wnum,&wnum,tmp); + + snum->top=snum->top+wnum.top-j; + + if (wnum.neg) + { + q--; + j=wnum.top; + BN_add(&wnum,&wnum,sdiv); + snum->top+=wnum.top-j; + } + *(resp--)=q; + wnump--; + } + if (rm != NULL) + { + BN_rshift(rm,snum,norm_shift); + rm->neg=num->neg; + } + return(1); +err: + return(0); + } + +#endif + +/* rem != m */ +int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) + { +#if 0 /* The old slow way */ + int i,nm,nd; + BIGNUM *dv; + + if (BN_ucmp(m,d) < 0) + return((BN_copy(rem,m) == NULL)?0:1); + + dv= &(ctx->bn[ctx->tos]); + + if (!BN_copy(rem,m)) return(0); + + nm=BN_num_bits(rem); + nd=BN_num_bits(d); + if (!BN_lshift(dv,d,nm-nd)) return(0); + for (i=nm-nd; i>=0; i--) + { + if (BN_cmp(rem,dv) >= 0) + { + if (!BN_sub(rem,rem,dv)) return(0); + } + if (!BN_rshift1(dv,dv)) return(0); + } + return(1); +#else + return(BN_div(NULL,rem,m,d,ctx)); +#endif + } + diff --git a/lib/dns/sec/openssl/bn_err.c b/lib/dns/sec/openssl/bn_err.c new file mode 100644 index 00000000..73e80774 --- /dev/null +++ b/lib/dns/sec/openssl/bn_err.c @@ -0,0 +1,116 @@ +/* crypto/bn/bn_err.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). + * + */ + +/* 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. + */ + +#include <stdio.h> +#include <openssl/err.h> +#include <openssl/bn.h> + +/* BEGIN ERROR CODES */ +#ifndef NO_ERR +static ERR_STRING_DATA BN_str_functs[]= + { +{ERR_PACK(0,BN_F_BN_BLINDING_CONVERT,0), "BN_BLINDING_convert"}, +{ERR_PACK(0,BN_F_BN_BLINDING_INVERT,0), "BN_BLINDING_invert"}, +{ERR_PACK(0,BN_F_BN_BLINDING_NEW,0), "BN_BLINDING_new"}, +{ERR_PACK(0,BN_F_BN_BLINDING_UPDATE,0), "BN_BLINDING_update"}, +{ERR_PACK(0,BN_F_BN_BN2DEC,0), "BN_bn2dec"}, +{ERR_PACK(0,BN_F_BN_BN2HEX,0), "BN_bn2hex"}, +{ERR_PACK(0,BN_F_BN_CTX_NEW,0), "BN_CTX_new"}, +{ERR_PACK(0,BN_F_BN_DIV,0), "BN_div"}, +{ERR_PACK(0,BN_F_BN_EXPAND2,0), "bn_expand2"}, +{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT,0), "BN_mod_exp_mont"}, +{ERR_PACK(0,BN_F_BN_MOD_INVERSE,0), "BN_mod_inverse"}, +{ERR_PACK(0,BN_F_BN_MOD_MUL_RECIPROCAL,0), "BN_mod_mul_reciprocal"}, +{ERR_PACK(0,BN_F_BN_MPI2BN,0), "BN_mpi2bn"}, +{ERR_PACK(0,BN_F_BN_NEW,0), "BN_new"}, +{ERR_PACK(0,BN_F_BN_RAND,0), "BN_rand"}, +{ERR_PACK(0,BN_F_BN_USUB,0), "BN_usub"}, +{0,NULL} + }; + +static ERR_STRING_DATA BN_str_reasons[]= + { +{BN_R_ARG2_LT_ARG3 ,"arg2 lt arg3"}, +{BN_R_BAD_RECIPROCAL ,"bad reciprocal"}, +{BN_R_CALLED_WITH_EVEN_MODULUS ,"called with even modulus"}, +{BN_R_DIV_BY_ZERO ,"div by zero"}, +{BN_R_ENCODING_ERROR ,"encoding error"}, +{BN_R_EXPAND_ON_STATIC_BIGNUM_DATA ,"expand on static bignum data"}, +{BN_R_INVALID_LENGTH ,"invalid length"}, +{BN_R_NOT_INITIALIZED ,"not initialized"}, +{BN_R_NO_INVERSE ,"no inverse"}, +{0,NULL} + }; + +#endif + +void ERR_load_BN_strings(void) + { + static int init=1; + + if (init) + { + init=0; +#ifndef NO_ERR + ERR_load_strings(ERR_LIB_BN,BN_str_functs); + ERR_load_strings(ERR_LIB_BN,BN_str_reasons); +#endif + + } + } diff --git a/lib/dns/sec/openssl/bn_exp.c b/lib/dns/sec/openssl/bn_exp.c new file mode 100644 index 00000000..2df1614a --- /dev/null +++ b/lib/dns/sec/openssl/bn_exp.c @@ -0,0 +1,549 @@ +/* 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.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +#define TABLE_SIZE 16 + +/* slow but works */ +int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) + { + BIGNUM *t; + int r=0; + + bn_check_top(a); + bn_check_top(b); + bn_check_top(m); + + t= &(ctx->bn[ctx->tos++]); + if (a == b) + { if (!BN_sqr(t,a,ctx)) goto err; } + else + { if (!BN_mul(t,a,b,ctx)) goto err; } + if (!BN_mod(ret,t,m,ctx)) goto err; + r=1; +err: + ctx->tos--; + return(r); + } + +#if 0 +/* this one works - simple but works */ +int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, BN_CTX *ctx) + { + int i,bits,ret=0; + BIGNUM *v,*tmp; + + v= &(ctx->bn[ctx->tos++]); + tmp= &(ctx->bn[ctx->tos++]); + + if (BN_copy(v,a) == NULL) goto err; + bits=BN_num_bits(p); + + if (BN_is_odd(p)) + { if (BN_copy(r,a) == NULL) goto err; } + else { if (!BN_one(r)) goto err; } + + for (i=1; i<bits; i++) + { + if (!BN_sqr(tmp,v,ctx)) goto err; + if (!BN_mod(v,tmp,m,ctx)) goto err; + if (BN_is_bit_set(p,i)) + { + if (!BN_mul(tmp,r,v,ctx)) goto err; + if (!BN_mod(r,tmp,m,ctx)) goto err; + } + } + ret=1; +err: + ctx->tos-=2; + return(ret); + } + +#endif + +/* this one works - simple but works */ +int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx) + { + int i,bits,ret=0,tos; + BIGNUM *v,*rr; + + tos=ctx->tos; + v= &(ctx->bn[ctx->tos++]); + if ((r == a) || (r == p)) + rr= &(ctx->bn[ctx->tos++]); + else + rr=r; + + 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; + } + } + ret=1; +err: + ctx->tos=tos; + if (r != rr) BN_copy(r,rr); + return(ret); + } + +int BN_mod_exp(BIGNUM *r, 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); + +#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)) + { 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 + + return(ret); + } + +/* #ifdef RECP_MUL_MOD */ +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,ts=0; + BIGNUM *aa; + BIGNUM val[TABLE_SIZE]; + BN_RECP_CTX recp; + + aa= &(ctx->bn[ctx->tos++]); + bits=BN_num_bits(p); + + if (bits == 0) + { + BN_one(r); + return(1); + } + BN_RECP_CTX_init(&recp); + if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err; + + BN_init(&(val[0])); + ts=1; + + if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */ + if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx)) + goto err; /* 2 */ + + if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */ + window=1; + else if (bits >= 256) + window=5; /* max size of window */ + else if (bits >= 128) + window=4; + else + window=3; + + j=1<<(window-1); + for (i=1; i<j; i++) + { + BN_init(&val[i]); + if (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx)) + goto err; + } + ts=i; + + 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: + ctx->tos--; + for (i=0; i<ts; i++) + BN_clear_free(&(val[i])); + BN_RECP_CTX_free(&recp); + return(ret); + } +/* #endif */ + +/* #ifdef MONT_MUL_MOD */ +int BN_mod_exp_mont(BIGNUM *rr, 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,ts=0; + BIGNUM *d,*r; + BIGNUM *aa; + BIGNUM val[TABLE_SIZE]; + BN_MONT_CTX *mont=NULL; + + bn_check_top(a); + bn_check_top(p); + bn_check_top(m); + + if (!(m->d[0] & 1)) + { + BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); + return(0); + } + d= &(ctx->bn[ctx->tos++]); + r= &(ctx->bn[ctx->tos++]); + bits=BN_num_bits(p); + if (bits == 0) + { + BN_one(r); + return(1); + } + + /* If this is not done, things will break in the montgomery + * part */ + +#if 1 + if (in_mont != NULL) + mont=in_mont; + else +#endif + { + if ((mont=BN_MONT_CTX_new()) == NULL) goto err; + if (!BN_MONT_CTX_set(mont,m,ctx)) goto err; + } + + BN_init(&val[0]); + ts=1; + if (BN_ucmp(a,m) >= 0) + { + BN_mod(&(val[0]),a,m,ctx); + aa= &(val[0]); + } + else + aa=a; + if (!BN_to_montgomery(&(val[0]),aa,mont,ctx)) goto err; /* 1 */ + if (!BN_mod_mul_montgomery(d,&(val[0]),&(val[0]),mont,ctx)) goto err; /* 2 */ + + if (bits <= 20) /* This is probably 3 or 0x10001, so just do singles */ + window=1; + else if (bits >= 256) + window=5; /* max size of window */ + else if (bits >= 128) + window=4; + else + window=3; + + j=1<<(window-1); + for (i=1; i<j; i++) + { + BN_init(&(val[i])); + if (!BN_mod_mul_montgomery(&(val[i]),&(val[i-1]),d,mont,ctx)) + goto err; + } + ts=i; + + 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; + } + BN_from_montgomery(rr,r,mont,ctx); + ret=1; +err: + if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); + ctx->tos-=2; + for (i=0; i<ts; i++) + BN_clear_free(&(val[i])); + return(ret); + } +/* #endif */ + +/* The old fallback, simple version :-) */ +int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m, + BN_CTX *ctx) + { + int i,j,bits,ret=0,wstart,wend,window,wvalue,ts=0; + int start=1; + BIGNUM *d; + BIGNUM val[TABLE_SIZE]; + + d= &(ctx->bn[ctx->tos++]); + bits=BN_num_bits(p); + + if (bits == 0) + { + BN_one(r); + return(1); + } + + BN_init(&(val[0])); + ts=1; + if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */ + if (!BN_mod_mul(d,&(val[0]),&(val[0]),m,ctx)) + goto err; /* 2 */ + + if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */ + window=1; + else if (bits >= 256) + window=5; /* max size of window */ + else if (bits >= 128) + window=4; + else + window=3; + + j=1<<(window-1); + for (i=1; i<j; i++) + { + BN_init(&(val[i])); + if (!BN_mod_mul(&(val[i]),&(val[i-1]),d,m,ctx)) + goto err; + } + ts=i; + + 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: + ctx->tos--; + for (i=0; i<ts; i++) + BN_clear_free(&(val[i])); + return(ret); + } + diff --git a/lib/dns/sec/openssl/bn_exp2.c b/lib/dns/sec/openssl/bn_exp2.c new file mode 100644 index 00000000..1132d533 --- /dev/null +++ b/lib/dns/sec/openssl/bn_exp2.c @@ -0,0 +1,195 @@ +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +/* I've done some timing with different table sizes. + * The main hassle is that even with bits set at 3, this requires + * 63 BIGNUMs to store the pre-calculated values. + * 512 1024 + * bits=1 75.4% 79.4% + * bits=2 61.2% 62.4% + * bits=3 61.3% 59.3% + * The lack of speed improvment is also a function of the pre-calculation + * which could be removed. + */ +#define EXP2_TABLE_BITS 2 /* 1 2 3 4 5 */ +#define EXP2_TABLE_SIZE 4 /* 2 4 8 16 32 */ + +int BN_mod_exp2_mont(BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2, + BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) + { + int i,j,k,bits,bits1,bits2,ret=0,wstart,wend,window,xvalue,yvalue; + int start=1,ts=0,x,y; + BIGNUM *d,*aa1,*aa2,*r; + BIGNUM val[EXP2_TABLE_SIZE][EXP2_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_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); + return(0); + } + d= &(ctx->bn[ctx->tos++]); + r= &(ctx->bn[ctx->tos++]); + bits1=BN_num_bits(p1); + bits2=BN_num_bits(p2); + if ((bits1 == 0) && (bits2 == 0)) + { + BN_one(r); + return(1); + } + bits=(bits1 > bits2)?bits1:bits2; + + /* 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; + } + + BN_init(&(val[0][0])); + BN_init(&(val[1][1])); + BN_init(&(val[0][1])); + BN_init(&(val[1][0])); + ts=1; + if (BN_ucmp(a1,m) >= 0) + { + BN_mod(&(val[1][0]),a1,m,ctx); + aa1= &(val[1][0]); + } + else + aa1=a1; + if (BN_ucmp(a2,m) >= 0) + { + BN_mod(&(val[0][1]),a2,m,ctx); + aa2= &(val[0][1]); + } + else + aa2=a2; + if (!BN_to_montgomery(&(val[1][0]),aa1,mont,ctx)) goto err; + if (!BN_to_montgomery(&(val[0][1]),aa2,mont,ctx)) goto err; + if (!BN_mod_mul_montgomery(&(val[1][1]), + &(val[1][0]),&(val[0][1]),mont,ctx)) + goto err; + +#if 0 + if (bits <= 20) /* This is probably 3 or 0x10001, so just do singles */ + window=1; + else if (bits > 250) + window=5; /* max size of window */ + else if (bits >= 120) + window=4; + else + window=3; +#else + window=EXP2_TABLE_BITS; +#endif + + k=1<<window; + for (x=0; x<k; x++) + { + if (x >= 2) + { + BN_init(&(val[x][0])); + BN_init(&(val[x][1])); + if (!BN_mod_mul_montgomery(&(val[x][0]), + &(val[1][0]),&(val[x-1][0]),mont,ctx)) goto err; + if (!BN_mod_mul_montgomery(&(val[x][1]), + &(val[1][0]),&(val[x-1][1]),mont,ctx)) goto err; + } + for (y=2; y<k; y++) + { + BN_init(&(val[x][y])); + if (!BN_mod_mul_montgomery(&(val[x][y]), + &(val[x][y-1]),&(val[0][1]),mont,ctx)) + goto err; + } + } + ts=k; + + start=1; /* This is used to avoid multiplication etc + * when there is only the value '1' in the + * buffer. */ + xvalue=0; /* The 'x value' of the window */ + yvalue=0; /* The 'y 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 (;;) + { + xvalue=BN_is_bit_set(p1,wstart); + yvalue=BN_is_bit_set(p2,wstart); + if (!(xvalue || yvalue)) + { + if (!start) + { + if (!BN_mod_mul_montgomery(r,r,r,mont,ctx)) + goto err; + } + wstart--; + if (wstart < 0) break; + 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; + /* xvalue=BN_is_bit_set(p1,wstart); already set */ + /* yvalue=BN_is_bit_set(p1,wstart); already set */ + wend=0; + for (i=1; i<window; i++) + { + if (wstart-i < 0) break; + xvalue+=xvalue; + xvalue|=BN_is_bit_set(p1,wstart-i); + yvalue+=yvalue; + yvalue|=BN_is_bit_set(p2,wstart-i); + } + + /* i is the size of the current window */ + /* add the 'bytes above' */ + if (!start) + for (j=0; j<i; j++) + { + if (!BN_mod_mul_montgomery(r,r,r,mont,ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ + if (xvalue || yvalue) + { + if (!BN_mod_mul_montgomery(r,r,&(val[xvalue][yvalue]), + mont,ctx)) goto err; + } + + /* move the 'window' down further */ + wstart-=i; + start=0; + if (wstart < 0) break; + } + BN_from_montgomery(rr,r,mont,ctx); + ret=1; +err: + if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); + ctx->tos-=2; + for (i=0; i<ts; i++) + { + for (j=0; j<ts; j++) + { + BN_clear_free(&(val[i][j])); + } + } + return(ret); + } diff --git a/lib/dns/sec/openssl/bn_gcd.c b/lib/dns/sec/openssl/bn_gcd.c new file mode 100644 index 00000000..64a76f44 --- /dev/null +++ b/lib/dns/sec/openssl/bn_gcd.c @@ -0,0 +1,204 @@ +/* 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.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +static BIGNUM *euclid(BIGNUM *a, BIGNUM *b); +int BN_gcd(BIGNUM *r, BIGNUM *in_a, BIGNUM *in_b, BN_CTX *ctx) + { + BIGNUM *a,*b,*t; + int ret=0; + + bn_check_top(in_a); + bn_check_top(in_b); + + a= &(ctx->bn[ctx->tos]); + b= &(ctx->bn[ctx->tos+1]); + + if (BN_copy(a,in_a) == NULL) goto err; + if (BN_copy(b,in_b) == NULL) goto err; + + 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: + return(ret); + } + +static BIGNUM *euclid(BIGNUM *a, BIGNUM *b) + { + BIGNUM *t; + int shifts=0; + + bn_check_top(a); + bn_check_top(b); + + for (;;) + { + if (BN_is_zero(b)) + break; + + 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++; + } + } + } + if (shifts) + { + if (!BN_lshift(a,a,shifts)) goto err; + } + return(a); +err: + return(NULL); + } + +/* solves ax == 1 (mod n) */ +BIGNUM *BN_mod_inverse(BIGNUM *in, BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) + { + BIGNUM *A,*B,*X,*Y,*M,*D,*R; + BIGNUM *T,*ret=NULL; + int sign; + + bn_check_top(a); + bn_check_top(n); + + A= &(ctx->bn[ctx->tos]); + B= &(ctx->bn[ctx->tos+1]); + X= &(ctx->bn[ctx->tos+2]); + D= &(ctx->bn[ctx->tos+3]); + M= &(ctx->bn[ctx->tos+4]); + Y= &(ctx->bn[ctx->tos+5]); + ctx->tos+=6; + if (in == NULL) + R=BN_new(); + else + R=in; + if (R == NULL) goto err; + + BN_zero(X); + BN_one(Y); + if (BN_copy(A,a) == NULL) goto err; + if (BN_copy(B,n) == NULL) goto err; + sign=1; + + while (!BN_is_zero(B)) + { + if (!BN_div(D,M,A,B,ctx)) goto err; + T=A; + A=B; + B=M; + /* T has a struct, M does not */ + + if (!BN_mul(T,D,X,ctx)) goto err; + if (!BN_add(T,T,Y)) goto err; + M=Y; + Y=X; + X=T; + sign= -sign; + } + if (sign < 0) + { + if (!BN_sub(Y,n,Y)) goto err; + } + + if (BN_is_one(A)) + { if (!BN_mod(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); + ctx->tos-=6; + return(ret); + } + diff --git a/lib/dns/sec/openssl/bn_lcl.h b/lib/dns/sec/openssl/bn_lcl.h new file mode 100644 index 00000000..de4a1d94 --- /dev/null +++ b/lib/dns/sec/openssl/bn_lcl.h @@ -0,0 +1,272 @@ +/* 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.] + */ + +#ifndef HEADER_BN_LCL_H +#define HEADER_BN_LCL_H + +#include <openssl/bn.h> + +#ifdef __cplusplus +extern "C" { +#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 0 +#ifndef BN_MUL_COMBA +/* #define bn_mul_comba8(r,a,b) bn_mul_normal(r,a,8,b,8) */ +/* #define bn_mul_comba4(r,a,b) bn_mul_normal(r,a,4,b,4) */ +#endif + +#ifndef BN_SQR_COMBA +/* This is probably faster than using the C code - I need to check */ +#define bn_sqr_comba8(r,a) bn_mul_normal(r,a,8,a,8) +#define bn_sqr_comba4(r,a) bn_mul_normal(r,a,4,a,4) +#endif +#endif + +/************************************************************* + * Using the long long type + */ +#define Lw(t) (((BN_ULONG)(t))&BN_MASK2) +#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2) + +/* These are used for internal error checking and are not normally used */ +#ifdef BN_DEBUG +#define bn_check_top(a) \ + { if (((a)->top < 0) || ((a)->top > (a)->max)) \ + { char *nullp=NULL; *nullp='z'; } } +#define bn_check_num(a) if ((a) < 0) { char *nullp=NULL; *nullp='z'; } +#else +#define bn_check_top(a) +#define bn_check_num(a) +#endif + +/* This macro is to add extra stuff for development checking */ +#ifdef BN_DEBUG +#define bn_set_max(r) ((r)->max=(r)->top,BN_set_flags((r),BN_FLG_STATIC_DATA)) +#else +#define bn_set_max(r) +#endif + +/* These macros are used to 'take' a section of a bignum for read only use */ +#define bn_set_low(r,a,n) \ + { \ + (r)->top=((a)->top > (n))?(n):(a)->top; \ + (r)->d=(a)->d; \ + (r)->neg=(a)->neg; \ + (r)->flags|=BN_FLG_STATIC_DATA; \ + bn_set_max(r); \ + } + +#define bn_set_high(r,a,n) \ + { \ + if ((a)->top > (n)) \ + { \ + (r)->top=(a)->top-n; \ + (r)->d= &((a)->d[n]); \ + } \ + else \ + (r)->top=0; \ + (r)->neg=(a)->neg; \ + (r)->flags|=BN_FLG_STATIC_DATA; \ + bn_set_max(r); \ + } + +/* #define bn_expand(n,b) ((((b)/BN_BITS2) <= (n)->max)?(n):bn_expand2((n),(b))) */ + +#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); \ + } + +#else +/************************************************************* + * No long long type + */ + +#define LBITS(a) ((a)&BN_MASK2l) +#define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2l) +#define L2HBITS(a) ((BN_ULONG)((a)&BN_MASK2l)<<BN_BITS4) + +#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(1L); \ + 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 + +/* BEW */ +#define OPENSSL_EXTERN extern +#define NO_BIO + +OPENSSL_EXTERN int bn_limit_bits; +OPENSSL_EXTERN int bn_limit_num; /* (1<<bn_limit_bits) */ +/* Recursive 'low' limit */ +OPENSSL_EXTERN int bn_limit_bits_low; +OPENSSL_EXTERN int bn_limit_num_low; /* (1<<bn_limit_bits_low) */ +/* Do modified 'high' part calculation' */ +OPENSSL_EXTERN int bn_limit_bits_high; +OPENSSL_EXTERN int bn_limit_num_high; /* (1<<bn_limit_bits_high) */ +OPENSSL_EXTERN int bn_limit_bits_mont; +OPENSSL_EXTERN int bn_limit_num_mont; /* (1<<bn_limit_bits_mont) */ + +BIGNUM *bn_expand2(BIGNUM *b, int bits); + +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, BN_ULONG *a, int n, BN_ULONG *tmp); +void bn_sqr_comba8(BN_ULONG *r,BN_ULONG *a); +void bn_sqr_comba4(BN_ULONG *r,BN_ULONG *a); +int bn_cmp_words(BN_ULONG *a,BN_ULONG *b,int n); +void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,BN_ULONG *t); +void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, + int tn, int n,BN_ULONG *t); +void bn_sqr_recursive(BN_ULONG *r,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); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/openssl/bn_lib.c b/lib/dns/sec/openssl/bn_lib.c new file mode 100644 index 00000000..26b11c41 --- /dev/null +++ b/lib/dns/sec/openssl/bn_lib.c @@ -0,0 +1,787 @@ +/* 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.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT; + +/* 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 + */ +OPENSSL_GLOBAL int bn_limit_bits=0; +OPENSSL_GLOBAL int bn_limit_num=8; /* (1<<bn_limit_bits) */ +OPENSSL_GLOBAL int bn_limit_bits_low=0; +OPENSSL_GLOBAL int bn_limit_num_low=8; /* (1<<bn_limit_bits_low) */ +OPENSSL_GLOBAL int bn_limit_bits_high=0; +OPENSSL_GLOBAL int bn_limit_num_high=8; /* (1<<bn_limit_bits_high) */ +OPENSSL_GLOBAL int bn_limit_bits_mont=0; +OPENSSL_GLOBAL 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 ((unsigned int)mult > (sizeof(int)*8)-1) + mult=sizeof(int)*8-1; + bn_limit_bits=mult; + bn_limit_num=1<<mult; + } + if (high >= 0) + { + if ((unsigned int)high > (sizeof(int)*8)-1) + high=sizeof(int)*8-1; + bn_limit_bits_high=high; + bn_limit_num_high=1<<high; + } + if (low >= 0) + { + if ((unsigned int)low > (sizeof(int)*8)-1) + low=sizeof(int)*8-1; + bn_limit_bits_low=low; + bn_limit_num_low=1<<low; + } + if (mont >= 0) + { + if ((unsigned int)mont > (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); + } + +BIGNUM *BN_value_one(void) + { + static BN_ULONG data_one=1L; + static BIGNUM const_one={&data_one,1,1,0,0}; + + return(&const_one); + } + +char *BN_options(void) + { + static int init=0; + static char data[16]; + + if (!init) + { + init++; +#ifdef BN_LLONG + sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULLONG)*8, + (int)sizeof(BN_ULONG)*8); +#else + sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULONG)*8, + (int)sizeof(BN_ULONG)*8); +#endif + } + return(data); + } + +int BN_num_bits_word(BN_ULONG l) + { + static const 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(SIXTEEN_BIT) || 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) + { + BN_ULONG l; + int i; + + bn_check_top(a); + + if (a->top == 0) return(0); + l=a->d[a->top-1]; + i=(a->top-1)*BN_BITS2; + if (l == 0) + { +#if !defined(NO_STDIO) && !defined(WIN16) + fprintf(stderr,"BAD TOP VALUE\n"); +#endif + abort(); + } + return(i+BN_num_bits_word(l)); + } + +void BN_clear_free(BIGNUM *a) + { + int i; + + if (a == NULL) return; + if (a->d != NULL) + { + memset(a->d,0,a->max*sizeof(a->d[0])); + if (!(BN_get_flags(a,BN_FLG_STATIC_DATA))) + Free(a->d); + } + i=BN_get_flags(a,BN_FLG_MALLOCED); + memset(a,0,sizeof(BIGNUM)); + if (i) + Free(a); + } + +void BN_free(BIGNUM *a) + { + if (a == NULL) return; + if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA))) + Free(a->d); + a->flags|=BN_FLG_FREE; /* REMOVE? */ + if (a->flags & BN_FLG_MALLOCED) + Free(a); + } + +void BN_init(BIGNUM *a) + { + memset(a,0,sizeof(BIGNUM)); + } + +BIGNUM *BN_new(void) + { + BIGNUM *ret; + + if ((ret=(BIGNUM *)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->max=0; + ret->d=NULL; + return(ret); + } + + +BN_CTX *BN_CTX_new(void) + { + BN_CTX *ret; + + ret=(BN_CTX *)Malloc(sizeof(BN_CTX)); + if (ret == NULL) + { + BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE); + return(NULL); + } + + BN_CTX_init(ret); + ret->flags=BN_FLG_MALLOCED; + return(ret); + } + +void BN_CTX_init(BN_CTX *ctx) + { + memset(ctx,0,sizeof(BN_CTX)); + ctx->tos=0; + ctx->flags=0; + } + +void BN_CTX_free(BN_CTX *c) + { + int i; + + if(c == NULL) + return; + + for (i=0; i<BN_CTX_NUM; i++) + BN_clear_free(&(c->bn[i])); + if (c->flags & BN_FLG_MALLOCED) + Free(c); + } + +BIGNUM *bn_expand2(BIGNUM *b, int words) + { + BN_ULONG *A,*a; + const BN_ULONG *B; + int i; + + bn_check_top(b); + + if (words > b->max) + { + bn_check_top(b); + if (BN_get_flags(b,BN_FLG_STATIC_DATA)) + { + BNerr(BN_F_BN_EXPAND2,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); + return(NULL); + } + a=A=(BN_ULONG *)Malloc(sizeof(BN_ULONG)*(words+1)); + if (A == NULL) + { + BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE); + return(NULL); + } +#if 1 + B=b->d; + /* Check if the previous number needs to be copied */ + if (B != NULL) + { +#if 0 + /* This lot is an unrolled loop to copy b->top + * BN_ULONGs from B to A + */ +/* + * I have nothing against unrolling but it's usually done for + * several reasons, namely: + * - minimize percentage of decision making code, i.e. branches; + * - avoid cache trashing; + * - make it possible to schedule loads earlier; + * Now let's examine the code below. The cornerstone of C is + * "programmer is always right" and that's what we love it for:-) + * For this very reason C compilers have to be paranoid when it + * comes to data aliasing and assume the worst. Yeah, but what + * does it mean in real life? This means that loop body below will + * be compiled to sequence of loads immediately followed by stores + * as compiler assumes the worst, something in A==B+1 style. As a + * result CPU pipeline is going to starve for incoming data. Secondly + * if A and B happen to share same cache line such code is going to + * cause severe cache trashing. Both factors have severe impact on + * performance of modern CPUs and this is the reason why this + * particulare piece of code is #ifdefed away and replaced by more + * "friendly" version found in #else section below. This comment + * also applies to BN_copy function. + * + * <appro@fy.chalmers.se> + */ + for (i=b->top&(~7); i>0; i-=8) + { + A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3]; + A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7]; + A+=8; + B+=8; + } + switch (b->top&7) + { + case 7: + A[6]=B[6]; + case 6: + A[5]=B[5]; + case 5: + A[4]=B[4]; + case 4: + A[3]=B[3]; + case 3: + A[2]=B[2]; + case 2: + A[1]=B[1]; + case 1: + A[0]=B[0]; + case 0: + /* I need the 'case 0' entry for utrix cc. + * If the optimiser is turned on, it does the + * switch table by doing + * a=top&7 + * a--; + * goto jump_table[a]; + * If top is 0, this makes us jump to 0xffffffc + * which is rather bad :-(. + * eric 23-Apr-1998 + */ + ; + } +#else + 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; + } + switch (b->top&3) + { + case 3: A[2]=B[2]; + case 2: A[1]=B[1]; + case 1: A[0]=B[0]; + case 0: ; /* ultrix cc workaround, see above */ + } +#endif + Free(b->d); + } + + b->d=a; + b->max=words; + + /* Now need to zero any data between b->top and b->max */ + + A= &(b->d[b->top]); + for (i=(b->max - 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->max - b->top)&7; i>0; i--,A++) + A[0]=0; +#else + memset(A,0,sizeof(BN_ULONG)*(words+1)); + memcpy(A,b->d,sizeof(b->d[0])*b->top); + b->d=a; + b->max=words; +#endif + +/* memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG)); */ +/* { int i; for (i=b->max; i<words+1; i++) p[i]=i;} */ + + } + return(b); + } + +BIGNUM *BN_dup(const BIGNUM *a) + { + BIGNUM *r; + + if (a == NULL) return NULL; + + bn_check_top(a); + + r=BN_new(); + if (r == NULL) return(NULL); + return((BIGNUM *)BN_copy(r,a)); + } + +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; + } + switch (b->top&3) + { + case 3: A[2]=B[2]; + case 2: A[1]=B[1]; + case 1: A[0]=B[0]; + case 0: ; /* ultrix cc workaround, see comments in bn_expand2 */ + } +#else + memcpy(a->d,b->d,sizeof(b->d[0])*b->top); +#endif + +/* memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/ + a->top=b->top; + if ((a->top == 0) && (a->d != NULL)) + a->d[0]=0; + a->neg=b->neg; + return(a); + } + +void BN_clear(BIGNUM *a) + { + if (a->d != NULL) + memset(a->d,0,a->max*sizeof(a->d[0])); + a->top=0; + a->neg=0; + } + +BN_ULONG BN_get_word(BIGNUM *a) + { + int i,n; + BN_ULONG ret=0; + + n=BN_num_bytes(a); + if ((unsigned int)n > sizeof(BN_ULONG)) + return(BN_MASK2); + for (i=a->top-1; i>=0; i--) + { +#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */ + ret<<=BN_BITS4; /* stops the compiler complaining */ + ret<<=BN_BITS4; +#else + ret=0; +#endif + ret|=a->d[i]; + } + return(ret); + } + +int BN_set_word(BIGNUM *a, BN_ULONG w) + { + int i,n; + if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0); + + n=sizeof(BN_ULONG)/BN_BYTES; + a->neg=0; + a->top=0; + a->d[0]=(BN_ULONG)w&BN_MASK2; + if (a->d[0] != 0) a->top=1; + for (i=1; i<n; i++) + { + /* the following is done instead of + * w>>=BN_BITS2 so compilers don't complain + * on builds where sizeof(long) == BN_TYPES */ +#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */ + w>>=BN_BITS4; + w>>=BN_BITS4; +#else + w=0; +#endif + a->d[i]=(BN_ULONG)w&BN_MASK2; + if (a->d[i] != 0) a->top=i+1; + } + return(1); + } + +/* ignore negative */ +BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) + { + unsigned int i,m; + unsigned int n; + BN_ULONG l; + + if (ret == NULL) ret=BN_new(); + if (ret == NULL) return(NULL); + l=0; + n=len; + if (n == 0) + { + ret->top=0; + return(ret); + } + if (bn_expand(ret,(int)(n+2)*8) == NULL) + return(NULL); + i=((n-1)/BN_BYTES)+1; + m=((n-1)%(BN_BYTES)); + ret->top=i; + while (n-- > 0) + { + 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_fix_top(ret); + return(ret); + } + +/* ignore negative */ +int BN_bn2bin(const BIGNUM *a, unsigned char *to) + { + int n,i; + BN_ULONG l; + + n=i=BN_num_bytes(a); + while (i-- > 0) + { + 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; + + 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); + return(1); + } + +int BN_clear_bit(BIGNUM *a, int n) + { + int i,j; + + i=n/BN_BITS2; + j=n%BN_BITS2; + if (a->top <= i) return(0); + + a->d[i]&=(~(((BN_ULONG)1)<<j)); + bn_fix_top(a); + return(1); + } + +int BN_is_bit_set(const BIGNUM *a, int n) + { + int i,j; + + if (n < 0) return(0); + i=n/BN_BITS2; + j=n%BN_BITS2; + if (a->top <= i) return(0); + return((a->d[i]&(((BN_ULONG)1)<<j))?1:0); + } + +int BN_mask_bits(BIGNUM *a, int n) + { + int b,w; + + 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_fix_top(a); + return(1); + } + +int bn_cmp_words(BN_ULONG *a, 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); + } + diff --git a/lib/dns/sec/openssl/bn_mont.c b/lib/dns/sec/openssl/bn_mont.c new file mode 100644 index 00000000..ee0f410c --- /dev/null +++ b/lib/dns/sec/openssl/bn_mont.c @@ -0,0 +1,407 @@ +/* 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.] + */ + +/* + * Details about Montgomery multiplication algorithms can be found at: + * http://www.ece.orst.edu/ISL/Publications.html + * http://www.ece.orst.edu/ISL/Koc/papers/j37acmon.pdf + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +#define MONT_WORD + +int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx) + { + BIGNUM *tmp,*tmp2; + + tmp= &(ctx->bn[ctx->tos]); + tmp2= &(ctx->bn[ctx->tos]); + ctx->tos+=2; + + bn_check_top(tmp); + bn_check_top(tmp2); + + if (a == b) + { +#if 0 + bn_wexpand(tmp,a->top*2); + bn_wexpand(tmp2,a->top*4); + bn_sqr_recursive(tmp->d,a->d,a->top,tmp2->d); + tmp->top=a->top*2; + if (tmp->d[tmp->top-1] == 0) + tmp->top--; +#else + if (!BN_sqr(tmp,a,ctx)) goto err; +#endif + } + else + { + if (!BN_mul(tmp,a,b,ctx)) goto err; + } + /* reduce from aRR to aR */ + if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err; + ctx->tos-=2; + return(1); +err: + return(0); + } + +int BN_from_montgomery(BIGNUM *ret, BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx) + { +#ifdef BN_RECURSION_MONT + if (mont->use_word) +#endif + { + BIGNUM *n,*r; + BN_ULONG *ap,*np,*rp,n0,v,*nrp; + int al,nl,max,i,x,ri; + int retn=0; + + r= &(ctx->bn[ctx->tos]); + + if (!BN_copy(r,a)) goto err1; + n= &(mont->N); + + ap=a->d; + /* mont->ri is the size of mont->N in bits/words */ + al=ri=mont->ri/BN_BITS2; + + nl=n->top; + if ((al == 0) || (nl == 0)) { r->top=0; return(1); } + + max=(nl+al+1); /* allow for overflow (no?) XXX */ + if (bn_wexpand(r,max) == NULL) goto err1; + if (bn_wexpand(ret,max) == NULL) goto err1; + + r->neg=a->neg^n->neg; + np=n->d; + rp=r->d; + nrp= &(r->d[nl]); + + /* clear the top words of T */ +#if 1 + for (i=r->top; i<max; i++) /* memset? XXX */ + r->d[i]=0; +#else + memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); +#endif + + r->top=max; + n0=mont->n0; + +#ifdef BN_COUNT +printf("word BN_from_montgomery %d * %d\n",nl,nl); +#endif + for (i=0; i<nl; i++) + { + v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2); + nrp++; + rp++; + if (((nrp[-1]+=v)&BN_MASK2) >= v) + continue; + else + { + if (((++nrp[0])&BN_MASK2) != 0) continue; + if (((++nrp[1])&BN_MASK2) != 0) continue; + for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ; + } + } + bn_fix_top(r); + + /* mont->ri will be a multiple of the word size */ +#if 0 + BN_rshift(ret,r,mont->ri); +#else + x=ri; + rp=ret->d; + ap= &(r->d[x]); + if (r->top < x) + al=0; + else + al=r->top-x; + ret->top=al; + al-=4; + for (i=0; i<al; i+=4) + { + BN_ULONG t1,t2,t3,t4; + + t1=ap[i+0]; + t2=ap[i+1]; + t3=ap[i+2]; + t4=ap[i+3]; + rp[i+0]=t1; + rp[i+1]=t2; + rp[i+2]=t3; + rp[i+3]=t4; + } + al+=4; + for (; i<al; i++) + rp[i]=ap[i]; +#endif + + if (BN_ucmp(ret, &(mont->N)) >= 0) + { + BN_usub(ret,ret,&(mont->N)); /* XXX */ + } + retn=1; +err1: + return(retn); + } +#ifdef BN_RECURSION_MONT + else /* bignum version */ + { + BIGNUM *t1,*t2,*t3; + int j,i; + +#ifdef BN_COUNT +printf("number BN_from_montgomery\n"); +#endif + + t1= &(ctx->bn[ctx->tos]); + t2= &(ctx->bn[ctx->tos+1]); + t3= &(ctx->bn[ctx->tos+2]); + + i=mont->Ni.top; + bn_wexpand(ret,i); /* perhaps only i*2 */ + bn_wexpand(t1,i*4); /* perhaps only i*2 */ + bn_wexpand(t2,i*2); /* perhaps only i */ + + bn_mul_low_recursive(t2->d,a->d,mont->Ni.d,i,t1->d); + + BN_zero(t3); + BN_set_bit(t3,mont->N.top*BN_BITS2); + bn_sub_words(t3->d,t3->d,a->d,i); + bn_mul_high(ret->d,t2->d,mont->N.d,t3->d,i,t1->d); + + /* hmm... if a is between i and 2*i, things are bad */ + if (a->top > i) + { + j=(int)(bn_add_words(ret->d,ret->d,&(a->d[i]),i)); + if (j) /* overflow */ + bn_sub_words(ret->d,ret->d,mont->N.d,i); + } + ret->top=i; + bn_fix_top(ret); + if (a->d[0]) + BN_add_word(ret,1); /* Always? */ + else /* Very very rare */ + { + for (i=1; i<mont->N.top-1; i++) + { + if (a->d[i]) + { + BN_add_word(ret,1); /* Always? */ + break; + } + } + } + + if (BN_ucmp(ret,&(mont->N)) >= 0) + BN_usub(ret,ret,&(mont->N)); + + return(1); + } +#endif + } + +BN_MONT_CTX *BN_MONT_CTX_new(void) + { + BN_MONT_CTX *ret; + + if ((ret=(BN_MONT_CTX *)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->use_word=0; + ctx->ri=0; + BN_init(&(ctx->RR)); + BN_init(&(ctx->N)); + BN_init(&(ctx->Ni)); + 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) + Free(mont); + } + +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) + { + BIGNUM Ri,*R; + + BN_init(&Ri); + R= &(mont->RR); /* grab RR as a temp */ + BN_copy(&(mont->N),mod); /* Set N */ + +#ifdef BN_RECURSION_MONT + if (mont->N.top < BN_MONT_CTX_SET_SIZE_WORD) +#endif + { + BIGNUM tmod; + BN_ULONG buf[2]; + + mont->use_word=1; + + mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; + BN_zero(R); + BN_set_bit(R,BN_BITS2); + /* I was bad, this modification of a passed variable was + * breaking the multithreaded stuff :-( + * z=mod->top; + * mod->top=1; */ + + buf[0]=mod->d[0]; + buf[1]=0; + tmod.d=buf; + tmod.top=1; + tmod.max=mod->max; + tmod.neg=mod->neg; + + if ((BN_mod_inverse(&Ri,R,&tmod,ctx)) == NULL) + goto err; + BN_lshift(&Ri,&Ri,BN_BITS2); /* R*Ri */ + if (!BN_is_zero(&Ri)) + { +#if 1 + BN_sub_word(&Ri,1); +#else + BN_usub(&Ri,&Ri,BN_value_one()); /* R*Ri - 1 */ +#endif + } + else + { + /* This is not common..., 1 in BN_MASK2, + * It happens when buf[0] was == 1. So for 8 bit, + * this is 1/256, 16bit, 1 in 2^16 etc. + */ + BN_set_word(&Ri,BN_MASK2); + } + BN_div(&Ri,NULL,&Ri,&tmod,ctx); + mont->n0=Ri.d[0]; + BN_free(&Ri); + /* mod->top=z; */ + } +#ifdef BN_RECURSION_MONT + else + { + mont->use_word=0; + mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; +#if 1 + BN_zero(R); + BN_set_bit(R,mont->ri); +#else + BN_lshift(R,BN_value_one(),mont->ri); /* R */ +#endif + if ((BN_mod_inverse(&Ri,R,mod,ctx)) == NULL) + goto err; + BN_lshift(&Ri,&Ri,mont->ri); /* R*Ri */ +#if 1 + BN_sub_word(&Ri,1); +#else + BN_usub(&Ri,&Ri,BN_value_one()); /* R*Ri - 1 */ +#endif + BN_div(&(mont->Ni),NULL,&Ri,mod,ctx); + BN_free(&Ri); + } +#endif + + /* setup RR for conversions */ +#if 1 + BN_zero(&(mont->RR)); + BN_set_bit(&(mont->RR),mont->ri*2); +#else + BN_lshift(mont->RR,BN_value_one(),mont->ri*2); +#endif + BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx); + + return(1); +err: + return(0); + } + +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) + { + if (to == from) return(to); + + BN_copy(&(to->RR),&(from->RR)); + BN_copy(&(to->N),&(from->N)); + BN_copy(&(to->Ni),&(from->Ni)); + to->use_word=from->use_word; + to->ri=from->ri; + to->n0=from->n0; + return(to); + } + diff --git a/lib/dns/sec/openssl/bn_mul.c b/lib/dns/sec/openssl/bn_mul.c new file mode 100644 index 00000000..38c47f3d --- /dev/null +++ b/lib/dns/sec/openssl/bn_mul.c @@ -0,0 +1,756 @@ +/* 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.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +#ifdef BN_RECURSION +/* 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 calulate + * 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_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, + BN_ULONG *t) + { + int n=n2/2,c1,c2; + unsigned int neg,zero; + BN_ULONG ln,lo,*p; + +#ifdef BN_COUNT +printf(" bn_mul_recursive %d * %d\n",n2,n2); +#endif +#ifdef BN_MUL_COMBA +/* if (n2 == 4) + { + bn_mul_comba4(r,a,b); + return; + } + else */ if (n2 == 8) + { + bn_mul_comba8(r,a,b); + return; + } +#endif + if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) + { + /* This should not happen */ + bn_mul_normal(r,a,n2,b,n2); + return; + } + /* r=(a[0]-a[1])*(b[1]-b[0]) */ + c1=bn_cmp_words(a,&(a[n]),n); + c2=bn_cmp_words(&(b[n]),b,n); + zero=neg=0; + switch (c1*3+c2) + { + case -4: + bn_sub_words(t, &(a[n]),a, n); /* - */ + bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ + break; + case -3: + zero=1; + break; + case -2: + bn_sub_words(t, &(a[n]),a, n); /* - */ + bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */ + neg=1; + break; + case -1: + case 0: + case 1: + zero=1; + break; + case 2: + bn_sub_words(t, a, &(a[n]),n); /* + */ + bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ + neg=1; + break; + case 3: + zero=1; + break; + case 4: + bn_sub_words(t, a, &(a[n]),n); + bn_sub_words(&(t[n]),&(b[n]),b, n); + break; + } + +#ifdef BN_MUL_COMBA + if (n == 4) + { + 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) + { + 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 + { + p= &(t[n2*2]); + if (!zero) + bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p); + else + memset(&(t[n2]),0,n2*sizeof(BN_ULONG)); + bn_mul_recursive(r,a,b,n,p); + bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,p); + } + + /* 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 */ +void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn, + int n, BN_ULONG *t) + { + int i,j,n2=n*2; + unsigned int c1; + BN_ULONG ln,lo,*p; + +#ifdef BN_COUNT +printf(" bn_mul_part_recursive %d * %d\n",tn+n,tn+n); +#endif + if (n < 8) + { + i=tn+n; + bn_mul_normal(r,a,i,b,i); + return; + } + + /* r=(a[0]-a[1])*(b[1]-b[0]) */ + bn_sub_words(t, a, &(a[n]),n); /* + */ + bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ + +/* 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 */ if (n == 8) + { + bn_mul_comba8(&(t[n2]),t,&(t[n])); + bn_mul_comba8(r,a,b); + bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn); + memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2)); + } + else + { + p= &(t[n2*2]); + bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p); + bn_mul_recursive(r,a,b,n,p); + i=n/2; + /* If there is only a bottom half to the number, + * just do it */ + j=tn-i; + if (j == 0) + { + bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),i,p); + memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2)); + } + else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */ + { + bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]), + j,i,p); + memset(&(r[n2+tn*2]),0, + sizeof(BN_ULONG)*(n2-tn*2)); + } + else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */ + { + memset(&(r[n2]),0,sizeof(BN_ULONG)*n2); + if (tn < BN_MUL_RECURSIVE_SIZE_NORMAL) + { + bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn); + } + else + { + for (;;) + { + i/=2; + if (i < tn) + { + bn_mul_part_recursive(&(r[n2]), + &(a[n]),&(b[n]), + tn-i,i,p); + break; + } + else if (i == tn) + { + bn_mul_recursive(&(r[n2]), + &(a[n]),&(b[n]), + 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)); + c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),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 < 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 +printf(" bn_mul_low_recursive %d * %d\n",n2,n2); +#endif + + bn_mul_recursive(r,a,b,n,&(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 +printf(" 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,&(t[n2])); + bn_mul_recursive(r,&(a[n]),&(b[n]),n,&(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 + +int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) + { + int top,al,bl; + BIGNUM *rr; +#ifdef BN_RECURSION + BIGNUM *t; + int i,j,k; +#endif + +#ifdef BN_COUNT +printf("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; + r->neg=a->neg^b->neg; + + if ((al == 0) || (bl == 0)) + { + BN_zero(r); + return(1); + } + top=al+bl; + + if ((r == a) || (r == b)) + rr= &(ctx->bn[ctx->tos+1]); + else + rr=r; + +#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) + if (al == bl) + { +# ifdef BN_MUL_COMBA +/* if (al == 4) + { + if (bn_wexpand(rr,8) == NULL) return(0); + rr->top=8; + bn_mul_comba4(rr->d,a->d,b->d); + goto end; + } + else */ if (al == 8) + { + if (bn_wexpand(rr,16) == NULL) return(0); + rr->top=16; + bn_mul_comba8(rr->d,a->d,b->d); + goto end; + } + else +# endif +#ifdef BN_RECURSION + if (al < BN_MULL_SIZE_NORMAL) +#endif + { + if (bn_wexpand(rr,top) == NULL) return(0); + rr->top=top; + bn_mul_normal(rr->d,a->d,al,b->d,bl); + goto end; + } +# ifdef BN_RECURSION + goto symetric; +# endif + } +#endif +#ifdef BN_RECURSION + else if ((al < BN_MULL_SIZE_NORMAL) || (bl < BN_MULL_SIZE_NORMAL)) + { + if (bn_wexpand(rr,top) == NULL) return(0); + rr->top=top; + bn_mul_normal(rr->d,a->d,al,b->d,bl); + goto end; + } + else + { + i=(al-bl); + if ((i == 1) && !BN_get_flags(b,BN_FLG_STATIC_DATA)) + { + bn_wexpand(b,al); + b->d[bl]=0; + bl++; + goto symetric; + } + else if ((i == -1) && !BN_get_flags(a,BN_FLG_STATIC_DATA)) + { + bn_wexpand(a,bl); + a->d[al]=0; + al++; + goto symetric; + } + } +#endif + + /* asymetric and >= 4 */ + if (bn_wexpand(rr,top) == NULL) return(0); + rr->top=top; + bn_mul_normal(rr->d,a->d,al,b->d,bl); + +#ifdef BN_RECURSION + if (0) + { +symetric: + /* symetric and > 4 */ + /* 16 or larger */ + j=BN_num_bits_word((BN_ULONG)al); + j=1<<(j-1); + k=j+j; + t= &(ctx->bn[ctx->tos]); + if (al == j) /* exact multiple */ + { + bn_wexpand(t,k*2); + bn_wexpand(rr,k*2); + bn_mul_recursive(rr->d,a->d,b->d,al,t->d); + } + else + { + bn_wexpand(a,k); + bn_wexpand(b,k); + bn_wexpand(t,k*4); + bn_wexpand(rr,k*4); + for (i=a->top; i<k; i++) + a->d[i]=0; + for (i=b->top; i<k; i++) + b->d[i]=0; + bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d); + } + rr->top=top; + } +#endif +#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) +end: +#endif + bn_fix_top(rr); + if (r != rr) BN_copy(r,rr); + return(1); + } + +void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) + { + BN_ULONG *rr; + +#ifdef BN_COUNT +printf(" bn_mul_normal %d * %d\n",na,nb); +#endif + + if (na < nb) + { + int itmp; + BN_ULONG *ltmp; + + itmp=na; na=nb; nb=itmp; + ltmp=a; a=b; b=ltmp; + + } + rr= &(r[na]); + 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 +printf(" 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/lib/dns/sec/openssl/bn_prime.c b/lib/dns/sec/openssl/bn_prime.c new file mode 100644 index 00000000..6fa0f9be --- /dev/null +++ b/lib/dns/sec/openssl/bn_prime.c @@ -0,0 +1,447 @@ +/* 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.] + */ + +#include <stdio.h> +#include <time.h> +#include "cryptlib.h" +#include "bn_lcl.h" +#include <openssl/rand.h> + +/* The quick seive 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 *a, BIGNUM *n, BN_CTX *ctx,BN_CTX *ctx2, + BN_MONT_CTX *mont); +static int probable_prime(BIGNUM *rnd, int bits); +static int probable_prime_dh(BIGNUM *rnd, int bits, + BIGNUM *add, BIGNUM *rem, BN_CTX *ctx); +static int probable_prime_dh_strong(BIGNUM *rnd, int bits, + BIGNUM *add, BIGNUM *rem, BN_CTX *ctx); +BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int strong, BIGNUM *add, + BIGNUM *rem, void (*callback)(int,int,void *), void *cb_arg) + { + BIGNUM *rnd=NULL; + BIGNUM t; + int i,j,c1=0; + BN_CTX *ctx; + + ctx=BN_CTX_new(); + if (ctx == NULL) goto err; + if (ret == NULL) + { + if ((rnd=BN_new()) == NULL) goto err; + } + else + rnd=ret; + BN_init(&t); +loop: + /* make a random number and set the top and bottom bits */ + if (add == NULL) + { + if (!probable_prime(rnd,bits)) goto err; + } + else + { + if (strong) + { + if (!probable_prime_dh_strong(rnd,bits,add,rem,ctx)) + goto err; + } + else + { + if (!probable_prime_dh(rnd,bits,add,rem,ctx)) + goto err; + } + } + /* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */ + if (callback != NULL) callback(0,c1++,cb_arg); + + if (!strong) + { + i=BN_is_prime(rnd,BN_prime_checks,callback,ctx,cb_arg); + if (i == -1) goto err; + if (i == 0) goto loop; + } + else + { + /* for a strong 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,rnd)) goto err; + + for (i=0; i<BN_prime_checks; i++) + { + j=BN_is_prime(rnd,1,callback,ctx,cb_arg); + if (j == -1) goto err; + if (j == 0) goto loop; + + j=BN_is_prime(&t,1,callback,ctx,cb_arg); + if (j == -1) goto err; + if (j == 0) goto loop; + + if (callback != NULL) callback(2,c1-1,cb_arg); + /* We have a strong prime test pass */ + } + } + /* we have a prime :-) */ + ret=rnd; +err: + if ((ret == NULL) && (rnd != NULL)) BN_free(rnd); + BN_free(&t); + if (ctx != NULL) BN_CTX_free(ctx); + return(ret); + } + +int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *), + BN_CTX *ctx_passed, void *cb_arg) + { + int i,j,c2=0,ret= -1; + BIGNUM *check; + BN_CTX *ctx=NULL,*ctx2=NULL; + BN_MONT_CTX *mont=NULL; + + if (!BN_is_odd(a)) + return(0); + if (ctx_passed != NULL) + ctx=ctx_passed; + else + if ((ctx=BN_CTX_new()) == NULL) goto err; + + if ((ctx2=BN_CTX_new()) == NULL) goto err; + if ((mont=BN_MONT_CTX_new()) == NULL) goto err; + + check= &(ctx->bn[ctx->tos++]); + + /* Setup the montgomery structure */ + if (!BN_MONT_CTX_set(mont,a,ctx2)) goto err; + + for (i=0; i<checks; i++) + { + if (!BN_rand(check,BN_num_bits(a)-1,0,0)) goto err; + j=witness(check,a,ctx,ctx2,mont); + if (j == -1) goto err; + if (j) + { + ret=0; + goto err; + } + if (callback != NULL) callback(1,c2++,cb_arg); + } + ret=1; +err: + ctx->tos--; + if ((ctx_passed == NULL) && (ctx != NULL)) + BN_CTX_free(ctx); + if (ctx2 != NULL) + BN_CTX_free(ctx2); + if (mont != NULL) BN_MONT_CTX_free(mont); + + return(ret); + } + +#define RECP_MUL_MOD + +static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx, BN_CTX *ctx2, + BN_MONT_CTX *mont) + { + int k,i,ret= -1,good; + BIGNUM *d,*dd,*tmp,*d1,*d2,*n1; + BIGNUM *mont_one,*mont_n1,*mont_a; + + d1= &(ctx->bn[ctx->tos]); + d2= &(ctx->bn[ctx->tos+1]); + n1= &(ctx->bn[ctx->tos+2]); + ctx->tos+=3; + + mont_one= &(ctx2->bn[ctx2->tos]); + mont_n1= &(ctx2->bn[ctx2->tos+1]); + mont_a= &(ctx2->bn[ctx2->tos+2]); + ctx2->tos+=3; + + d=d1; + dd=d2; + if (!BN_one(d)) goto err; + if (!BN_sub(n1,n,d)) goto err; /* n1=n-1; */ + k=BN_num_bits(n1); + + if (!BN_to_montgomery(mont_one,BN_value_one(),mont,ctx2)) goto err; + if (!BN_to_montgomery(mont_n1,n1,mont,ctx2)) goto err; + if (!BN_to_montgomery(mont_a,a,mont,ctx2)) goto err; + + BN_copy(d,mont_one); + for (i=k-1; i>=0; i--) + { + if ( (BN_cmp(d,mont_one) != 0) && + (BN_cmp(d,mont_n1) != 0)) + good=1; + else + good=0; + + BN_mod_mul_montgomery(dd,d,d,mont,ctx2); + + if (good && (BN_cmp(dd,mont_one) == 0)) + { + ret=1; + goto err; + } + if (BN_is_bit_set(n1,i)) + { + BN_mod_mul_montgomery(d,dd,mont_a,mont,ctx2); + } + else + { + tmp=d; + d=dd; + dd=tmp; + } + } + if (BN_cmp(d,mont_one) == 0) + i=0; + else i=1; + ret=i; +err: + ctx->tos-=3; + ctx2->tos-=3; + return(ret); + } + +static int probable_prime(BIGNUM *rnd, int bits) + { + int i; + MS_STATIC BN_ULONG mods[NUMPRIMES]; + BN_ULONG delta,d; + +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]=BN_mod_word(rnd,(BN_ULONG)primes[i]); + 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) + { + d=delta; + delta+=2; + /* perhaps need to check for overflow of + * delta (but delta can be upto 2^32) + * 21-May-98 eay - added overflow check */ + if (delta < d) goto again; + goto loop; + } + } + if (!BN_add_word(rnd,delta)) return(0); + return(1); + } + +static int probable_prime_dh(BIGNUM *rnd, int bits, BIGNUM *add, BIGNUM *rem, + BN_CTX *ctx) + { + int i,ret=0; + BIGNUM *t1; + + t1= &(ctx->bn[ctx->tos++]); + + 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: + ctx->tos--; + return(ret); + } + +static int probable_prime_dh_strong(BIGNUM *p, int bits, BIGNUM *padd, + BIGNUM *rem, BN_CTX *ctx) + { + int i,ret=0; + BIGNUM *t1,*qadd=NULL,*q=NULL; + + bits--; + t1= &(ctx->bn[ctx->tos++]); + q= &(ctx->bn[ctx->tos++]); + qadd= &(ctx->bn[ctx->tos++]); + + 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: + ctx->tos-=3; + return(ret); + } + +#if 0 +static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx) + { + int k,i,nb,ret= -1; + BIGNUM *d,*dd,*tmp; + BIGNUM *d1,*d2,*x,*n1,*inv; + + d1= &(ctx->bn[ctx->tos]); + d2= &(ctx->bn[ctx->tos+1]); + x= &(ctx->bn[ctx->tos+2]); + n1= &(ctx->bn[ctx->tos+3]); + inv=&(ctx->bn[ctx->tos+4]); + ctx->tos+=5; + + d=d1; + dd=d2; + if (!BN_one(d)) goto err; + if (!BN_sub(n1,n,d)) goto err; /* n1=n-1; */ + k=BN_num_bits(n1); + + /* i=BN_num_bits(n); */ +#ifdef RECP_MUL_MOD + nb=BN_reciprocal(inv,n,ctx); /**/ + if (nb == -1) goto err; +#endif + + for (i=k-1; i>=0; i--) + { + if (BN_copy(x,d) == NULL) goto err; +#ifndef RECP_MUL_MOD + if (!BN_mod_mul(dd,d,d,n,ctx)) goto err; +#else + if (!BN_mod_mul_reciprocal(dd,d,d,n,inv,nb,ctx)) goto err; +#endif + if ( BN_is_one(dd) && + !BN_is_one(x) && + (BN_cmp(x,n1) != 0)) + { + ret=1; + goto err; + } + if (BN_is_bit_set(n1,i)) + { +#ifndef RECP_MUL_MOD + if (!BN_mod_mul(d,dd,a,n,ctx)) goto err; +#else + if (!BN_mod_mul_reciprocal(d,dd,a,n,inv,nb,ctx)) goto err; +#endif + } + else + { + tmp=d; + d=dd; + dd=tmp; + } + } + if (BN_is_one(d)) + i=0; + else i=1; + ret=i; +err: + ctx->tos-=5; + return(ret); + } +#endif diff --git a/lib/dns/sec/openssl/bn_prime.h b/lib/dns/sec/openssl/bn_prime.h new file mode 100644 index 00000000..6fce0210 --- /dev/null +++ b/lib/dns/sec/openssl/bn_prime.h @@ -0,0 +1,325 @@ +/* crypto/bn/bn_prime.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 EIGHT_BIT +#define NUMPRIMES 2048 +#else +#define NUMPRIMES 54 +#endif +static unsigned int 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/lib/dns/sec/openssl/bn_print.c b/lib/dns/sec/openssl/bn_print.c new file mode 100644 index 00000000..c5469f9e --- /dev/null +++ b/lib/dns/sec/openssl/bn_print.c @@ -0,0 +1,327 @@ +/* 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 'Free' the returned data */ +char *BN_bn2hex(const BIGNUM *a) + { + int i,j,v,z=0; + char *buf; + char *p; + + buf=(char *)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 (a->top == 0) *(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); + } + +#if 0 +/* Must 'Free' the returned data */ +char *BN_bn2dec(const BIGNUM *a) + { + int i=0,num; + char *buf=NULL; + char *p; + BIGNUM *t=NULL; + BN_ULONG *bn_data=NULL,*lp; + + i=BN_num_bits(a)*3; + num=(i/10+i/1000+3)+1; + bn_data=(BN_ULONG *)Malloc((num/BN_DEC_NUM+1)*sizeof(BN_ULONG)); + buf=(char *)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; + + p=buf; + lp=bn_data; + if (t->neg) *(p++)='-'; + if (t->top == 0) + { + *(p++)='0'; + *(p++)='\0'; + } + else + { + 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 trucation. + * The blocks need to be reversed in order. */ + sprintf(p,BN_DEC_FMT1,*lp); + while (*p) p++; + while (lp != bn_data) + { + lp--; + sprintf(p,BN_DEC_FMT2,*lp); + while (*p) p++; + } + } +err: + if (bn_data != NULL) Free(bn_data); + if (t != NULL) BN_free(t); + return(buf); + } +#endif + +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 digets, 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 significate '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_fix_top(ret); + ret->neg=neg; + + *bn=ret; + return(num); +err: + if (*bn == NULL) BN_free(ret); + return(0); + } + +#if 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 digets, and it is 'i' long. + * We chop it into BN_DEC_NUM digets 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_fix_top(ret); + *bn=ret; + return(num); +err: + if (*bn == NULL) BN_free(ret); + return(0); + } +#endif + +#ifndef NO_BIO + +#ifndef NO_FP_API +int BN_print_fp(FILE *fp, 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 ((a->top == 0) && (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 diff --git a/lib/dns/sec/openssl/bn_rand.c b/lib/dns/sec/openssl/bn_rand.c new file mode 100644 index 00000000..91b8e34a --- /dev/null +++ b/lib/dns/sec/openssl/bn_rand.c @@ -0,0 +1,117 @@ +/* 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.] + */ + +#include <stdio.h> +#include <time.h> +#include "cryptlib.h" +#include "bn_lcl.h" +#include <openssl/rand.h> + +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) + { + unsigned char *buf=NULL; + int ret=0,bit,bytes,mask; + time_t tim; + + bytes=(bits+7)/8; + bit=(bits-1)%8; + mask=0xff<<bit; + + buf=(unsigned char *)Malloc(bytes); + if (buf == NULL) + { + BNerr(BN_F_BN_RAND,ERR_R_MALLOC_FAILURE); + goto err; + } + + /* make a random number and set the top and bottom bits */ + time(&tim); + RAND_seed(&tim,sizeof(tim)); + + RAND_bytes(buf,(int)bytes); + if (top) + { + if (bit == 0) + { + buf[0]=1; + buf[1]|=0x80; + } + else + { + buf[0]|=(3<<(bit-1)); + buf[0]&= ~(mask<<1); + } + } + else + { + buf[0]|=(1<<bit); + buf[0]&= ~(mask<<1); + } + if (bottom) /* set bottom bits to whatever odd is */ + buf[bytes-1]|=1; + if (!BN_bin2bn(buf,bytes,rnd)) goto err; + ret=1; +err: + if (buf != NULL) + { + memset(buf,0,bytes); + Free(buf); + } + return(ret); + } + diff --git a/lib/dns/sec/openssl/bn_recp.c b/lib/dns/sec/openssl/bn_recp.c new file mode 100644 index 00000000..9419ce02 --- /dev/null +++ b/lib/dns/sec/openssl/bn_recp.c @@ -0,0 +1,228 @@ +/* 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 *)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) + Free(recp); + } + +int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx) + { + ctx = ctx; /* BEW - quiet the compiler */ + BN_copy(&(recp->N),d); + BN_zero(&(recp->Nr)); + recp->num_bits=BN_num_bits(d); + recp->shift=0; + return(1); + } + +int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp, + BN_CTX *ctx) + { + int ret=0; + BIGNUM *a; + + a= &(ctx->bn[ctx->tos++]); + if (y != NULL) + { + if (x == y) + { if (!BN_sqr(a,x,ctx)) goto err; } + else + { if (!BN_mul(a,x,y,ctx)) goto err; } + } + else + a=x; /* Just do the mod */ + + BN_div_recp(NULL,r,a,recp,ctx); + ret=1; +err: + ctx->tos--; + return(ret); + } + +int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp, + BN_CTX *ctx) + { + int i,j,tos,ret=0,ex; + BIGNUM *a,*b,*d,*r; + + tos=ctx->tos; + a= &(ctx->bn[ctx->tos++]); + b= &(ctx->bn[ctx->tos++]); + if (dv != NULL) + d=dv; + else + d= &(ctx->bn[ctx->tos++]); + if (rem != NULL) + r=rem; + else + r= &(ctx->bn[ctx->tos++]); + + if (BN_ucmp(m,&(recp->N)) < 0) + { + BN_zero(d); + BN_copy(r,m); + ctx->tos=tos; + return(1); + } + + /* We want the remainder + * Given input of ABCDEF / ab + * we need multiply ABCDEF by 3 digests of the reciprocal of ab + * + */ + i=BN_num_bits(m); + + j=recp->num_bits*2; + if (j > i) + { + i=j; + ex=0; + } + else + { + ex=(i-j)/2; + } + + j=i/2; + + if (i != recp->shift) + recp->shift=BN_reciprocal(&(recp->Nr),&(recp->N), + i,ctx); + + if (!BN_rshift(a,m,j-ex)) goto err; + if (!BN_mul(b,a,&(recp->Nr),ctx)) goto err; + if (!BN_rshift(d,b,j+ex)) 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; + + j=0; +#if 1 + while (BN_ucmp(r,&(recp->N)) >= 0) + { + if (j++ > 2) + { + BNerr(BN_F_BN_MOD_MUL_RECIPROCAL,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: + ctx->tos=tos; + 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. + */ +int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx) + { + int ret= -1; + BIGNUM t; + + BN_init(&t); + + BN_zero(&t); + if (!BN_set_bit(&t,len)) goto err; + + if (!BN_div(r,NULL,&t,m,ctx)) goto err; + ret=len; +err: + BN_free(&t); + return(ret); + } + diff --git a/lib/dns/sec/openssl/bn_shift.c b/lib/dns/sec/openssl/bn_shift.c new file mode 100644 index 00000000..61aae65a --- /dev/null +++ b/lib/dns/sec/openssl/bn_shift.c @@ -0,0 +1,200 @@ +/* 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, BIGNUM *a) + { + register BN_ULONG *ap,*rp,t,c; + int i; + + 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++; + } + return(1); + } + +int BN_rshift1(BIGNUM *r, BIGNUM *a) + { + BN_ULONG *ap,*rp,t,c; + int i; + + if (BN_is_zero(a)) + { + BN_zero(r); + return(1); + } + if (a != r) + { + if (bn_wexpand(r,a->top) == NULL) return(0); + r->top=a->top; + r->neg=a->neg; + } + ap=a->d; + rp=r->d; + c=0; + for (i=a->top-1; i>=0; i--) + { + t=ap[i]; + rp[i]=((t>>1)&BN_MASK2)|c; + c=(t&1)?BN_TBIT:0; + } + bn_fix_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; + + r->neg=a->neg; + if (bn_wexpand(r,a->top+(n/BN_BITS2)+1) == NULL) return(0); + nw=n/BN_BITS2; + 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_fix_top(r); + return(1); + } + +int BN_rshift(BIGNUM *r, BIGNUM *a, int n) + { + int i,j,nw,lb,rb; + BN_ULONG *t,*f; + BN_ULONG l,tmp; + + nw=n/BN_BITS2; + rb=n%BN_BITS2; + lb=BN_BITS2-rb; + if (nw > a->top) + { + BN_zero(r); + return(1); + } + if (r != a) + { + r->neg=a->neg; + if (bn_wexpand(r,a->top-nw+1) == NULL) return(0); + } + + f= &(a->d[nw]); + t=r->d; + j=a->top-nw; + r->top=j; + + if (rb == 0) + { + for (i=j+1; i > 0; i--) + *(t++)= *(f++); + } + else + { + l= *(f++); + for (i=1; i<j; i++) + { + tmp =(l>>rb)&BN_MASK2; + l= *(f++); + *(t++) =(tmp|(l<<lb))&BN_MASK2; + } + *(t++) =(l>>rb)&BN_MASK2; + } + *t=0; + bn_fix_top(r); + return(1); + } diff --git a/lib/dns/sec/openssl/bn_sqr.c b/lib/dns/sec/openssl/bn_sqr.c new file mode 100644 index 00000000..12cce4d7 --- /dev/null +++ b/lib/dns/sec/openssl/bn_sqr.c @@ -0,0 +1,281 @@ +/* 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, BIGNUM *a, BN_CTX *ctx) + { + int max,al; + BIGNUM *tmp,*rr; + +#ifdef BN_COUNT +printf("BN_sqr %d * %d\n",a->top,a->top); +#endif + bn_check_top(a); + tmp= &(ctx->bn[ctx->tos]); + rr=(a != r)?r: (&ctx->bn[ctx->tos+1]); + + al=a->top; + if (al <= 0) + { + r->top=0; + return(1); + } + + max=(al+al); + if (bn_wexpand(rr,max+1) == NULL) return(0); + + r->neg=0; + 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(a,k*2) == NULL) return(0); + if (bn_wexpand(tmp,k*2) == NULL) return(0); + bn_sqr_recursive(rr->d,a->d,al,tmp->d); + } + else + { + if (bn_wexpand(tmp,max) == NULL) return(0); + bn_sqr_normal(rr->d,a->d,al,tmp->d); + } + } +#else + if (bn_wexpand(tmp,max) == NULL) return(0); + bn_sqr_normal(rr->d,a->d,al,tmp->d); +#endif + } + + rr->top=max; + if ((max > 0) && (rr->d[max-1] == 0)) rr->top--; + if (rr != r) BN_copy(r,rr); + return(1); + } + +/* tmp must have 2*n words */ +void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp) + { + int i,j,max; + BN_ULONG *ap,*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. + * n must be a power of 2. + * We multiply and return the result. + * t must be 2*n words in size + * We calulate + * 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, BN_ULONG *a, int n2, BN_ULONG *t) + { + int n=n2/2; + int zero,c1; + BN_ULONG ln,lo,*p; + +#ifdef BN_COUNT +printf(" 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,n*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/lib/dns/sec/openssl/bn_word.c b/lib/dns/sec/openssl/bn_word.c new file mode 100644 index 00000000..c0cfbc67 --- /dev/null +++ b/lib/dns/sec/openssl/bn_word.c @@ -0,0 +1,194 @@ +/* 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(BIGNUM *a, BN_ULONG w) + { +#ifndef BN_LLONG + BN_ULONG ret=0; +#else + BN_ULLONG ret=0; +#endif + int i; + + 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; + int i; + + if (a->top == 0) return(0); + ret=0; + w&=BN_MASK2; + 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--; + return(ret); + } + +int BN_add_word(BIGNUM *a, BN_ULONG w) + { + BN_ULONG l; + int i; + + if (a->neg) + { + a->neg=0; + i=BN_sub_word(a,w); + if (!BN_is_zero(a)) + a->neg=1; + return(i); + } + w&=BN_MASK2; + if (bn_wexpand(a,a->top+1) == NULL) return(0); + i=0; + for (;;) + { + l=(a->d[i]+(BN_ULONG)w)&BN_MASK2; + a->d[i]=l; + if (w > l) + w=1; + else + break; + i++; + } + if (i >= a->top) + a->top++; + return(1); + } + +int BN_sub_word(BIGNUM *a, BN_ULONG w) + { + int i; + + if (a->neg) + { + a->neg=0; + i=BN_add_word(a,w); + a->neg=1; + return(i); + } + + w&=BN_MASK2; + 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--; + return(1); + } + +int BN_mul_word(BIGNUM *a, BN_ULONG w) + { + BN_ULONG ll; + + w&=BN_MASK2; + if (a->top) + { + 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; + } + } + return(1); + } + diff --git a/lib/dns/sec/openssl/buffer.c b/lib/dns/sec/openssl/buffer.c new file mode 100644 index 00000000..c3a108ea --- /dev/null +++ b/lib/dns/sec/openssl/buffer.c @@ -0,0 +1,144 @@ +/* crypto/buffer/buffer.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 <openssl/buffer.h> + +BUF_MEM *BUF_MEM_new(void) + { + BUF_MEM *ret; + + ret=Malloc(sizeof(BUF_MEM)); + if (ret == NULL) + { + BUFerr(BUF_F_BUF_MEM_NEW,ERR_R_MALLOC_FAILURE); + return(NULL); + } + ret->length=0; + ret->max=0; + ret->data=NULL; + return(ret); + } + +void BUF_MEM_free(BUF_MEM *a) + { + if(a == NULL) + return; + + if (a->data != NULL) + { + memset(a->data,0,(unsigned int)a->max); + Free(a->data); + } + Free(a); + } + +int BUF_MEM_grow(BUF_MEM *str, int len) + { + char *ret; + unsigned int n; + + if (str->length >= len) + { + str->length=len; + return(len); + } + if (str->max >= len) + { + memset(&str->data[str->length],0,len-str->length); + str->length=len; + return(len); + } + n=(len+3)/3*4; + if (str->data == NULL) + ret=Malloc(n); + else + ret=Realloc(str->data,n); + if (ret == NULL) + { + BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); + len=0; + } + else + { + str->data=ret; + str->length=len; + str->max=n; + } + return(len); + } + +char *BUF_strdup(const char *str) + { + char *ret; + int n; + + if (str == NULL) return(NULL); + + n=strlen(str); + ret=Malloc(n+1); + if (ret == NULL) + { + BUFerr(BUF_F_BUF_STRDUP,ERR_R_MALLOC_FAILURE); + return(NULL); + } + memcpy(ret,str,n+1); + return(ret); + } + diff --git a/lib/dns/sec/openssl/cryptlib.c b/lib/dns/sec/openssl/cryptlib.c new file mode 100644 index 00000000..be5e68eb --- /dev/null +++ b/lib/dns/sec/openssl/cryptlib.c @@ -0,0 +1,296 @@ +/* crypto/cryptlib.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 <string.h> +#include "cryptlib.h" +#include <openssl/crypto.h> +/*#include "date.h"*/ + +#if defined(WIN32) || defined(WIN16) +static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */ +#endif + +/* real #defines in crypto.h, keep these upto date */ +static const char* lock_names[CRYPTO_NUM_LOCKS] = + { + "<<ERROR>>", + "err", + "err_hash", + "x509", + "x509_info", + "x509_pkey", + "x509_crl", + "x509_req", + "dsa", + "rsa", + "evp_pkey", + "x509_store", + "ssl_ctx", + "ssl_cert", + "ssl_session", + "ssl_sess_cert", + "ssl", + "rand", + "debug_malloc", + "BIO", + "gethostbyname", + "getservbyname", + "readdir", + "RSA_blinding", +#if CRYPTO_NUM_LOCKS != 24 +# error "Inconsistency between crypto.h and cryptlib.c" +#endif + }; + +static STACK *app_locks=NULL; + +static void (MS_FAR *locking_callback)(int mode,int type, + const char *file,int line)=NULL; +static int (MS_FAR *add_lock_callback)(int *pointer,int amount, + int type,const char *file,int line)=NULL; +static unsigned long (MS_FAR *id_callback)(void)=NULL; +int CRYPTO_get_new_lockid(char *name) + { + char *str; + int i; + + /* A hack to make Visual C++ 5.0 work correctly when linking as + * a DLL using /MT. Without this, the application cannot use + * and floating point printf's. + * It also seems to be needed for Visual C 1.5 (win16) */ +#if defined(WIN32) || defined(WIN16) + SSLeay_MSVC5_hack=(double)name[0]*(double)name[1]; +#endif + + if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL)) + { + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); + return(0); + } + if ((str=BUF_strdup(name)) == NULL) + return(0); + i=sk_push(app_locks,str); + if (!i) + Free(str); + else + i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */ + return(i); + } + +void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file, + int line) + { + return(locking_callback); + } + +int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type, + const char *file,int line) + { + return(add_lock_callback); + } + +void CRYPTO_set_locking_callback(void (*func)(int mode,int type, + const char *file,int line)) + { + locking_callback=func; + } + +void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type, + const char *file,int line)) + { + add_lock_callback=func; + } + +unsigned long (*CRYPTO_get_id_callback(void))(void) + { + return(id_callback); + } + +void CRYPTO_set_id_callback(unsigned long (*func)(void)) + { + id_callback=func; + } + +unsigned long CRYPTO_thread_id(void) + { + unsigned long ret=0; + + if (id_callback == NULL) + { +#ifdef WIN16 + ret=(unsigned long)GetCurrentTask(); +#elif defined(WIN32) + ret=(unsigned long)GetCurrentThreadId(); +#elif defined(MSDOS) + ret=1L; +#else + ret=(unsigned long)getpid(); +#endif + } + else + ret=id_callback(); + return(ret); + } + +void CRYPTO_lock(int mode, int type, const char *file, int line) + { +#ifdef LOCK_DEBUG + { + char *rw_text,*operation_text; + + if (mode & CRYPTO_LOCK) + operation_text="lock "; + else if (mode & CRYPTO_UNLOCK) + operation_text="unlock"; + else + operation_text="ERROR "; + + if (mode & CRYPTO_READ) + rw_text="r"; + else if (mode & CRYPTO_WRITE) + rw_text="w"; + else + rw_text="ERROR"; + + fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n", + CRYPTO_thread_id(), rw_text, operation_text, + CRYPTO_get_lock_name(type), file, line); + } +#endif + if (locking_callback != NULL) + locking_callback(mode,type,file,line); + } + +int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, + int line) + { + int ret; + + if (add_lock_callback != NULL) + { +#ifdef LOCK_DEBUG + int before= *pointer; +#endif + + ret=add_lock_callback(pointer,amount,type,file,line); +#ifdef LOCK_DEBUG + fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", + CRYPTO_thread_id(), + before,amount,ret, + CRYPTO_get_lock_name(type), + file,line); +#endif + *pointer=ret; + } + else + { + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line); + + ret= *pointer+amount; +#ifdef LOCK_DEBUG + fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", + CRYPTO_thread_id(), + *pointer,amount,ret, + CRYPTO_get_lock_name(type), + file,line); +#endif + *pointer=ret; + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line); + } + return(ret); + } + +const char *CRYPTO_get_lock_name(int type) + { + if (type < 0) + return("ERROR"); + else if (type < CRYPTO_NUM_LOCKS) + return(lock_names[type]); + else if (type-CRYPTO_NUM_LOCKS >= sk_num(app_locks)) + return("ERROR"); + else + return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS)); + } + +#ifdef _DLL +#ifdef WIN32 + +/* All we really need to do is remove the 'error' state when a thread + * detaches */ + +BOOL WINAPI DLLEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, + LPVOID lpvReserved) + { + switch(fdwReason) + { + case DLL_PROCESS_ATTACH: + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + ERR_remove_state(0); + break; + case DLL_PROCESS_DETACH: + break; + } + return(TRUE); + } +#endif + +#endif diff --git a/lib/dns/sec/openssl/cryptlib.h b/lib/dns/sec/openssl/cryptlib.h new file mode 100644 index 00000000..e3d38524 --- /dev/null +++ b/lib/dns/sec/openssl/cryptlib.h @@ -0,0 +1,96 @@ +/* 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> + +#ifdef __cplusplus +extern "C" { +#endif + +#include "openssl/e_os.h" + +#include <openssl/crypto.h> +#include <openssl/buffer.h> +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/opensslconf.h> + +#ifndef 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" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/openssl/dh_err.c b/lib/dns/sec/openssl/dh_err.c new file mode 100644 index 00000000..0348bd24 --- /dev/null +++ b/lib/dns/sec/openssl/dh_err.c @@ -0,0 +1,98 @@ +/* crypto/dh/dh_err.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). + * + */ + +/* 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. + */ + +#include <stdio.h> +#include <openssl/err.h> +#include <openssl/dh.h> + +/* BEGIN ERROR CODES */ +#ifndef NO_ERR +static ERR_STRING_DATA DH_str_functs[]= + { +{ERR_PACK(0,DH_F_DHPARAMS_PRINT,0), "DHparams_print"}, +{ERR_PACK(0,DH_F_DHPARAMS_PRINT_FP,0), "DHparams_print_fp"}, +{ERR_PACK(0,DH_F_DH_COMPUTE_KEY,0), "DH_compute_key"}, +{ERR_PACK(0,DH_F_DH_GENERATE_KEY,0), "DH_generate_key"}, +{ERR_PACK(0,DH_F_DH_GENERATE_PARAMETERS,0), "DH_generate_parameters"}, +{ERR_PACK(0,DH_F_DH_NEW,0), "DH_new"}, +{0,NULL} + }; + +static ERR_STRING_DATA DH_str_reasons[]= + { +{DH_R_NO_PRIVATE_VALUE ,"no private value"}, +{0,NULL} + }; + +#endif + +void ERR_load_DH_strings(void) + { + static int init=1; + + if (init) + { + init=0; +#ifndef NO_ERR + ERR_load_strings(ERR_LIB_DH,DH_str_functs); + ERR_load_strings(ERR_LIB_DH,DH_str_reasons); +#endif + + } + } diff --git a/lib/dns/sec/openssl/dh_gen.c b/lib/dns/sec/openssl/dh_gen.c new file mode 100644 index 00000000..b7bcd2c7 --- /dev/null +++ b/lib/dns/sec/openssl/dh_gen.c @@ -0,0 +1,148 @@ +/* crypto/dh/dh_gen.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 <openssl/bn.h> +#include <openssl/dh.h> + +/* We generate DH parameters as follows + * find a prime q which is prime_len/2 bits long. + * p=(2*q)+1 or (p-1)/2 = q + * For this case, g is a generator if + * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1. + * Since the factors of p-1 are q and 2, we just need to check + * g^2 mod p != 1 and g^q mod p != 1. + * + * Having said all that, + * there is another special case method for the generators 2, 3 and 5. + * for 2, p mod 24 == 11 + * for 3, p mod 12 == 5 <<<<< does not work for strong primes. + * for 5, p mod 10 == 3 or 7 + * + * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the + * special generators and for answering some of my questions. + * + * I've implemented the second simple method :-). + * Since DH should be using a strong prime (both p and q are prime), + * this generator function can take a very very long time to run. + */ + +DH *DH_generate_parameters(int prime_len, int generator, + void (*callback)(int,int,void *), void *cb_arg) + { + BIGNUM *p=NULL,*t1,*t2; + DH *ret=NULL; + int g,ok= -1; + BN_CTX *ctx=NULL; + + ret=DH_new(); + if (ret == NULL) goto err; + ctx=BN_CTX_new(); + if (ctx == NULL) goto err; + t1= &(ctx->bn[0]); + t2= &(ctx->bn[1]); + ctx->tos=2; + + if (generator == DH_GENERATOR_2) + { + BN_set_word(t1,24); + BN_set_word(t2,11); + g=2; + } +#ifdef undef /* does not work for strong primes */ + else if (generator == DH_GENERATOR_3) + { + BN_set_word(t1,12); + BN_set_word(t2,5); + g=3; + } +#endif + else if (generator == DH_GENERATOR_5) + { + BN_set_word(t1,10); + BN_set_word(t2,3); + /* BN_set_word(t3,7); just have to miss + * out on these ones :-( */ + g=5; + } + else + g=generator; + + p=BN_generate_prime(NULL,prime_len,1,t1,t2,callback,cb_arg); + if (p == NULL) goto err; + if (callback != NULL) callback(3,0,cb_arg); + ret->p=p; + ret->g=BN_new(); + if (!BN_set_word(ret->g,g)) goto err; + ok=1; +err: + if (ok == -1) + { + DHerr(DH_F_DH_GENERATE_PARAMETERS,ERR_R_BN_LIB); + ok=0; + } + + if (ctx != NULL) BN_CTX_free(ctx); + if (!ok && (ret != NULL)) + { + DH_free(ret); + ret=NULL; + } + return(ret); + } diff --git a/lib/dns/sec/openssl/dh_key.c b/lib/dns/sec/openssl/dh_key.c new file mode 100644 index 00000000..cede53bf --- /dev/null +++ b/lib/dns/sec/openssl/dh_key.c @@ -0,0 +1,154 @@ +/* crypto/dh/dh_key.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 <openssl/bn.h> +#include <openssl/rand.h> +#include <openssl/dh.h> + +int DH_generate_key(DH *dh) + { + int ok=0; + unsigned int i; + BN_CTX ctx; + BN_MONT_CTX *mont; + BIGNUM *pub_key=NULL,*priv_key=NULL; + + BN_CTX_init(&ctx); + + if (dh->priv_key == NULL) + { + i=dh->length; + if (i == 0) + { + /* Make the number p-1 bits long */ + i=BN_num_bits(dh->p)-1; + } + priv_key=BN_new(); + if (priv_key == NULL) goto err; + if (!BN_rand(priv_key,i,0,0)) goto err; + } + else + priv_key=dh->priv_key; + + if (dh->pub_key == NULL) + { + pub_key=BN_new(); + if (pub_key == NULL) goto err; + } + else + pub_key=dh->pub_key; + + if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P)) + { + if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL) + if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p, + dh->p,&ctx)) goto err; + } + mont=(BN_MONT_CTX *)dh->method_mont_p; + + if (!BN_mod_exp_mont(pub_key,dh->g,priv_key,dh->p,&ctx,mont)) goto err; + + dh->pub_key=pub_key; + dh->priv_key=priv_key; + ok=1; +err: + if (ok != 1) + DHerr(DH_F_DH_GENERATE_KEY,ERR_R_BN_LIB); + + if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key); + if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key); + BN_CTX_free(&ctx); + return(ok); + } + +int DH_compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh) + { + BN_CTX ctx; + BN_MONT_CTX *mont; + BIGNUM *tmp; + int ret= -1; + + BN_CTX_init(&ctx); + tmp= &(ctx.bn[ctx.tos++]); + + if (dh->priv_key == NULL) + { + DHerr(DH_F_DH_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE); + goto err; + } + if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P)) + { + if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL) + if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p, + dh->p,&ctx)) goto err; + } + + mont=(BN_MONT_CTX *)dh->method_mont_p; + if (!BN_mod_exp_mont(tmp,pub_key,dh->priv_key,dh->p,&ctx,mont)) + { + DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB); + goto err; + } + + ret=BN_bn2bin(tmp,key); +err: + BN_CTX_free(&ctx); + return(ret); + } diff --git a/lib/dns/sec/openssl/dh_lib.c b/lib/dns/sec/openssl/dh_lib.c new file mode 100644 index 00000000..61e0720e --- /dev/null +++ b/lib/dns/sec/openssl/dh_lib.c @@ -0,0 +1,103 @@ +/* crypto/dh/dh_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.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/bn.h> +#include <openssl/dh.h> + +const char *DH_version="Diffie-Hellman" OPENSSL_VERSION_PTEXT; + +DH *DH_new(void) + { + DH *ret; + + ret=(DH *)Malloc(sizeof(DH)); + if (ret == NULL) + { + DHerr(DH_F_DH_NEW,ERR_R_MALLOC_FAILURE); + return(NULL); + } + ret->pad=0; + ret->version=0; + ret->p=NULL; + ret->g=NULL; + ret->length=0; + ret->pub_key=NULL; + ret->priv_key=NULL; + ret->flags=DH_FLAG_CACHE_MONT_P; + ret->method_mont_p=NULL; + return(ret); + } + +void DH_free(DH *r) + { + if(r == NULL) return; + if (r->p != NULL) BN_clear_free(r->p); + if (r->g != NULL) BN_clear_free(r->g); + if (r->pub_key != NULL) BN_clear_free(r->pub_key); + if (r->priv_key != NULL) BN_clear_free(r->priv_key); + if (r->method_mont_p != NULL) + BN_MONT_CTX_free((BN_MONT_CTX *)r->method_mont_p); + Free(r); + } + +int DH_size(DH *dh) + { + return(BN_num_bytes(dh->p)); + } diff --git a/lib/dns/sec/openssl/dsa_asn1.c b/lib/dns/sec/openssl/dsa_asn1.c new file mode 100644 index 00000000..3bc02163 --- /dev/null +++ b/lib/dns/sec/openssl/dsa_asn1.c @@ -0,0 +1,99 @@ +/* crypto/dsa/dsa_asn1.c */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/dsa.h> +/*#include <openssl/asn1.h>*/ +/*#include <openssl/asn1_mac.h>*/ + +DSA_SIG *DSA_SIG_new(void) +{ + DSA_SIG *ret; + + ret = Malloc(sizeof(DSA_SIG)); + if (ret == NULL) + { + DSAerr(DSA_F_DSA_SIG_NEW,ERR_R_MALLOC_FAILURE); + return(NULL); + } + ret->r = NULL; + ret->s = NULL; + return(ret); +} + +void DSA_SIG_free(DSA_SIG *r) +{ + if (r == NULL) return; + if (r->r) BN_clear_free(r->r); + if (r->s) BN_clear_free(r->s); + Free(r); +} + +#if 0 +/* BEW */ +int i2d_DSA_SIG(DSA_SIG *v, unsigned char **pp) +{ + int t=0,len; + ASN1_INTEGER rbs,sbs; + unsigned char *p; + + rbs.data=Malloc(BN_num_bits(v->r)/8+1); + if (rbs.data == NULL) + { + DSAerr(DSA_F_I2D_DSA_SIG, ERR_R_MALLOC_FAILURE); + return(0); + } + rbs.type=V_ASN1_INTEGER; + rbs.length=BN_bn2bin(v->r,rbs.data); + sbs.data=Malloc(BN_num_bits(v->s)/8+1); + if (sbs.data == NULL) + { + Free(rbs.data); + DSAerr(DSA_F_I2D_DSA_SIG, ERR_R_MALLOC_FAILURE); + return(0); + } + sbs.type=V_ASN1_INTEGER; + sbs.length=BN_bn2bin(v->s,sbs.data); + + len=i2d_ASN1_INTEGER(&rbs,NULL); + len+=i2d_ASN1_INTEGER(&sbs,NULL); + + if (pp) + { + p=*pp; + ASN1_put_object(&p,1,len,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL); + i2d_ASN1_INTEGER(&rbs,&p); + i2d_ASN1_INTEGER(&sbs,&p); + } + t=ASN1_object_size(1,len,V_ASN1_SEQUENCE); + Free(rbs.data); + Free(sbs.data); + return(t); +} + +DSA_SIG *d2i_DSA_SIG(DSA_SIG **a, unsigned char **pp, long length) +{ + int i=ERR_R_NESTED_ASN1_ERROR; + ASN1_INTEGER *bs=NULL; + M_ASN1_D2I_vars(a,DSA_SIG *,DSA_SIG_new); + + M_ASN1_D2I_Init(); + M_ASN1_D2I_start_sequence(); + M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER); + if ((ret->r=BN_bin2bn(bs->data,bs->length,ret->r)) == NULL) + goto err_bn; + M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER); + if ((ret->s=BN_bin2bn(bs->data,bs->length,ret->s)) == NULL) + goto err_bn; + ASN1_BIT_STRING_free(bs); + M_ASN1_D2I_Finish_2(a); + +err_bn: + i=ERR_R_BN_LIB; +err: + DSAerr(DSA_F_D2I_DSA_SIG,i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) DSA_SIG_free(ret); + if (bs != NULL) ASN1_BIT_STRING_free(bs); + return(NULL); +} +#endif diff --git a/lib/dns/sec/openssl/dsa_err.c b/lib/dns/sec/openssl/dsa_err.c new file mode 100644 index 00000000..33a8270a --- /dev/null +++ b/lib/dns/sec/openssl/dsa_err.c @@ -0,0 +1,106 @@ +/* crypto/dsa/dsa_err.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). + * + */ + +/* 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. + */ + +#include <stdio.h> +#include <openssl/err.h> +#include <openssl/dsa.h> + +/* BEGIN ERROR CODES */ +#ifndef NO_ERR +static ERR_STRING_DATA DSA_str_functs[]= + { +{ERR_PACK(0,DSA_F_D2I_DSA_SIG,0), "d2i_DSA_SIG"}, +{ERR_PACK(0,DSA_F_DSAPARAMS_PRINT,0), "DSAparams_print"}, +{ERR_PACK(0,DSA_F_DSAPARAMS_PRINT_FP,0), "DSAparams_print_fp"}, +{ERR_PACK(0,DSA_F_DSA_DO_SIGN,0), "DSA_do_sign"}, +{ERR_PACK(0,DSA_F_DSA_DO_VERIFY,0), "DSA_do_verify"}, +{ERR_PACK(0,DSA_F_DSA_IS_PRIME,0), "DSA_is_prime"}, +{ERR_PACK(0,DSA_F_DSA_NEW,0), "DSA_new"}, +{ERR_PACK(0,DSA_F_DSA_PRINT,0), "DSA_print"}, +{ERR_PACK(0,DSA_F_DSA_PRINT_FP,0), "DSA_print_fp"}, +{ERR_PACK(0,DSA_F_DSA_SIGN,0), "DSA_sign"}, +{ERR_PACK(0,DSA_F_DSA_SIGN_SETUP,0), "DSA_sign_setup"}, +{ERR_PACK(0,DSA_F_DSA_SIG_NEW,0), "DSA_SIG_new"}, +{ERR_PACK(0,DSA_F_DSA_VERIFY,0), "DSA_verify"}, +{ERR_PACK(0,DSA_F_I2D_DSA_SIG,0), "i2d_DSA_SIG"}, +{0,NULL} + }; + +static ERR_STRING_DATA DSA_str_reasons[]= + { +{DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE ,"data too large for key size"}, +{0,NULL} + }; + +#endif + +void ERR_load_DSA_strings(void) + { + static int init=1; + + if (init) + { + init=0; +#ifndef NO_ERR + ERR_load_strings(ERR_LIB_DSA,DSA_str_functs); + ERR_load_strings(ERR_LIB_DSA,DSA_str_reasons); +#endif + + } + } diff --git a/lib/dns/sec/openssl/dsa_gen.c b/lib/dns/sec/openssl/dsa_gen.c new file mode 100644 index 00000000..b5e5ec06 --- /dev/null +++ b/lib/dns/sec/openssl/dsa_gen.c @@ -0,0 +1,333 @@ +/* crypto/dsa/dsa_gen.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.] + */ + +#undef GENUINE_DSA + +#ifdef GENUINE_DSA +#define HASH SHA +#else +#define HASH SHA1 +#endif + +#ifndef NO_SHA +#include <stdio.h> +#include <time.h> +#include "cryptlib.h" +#include <openssl/sha.h> +#include <openssl/bn.h> +#include <openssl/dsa.h> +#include <openssl/rand.h> + +DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, + int *counter_ret, unsigned long *h_ret, void (*callback)(), + char *cb_arg) + { + int ok=0; + unsigned char seed[SHA_DIGEST_LENGTH]; + unsigned char md[SHA_DIGEST_LENGTH]; + unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH]; + BIGNUM *r0,*W,*X,*c,*test; + BIGNUM *g=NULL,*q=NULL,*p=NULL; + BN_MONT_CTX *mont=NULL; + int k,n=0,i,b,m=0; + int counter=0; + BN_CTX *ctx=NULL,*ctx2=NULL; + unsigned int h=2; + DSA *ret=NULL; + + if (bits < 512) bits=512; + bits=(bits+63)/64*64; + + if ((seed_in != NULL) && (seed_len == 20)) + memcpy(seed,seed_in,seed_len); + + if ((ctx=BN_CTX_new()) == NULL) goto err; + if ((ctx2=BN_CTX_new()) == NULL) goto err; + if ((ret=DSA_new()) == NULL) goto err; + + if ((mont=BN_MONT_CTX_new()) == NULL) goto err; + + r0= &(ctx2->bn[0]); + g= &(ctx2->bn[1]); + W= &(ctx2->bn[2]); + q= &(ctx2->bn[3]); + X= &(ctx2->bn[4]); + c= &(ctx2->bn[5]); + p= &(ctx2->bn[6]); + test= &(ctx2->bn[7]); + + BN_lshift(test,BN_value_one(),bits-1); + + for (;;) + { + for (;;) + { + /* step 1 */ + if (callback != NULL) callback(0,m++,cb_arg); + + if (!seed_len) + RAND_bytes(seed,SHA_DIGEST_LENGTH); + else + seed_len=0; + + memcpy(buf,seed,SHA_DIGEST_LENGTH); + memcpy(buf2,seed,SHA_DIGEST_LENGTH); + for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) + { + buf[i]++; + if (buf[i] != 0) break; + } + + /* step 2 */ + HASH(seed,SHA_DIGEST_LENGTH,md); + HASH(buf,SHA_DIGEST_LENGTH,buf2); + for (i=0; i<SHA_DIGEST_LENGTH; i++) + md[i]^=buf2[i]; + + /* step 3 */ + md[0]|=0x80; + md[SHA_DIGEST_LENGTH-1]|=0x01; + if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) abort(); + + /* step 4 */ + if (DSA_is_prime(q,callback,cb_arg) > 0) break; + /* do a callback call */ + /* step 5 */ + } + + if (callback != NULL) callback(2,0,cb_arg); + if (callback != NULL) callback(3,0,cb_arg); + + /* step 6 */ + counter=0; + + n=(bits-1)/160; + b=(bits-1)-n*160; + + for (;;) + { + /* step 7 */ + BN_zero(W); + for (k=0; k<=n; k++) + { + for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) + { + buf[i]++; + if (buf[i] != 0) break; + } + + HASH(buf,SHA_DIGEST_LENGTH,md); + + /* step 8 */ + if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0)) abort(); + BN_lshift(r0,r0,160*k); + BN_add(W,W,r0); + } + + /* more of step 8 */ + BN_mask_bits(W,bits-1); + BN_copy(X,W); /* this should be ok */ + BN_add(X,X,test); /* this should be ok */ + + /* step 9 */ + BN_lshift1(r0,q); + BN_mod(c,X,r0,ctx); + BN_sub(r0,c,BN_value_one()); + BN_sub(p,X,r0); + + /* step 10 */ + if (BN_cmp(p,test) >= 0) + { + /* step 11 */ + if (DSA_is_prime(p,callback,cb_arg) > 0) + goto end; + } + + /* step 13 */ + counter++; + + /* step 14 */ + if (counter >= 4096) break; + + if (callback != NULL) callback(0,counter,cb_arg); + } + } +end: + if (callback != NULL) callback(2,1,cb_arg); + + /* We now need to gernerate g */ + /* Set r0=(p-1)/q */ + BN_sub(test,p,BN_value_one()); + BN_div(r0,NULL,test,q,ctx); + + BN_set_word(test,h); + BN_MONT_CTX_set(mont,p,ctx); + + for (;;) + { + /* g=test^r0%p */ + BN_mod_exp_mont(g,test,r0,p,ctx,mont); + if (!BN_is_one(g)) break; + BN_add(test,test,BN_value_one()); + h++; + } + + if (callback != NULL) callback(3,1,cb_arg); + + ok=1; +err: + if (!ok) + { + if (ret != NULL) DSA_free(ret); + } + else + { + ret->p=BN_dup(p); + ret->q=BN_dup(q); + ret->g=BN_dup(g); + if ((m > 1) && (seed_in != NULL)) memcpy(seed_in,seed,20); + if (counter_ret != NULL) *counter_ret=counter; + if (h_ret != NULL) *h_ret=h; + } + if (ctx != NULL) BN_CTX_free(ctx); + if (ctx != NULL) BN_CTX_free(ctx2); + if (mont != NULL) BN_MONT_CTX_free(mont); + return(ok?ret:NULL); + } + +int DSA_is_prime(BIGNUM *w, void (*callback)(), char *cb_arg) + { + int ok= -1,j,i,n; + BN_CTX *ctx=NULL,*ctx2=NULL; + BIGNUM *w_1,*b,*m,*z,*tmp,*mont_1; + int a; + BN_MONT_CTX *mont=NULL; + + if (!BN_is_bit_set(w,0)) return(0); + + if ((ctx=BN_CTX_new()) == NULL) goto err; + if ((ctx2=BN_CTX_new()) == NULL) goto err; + if ((mont=BN_MONT_CTX_new()) == NULL) goto err; + + m= &(ctx2->bn[2]); + b= &(ctx2->bn[3]); + z= &(ctx2->bn[4]); + w_1= &(ctx2->bn[5]); + tmp= &(ctx2->bn[6]); + mont_1= &(ctx2->bn[7]); + + /* step 1 */ + n=50; + + /* step 2 */ + if (!BN_sub(w_1,w,BN_value_one())) goto err; + for (a=1; !BN_is_bit_set(w_1,a); a++) + ; + if (!BN_rshift(m,w_1,a)) goto err; + + BN_MONT_CTX_set(mont,w,ctx); + BN_to_montgomery(mont_1,BN_value_one(),mont,ctx); + BN_to_montgomery(w_1,w_1,mont,ctx); + for (i=1; i < n; i++) + { + /* step 3 */ + BN_rand(b,BN_num_bits(w)-2/*-1*/,0,0); + /* BN_set_word(b,0x10001L); */ + + /* step 4 */ + j=0; + if (!BN_mod_exp_mont(z,b,m,w,ctx,mont)) goto err; + + if (!BN_to_montgomery(z,z,mont,ctx)) goto err; + + /* step 5 */ + for (;;) + { + if (((j == 0) && (BN_cmp(z,mont_1) == 0)) || + (BN_cmp(z,w_1) == 0)) + break; + + /* step 6 */ + if ((j > 0) && (BN_cmp(z,mont_1) == 0)) + { + ok=0; + goto err; + } + + j++; + if (j >= a) + { + ok=0; + goto err; + } + + if (!BN_mod_mul_montgomery(z,z,z,mont,ctx)) goto err; + if (callback != NULL) callback(1,j,cb_arg); + } + } + + ok=1; +err: + if (ok == -1) DSAerr(DSA_F_DSA_IS_PRIME,ERR_R_BN_LIB); + BN_CTX_free(ctx); + BN_CTX_free(ctx2); + BN_MONT_CTX_free(mont); + + return(ok); + } +#endif diff --git a/lib/dns/sec/openssl/dsa_key.c b/lib/dns/sec/openssl/dsa_key.c new file mode 100644 index 00000000..ab7f38fc --- /dev/null +++ b/lib/dns/sec/openssl/dsa_key.c @@ -0,0 +1,112 @@ +/* crypto/dsa/dsa_key.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 NO_SHA +#include <stdio.h> +#include <time.h> +#include "cryptlib.h" +#include <openssl/sha.h> +#include <openssl/bn.h> +#include <openssl/dsa.h> +#include <openssl/rand.h> + +int DSA_generate_key(DSA *dsa) + { + int ok=0; + unsigned int i; + BN_CTX *ctx=NULL; + BIGNUM *pub_key=NULL,*priv_key=NULL; + + if ((ctx=BN_CTX_new()) == NULL) goto err; + + if (dsa->priv_key == NULL) + { + if ((priv_key=BN_new()) == NULL) goto err; + } + else + priv_key=dsa->priv_key; + + i=BN_num_bits(dsa->q); + for (;;) + { + BN_rand(priv_key,i,1,0); + if (BN_cmp(priv_key,dsa->q) >= 0) + BN_sub(priv_key,priv_key,dsa->q); + if (!BN_is_zero(priv_key)) break; + } + + if (dsa->pub_key == NULL) + { + if ((pub_key=BN_new()) == NULL) goto err; + } + else + pub_key=dsa->pub_key; + + if (!BN_mod_exp(pub_key,dsa->g,priv_key,dsa->p,ctx)) goto err; + + dsa->priv_key=priv_key; + dsa->pub_key=pub_key; + ok=1; + +err: + if ((pub_key != NULL) && (dsa->pub_key == NULL)) BN_free(pub_key); + if ((priv_key != NULL) && (dsa->priv_key == NULL)) BN_free(priv_key); + if (ctx != NULL) BN_CTX_free(ctx); + return(ok); + } +#endif diff --git a/lib/dns/sec/openssl/dsa_lib.c b/lib/dns/sec/openssl/dsa_lib.c new file mode 100644 index 00000000..6208b2a8 --- /dev/null +++ b/lib/dns/sec/openssl/dsa_lib.c @@ -0,0 +1,150 @@ +/* crypto/dsa/dsa_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.] + */ + +/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/bn.h> +#include <openssl/dsa.h> +/*#include <openssl/asn1.h>*/ + +const char *DSA_version="DSA" OPENSSL_VERSION_PTEXT; + +DSA *DSA_new(void) + { + DSA *ret; + + ret=(DSA *)Malloc(sizeof(DSA)); + if (ret == NULL) + { + DSAerr(DSA_F_DSA_NEW,ERR_R_MALLOC_FAILURE); + return(NULL); + } + ret->pad=0; + ret->version=0; + ret->write_params=1; + ret->p=NULL; + ret->q=NULL; + ret->g=NULL; + ret->flags=DSA_FLAG_CACHE_MONT_P; + + ret->pub_key=NULL; + ret->priv_key=NULL; + + ret->kinv=NULL; + ret->r=NULL; + ret->method_mont_p=NULL; + + ret->references=1; + return(ret); + } + +void DSA_free(DSA *r) + { + int i; + + if (r == NULL) return; + + i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_DSA); +#ifdef REF_PRINT + REF_PRINT("DSA",r); +#endif + if (i > 0) return; +#ifdef REF_CHECK + if (i < 0) + { + fprintf(stderr,"DSA_free, bad reference count\n"); + abort(); + } +#endif + + if (r->p != NULL) BN_clear_free(r->p); + if (r->q != NULL) BN_clear_free(r->q); + if (r->g != NULL) BN_clear_free(r->g); + if (r->pub_key != NULL) BN_clear_free(r->pub_key); + if (r->priv_key != NULL) BN_clear_free(r->priv_key); + if (r->kinv != NULL) BN_clear_free(r->kinv); + if (r->r != NULL) BN_clear_free(r->r); + if (r->method_mont_p != NULL) + BN_MONT_CTX_free((BN_MONT_CTX *)r->method_mont_p); + Free(r); + } + +#if 0 +/* BEW */ +int DSA_size(DSA *r) + { + int ret,i; + ASN1_INTEGER bs; + unsigned char buf[4]; + + i=BN_num_bits(r->q); + 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); + return(ret); + } +#endif + diff --git a/lib/dns/sec/openssl/dsa_sign.c b/lib/dns/sec/openssl/dsa_sign.c new file mode 100644 index 00000000..6d8a21d7 --- /dev/null +++ b/lib/dns/sec/openssl/dsa_sign.c @@ -0,0 +1,214 @@ +/* crypto/dsa/dsa_sign.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.] + */ + +/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/bn.h> +#include <openssl/dsa.h> +#include <openssl/rand.h> +/*#include <openssl/asn1.h>*/ + +DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) + { + BIGNUM *kinv=NULL,*r=NULL,*s=NULL; + BIGNUM m; + BIGNUM xr; + BN_CTX *ctx=NULL; + int i,reason=ERR_R_BN_LIB; + DSA_SIG *ret=NULL; + + BN_init(&m); + BN_init(&xr); + s=BN_new(); + if (s == NULL) goto err; + + i=BN_num_bytes(dsa->q); /* should be 20 */ + if ((dlen > i) || (dlen > 50)) + { + reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE; + goto err; + } + + ctx=BN_CTX_new(); + if (ctx == NULL) goto err; + + if ((dsa->kinv == NULL) || (dsa->r == NULL)) + { + if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err; + } + else + { + kinv=dsa->kinv; + dsa->kinv=NULL; + r=dsa->r; + dsa->r=NULL; + } + + if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err; + + /* Compute s = inv(k) (m + xr) mod q */ + if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */ + if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */ + if (BN_cmp(s,dsa->q) > 0) + BN_sub(s,s,dsa->q); + if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err; + + ret=DSA_SIG_new(); + if (ret == NULL) goto err; + ret->r = r; + ret->s = s; + +err: + if (!ret) + { + DSAerr(DSA_F_DSA_DO_SIGN,reason); + BN_free(r); + BN_free(s); + } + if (ctx != NULL) BN_CTX_free(ctx); + BN_clear_free(&m); + BN_clear_free(&xr); + if (kinv != NULL) /* dsa->kinv is NULL now if we used it */ + BN_clear_free(kinv); + return(ret); + } + +/* data has already been hashed (probably with SHA or SHA-1). */ + +/* BEW */ +#if 0 +/* unsigned char *sig: out */ +/* unsigned int *siglen: out */ +int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, + unsigned int *siglen, DSA *dsa) + { + DSA_SIG *s; + s=DSA_do_sign(dgst,dlen,dsa); + if (s == NULL) + { + *siglen=0; + return(0); + } + *siglen=i2d_DSA_SIG(s,&sig); + DSA_SIG_free(s); + return(1); + } +#endif + +int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) + { + BN_CTX *ctx; + BIGNUM k,*kinv=NULL,*r=NULL; + int ret=0; + + if (ctx_in == NULL) + { + if ((ctx=BN_CTX_new()) == NULL) goto err; + } + else + ctx=ctx_in; + + BN_init(&k); + if ((r=BN_new()) == NULL) goto err; + kinv=NULL; + + /* Get random k */ + for (;;) + { + if (!BN_rand(&k, BN_num_bits(dsa->q), 1, 0)) goto err; + if (BN_cmp(&k,dsa->q) >= 0) + BN_sub(&k,&k,dsa->q); + if (!BN_is_zero(&k)) break; + } + + if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P)) + { + if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL) + if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p, + dsa->p,ctx)) goto err; + } + + /* Compute r = (g^k mod p) mod q */ + if (!BN_mod_exp_mont(r,dsa->g,&k,dsa->p,ctx, + (BN_MONT_CTX *)dsa->method_mont_p)) goto err; + if (!BN_mod(r,r,dsa->q,ctx)) goto err; + + /* Compute part of 's = inv(k) (m + xr) mod q' */ + if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err; + + if (*kinvp != NULL) BN_clear_free(*kinvp); + *kinvp=kinv; + kinv=NULL; + if (*rp != NULL) BN_clear_free(*rp); + *rp=r; + ret=1; +err: + if (!ret) + { + DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB); + if (kinv != NULL) BN_clear_free(kinv); + if (r != NULL) BN_clear_free(r); + } + if (ctx_in == NULL) BN_CTX_free(ctx); + if (kinv != NULL) BN_clear_free(kinv); + BN_clear_free(&k); + return(ret); + } + diff --git a/lib/dns/sec/openssl/dsa_vrf.c b/lib/dns/sec/openssl/dsa_vrf.c new file mode 100644 index 00000000..9e0ab3f6 --- /dev/null +++ b/lib/dns/sec/openssl/dsa_vrf.c @@ -0,0 +1,163 @@ +/* crypto/dsa/dsa_vrf.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.] + */ + +/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */ + +#include <stdio.h> +#include "cryptlib.h" +#include <openssl/bn.h> +#include <openssl/dsa.h> +#include <openssl/rand.h> +/*#include <openssl/asn1.h>*/ +/*#include <openssl/asn1_mac.h>*/ + +int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, + DSA *dsa) + { + BN_CTX *ctx; + BIGNUM u1,u2,t1; + BN_MONT_CTX *mont=NULL; + int ret = -1; + + if ((ctx=BN_CTX_new()) == NULL) goto err; + BN_init(&u1); + BN_init(&u2); + BN_init(&t1); + + /* Calculate W = inv(S) mod Q + * save W in u2 */ + if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err; + + /* save M in u1 */ + if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err; + + /* u1 = M * w mod q */ + if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err; + + /* u2 = r * w mod q */ + if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err; + + if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P)) + { + if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL) + if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p, + dsa->p,ctx)) goto err; + } + mont=(BN_MONT_CTX *)dsa->method_mont_p; + +#if 0 + { + BIGNUM t2; + + BN_init(&t2); + /* v = ( g^u1 * y^u2 mod p ) mod q */ + /* let t1 = g ^ u1 mod p */ + if (!BN_mod_exp_mont(&t1,dsa->g,&u1,dsa->p,ctx,mont)) goto err; + /* let t2 = y ^ u2 mod p */ + if (!BN_mod_exp_mont(&t2,dsa->pub_key,&u2,dsa->p,ctx,mont)) goto err; + /* let u1 = t1 * t2 mod p */ + if (!BN_mod_mul(&u1,&t1,&t2,dsa->p,ctx)) goto err_bn; + BN_free(&t2); + } + /* let u1 = u1 mod q */ + if (!BN_mod(&u1,&u1,dsa->q,ctx)) goto err; +#else + { + if (!BN_mod_exp2_mont(&t1,dsa->g,&u1,dsa->pub_key,&u2,dsa->p,ctx,mont)) + goto err; + /* BN_copy(&u1,&t1); */ + /* let u1 = u1 mod q */ + if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err; + } +#endif + /* V is now in u1. If the signature is correct, it will be + * equal to R. */ + ret=(BN_ucmp(&u1, sig->r) == 0); + + err: + if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB); + if (ctx != NULL) BN_CTX_free(ctx); + BN_free(&u1); + BN_free(&u2); + BN_free(&t1); + return(ret); + } + +#if 0 +/* BEW */ +/* data has already been hashed (probably with SHA or SHA-1). */ +/* returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, + unsigned char *sigbuf, int siglen, DSA *dsa) + { + DSA_SIG *s; + int ret=-1; + + s = DSA_SIG_new(); + if (s == NULL) return(ret); + if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err; + ret=DSA_do_verify(dgst,dgst_len,s,dsa); +err: + DSA_SIG_free(s); + return(ret); + } +#endif diff --git a/lib/dns/sec/openssl/err.c b/lib/dns/sec/openssl/err.c new file mode 100644 index 00000000..d62680da --- /dev/null +++ b/lib/dns/sec/openssl/err.c @@ -0,0 +1,642 @@ +/* crypto/err/err.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 <stdarg.h> +#include <openssl/lhash.h> +#include <openssl/crypto.h> +#include "cryptlib.h" +#include <openssl/buffer.h> +#include <openssl/err.h> +#include <openssl/crypto.h> + + +static LHASH *error_hash=NULL; +static LHASH *thread_hash=NULL; + +static unsigned long err_hash(ERR_STRING_DATA *a); +static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b); +static unsigned long pid_hash(ERR_STATE *pid); +static int pid_cmp(ERR_STATE *a,ERR_STATE *pid); +static unsigned long get_error_values(int inc,const char **file,int *line, + const char **data,int *flags); +static void ERR_STATE_free(ERR_STATE *s); +#ifndef NO_ERR +static ERR_STRING_DATA ERR_str_libraries[]= + { +{ERR_PACK(ERR_LIB_NONE,0,0) ,"unknown library"}, +{ERR_PACK(ERR_LIB_SYS,0,0) ,"system library"}, +{ERR_PACK(ERR_LIB_BN,0,0) ,"bignum routines"}, +{ERR_PACK(ERR_LIB_RSA,0,0) ,"rsa routines"}, +{ERR_PACK(ERR_LIB_DH,0,0) ,"Diffie-Hellman routines"}, +{ERR_PACK(ERR_LIB_EVP,0,0) ,"digital envelope routines"}, +{ERR_PACK(ERR_LIB_BUF,0,0) ,"memory buffer routines"}, +{ERR_PACK(ERR_LIB_BIO,0,0) ,"BIO routines"}, +{ERR_PACK(ERR_LIB_OBJ,0,0) ,"object identifier routines"}, +{ERR_PACK(ERR_LIB_PEM,0,0) ,"PEM routines"}, +{ERR_PACK(ERR_LIB_ASN1,0,0) ,"asn1 encoding routines"}, +{ERR_PACK(ERR_LIB_X509,0,0) ,"x509 certificate routines"}, +{ERR_PACK(ERR_LIB_CONF,0,0) ,"configuation file routines"}, +{ERR_PACK(ERR_LIB_METH,0,0) ,"X509 lookup 'method' routines"}, +{ERR_PACK(ERR_LIB_SSL,0,0) ,"SSL routines"}, +{ERR_PACK(ERR_LIB_RSAREF,0,0) ,"RSAref routines"}, +{ERR_PACK(ERR_LIB_PROXY,0,0) ,"Proxy routines"}, +{ERR_PACK(ERR_LIB_BIO,0,0) ,"BIO routines"}, +{ERR_PACK(ERR_LIB_PKCS7,0,0) ,"PKCS7 routines"}, +{ERR_PACK(ERR_LIB_X509V3,0,0) ,"X509 V3 routines"}, +{ERR_PACK(ERR_LIB_PKCS12,0,0) ,"PKCS12 routines"}, +{0,NULL}, + }; + +static ERR_STRING_DATA ERR_str_functs[]= + { + {ERR_PACK(0,SYS_F_FOPEN,0), "fopen"}, + {ERR_PACK(0,SYS_F_CONNECT,0), "connect"}, + {ERR_PACK(0,SYS_F_GETSERVBYNAME,0), "getservbyname"}, + {ERR_PACK(0,SYS_F_SOCKET,0), "socket"}, + {ERR_PACK(0,SYS_F_IOCTLSOCKET,0), "ioctlsocket"}, + {ERR_PACK(0,SYS_F_BIND,0), "bind"}, + {ERR_PACK(0,SYS_F_LISTEN,0), "listen"}, + {ERR_PACK(0,SYS_F_ACCEPT,0), "accept"}, +#ifdef WINDOWS + {ERR_PACK(0,SYS_F_WSASTARTUP,0), "WSAstartup"}, +#endif + {0,NULL}, + }; + +static ERR_STRING_DATA ERR_str_reasons[]= + { +{ERR_R_FATAL ,"fatal"}, +{ERR_R_SYS_LIB ,"system lib"}, +{ERR_R_BN_LIB ,"BN lib"}, +{ERR_R_RSA_LIB ,"RSA lib"}, +{ERR_R_DH_LIB ,"DH lib"}, +{ERR_R_EVP_LIB ,"EVP lib"}, +{ERR_R_BUF_LIB ,"BUF lib"}, +{ERR_R_BIO_LIB ,"BIO lib"}, +{ERR_R_OBJ_LIB ,"OBJ lib"}, +{ERR_R_PEM_LIB ,"PEM lib"}, +{ERR_R_X509_LIB ,"X509 lib"}, +{ERR_R_METH_LIB ,"METH lib"}, +{ERR_R_ASN1_LIB ,"ASN1 lib"}, +{ERR_R_CONF_LIB ,"CONF lib"}, +{ERR_R_SSL_LIB ,"SSL lib"}, +{ERR_R_PROXY_LIB ,"PROXY lib"}, +{ERR_R_BIO_LIB ,"BIO lib"}, +{ERR_R_PKCS7_LIB ,"PKCS7 lib"}, +{ERR_R_PKCS12_LIB ,"PKCS12 lib"}, +{ERR_R_MALLOC_FAILURE ,"Malloc failure"}, +{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED ,"called a fuction you should not call"}, +{ERR_R_PASSED_NULL_PARAMETER ,"passed a null parameter"}, +{ERR_R_NESTED_ASN1_ERROR ,"nested asn1 error"}, +{ERR_R_BAD_ASN1_OBJECT_HEADER ,"bad asn1 object header"}, +{ERR_R_BAD_GET_ASN1_OBJECT_CALL ,"bad get asn1 object call"}, +{ERR_R_EXPECTING_AN_ASN1_SEQUENCE ,"expecting an asn1 sequence"}, +{ERR_R_ASN1_LENGTH_MISMATCH ,"asn1 length mismatch"}, +{ERR_R_MISSING_ASN1_EOS ,"missing asn1 eos"}, + +{0,NULL}, + }; +#endif + +#define err_clear_data(p,i) \ + if (((p)->err_data[i] != NULL) && \ + (p)->err_data_flags[i] & ERR_TXT_MALLOCED) \ + { \ + Free((p)->err_data[i]); \ + (p)->err_data[i]=NULL; \ + } \ + (p)->err_data_flags[i]=0; + +static void ERR_STATE_free(ERR_STATE *s) + { + int i; + + if(s == NULL) + return; + + for (i=0; i<ERR_NUM_ERRORS; i++) + { + err_clear_data(s,i); + } + Free(s); + } + +void ERR_load_ERR_strings(void) + { + static int init=1; + + if (init) + { + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (init == 0) + { + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + return; + } + init=0; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + +#ifndef NO_ERR + ERR_load_strings(0,ERR_str_libraries); + ERR_load_strings(0,ERR_str_reasons); + ERR_load_strings(ERR_LIB_SYS,ERR_str_functs); +#endif + } + } + +void ERR_load_strings(int lib, ERR_STRING_DATA *str) + { + if (error_hash == NULL) + { + CRYPTO_w_lock(CRYPTO_LOCK_ERR_HASH); + error_hash=lh_new(err_hash,err_cmp); + if (error_hash == NULL) + { + CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH); + return; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH); + + ERR_load_ERR_strings(); + } + + CRYPTO_w_lock(CRYPTO_LOCK_ERR_HASH); + while (str->error) + { + str->error|=ERR_PACK(lib,0,0); + lh_insert(error_hash,(char *)str); + str++; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR_HASH); + } + +void ERR_free_strings(void) + { + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + + if (error_hash != NULL) + { + lh_free(error_hash); + error_hash=NULL; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + } + +/********************************************************/ + +void ERR_put_error(int lib, int func, int reason, const char *file, + int line) + { + ERR_STATE *es; + +#ifdef _OSD_POSIX + /* In the BS2000-OSD POSIX subsystem, the compiler generates + * path names in the form "*POSIX(/etc/passwd)". + * This dirty hack strips them to something sensible. + * @@@ We shouldn't modify a const string, though. + */ + if (strncmp(file,"*POSIX(", sizeof("*POSIX(")-1) == 0) { + char *end; + + /* Skip the "*POSIX(" prefix */ + file += sizeof("*POSIX(")-1; + end = &file[strlen(file)-1]; + if (*end == ')') + *end = '\0'; + /* Optional: use the basename of the path only. */ + if ((end = strrchr(file, '/')) != NULL) + file = &end[1]; + } +#endif + es=ERR_get_state(); + + es->top=(es->top+1)%ERR_NUM_ERRORS; + if (es->top == es->bottom) + es->bottom=(es->bottom+1)%ERR_NUM_ERRORS; + es->err_buffer[es->top]=ERR_PACK(lib,func,reason); + es->err_file[es->top]=file; + es->err_line[es->top]=line; + err_clear_data(es,es->top); + } + +void ERR_clear_error(void) + { + ERR_STATE *es; + + es=ERR_get_state(); + +#if 0 + /* hmm... is this needed */ + for (i=0; i<ERR_NUM_ERRORS; i++) + { + es->err_buffer[i]=0; + es->err_file[i]=NULL; + es->err_line[i]= -1; + err_clear_data(es,i); + } +#endif + es->top=es->bottom=0; + } + + +unsigned long ERR_get_error(void) + { return(get_error_values(1,NULL,NULL,NULL,NULL)); } + +unsigned long ERR_get_error_line(const char **file, + int *line) + { return(get_error_values(1,file,line,NULL,NULL)); } + +unsigned long ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags) + { return(get_error_values(1,file,line, + data,flags)); } + +unsigned long ERR_peek_error(void) + { return(get_error_values(0,NULL,NULL,NULL,NULL)); } + +unsigned long ERR_peek_error_line(const char **file, + int *line) + { return(get_error_values(0,file,line,NULL,NULL)); } + +unsigned long ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags) + { return(get_error_values(0,file,line, + data,flags)); } + +static unsigned long get_error_values(int inc, const char **file, int *line, + const char **data, int *flags) + { + int i=0; + ERR_STATE *es; + unsigned long ret; + + es=ERR_get_state(); + + if (es->bottom == es->top) return(0); + i=(es->bottom+1)%ERR_NUM_ERRORS; + + ret=es->err_buffer[i]; + if (inc) + { + es->bottom=i; + es->err_buffer[i]=0; + } + + if ((file != NULL) && (line != NULL)) + { + if (es->err_file[i] == NULL) + { + *file="NA"; + if (line != NULL) *line=0; + } + else + { + *file=es->err_file[i]; + if (line != NULL) *line=es->err_line[i]; + } + } + + if (data != NULL) + { + if (es->err_data[i] == NULL) + { + *data=""; + if (flags != NULL) *flags=0; + } + else + { + *data=es->err_data[i]; + if (flags != NULL) *flags=es->err_data_flags[i]; + } + } + return(ret); + } + +/* BAD for multi-threaded, uses a local buffer if ret == NULL */ +char *ERR_error_string(unsigned long e, char *ret) + { + static char buf[256]; + const char *ls,*fs,*rs; + unsigned long l,f,r; + int i; + + l=ERR_GET_LIB(e); + f=ERR_GET_FUNC(e); + r=ERR_GET_REASON(e); + + ls=ERR_lib_error_string(e); + fs=ERR_func_error_string(e); + rs=ERR_reason_error_string(e); + + if (ret == NULL) ret=buf; + + sprintf(&(ret[0]),"error:%08lX:",e); + i=strlen(ret); + if (ls == NULL) + sprintf(&(ret[i]),":lib(%lu) ",l); + else sprintf(&(ret[i]),"%s",ls); + i=strlen(ret); + if (fs == NULL) + sprintf(&(ret[i]),":func(%lu) ",f); + else sprintf(&(ret[i]),":%s",fs); + i=strlen(ret); + if (rs == NULL) + sprintf(&(ret[i]),":reason(%lu)",r); + else sprintf(&(ret[i]),":%s",rs); + + return(ret); + } + +LHASH *ERR_get_string_table(void) + { + return(error_hash); + } + +LHASH *ERR_get_err_state_table(void) + { + return(thread_hash); + } + +const char *ERR_lib_error_string(unsigned long e) + { + ERR_STRING_DATA d,*p=NULL; + unsigned long l; + + l=ERR_GET_LIB(e); + + CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH); + + if (error_hash != NULL) + { + d.error=ERR_PACK(l,0,0); + p=(ERR_STRING_DATA *)lh_retrieve(error_hash,(char *)&d); + } + + CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH); + + return((p == NULL)?NULL:p->string); + } + +const char *ERR_func_error_string(unsigned long e) + { + ERR_STRING_DATA d,*p=NULL; + unsigned long l,f; + + l=ERR_GET_LIB(e); + f=ERR_GET_FUNC(e); + + CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH); + + if (error_hash != NULL) + { + d.error=ERR_PACK(l,f,0); + p=(ERR_STRING_DATA *)lh_retrieve(error_hash,(char *)&d); + } + + CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH); + + return((p == NULL)?NULL:p->string); + } + +const char *ERR_reason_error_string(unsigned long e) + { + ERR_STRING_DATA d,*p=NULL; + unsigned long l,r; + + l=ERR_GET_LIB(e); + r=ERR_GET_REASON(e); + + CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH); + + if (error_hash != NULL) + { + d.error=ERR_PACK(l,0,r); + p=(ERR_STRING_DATA *)lh_retrieve(error_hash,(char *)&d); + if (p == NULL) + { + d.error=ERR_PACK(0,0,r); + p=(ERR_STRING_DATA *)lh_retrieve(error_hash, + (char *)&d); + } + } + + CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH); + + return((p == NULL)?NULL:p->string); + } + +static unsigned long err_hash(ERR_STRING_DATA *a) + { + unsigned long ret,l; + + l=a->error; + ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l); + return(ret^ret%19*13); + } + +static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b) + { + return((int)(a->error-b->error)); + } + +static unsigned long pid_hash(ERR_STATE *a) + { + return(a->pid*13); + } + +static int pid_cmp(ERR_STATE *a, ERR_STATE *b) + { + return((int)((long)a->pid - (long)b->pid)); + } + +void ERR_remove_state(unsigned long pid) + { + ERR_STATE *p,tmp; + + if (thread_hash == NULL) + return; + if (pid == 0) + pid=(unsigned long)CRYPTO_thread_id(); + tmp.pid=pid; + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p=(ERR_STATE *)lh_delete(thread_hash,(char *)&tmp); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + if (p != NULL) ERR_STATE_free(p); + } + +ERR_STATE *ERR_get_state(void) + { + static ERR_STATE fallback; + ERR_STATE *ret=NULL,tmp,*tmpp; + int i; + unsigned long pid; + + pid=(unsigned long)CRYPTO_thread_id(); + + CRYPTO_r_lock(CRYPTO_LOCK_ERR); + if (thread_hash == NULL) + { + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (thread_hash == NULL) + { + MemCheck_off(); + thread_hash=lh_new(pid_hash,pid_cmp); + MemCheck_on(); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + if (thread_hash == NULL) return(&fallback); + } + else + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + } + else + { + tmp.pid=pid; + ret=(ERR_STATE *)lh_retrieve(thread_hash,(char *)&tmp); + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + } + + /* ret == the error state, if NULL, make a new one */ + if (ret == NULL) + { + ret=(ERR_STATE *)Malloc(sizeof(ERR_STATE)); + if (ret == NULL) return(&fallback); + ret->pid=pid; + ret->top=0; + ret->bottom=0; + for (i=0; i<ERR_NUM_ERRORS; i++) + { + ret->err_data[i]=NULL; + ret->err_data_flags[i]=0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + tmpp=(ERR_STATE *)lh_insert(thread_hash,(char *)ret); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + if (tmpp != NULL) /* old entry - should not happen */ + { + ERR_STATE_free(tmpp); + } + } + return(ret); + } + +int ERR_get_next_error_library(void) + { + static int value=ERR_LIB_USER; + + return(value++); + } + +void ERR_set_error_data(char *data, int flags) + { + ERR_STATE *es; + int i; + + es=ERR_get_state(); + + i=es->top; + if (i == 0) + i=ERR_NUM_ERRORS-1; + + es->err_data[i]=data; + es->err_data_flags[es->top]=flags; + } + +void ERR_add_error_data(int num, ...) + { + va_list args; + int i,n,s; + char *str,*p,*a; + + s=64; + str=Malloc(s+1); + if (str == NULL) return; + str[0]='\0'; + + va_start(args, num); + n=0; + for (i=0; i<num; i++) + { + a=va_arg(args, char*); + /* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */ + if (a != NULL) + { + n+=strlen(a); + if (n > s) + { + s=n+20; + p=Realloc(str,s+1); + if (p == NULL) + { + Free(str); + return; + } + else + str=p; + } + strcat(str,a); + } + } + ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING); + + va_end(args); + } + diff --git a/lib/dns/sec/openssl/include/.cvsignore b/lib/dns/sec/openssl/include/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/lib/dns/sec/openssl/include/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/lib/dns/sec/openssl/include/Makefile.in b/lib/dns/sec/openssl/include/Makefile.in new file mode 100644 index 00000000..dec51fc7 --- /dev/null +++ b/lib/dns/sec/openssl/include/Makefile.in @@ -0,0 +1,23 @@ +# Copyright (C) 1998, 1999, 2000 Internet Software Consortium. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS +# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE +# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +# SOFTWARE. + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +SUBDIRS = openssl +TARGETS = + +@BIND9_MAKE_RULES@ diff --git a/lib/dns/sec/openssl/include/openssl/.cvsignore b/lib/dns/sec/openssl/include/openssl/.cvsignore new file mode 100644 index 00000000..f3c7a7c5 --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/lib/dns/sec/openssl/include/openssl/Makefile.in b/lib/dns/sec/openssl/include/openssl/Makefile.in new file mode 100644 index 00000000..b40cd263 --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/Makefile.in @@ -0,0 +1,41 @@ +# Copyright (C) 1998, 1999, 2000 Internet Software Consortium. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS +# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE +# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +# SOFTWARE. + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_VERSION@ + +HEADERS = bio.h bn.h buffer.h crypto.h dh.h dsa.h e_os.h e_os2.h err.h \ + lhash.h md5.h opensslconf.h opensslv.h rand.h sha.h stack.h + +SUBDIRS = +TARGETS = + +@BIND9_MAKE_RULES@ + +installdirs: + if [ ! -d ${includedir} ]; then \ + mkdir ${includedir} ; \ + fi + if [ ! -d ${includedir}/dst ]; then \ + mkdir ${includedir}/dst ; \ + fi + +install:: installdirs + for i in ${HEADERS}; do \ + ${INSTALL_DATA} ${srcdir}/$$i ${includedir}/dst ; \ + done diff --git a/lib/dns/sec/openssl/include/openssl/bio.h b/lib/dns/sec/openssl/include/openssl/bio.h new file mode 100644 index 00000000..c41db123 --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/bio.h @@ -0,0 +1,596 @@ +/* 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 + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <openssl/crypto.h> + +/* 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) /* pasive 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_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 */ + +/* 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 + +/* 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 + +#define BIO_set_flags(b,f) ((b)->flags|=(f)) +#define BIO_get_flags(b) ((b)->flags) +#define BIO_set_retry_special(b) \ + ((b)->flags|=(BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) +#define BIO_set_retry_read(b) \ + ((b)->flags|=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) +#define BIO_set_retry_write(b) \ + ((b)->flags|=(BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) + +/* These are normally used internally in BIOs */ +#define BIO_clear_flags(b,f) ((b)->flags&= ~(f)) +#define BIO_clear_retry_flags(b) \ + ((b)->flags&= ~(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) +#define BIO_get_retry_flags(b) \ + ((b)->flags&(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + +/* These shouldbe used by the application to tell why we should retry */ +#define BIO_should_read(a) ((a)->flags & BIO_FLAGS_READ) +#define BIO_should_write(a) ((a)->flags & BIO_FLAGS_WRITE) +#define BIO_should_io_special(a) ((a)->flags & BIO_FLAGS_IO_SPECIAL) +#define BIO_retry_type(a) ((a)->flags & BIO_FLAGS_RWS) +#define BIO_should_retry(a) ((a)->flags & BIO_FLAGS_SHOULD_RETRY) + +/* The next two 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 + +/* 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) + +#define BIO_set_callback(b,cb) ((b)->callback=(cb)) +#define BIO_set_callback_arg(b,arg) ((b)->cb_arg=(char *)(arg)) +#define BIO_get_callback_arg(b) ((b)->cb_arg) +#define BIO_get_callback(b) ((b)->callback) +#define BIO_method_name(b) ((b)->method->name) +#define BIO_method_type(b) ((b)->method->type) + +#ifndef WIN16 +typedef struct bio_method_st + { + int type; + const char *name; + int (*bwrite)(); + int (*bread)(); + int (*bputs)(); + int (*bgets)(); + long (*ctrl)(); + int (*create)(); + int (*destroy)(); + } BIO_METHOD; +#else +typedef struct bio_method_st + { + int type; + const char *name; + int (_far *bwrite)(); + int (_far *bread)(); + int (_far *bputs)(); + int (_far *bgets)(); + long (_far *ctrl)(); + int (_far *create)(); + int (_far *destroy)(); + } BIO_METHOD; +#endif + +typedef 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; + char *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; + } BIO; + +typedef struct bio_f_buffer_ctx_struct + { + /* 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; + +/* 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_number_read(b) ((b)->num_read) +#define BIO_number_written(b) ((b)->num_write) + +#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_set_app_data(s,arg) BIO_set_ex_data(s,0,(char *)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,ip) BIO_ptr_ctrl(b,BIO_C_SET_CONNECT,2) +#define BIO_get_conn_int_port(b,port) BIO_int_ctrl(b,BIO_C_SET_CONNECT,3,port) + + +#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)?"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_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(char *)(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_SET_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) +#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,(char *)cbp) +#define BIO_set_info_callback(b,cb) (int)BIO_ctrl(b,BIO_CTRL_SET_CALLBACK,0,(char *)cb) + +/* For the BIO_f_buffer() type */ +#define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL) + +#ifdef NO_STDIO +#define NO_FP_API +#endif + + +/* 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,char *data); +char *BIO_get_ex_data(BIO *bio,int idx); +int BIO_get_ex_new_index(long argl, char *argp, int (*new_func)(), + int (*dup_func)(), void (*free_func)()); + +# if defined(WIN16) && defined(_WINDLL) +BIO_METHOD *BIO_s_file_internal(void); +BIO *BIO_new_file_internal(char *filename, char *mode); +BIO *BIO_new_fp_internal(FILE *stream, int close_flag); +# define BIO_s_file BIO_s_file_internal +# define BIO_new_file BIO_new_file_internal +# define BIO_new_fp BIO_new_fp_internal +# else /* FP_API */ +BIO_METHOD *BIO_s_file(void ); +BIO *BIO_new_file(char *filename, char *mode); +BIO *BIO_new_fp(FILE *stream, int close_flag); +# define BIO_s_file_internal BIO_s_file +# define BIO_new_file_internal BIO_new_file +# define BIO_new_fp_internal BIO_s_file +# endif /* FP_API */ +BIO * BIO_new(BIO_METHOD *type); +int BIO_set(BIO *a,BIO_METHOD *type); +int BIO_free(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 char *data, int len); +int BIO_puts(BIO *bp,const char *buf); +long BIO_ctrl(BIO *bp,int cmd,long larg,char *parg); +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_get_retry_BIO(BIO *bio, int *reason); +int BIO_get_retry_reason(BIO *bio); +BIO * BIO_dup_chain(BIO *in); + +#ifndef WIN16 +long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi, + long argl,long ret); +#else +long _far _loadds BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi, + long argl,long ret); +#endif + +BIO_METHOD *BIO_s_mem(void); +BIO_METHOD *BIO_s_socket(void); +BIO_METHOD *BIO_s_connect(void); +BIO_METHOD *BIO_s_accept(void); +BIO_METHOD *BIO_s_fd(void); +BIO_METHOD *BIO_s_log(void); +BIO_METHOD *BIO_s_null(void); +BIO_METHOD *BIO_f_null(void); +BIO_METHOD *BIO_f_buffer(void); +BIO_METHOD *BIO_f_nbio_test(void); +/* BIO_METHOD *BIO_f_ber(void); */ + +int BIO_sock_should_retry(int i); +int BIO_sock_non_fatal_error(int error); +int BIO_fd_should_retry(int i); +int BIO_fd_non_fatal_error(int error); +int BIO_dump(BIO *b,const char *bytes,int len); + +struct hostent *BIO_gethostbyname(const char *name); +int BIO_sock_error(int sock); +int BIO_socket_ioctl(int fd, long type, unsigned long *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); + +void ERR_load_BIO_strings(void ); + +BIO *BIO_new_socket(int sock, int close_flag); +BIO *BIO_new_fd(int fd, int close_flag); +BIO *BIO_new_connect(char *host_port); +BIO *BIO_new_accept(char *host_port); + +void BIO_copy_next_retry(BIO *b); + +long BIO_ghbn_ctrl(int cmd,int iarg,char *parg); + +int BIO_printf(BIO *bio, ...); + +/* 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. + */ + +/* 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_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_NEW 108 +#define BIO_F_BIO_NEW_FILE 109 +#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_STATE 115 +#define BIO_F_FILE_CTRL 116 +#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_CONNECT_ERROR 103 +#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_IP_ADDRESS 108 +#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_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_WSASTARTUP 122 + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/lib/dns/sec/openssl/include/openssl/bn.h b/lib/dns/sec/openssl/include/openssl/bn.h new file mode 100644 index 00000000..68aad7b7 --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/bn.h @@ -0,0 +1,473 @@ +/* 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.] + */ + +#ifndef HEADER_BN_H +#define HEADER_BN_H + +#ifndef WIN16 +#include <stdio.h> /* FILE */ +#endif +#include <openssl/opensslconf.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef VMS +#undef BN_LLONG /* experimental, so far... */ +#endif + +#define BN_MUL_COMBA +#define BN_SQR_COMBA +#define BN_RECURSION +#define RECP_MUL_MOD +#define MONT_MUL_MOD +#ifndef WIN32 +#define SIXTY_FOUR_BIT /* BEW */ +#define NO_ASM /* BEW */ +#else +#define THIRTY_TWO_BIT /* DCL */ +#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 nornal cc. This would + * be a common occurance 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 assember code. */ +#if defined(MSDOS) || defined(WINDOWS) || defined(linux) +#define BN_DIV2W +#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 +#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 relevent + * assember 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 (10000000000000000000LL) +#define BN_DEC_FMT1 "%llu" +#define BN_DEC_FMT2 "%019llu" +#define BN_DEC_NUM 19 +#endif + +#ifdef THIRTY_TWO_BIT +#if defined(WIN32) && !defined(__GNUC__) +#define BN_ULLONG unsigned _int64 +#else +#define BN_ULLONG unsigned long long +#endif +#define BN_ULONG unsigned long +#define BN_LONG long +#define BN_BITS 64 +#define BN_BYTES 4 +#define BN_BITS2 32 +#define BN_BITS4 16 +#ifdef WIN32 +/* VC++ doesn't like the LL suffix */ +#define BN_MASK (0xffffffffffffffffL) +#else +#define BN_MASK (0xffffffffffffffffLL) +#endif +#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 "%lu" +#define BN_DEC_FMT2 "%09lu" +#define BN_DEC_NUM 9 +#endif + +#ifdef SIXTEEN_BIT +#ifndef BN_DIV2W +#define BN_DIV2W +#endif +#define BN_ULLONG unsigned long +#define BN_ULONG unsigned short +#define BN_LONG short +#define BN_BITS 32 +#define BN_BYTES 2 +#define BN_BITS2 16 +#define BN_BITS4 8 +#define BN_MASK (0xffffffff) +#define BN_MASK2 (0xffff) +#define BN_MASK2l (0xff) +#define BN_MASK2h1 (0xff80) +#define BN_MASK2h (0xff00) +#define BN_TBIT (0x8000) +#define BN_DEC_CONV (100000) +#define BN_DEC_FMT1 "%u" +#define BN_DEC_FMT2 "%05u" +#define BN_DEC_NUM 5 +#endif + +#ifdef EIGHT_BIT +#ifndef BN_DIV2W +#define BN_DIV2W +#endif +#define BN_ULLONG unsigned short +#define BN_ULONG unsigned char +#define BN_LONG char +#define BN_BITS 16 +#define BN_BYTES 1 +#define BN_BITS2 8 +#define BN_BITS4 4 +#define BN_MASK (0xffff) +#define BN_MASK2 (0xff) +#define BN_MASK2l (0xf) +#define BN_MASK2h1 (0xf8) +#define BN_MASK2h (0xf0) +#define BN_TBIT (0x80) +#define BN_DEC_CONV (100) +#define BN_DEC_FMT1 "%u" +#define BN_DEC_FMT2 "%02u" +#define BN_DEC_NUM 2 +#endif + +#define BN_DEFAULT_BITS 1280 + +#ifdef BIGNUM +#undef BIGNUM +#endif + +#define BN_FLG_MALLOCED 0x01 +#define BN_FLG_STATIC_DATA 0x02 +#define BN_FLG_FREE 0x8000 /* used for debuging */ +#define BN_set_flags(b,n) ((b)->flags|=(n)) +#define BN_get_flags(b,n) ((b)->flags&(n)) + +typedef 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 max; /* Size of the d array. */ + int neg; /* one if the number is negative */ + int flags; + } BIGNUM; + +/* Used for temp variables */ +#define BN_CTX_NUM 12 +typedef struct bignum_ctx + { + int tos; + BIGNUM bn[BN_CTX_NUM+1]; + int flags; + } BN_CTX; + +typedef struct bn_blinding_st + { + int init; + BIGNUM *A; + BIGNUM *Ai; + BIGNUM *mod; /* just a reference */ + } BN_BLINDING; + +/* Used for montgomery multiplication */ +typedef struct bn_mont_ctx_st + { + int use_word; /* 0 for word form, 1 for long form */ + int ri; /* number of bits in R */ + BIGNUM RR; /* used to convert to montgomery form */ + BIGNUM N; /* The modulus */ + BIGNUM Ni; /* The inverse of N */ + BN_ULONG n0; /* word form of inverse, normally only one of + * Ni or n0 is defined */ + int flags; + } BN_MONT_CTX; + +/* Used for reciprocal division/mod functions + * It cannot be shared between threads + */ +typedef struct bn_recp_ctx_st + { + BIGNUM N; /* the divisor */ + BIGNUM Nr; /* the reciprocal */ + int num_bits; + int shift; + int flags; + } BN_RECP_CTX; + +#define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ + r,a,&((mont)->RR),(mont),ctx) + +#define BN_prime_checks (5) + +#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) +#define BN_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) +#define BN_is_zero(a) (((a)->top == 0) || BN_is_word(a,0)) +#define BN_is_one(a) (BN_is_word((a),1)) +#define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1)) +#define BN_one(a) (BN_set_word((a),1)) +#define BN_zero(a) (BN_set_word((a),0)) + +/*#define BN_ascii2bn(a) BN_hex2bn(a) */ +/*#define BN_bn2ascii(a) BN_bn2hex(a) */ + +#define bn_expand(n,b) ((((((b+BN_BITS2-1))/BN_BITS2)) <= (n)->max)?\ + (n):bn_expand2((n),(b)/BN_BITS2+1)) +#define bn_wexpand(n,b) (((b) <= (n)->max)?(n):bn_expand2((n),(b))) + +#define bn_fix_top(a) \ + { \ + BN_ULONG *ftl; \ + if ((a)->top > 0) \ + { \ + for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \ + if (*(ftl--)) break; \ + } \ + } + +BIGNUM *BN_value_one(void); +char * BN_options(void); +BN_CTX *BN_CTX_new(void); +void BN_CTX_init(BN_CTX *c); +void BN_CTX_free(BN_CTX *c); +int BN_rand(BIGNUM *rnd, int bits, int top,int bottom); +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); +BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret); +int BN_bn2bin(const BIGNUM *a, unsigned char *to); +BIGNUM *BN_mpi2bn(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, BIGNUM *a, BIGNUM *b); +int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, + BN_CTX *ctx); +int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b,BN_CTX *ctx); +int BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx); +BN_ULONG BN_mod_word(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(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, BIGNUM *a); +int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p,BN_CTX *ctx); +int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m,BN_CTX *ctx); +int BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp2_mont(BIGNUM *r, BIGNUM *a1, BIGNUM *p1,BIGNUM *a2, + BIGNUM *p2,BIGNUM *m,BN_CTX *ctx,BN_MONT_CTX *m_ctx); +int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, + BIGNUM *m,BN_CTX *ctx); +int BN_mask_bits(BIGNUM *a,int n); +int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); +#ifndef WIN16 +int BN_print_fp(FILE *fp, BIGNUM *a); +#endif +#ifdef HEADER_BIO_H +int BN_print(BIO *fp, const BIGNUM *a); +#else +int BN_print(char *fp, const BIGNUM *a); +#endif +int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx); +int BN_rshift(BIGNUM *r, BIGNUM *a, int n); +int BN_rshift1(BIGNUM *r, BIGNUM *a); +void BN_clear(BIGNUM *a); +BIGNUM *bn_expand2(BIGNUM *b, int bits); +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_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx); +BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); +BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int strong,BIGNUM *add, + BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg); +int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int,void *), + BN_CTX *ctx,void *cb_arg); +void ERR_load_BN_strings(void ); + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w); +BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w); +void bn_sqr_words(BN_ULONG *rp, 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, BN_ULONG *ap, BN_ULONG *bp,int num); +BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num); + +BN_MONT_CTX *BN_MONT_CTX_new(void ); +void BN_MONT_CTX_init(BN_MONT_CTX *ctx); +int BN_mod_mul_montgomery(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_MONT_CTX *mont, + BN_CTX *ctx); +int BN_from_montgomery(BIGNUM *r,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 *modulus,BN_CTX *ctx); +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from); + +BN_BLINDING *BN_BLINDING_new(BIGNUM *A,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 *r, BN_CTX *ctx); +int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); + +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 */ + +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, BIGNUM *x, 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, BIGNUM *m, + BN_RECP_CTX *recp, BN_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. + */ + +/* Error codes for the BN functions. */ + +/* Function codes. */ +#define BN_F_BN_BLINDING_CONVERT 100 +#define BN_F_BN_BLINDING_INVERT 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_NEW 106 +#define BN_F_BN_DIV 107 +#define BN_F_BN_EXPAND2 108 +#define BN_F_BN_MOD_EXP_MONT 109 +#define BN_F_BN_MOD_INVERSE 110 +#define BN_F_BN_MOD_MUL_RECIPROCAL 111 +#define BN_F_BN_MPI2BN 112 +#define BN_F_BN_NEW 113 +#define BN_F_BN_RAND 114 +#define BN_F_BN_USUB 115 + +/* Reason codes. */ +#define BN_R_ARG2_LT_ARG3 100 +#define BN_R_BAD_RECIPROCAL 101 +#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_INVALID_LENGTH 106 +#define BN_R_NOT_INITIALIZED 107 +#define BN_R_NO_INVERSE 108 + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/lib/dns/sec/openssl/include/openssl/buffer.h b/lib/dns/sec/openssl/include/openssl/buffer.h new file mode 100644 index 00000000..bff26bf3 --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/buffer.h @@ -0,0 +1,98 @@ +/* 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 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct buf_mem_st + { + int length; /* current number of bytes */ + char *data; + int max; /* size of buffer */ + } BUF_MEM; + +BUF_MEM *BUF_MEM_new(void); +void BUF_MEM_free(BUF_MEM *a); +int BUF_MEM_grow(BUF_MEM *str, int len); +char * BUF_strdup(const char *str); + +void ERR_load_BUF_strings(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. + */ + +/* Error codes for the BUF functions. */ + +/* Function codes. */ +#define BUF_F_BUF_MEM_GROW 100 +#define BUF_F_BUF_MEM_NEW 101 +#define BUF_F_BUF_STRDUP 102 + +/* Reason codes. */ + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/lib/dns/sec/openssl/include/openssl/crypto.h b/lib/dns/sec/openssl/include/openssl/crypto.h new file mode 100644 index 00000000..7418274b --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/crypto.h @@ -0,0 +1,314 @@ +/* crypto/crypto.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_CRYPTO_H +#define HEADER_CRYPTO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NO_FP_API +#include <stdio.h> +#endif + +#include <openssl/stack.h> +#include <openssl/opensslv.h> + +/* 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 + +/* 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_ERR_HASH 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_RAND 17 +#define CRYPTO_LOCK_MALLOC 18 +#define CRYPTO_LOCK_BIO 19 +#define CRYPTO_LOCK_GETHOSTBYNAME 20 +#define CRYPTO_LOCK_GETSERVBYNAME 21 +#define CRYPTO_LOCK_READDIR 22 +#define CRYPTO_LOCK_RSA_BLINDING 23 +#define CRYPTO_NUM_LOCKS 24 + +#define CRYPTO_LOCK 1 +#define CRYPTO_UNLOCK 2 +#define CRYPTO_READ 4 +#define CRYPTO_WRITE 8 + +#ifndef 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 + +/* 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 */ + +/* +typedef struct crypto_mem_st + { + char *(*malloc_func)(); + char *(*realloc_func)(); + void (*free_func)(); + } CRYPTO_MEM_FUNC; +*/ + +/* predec of the BIO type */ +typedef struct bio_st BIO_dummy; + +typedef struct crypto_ex_data_st + { + STACK *sk; + int dummy; /* gcc is screwing up this data structure :-( */ + } CRYPTO_EX_DATA; + +/* This stuff is basically class callback functions + * The current classes are SSL_CTX, SSL, SSL_SESION, and a few more */ +typedef struct crypto_ex_data_func_st + { + long argl; /* Arbitary long */ + char *argp; /* Arbitary char * */ + /* Called when a new object is created */ + int (*new_func)(/*char *obj, + char *item,int index,long argl,char *argp*/); + /* Called when this object is free()ed */ + void (*free_func)(/*char *obj, + char *item,int index,long argl,char *argp*/); + + /* Called when we need to dup this one */ + int (*dup_func)(/*char *obj_to,char *obj_from, + char **new,int index,long argl,char *argp*/); + } 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 + +/* Use this for win32 DLL's */ +#define CRYPTO_malloc_init() CRYPTO_set_mem_functions(\ + (char *(*)())malloc,\ + (char *(*)())realloc,\ + (void (*)())free) + +#ifdef CRYPTO_MDEBUG +#define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) +#define MemCheck_stop() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) +#define MemCheck_on() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) +#define MemCheck_off() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) +#define Malloc(num) CRYPTO_dbg_malloc((int)num,__FILE__,__LINE__) +#define Realloc(addr,num) \ + CRYPTO_dbg_realloc((char *)addr,(int)num,__FILE__,__LINE__) +#define Remalloc(addr,num) \ + CRYPTO_dbg_remalloc((char **)addr,(int)num,__FILE__,__LINE__) +#define FreeFunc CRYPTO_dbg_free +#define Free(addr) CRYPTO_dbg_free(addr) +#define Malloc_locked(num) CRYPTO_malloc_locked((int)num) +#define Free_locked(addr) CRYPTO_free_locked(addr) +#else +#define MemCheck_start() +#define MemCheck_stop() +#define MemCheck_on() +#define MemCheck_off() +#define Remalloc CRYPTO_remalloc +#if defined(WIN32) || defined(MFUNC) +#define Malloc CRYPTO_malloc +#define Realloc(a,n) CRYPTO_realloc(a,(n)) +#define FreeFunc CRYPTO_free +#define Free(addr) CRYPTO_free(addr) +#define Malloc_locked CRYPTO_malloc_locked +#define Free_locked(addr) CRYPTO_free_locked(addr) +#else +#define Malloc malloc +#define Realloc realloc +#define FreeFunc free +#define Free(addr) free(addr) +#define Malloc_locked malloc +#define Free_locked(addr) free(addr) +#endif /* WIN32 || MFUNC */ +#endif /* MDEBUG */ + +/* Case insensiteve linking causes problems.... */ +#if defined(WIN16) || defined(VMS) +#define ERR_load_CRYPTO_strings ERR_load_CRYPTOlib_strings +#endif + + +const char *SSLeay_version(int type); +unsigned long SSLeay(void); + +int CRYPTO_get_ex_new_index(int idx,STACK **sk,long argl,char *argp, + int (*new_func)(),int (*dup_func)(),void (*free_func)()); +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad,int idx,char *val); +char *CRYPTO_get_ex_data(CRYPTO_EX_DATA *ad,int idx); +int CRYPTO_dup_ex_data(STACK *meth,CRYPTO_EX_DATA *from,CRYPTO_EX_DATA *to); +void CRYPTO_free_ex_data(STACK *meth,char *obj,CRYPTO_EX_DATA *ad); +void CRYPTO_new_ex_data(STACK *meth, char *obj, CRYPTO_EX_DATA *ad); + +int CRYPTO_mem_ctrl(int mode); +int CRYPTO_get_new_lockid(char *name); +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); +void CRYPTO_set_id_callback(unsigned long (*func)(void)); +unsigned long (*CRYPTO_get_id_callback(void))(void); +unsigned long CRYPTO_thread_id(void); +const char *CRYPTO_get_lock_name(int type); +int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file, + int line); + +void CRYPTO_set_mem_functions(void *(*m)(),void *(*r)(), void (*free_func)()); +void CRYPTO_get_mem_functions(void *(**m)(),void *(**r)(), void (**f)()); +void CRYPTO_set_locked_mem_functions(void *(*m)(), void (*free_func)()); +void CRYPTO_get_locked_mem_functions(void *(**m)(), void (**f)()); + +void *CRYPTO_malloc_locked(int num); +void CRYPTO_free_locked(void *); +void *CRYPTO_malloc(int num); +void CRYPTO_free(void *); +void *CRYPTO_realloc(void *addr,int num); +void *CRYPTO_remalloc(void *addr,int num); + +void *CRYPTO_dbg_malloc(int num,const char *file,int line); +void *CRYPTO_dbg_realloc(void *addr,int num,const char *file,int line); +void CRYPTO_dbg_free(void *); +void *CRYPTO_dbg_remalloc(void *addr,int num,const char *file,int line); +#ifndef 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 */ +void CRYPTO_mem_leaks_cb(void (*cb)()); + +void ERR_load_CRYPTO_strings(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. + */ + +/* Error codes for the CRYPTO functions. */ + +/* Function codes. */ +#define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100 +#define CRYPTO_F_CRYPTO_GET_NEW_LOCKID 101 +#define CRYPTO_F_CRYPTO_SET_EX_DATA 102 + +/* Reason codes. */ + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/lib/dns/sec/openssl/include/openssl/dh.h b/lib/dns/sec/openssl/include/openssl/dh.h new file mode 100644 index 00000000..2cc3797a --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/dh.h @@ -0,0 +1,158 @@ +/* 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 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef NO_DH +#error DH is disabled. +#endif + +#include <openssl/bn.h> + +#define DH_FLAG_CACHE_MONT_P 0x01 + +typedef 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; + int length; /* optional */ + BIGNUM *pub_key; /* y */ + BIGNUM *priv_key; /* x */ + + int flags; + char *method_mont_p; + } DH; + +#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_STRONG_PRIME 0x02 +#define DH_UNABLE_TO_CHECK_GENERATOR 0x04 +#define DH_NOT_SUITABLE_GENERATOR 0x08 + +#define DHparams_dup(x) (DH *)ASN1_dup((int (*)())i2d_DHparams, \ + (char *(*)())d2i_DHparams,(char *)(x)) +#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) (DH *)ASN1_d2i_bio((char *(*)())DH_new, \ + (char *(*)())d2i_DHparams,(bp),(unsigned char **)(x)) +#ifdef __cplusplus +#define i2d_DHparams_bio(bp,x) ASN1_i2d_bio((int (*)())i2d_DHparams,(bp), \ + (unsigned char *)(x)) +#else +#define i2d_DHparams_bio(bp,x) ASN1_i2d_bio(i2d_DHparams,(bp), \ + (unsigned char *)(x)) +#endif + +DH * DH_new(void); +void DH_free(DH *dh); +int DH_size(DH *dh); +DH * DH_generate_parameters(int prime_len,int generator, + void (*callback)(int,int,void *),void *cb_arg); +int DH_check(DH *dh,int *codes); +int DH_generate_key(DH *dh); +int DH_compute_key(unsigned char *key,BIGNUM *pub_key,DH *dh); +DH * d2i_DHparams(DH **a,unsigned char **pp, long length); +int i2d_DHparams(DH *a,unsigned char **pp); +#ifndef NO_FP_API +int DHparams_print_fp(FILE *fp, DH *x); +#endif +#ifdef HEADER_BIO_H +int DHparams_print(BIO *bp, DH *x); +#else +int DHparams_print(char *bp, DH *x); +#endif +void ERR_load_DH_strings(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. + */ + +/* Error codes for the DH functions. */ + +/* Function codes. */ +#define DH_F_DHPARAMS_PRINT 100 +#define DH_F_DHPARAMS_PRINT_FP 101 +#define DH_F_DH_COMPUTE_KEY 102 +#define DH_F_DH_GENERATE_KEY 103 +#define DH_F_DH_GENERATE_PARAMETERS 104 +#define DH_F_DH_NEW 105 + +/* Reason codes. */ +#define DH_R_NO_PRIVATE_VALUE 100 + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/lib/dns/sec/openssl/include/openssl/dsa.h b/lib/dns/sec/openssl/include/openssl/dsa.h new file mode 100644 index 00000000..d9ff1933 --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/dsa.h @@ -0,0 +1,195 @@ +/* crypto/dsa/dsa.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.] + */ + +/* + * The DSS routines are based on patches supplied by + * Steven Schoch <schoch@sheba.arc.nasa.gov>. He basically did the + * work and I have just tweaked them a little to fit into my + * stylistic vision for SSLeay :-) */ + +#ifndef HEADER_DSA_H +#define HEADER_DSA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef NO_DSA +#error DSA is disabled. +#endif + +#include <openssl/bn.h> + +#define DSA_FLAG_CACHE_MONT_P 0x01 + +typedef struct dsa_st + { + /* This first variable is used to pick up errors where + * a DSA is passed instead of of a EVP_PKEY */ + int pad; + int version; + int write_params; + BIGNUM *p; + BIGNUM *q; /* == 20 */ + BIGNUM *g; + + BIGNUM *pub_key; /* y public key */ + BIGNUM *priv_key; /* x private key */ + + BIGNUM *kinv; /* Signing pre-calc */ + BIGNUM *r; /* Signing pre-calc */ + + int flags; + /* Normally used to cache montgomery values */ + char *method_mont_p; + + int references; + } DSA; + +typedef struct DSA_SIG_st + { + BIGNUM *r; + BIGNUM *s; + } DSA_SIG; + +#define DSAparams_dup(x) (DSA *)ASN1_dup((int (*)())i2d_DSAparams, \ + (char *(*)())d2i_DSAparams,(char *)(x)) +#define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \ + (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x)) +#define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \ + (unsigned char *)(x)) +#define d2i_DSAparams_bio(bp,x) (DSA *)ASN1_d2i_bio((char *(*)())DSA_new, \ + (char *(*)())d2i_DSAparams,(bp),(unsigned char **)(x)) +#define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio(i2d_DSAparams,(bp), \ + (unsigned char *)(x)) + + +DSA_SIG * DSA_SIG_new(void); +void DSA_SIG_free(DSA_SIG *a); +int i2d_DSA_SIG(DSA_SIG *a, unsigned char **pp); +DSA_SIG * d2i_DSA_SIG(DSA_SIG **v, unsigned char **pp, long length); + +DSA_SIG * DSA_do_sign(const unsigned char *dgst,int dlen,DSA *dsa); +int DSA_do_verify(const unsigned char *dgst,int dgst_len, + DSA_SIG *sig,DSA *dsa); + +DSA * DSA_new(void); +int DSA_size(DSA *); + /* next 4 return -1 on error */ +int DSA_sign_setup( DSA *dsa,BN_CTX *ctx_in,BIGNUM **kinvp,BIGNUM **rp); +int DSA_sign(int type,const unsigned char *dgst,int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa); +int DSA_verify(int type,const unsigned char *dgst,int dgst_len, + unsigned char *sigbuf, int siglen, DSA *dsa); +void DSA_free (DSA *r); + +void ERR_load_DSA_strings(void ); + +DSA * d2i_DSAPublicKey(DSA **a, unsigned char **pp, long length); +DSA * d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length); +DSA * d2i_DSAparams(DSA **a, unsigned char **pp, long length); +DSA * DSA_generate_parameters(int bits, unsigned char *seed,int seed_len, + int *counter_ret, unsigned long *h_ret,void + (*callback)(),char *cb_arg); +int DSA_generate_key(DSA *a); +int i2d_DSAPublicKey(DSA *a, unsigned char **pp); +int i2d_DSAPrivateKey(DSA *a, unsigned char **pp); +int i2d_DSAparams(DSA *a,unsigned char **pp); + +#ifdef HEADER_BIO_H +int DSAparams_print(BIO *bp, DSA *x); +int DSA_print(BIO *bp, DSA *x, int off); +#endif +#ifndef NO_FP_API +int DSAparams_print_fp(FILE *fp, DSA *x); +int DSA_print_fp(FILE *bp, DSA *x, int off); +#endif + +int DSA_is_prime(BIGNUM *q,void (*callback)(),char *cb_arg); + +/* 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. + */ + +/* Error codes for the DSA functions. */ + +/* Function codes. */ +#define DSA_F_D2I_DSA_SIG 110 +#define DSA_F_DSAPARAMS_PRINT 100 +#define DSA_F_DSAPARAMS_PRINT_FP 101 +#define DSA_F_DSA_DO_SIGN 112 +#define DSA_F_DSA_DO_VERIFY 113 +#define DSA_F_DSA_IS_PRIME 102 +#define DSA_F_DSA_NEW 103 +#define DSA_F_DSA_PRINT 104 +#define DSA_F_DSA_PRINT_FP 105 +#define DSA_F_DSA_SIGN 106 +#define DSA_F_DSA_SIGN_SETUP 107 +#define DSA_F_DSA_SIG_NEW 109 +#define DSA_F_DSA_VERIFY 108 +#define DSA_F_I2D_DSA_SIG 111 + +/* Reason codes. */ +#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/lib/dns/sec/openssl/include/openssl/e_os.h b/lib/dns/sec/openssl/include/openssl/e_os.h new file mode 100644 index 00000000..b8d053bd --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/e_os.h @@ -0,0 +1,373 @@ +/* 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/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 your 'random' device if you have one. + * My default, we will try to read this file */ +#define DEVRANDOM "/dev/urandom" +#endif + +/******************************************************************** + The Microsoft section + ********************************************************************/ +/* The following is used becaue of the small stack in some + * Microsoft operating systems */ +#if defined(WIN16) || defined(MSDOS) +# define MS_STATIC static +#else +# define MS_STATIC +#endif + +#if defined(WIN32) || defined(WIN16) +# ifndef WINDOWS +# define WINDOWS +# endif +# ifndef MSDOS +# define MSDOS +# endif +#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 + +#ifdef 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) +#define EADDRINUSE WSAEADDRINUSE +#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 +# define NO_FP_API +# define MS_CALLBACK _far _loadds +# define MS_FAR _far +#else +# define MS_CALLBACK +# define MS_FAR +#endif + +#ifdef NO_STDIO +# define NO_FP_API +#endif + +#if defined(WINDOWS) || defined(MSDOS) + +#ifndef S_IFDIR +#define S_IFDIR _S_IFDIR +#endif + +#ifndef S_IFMT +#define S_IFMT _S_IFMT + +#if !defined(WINNT) +#define NO_SYSLOG +#endif +#define NO_DIRENT + +#endif + +# ifdef WINDOWS +# include <windows.h> +# include <stddef.h> +# include <errno.h> +# include <string.h> +# include <malloc.h> +# endif +# include <io.h> +# include <fcntl.h> + +#if defined (__BORLANDC__) +#define _setmode setmode +#define _O_TEXT O_TEXT +#define _O_BINARY O_BINARY +#define _int64 __int64 +#endif + +#if defined(WIN16) && !defined(MONOLITH) && defined(SSLEAY) && defined(_WINEXITNOPERSIST) +# define EXIT(n) { if (n == 0) _wsetexit(_WINEXITNOPERSIST); return(n); } +#else +# define EXIT(n) return(n); +#endif +# 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" + +#else /* The non-microsoft world world */ + +# if defined(__VMS) && !defined(VMS) +# define VMS 1 +# endif + +# ifdef VMS + /* 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 need to do this, because DEC C converts exit code 0 to 1, but not 1 + to 0. We will convert 1 to 3! Also, add the inhibit message bit... */ +# ifndef MONOLITH +# define EXIT(n) do { int __VMS_EXIT = n; \ + if (__VMS_EXIT == 1) __VMS_EXIT = 3; \ + __VMS_EXIT |= 0x10000000; \ + exit(n); return(n); } while(0) +# else +# define EXIT(n) do { int __VMS_EXIT = n; \ + if (__VMS_EXIT == 1) __VMS_EXIT = 3; \ + __VMS_EXIT |= 0x10000000; \ + return(n); } while(0) +# endif +# else +# include <unistd.h> + +# define OPENSSL_CONF "openssl.cnf" +# define SSLEAY_CONF OPENSSL_CONF +# define RFILE ".rnd" +# define LIST_SEPARATOR_CHAR ':' +# define NUL_DEV "/dev/null" +# ifndef MONOLITH +# define EXIT(n) exit(n); return(n) +# else +# define EXIT(n) return(n) +# endif +# endif + +# define SSLeay_getpid() getpid() + +#endif + + +/*************/ + +#ifdef USE_SOCKETS +# if defined(WINDOWS) || defined(MSDOS) + /* windows world */ + +# ifdef 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) +# else +# include <winsock.h> +extern HINSTANCE _hInstance; +# 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); } +# endif + + +# else + +# include <sys/types.h> +# ifndef VMS +# include <sys/param.h> +# endif +# include <sys/time.h> /* Needed under linux for FD_XXX */ + +# include <netdb.h> +# if defined(VMS) && !defined(__DECC) +# include <socket.h> +# include <in.h> +# else +# include <sys/socket.h> +# ifdef FILIO_H +# include <sys/filio.h> /* Added for FIONBIO under unixware */ +# endif +# include <netinet/in.h> +# endif + +# if defined(NeXT) || defined(_NEXT_SOURCE) +# include <sys/fcntl.h> +# include <sys/types.h> +# endif + +# ifdef AIX +# 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); close((fd)); } +# define SHUTDOWN2(fd) { shutdown((fd),2); close((fd)); } +# define INVALID_SOCKET (-1) +# endif +#endif + +#if defined(THREADS) || defined(sun) +#ifndef _REENTRANT +#define _REENTRANT +#endif +#endif + +/***********************************************/ + +/* do we need to do this for getenv. + * Just define getenv for use under windows */ + +#ifdef WIN16 +/* How to do this needs to be thought out a bit more.... */ +/*char *GETENV(char *); +#define Getenv GETENV*/ +#define Getenv getenv +#else +#define Getenv getenv +#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 SNI +#define IRIX_CC_BUG /* CDS++ up to V2.0Bsomething suffered from the same bug.*/ +#endif + +#ifdef NO_MD2 +#define MD2_Init MD2Init +#define MD2_Update MD2Update +#define MD2_Final MD2Final +#define MD2_DIGEST_LENGTH 16 +#endif +#ifdef NO_MD5 +#define MD5_Init MD5Init +#define MD5_Update MD5Update +#define MD5_Final MD5Final +#define MD5_DIGEST_LENGTH 16 +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/lib/dns/sec/openssl/include/openssl/e_os2.h b/lib/dns/sec/openssl/include/openssl/e_os2.h new file mode 100644 index 00000000..2bc0b487 --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/e_os2.h @@ -0,0 +1,28 @@ +/* e_os2.h */ + +#ifndef HEADER_E_OS2_H +#define HEADER_E_OS2_H + +#ifdef __cplusplus +extern "C" { +#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. On other OS:es, + these macros are defined with something sensible. */ + +#if defined(VMS) && !defined(__DECC) +# define OPENSSL_EXTERN globalref +# define OPENSSL_GLOBAL globaldef +#else +# define OPENSSL_EXTERN extern +# define OPENSSL_GLOBAL +#endif + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/lib/dns/sec/openssl/include/openssl/err.h b/lib/dns/sec/openssl/include/openssl/err.h new file mode 100644 index 00000000..0ef83d5e --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/err.h @@ -0,0 +1,262 @@ +/* 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.] + */ + +#ifndef HEADER_ERR_H +#define HEADER_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NO_FP_API +#include <stdio.h> +#endif + +/* The following is a bit of a trick to help the object files only contain + * the 'name of the file' string once. Since 'err.h' is protected by the + * HEADER_ERR_H stuff, this should be included only once per file. */ + +#define ERR_file_name __FILE__ + +#ifndef 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_NUM_ERRORS 16 +typedef struct err_state_st + { + unsigned long pid; + 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_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_USER 128 + +#define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),ERR_file_name,__LINE__) +#define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),ERR_file_name,__LINE__) +#define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),ERR_file_name,__LINE__) +#define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),ERR_file_name,__LINE__) +#define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),ERR_file_name,__LINE__) +#define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),ERR_file_name,__LINE__) +#define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),ERR_file_name,__LINE__) +#define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),ERR_file_name,__LINE__) +#define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),ERR_file_name,__LINE__) +#define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),ERR_file_name,__LINE__) +#define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),ERR_file_name,__LINE__) +#define METHerr(f,r) ERR_PUT_error(ERR_LIB_METH,(f),(r),ERR_file_name,__LINE__) +#define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),ERR_file_name,__LINE__) +#define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),ERR_file_name,__LINE__) +#define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),ERR_file_name,__LINE__) +#define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),ERR_file_name,__LINE__) +#define SSL23err(f,r) ERR_PUT_error(ERR_LIB_SSL23,(f),(r),ERR_file_name,__LINE__) +#define SSL2err(f,r) ERR_PUT_error(ERR_LIB_SSL2,(f),(r),ERR_file_name,__LINE__) +#define SSL3err(f,r) ERR_PUT_error(ERR_LIB_SSL3,(f),(r),ERR_file_name,__LINE__) +#define RSAREFerr(f,r) ERR_PUT_error(ERR_LIB_RSAREF,(f),(r),ERR_file_name,__LINE__) +#define PROXYerr(f,r) ERR_PUT_error(ERR_LIB_PROXY,(f),(r),ERR_file_name,__LINE__) +#define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),ERR_file_name,__LINE__) +#define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),ERR_file_name,__LINE__) +#define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),ERR_file_name,__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 fuctions */ +#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 ERR_R_FATAL 32 +/* reasons */ +#define ERR_R_SYS_LIB ERR_LIB_SYS +#define ERR_R_BN_LIB ERR_LIB_BN +#define ERR_R_RSA_LIB ERR_LIB_RSA +#define ERR_R_DSA_LIB ERR_LIB_DSA +#define ERR_R_DH_LIB ERR_LIB_DH +#define ERR_R_EVP_LIB ERR_LIB_EVP +#define ERR_R_BUF_LIB ERR_LIB_BUF +#define ERR_R_BIO_LIB ERR_LIB_BIO +#define ERR_R_OBJ_LIB ERR_LIB_OBJ +#define ERR_R_PEM_LIB ERR_LIB_PEM +#define ERR_R_X509_LIB ERR_LIB_X509 +#define ERR_R_METH_LIB ERR_LIB_METH +#define ERR_R_ASN1_LIB ERR_LIB_ASN1 +#define ERR_R_CONF_LIB ERR_LIB_CONF +#define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO +#define ERR_R_SSL_LIB ERR_LIB_SSL +#define ERR_R_SSL23_LIB ERR_LIB_SSL23 +#define ERR_R_SSL2_LIB ERR_LIB_SSL2 +#define ERR_R_SSL3_LIB ERR_LIB_SSL3 +#define ERR_R_PROXY_LIB ERR_LIB_PROXY +#define ERR_R_BIO_LIB ERR_LIB_BIO +#define ERR_R_PKCS7_LIB ERR_LIB_PKCS7 +#define ERR_R_PKCS12_LIB ERR_LIB_PKCS12 + +/* fatal error */ +#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_NESTED_ASN1_ERROR (4) +#define ERR_R_BAD_ASN1_OBJECT_HEADER (5) +#define ERR_R_BAD_GET_ASN1_OBJECT_CALL (6) +#define ERR_R_EXPECTING_AN_ASN1_SEQUENCE (7) +#define ERR_R_ASN1_LENGTH_MISMATCH (8) +#define ERR_R_MISSING_ASN1_EOS (9) + +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); +void ERR_clear_error(void ); +char *ERR_error_string(unsigned long e,char *buf); +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); +#ifndef NO_FP_API +void ERR_print_errors_fp(FILE *fp); +#endif +#ifdef HEADER_BIO_H +void ERR_print_errors(BIO *bp); +void ERR_add_error_data(int num, ...); +#endif +void ERR_load_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_state(unsigned long pid); /* if zero we look it up */ +ERR_STATE *ERR_get_state(void); + +#ifdef HEADER_LHASH_H +LHASH *ERR_get_string_table(void ); +LHASH *ERR_get_err_state_table(void ); +#else +char *ERR_get_string_table(void ); +char *ERR_get_err_state_table(void ); +#endif + +int ERR_get_next_error_library(void ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/openssl/include/openssl/lhash.h b/lib/dns/sec/openssl/include/openssl/lhash.h new file mode 100644 index 00000000..6e5a1fe7 --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/lhash.h @@ -0,0 +1,144 @@ +/* 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 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NO_FP_API +#include <stdio.h> +#endif + +typedef struct lhash_node_st + { + char *data; + struct lhash_node_st *next; +#ifndef NO_HASH_COMP + unsigned long hash; +#endif + } LHASH_NODE; + +typedef struct lhash_st + { + LHASH_NODE **b; + int (*comp)(); + unsigned long (*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; + +#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(unsigned long (*h)(), int (*c)()); +void lh_free(LHASH *lh); +char *lh_insert(LHASH *lh, char *data); +char *lh_delete(LHASH *lh, char *data); +char *lh_retrieve(LHASH *lh, char *data); +void lh_doall(LHASH *lh, void (*func)(/* char *b */)); +void lh_doall_arg(LHASH *lh, void (*func)(/*char *a,char *b*/),char *arg); +unsigned long lh_strhash(const char *c); + +#ifndef NO_FP_API +void lh_stats(LHASH *lh, FILE *out); +void lh_node_stats(LHASH *lh, FILE *out); +void lh_node_usage_stats(LHASH *lh, FILE *out); +#endif + +#ifdef HEADER_BIO_H +void lh_stats_bio(LHASH *lh, BIO *out); +void lh_node_stats_bio(LHASH *lh, BIO *out); +void lh_node_usage_stats_bio(LHASH *lh, BIO *out); +#endif +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/lib/dns/sec/openssl/include/openssl/md5.h b/lib/dns/sec/openssl/include/openssl/md5.h new file mode 100644 index 00000000..bdab6d45 --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/md5.h @@ -0,0 +1,114 @@ +/* crypto/md5/md5.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_MD5_H +#define HEADER_MD5_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef NO_MD5 +#error MD5 is disabled. +#endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! MD5_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#if defined(WIN16) || defined(__LP32__) +#define MD5_LONG unsigned long +#elif defined(_CRAY) || defined(__ILP64__) +#define MD5_LONG unsigned long +#define MD5_LONG_LOG2 3 +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * <appro@fy.chalmers.se> + */ +#else +#define MD5_LONG unsigned int +#endif + +#define MD5_CBLOCK 64 +#define MD5_LBLOCK (MD5_CBLOCK/4) +#define MD5_DIGEST_LENGTH 16 + +typedef struct MD5state_st + { + MD5_LONG A,B,C,D; + MD5_LONG Nl,Nh; + MD5_LONG data[MD5_LBLOCK]; + int num; + } MD5_CTX; + +void MD5_Init(MD5_CTX *c); +void MD5_Update(MD5_CTX *c, const unsigned char *data, unsigned long len); +void MD5_Final(unsigned char *md, MD5_CTX *c); +unsigned char *MD5(unsigned char *d, unsigned long n, unsigned char *md); +void MD5_Transform(MD5_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/openssl/include/openssl/opensslconf.h b/lib/dns/sec/openssl/include/openssl/opensslconf.h new file mode 100644 index 00000000..1ff8fea1 --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/opensslconf.h @@ -0,0 +1,7 @@ +#ifndef HEADER_OPENSSLCONF_H +#define HEADER_OPENSSLCONF_H + +/* This would be filled in by the openssl configure script if it was run. */ + +#endif /* HEADER_OPENSSLCONF_H */ + diff --git a/lib/dns/sec/openssl/include/openssl/opensslv.h b/lib/dns/sec/openssl/include/openssl/opensslv.h new file mode 100644 index 00000000..b34462e9 --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/opensslv.h @@ -0,0 +1,20 @@ +#ifndef HEADER_OPENSSLV_H +#define HEADER_OPENSSLV_H + +/* Numeric release version identifier: + * MMNNFFRBB: major minor fix final beta/patch + * For example: + * 0.9.3-dev 0x00903000 + * 0.9.3beta1 0x00903001 + * 0.9.3beta2-dev 0x00903002 + * 0.9.3beta2 0x00903002 + * 0.9.3 0x00903100 + * 0.9.3a 0x00903101 + * 1.2.3z 0x1020311a + * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.) + */ +#define OPENSSL_VERSION_NUMBER 0x00903101L +#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.3a 29 May 1999" +#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT + +#endif /* HEADER_OPENSSLV_H */ diff --git a/lib/dns/sec/openssl/include/openssl/rand.h b/lib/dns/sec/openssl/include/openssl/rand.h new file mode 100644 index 00000000..fd8ee383 --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/rand.h @@ -0,0 +1,89 @@ +/* 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 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rand_meth_st + { + void (*seed)(const void *buf, int num); + void (*bytes)(unsigned char *buf, int num); + void (*cleanup)(void); + } RAND_METHOD; + +void RAND_set_rand_method(RAND_METHOD *meth); +RAND_METHOD *RAND_get_rand_method(void ); +RAND_METHOD *RAND_SSLeay(void); +void RAND_cleanup(void ); +void RAND_bytes(unsigned char *buf,int num); +void RAND_seed(const void *buf,int num); +int RAND_load_file(const char *file,long max_bytes); +int RAND_write_file(const char *file); +char *RAND_file_name(char *file,int num); +#ifdef WINDOWS +void RAND_screen(void); +#endif +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/openssl/include/openssl/sha.h b/lib/dns/sec/openssl/include/openssl/sha.h new file mode 100644 index 00000000..cd6960ee --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/sha.h @@ -0,0 +1,119 @@ +/* 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 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef NO_SHA +#error SHA is disabled. +#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(WIN16) || defined(__LP32__) +#define SHA_LONG unsigned long +#elif defined(_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]; + int num; + } SHA_CTX; + +#ifndef NO_SHA0 +void SHA_Init(SHA_CTX *c); +void SHA_Update(SHA_CTX *c, const unsigned char *data, unsigned long len); +void SHA_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA(const unsigned char *d, unsigned long n,unsigned char *md); +void SHA_Transform(SHA_CTX *c, unsigned char *data); +#endif +#ifndef NO_SHA1 +void SHA1_Init(SHA_CTX *c); +void SHA1_Update(SHA_CTX *c, const unsigned char *data, unsigned long len); +void SHA1_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA1(const unsigned char *d, unsigned long n,unsigned char *md); +void SHA1_Transform(SHA_CTX *c, unsigned char *data); +#endif +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/openssl/include/openssl/stack.h b/lib/dns/sec/openssl/include/openssl/stack.h new file mode 100644 index 00000000..ec629d0f --- /dev/null +++ b/lib/dns/sec/openssl/include/openssl/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)(); + } STACK; + + +#define sk_new_null() sk_new(NULL) + +#define M_sk_num(sk) ((sk)->num) +#define M_sk_value(sk,n) ((sk)->data[n]) + +int sk_num(STACK *); +char *sk_value(STACK *, int); + +char *sk_set(STACK *, int, char *); + +STACK *sk_new(int (*cmp)()); +void sk_free(STACK *); +void sk_pop_free(STACK *st, void (*func)()); +int sk_insert(STACK *sk,char *data,int where); +char *sk_delete(STACK *st,int loc); +char *sk_delete_ptr(STACK *st, char *p); +int sk_find(STACK *st,char *data); +int sk_push(STACK *st,char *data); +int sk_unshift(STACK *st,char *data); +char *sk_shift(STACK *st); +char *sk_pop(STACK *st); +void sk_zero(STACK *st); +int (*sk_set_cmp_func(STACK *sk, int (*c)()))(); +STACK *sk_dup(STACK *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/dns/sec/openssl/lhash.c b/lib/dns/sec/openssl/lhash.c new file mode 100644 index 00000000..801322be --- /dev/null +++ b/lib/dns/sec/openssl/lhash.c @@ -0,0 +1,476 @@ +/* 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 occured 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 + * skiping 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) */ + + +#define P_CP char * +#define P_CPP char *,char * +static void expand(LHASH *lh); +static void contract(LHASH *lh); +static LHASH_NODE **getrn(LHASH *lh, char *data, unsigned long *rhash); + +LHASH *lh_new(unsigned long (*h)(), int (*c)()) + { + LHASH *ret; + int i; + + if ((ret=(LHASH *)Malloc(sizeof(LHASH))) == NULL) + goto err0; + if ((ret->b=(LHASH_NODE **)Malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL) + goto err1; + for (i=0; i<MIN_NODES; i++) + ret->b[i]=NULL; + ret->comp=((c == NULL)?(int (*)())strcmp:c); + ret->hash=((h == NULL)?(unsigned long (*)())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: + Free((char *)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; + Free(n); + n=nn; + } + } + Free((char *)lh->b); + Free((char *)lh); + } + +char *lh_insert(LHASH *lh, char *data) + { + unsigned long hash; + LHASH_NODE *nn,**rn; + char *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 *)Malloc(sizeof(LHASH_NODE))) == NULL) + { + lh->error++; + return(NULL); + } + nn->data=data; + nn->next=NULL; +#ifndef 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); + } + +char *lh_delete(LHASH *lh, char *data) + { + unsigned long hash; + LHASH_NODE *nn,**rn; + char *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; + Free((char *)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); + } + +char *lh_retrieve(LHASH *lh, char *data) + { + unsigned long hash; + LHASH_NODE **rn; + char *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); + } + +void lh_doall(LHASH *lh, void (*func)()) + { + lh_doall_arg(lh,func,NULL); + } + +void lh_doall_arg(LHASH *lh, void (*func)(), char *arg) + { + int i; + LHASH_NODE *a,*n; + + /* 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 */ + n=a->next; + func(a->data,arg); + a=n; + } + } + } + +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 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 **)Realloc((char *)lh->b, + (unsigned 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 **)Realloc((char *)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, char *data, unsigned long *rhash) + { + LHASH_NODE **ret,*n1; + unsigned long hash,nn; + int (*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 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); + } + +/* +static unsigned long lh_strhash(str) +char *str; + { + int i,l; + unsigned long ret=0; + unsigned short *s; + + if (str == NULL) return(0); + l=(strlen(str)+1)/2; + s=(unsigned short *)str; + for (i=0; i<l; i++) + ret^=(s[i]<<(i&0x0f)); + 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); + } + diff --git a/lib/dns/sec/openssl/md32_common.h b/lib/dns/sec/openssl/md32_common.h new file mode 100644 index 00000000..f19e1bf7 --- /dev/null +++ b/lib/dns/sec/openssl/md32_common.h @@ -0,0 +1,594 @@ +/* crypto/md32_common.h */ +/* ==================================================================== + * 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). + * + */ + +/* + * 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; + * HASH_LONG data[HASH_LBLOCK]; + * int num; + * ... + * } HASH_CTX; + * 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_HOST_ORDER + * name of "block" function treating *aligned* input message + * in host byte order, implemented externally. + * HASH_BLOCK_DATA_ORDER + * name of "block" function treating *unaligned* input message + * in original (data) byte order, implemented externally (it + * actually is optional if data and host are of the same + * "endianess"). + * + * Optional macros: + * + * B_ENDIAN or L_ENDIAN + * defines host byte-order. + * HASH_LONG_LOG2 + * defaults to 2 if not states otherwise. + * HASH_LBLOCK + * assumed to be HASH_CBLOCK/4 if not stated otherwise. + * HASH_BLOCK_DATA_ORDER_ALIGNED + * alternative "block" function capable of treating + * aligned input message in original (data) order, + * implemented externally. + * + * 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_LBLOCK MD5_LBLOCK + * #define HASH_UPDATE MD5_Update + * #define HASH_TRANSFORM MD5_Transform + * #define HASH_FINAL MD5_Final + * #define HASH_BLOCK_HOST_ORDER md5_block_host_order + * #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_HOST_ORDER +#error "HASH_BLOCK_HOST_ORDER must be defined!" +#endif + +#if 0 +/* + * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED + * isn't defined. + */ +#ifndef HASH_BLOCK_DATA_ORDER +#error "HASH_BLOCK_DATA_ORDER must be defined!" +#endif +#endif + +#ifndef HASH_LBLOCK +#define HASH_LBLOCK (HASH_CBLOCK/4) +#endif + +#ifndef HASH_LONG_LOG2 +#define HASH_LONG_LOG2 2 +#endif + +/* + * Engage compiler specific rotate intrinsic function if available. + */ +#undef ROTATE +#ifndef PEDANTIC +# if defined(_MSC_VER) +# define ROTATE(a,n) _lrotl(a,n) +# elif defined(__GNUC__) && __GNUC__>=2 + /* + * 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) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm volatile ( \ + "roll %1,%0" \ + : "=r"(ret) \ + : "I"(n), "0"(a) \ + : "cc"); \ + ret; \ + }) +# elif defined(__powerpc) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm volatile ( \ + "rlwinm %0,%1,%2,0,31" \ + : "=r"(ret) \ + : "r"(a), "I"(n)); \ + ret; \ + }) +# endif +# endif + +/* + * Engage compiler specific "fetch in reverse byte order" + * intrinsic function if available. + */ +# if defined(__GNUC__) && __GNUC__>=2 + /* some GNU C inline assembler templates by <appro@fy.chalmers.se> */ +# if defined(__i386) && !defined(I386_ONLY) +# define BE_FETCH32(a) ({ register unsigned int l=(a);\ + asm volatile ( \ + "bswapl %0" \ + : "=r"(l) : "0"(l)); \ + l; \ + }) +# elif defined(__powerpc) +# define LE_FETCH32(a) ({ register unsigned int l; \ + asm volatile ( \ + "lwbrx %0,0,%1" \ + : "=r"(l) \ + : "r"(a)); \ + l; \ + }) + +# elif defined(__sparc) && defined(ULTRASPARC) +# define LE_FETCH32(a) ({ register unsigned int l; \ + asm volatile ( \ + "lda [%1]#ASI_PRIMARY_LITTLE,%0"\ + : "=r"(l) \ + : "r"(a)); \ + l; \ + }) +# endif +# endif +#endif /* PEDANTIC */ + +#if HASH_LONG_LOG2==2 /* Engage only if sizeof(HASH_LONG)== 4 */ +/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */ +#ifdef ROTATE +/* 5 instructions with rotate instruction, else 9 */ +#define REVERSE_FETCH32(a,l) ( \ + l=*(const HASH_LONG *)(a), \ + ((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24))) \ + ) +#else +/* 6 instructions with rotate instruction, else 8 */ +#define REVERSE_FETCH32(a,l) ( \ + l=*(const HASH_LONG *)(a), \ + l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)), \ + ROTATE(l,16) \ + ) +/* + * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|... + * It's rewritten as above for two reasons: + * - RISCs aren't good at long constants and have to explicitely + * compose 'em with several (well, usually 2) instructions in a + * register before performing the actual operation and (as you + * already realized:-) having same constant should inspire the + * compiler to permanently allocate the only register for it; + * - most modern CPUs have two ALUs, but usually only one has + * circuitry for shifts:-( this minor tweak inspires compiler + * to schedule shift instructions in a better way... + * + * <appro@fy.chalmers.se> + */ +#endif +#endif + +#ifndef ROTATE +#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) +#endif + +/* + * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED + * and HASH_BLOCK_HOST_ORDER ought to be the same if input data + * and host are of the same "endianess". It's possible to mask + * this with blank #define HASH_BLOCK_DATA_ORDER though... + * + * <appro@fy.chalmers.se> + */ +#if defined(B_ENDIAN) +# if defined(DATA_ORDER_IS_BIG_ENDIAN) +# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 +# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER +# endif +# elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) +# ifndef HOST_FETCH32 +# ifdef LE_FETCH32 +# define HOST_FETCH32(p,l) LE_FETCH32(p) +# elif defined(REVERSE_FETCH32) +# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l) +# endif +# endif +# endif +#elif defined(L_ENDIAN) +# if defined(DATA_ORDER_IS_LITTLE_ENDIAN) +# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 +# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER +# endif +# elif defined(DATA_ORDER_IS_BIG_ENDIAN) +# ifndef HOST_FETCH32 +# ifdef BE_FETCH32 +# define HOST_FETCH32(p,l) BE_FETCH32(p) +# elif defined(REVERSE_FETCH32) +# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l) +# endif +# endif +# endif +#endif + +#if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) || HASH_BLOCK_DATA_ORDER_ALIGNED==1 +#ifndef HASH_BLOCK_DATA_ORDER +#error "HASH_BLOCK_DATA_ORDER must be defined!" +#endif +#endif + +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + +#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++))) ), \ + l) +#define HOST_p_c2l(c,l,n) { \ + switch (n) { \ + case 0: l =((unsigned long)(*((c)++)))<<24; \ + case 1: l|=((unsigned long)(*((c)++)))<<16; \ + case 2: l|=((unsigned long)(*((c)++)))<< 8; \ + case 3: l|=((unsigned long)(*((c)++))); \ + } } +#define HOST_p_c2l_p(c,l,sc,len) { \ + switch (sc) { \ + case 0: l =((unsigned long)(*((c)++)))<<24; \ + if (--len == 0) break; \ + case 1: l|=((unsigned long)(*((c)++)))<<16; \ + if (--len == 0) break; \ + case 2: l|=((unsigned long)(*((c)++)))<< 8; \ + } } +/* NOTE the pointer is not incremented at the end of this */ +#define HOST_c2l_p(c,l,n) { \ + l=0; (c)+=n; \ + switch (n) { \ + case 3: l =((unsigned long)(*(--(c))))<< 8; \ + case 2: l|=((unsigned long)(*(--(c))))<<16; \ + case 1: l|=((unsigned long)(*(--(c))))<<24; \ + } } +#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) + +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + +#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24), \ + l) +#define HOST_p_c2l(c,l,n) { \ + switch (n) { \ + case 0: l =((unsigned long)(*((c)++))); \ + case 1: l|=((unsigned long)(*((c)++)))<< 8; \ + case 2: l|=((unsigned long)(*((c)++)))<<16; \ + case 3: l|=((unsigned long)(*((c)++)))<<24; \ + } } +#define HOST_p_c2l_p(c,l,sc,len) { \ + switch (sc) { \ + case 0: l =((unsigned long)(*((c)++))); \ + if (--len == 0) break; \ + case 1: l|=((unsigned long)(*((c)++)))<< 8; \ + if (--len == 0) break; \ + case 2: l|=((unsigned long)(*((c)++)))<<16; \ + } } +/* NOTE the pointer is not incremented at the end of this */ +#define HOST_c2l_p(c,l,n) { \ + l=0; (c)+=n; \ + switch (n) { \ + case 3: l =((unsigned long)(*(--(c))))<<16; \ + case 2: l|=((unsigned long)(*(--(c))))<< 8; \ + case 1: l|=((unsigned long)(*(--(c)))); \ + } } +#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 + +/* + * Time for some action:-) + */ + +void HASH_UPDATE (HASH_CTX *c, const unsigned char *data, unsigned long len) + { + register HASH_LONG * p; + register unsigned long l; + int sw,sc,ew,ec; + + if (len==0) return; + + l=(c->Nl+(len<<3))&0xffffffffL; + /* 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+=(len>>29); + c->Nl=l; + + if (c->num != 0) + { + p=c->data; + sw=c->num>>2; + sc=c->num&0x03; + + if ((c->num+len) >= HASH_CBLOCK) + { + l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l; + for (; sw<HASH_LBLOCK; sw++) + { + HOST_c2l(data,l); p[sw]=l; + } + HASH_BLOCK_HOST_ORDER (c,p,1); + len-=(HASH_CBLOCK-c->num); + c->num=0; + /* drop through and do the rest */ + } + else + { + c->num+=len; + if ((sc+len) < 4) /* ugly, add char's to a word */ + { + l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l; + } + else + { + ew=(c->num>>2); + ec=(c->num&0x03); + l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l; + for (; sw < ew; sw++) + { + HOST_c2l(data,l); p[sw]=l; + } + if (ec) + { + HOST_c2l_p(data,l,ec); p[sw]=l; + } + } + return; + } + } + + sw=len/HASH_CBLOCK; + if (sw > 0) + { +#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_BLOCK_DATA_ORDER_ALIGNED!=1 + /* + * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined + * only if sizeof(HASH_LONG)==4. + */ + if ((((unsigned long)data)%4) == 0) + { + /* data is properly aligned so that we can cast it: */ + HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,sw); + sw*=HASH_CBLOCK; + data+=sw; + len-=sw; + } + else +#if !defined(HASH_BLOCK_DATA_ORDER) + while (sw--) + { + memcpy (p=c->data,data,HASH_CBLOCK); + HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1); + data+=HASH_CBLOCK; + len-=HASH_CBLOCK; + } +#endif +#endif +#if defined(HASH_BLOCK_DATA_ORDER) + { + HASH_BLOCK_DATA_ORDER(c,data,sw); + sw*=HASH_CBLOCK; + data+=sw; + len-=sw; + } +#endif + } + + if (len!=0) + { + p = c->data; + c->num = len; + ew=len>>2; /* words to copy */ + ec=len&0x03; + for (; ew; ew--,p++) + { + HOST_c2l(data,l); *p=l; + } + HOST_c2l_p(data,l,ec); + *p=l; + } + } + + +void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data) + { +#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_BLOCK_DATA_ORDER_ALIGNED!=1 + if ((((unsigned long)data)%4) == 0) + /* data is properly aligned so that we can cast it: */ + HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,1); + else +#if !defined(HASH_BLOCK_DATA_ORDER) + { + memcpy (c->data,data,HASH_CBLOCK); + HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1); + } +#endif +#endif +#if defined(HASH_BLOCK_DATA_ORDER) + HASH_BLOCK_DATA_ORDER (c,data,1); +#endif + } + + +void HASH_FINAL (unsigned char *md, HASH_CTX *c) + { + register HASH_LONG *p; + register unsigned long l; + register int i,j; + static const unsigned char end[4]={0x80,0x00,0x00,0x00}; + const unsigned char *cp=end; + + /* c->num should definitly have room for at least one more byte. */ + p=c->data; + i=c->num>>2; + j=c->num&0x03; + +#if 0 + /* purify often complains about the following line as an + * Uninitialized Memory Read. While this can be true, the + * following p_c2l macro will reset l when that case is true. + * This is because j&0x03 contains the number of 'valid' bytes + * already in p[i]. If and only if j&0x03 == 0, the UMR will + * occur but this is also the only time p_c2l will do + * l= *(cp++) instead of l|= *(cp++) + * Many thanks to Alex Tang <altitude@cic.net> for pickup this + * 'potential bug' */ +#ifdef PURIFY + if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */ +#endif + l=p[i]; +#else + l = (j==0) ? 0 : p[i]; +#endif + HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */ + + if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */ + { + if (i<HASH_LBLOCK) p[i]=0; + HASH_BLOCK_HOST_ORDER (c,p,1); + i=0; + } + for (; i<(HASH_LBLOCK-2); i++) + p[i]=0; + +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + p[HASH_LBLOCK-2]=c->Nh; + p[HASH_LBLOCK-1]=c->Nl; +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + p[HASH_LBLOCK-2]=c->Nl; + p[HASH_LBLOCK-1]=c->Nh; +#endif + HASH_BLOCK_HOST_ORDER (c,p,1); + + l=c->A; HOST_l2c(l,md); + l=c->B; HOST_l2c(l,md); + l=c->C; HOST_l2c(l,md); + l=c->D; HOST_l2c(l,md); + + c->num=0; + /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack + * but I'm not worried :-) + memset((void *)c,0,sizeof(HASH_CTX)); + */ + } diff --git a/lib/dns/sec/openssl/md5_dgst.c b/lib/dns/sec/openssl/md5_dgst.c new file mode 100644 index 00000000..ba0115ae --- /dev/null +++ b/lib/dns/sec/openssl/md5_dgst.c @@ -0,0 +1,317 @@ +/* crypto/md5/md5_dgst.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 "md5_locl.h" +#include <openssl/opensslv.h> + +char *MD5_version="MD5" OPENSSL_VERSION_PTEXT; + +/* Implemented from RFC1321 The MD5 Message-Digest Algorithm + */ + +#define INIT_DATA_A (unsigned long)0x67452301L +#define INIT_DATA_B (unsigned long)0xefcdab89L +#define INIT_DATA_C (unsigned long)0x98badcfeL +#define INIT_DATA_D (unsigned long)0x10325476L + +void MD5_Init(MD5_CTX *c) + { + c->A=INIT_DATA_A; + c->B=INIT_DATA_B; + c->C=INIT_DATA_C; + c->D=INIT_DATA_D; + c->Nl=0; + c->Nh=0; + c->num=0; + } + +#ifndef md5_block_host_order +void md5_block_host_order (MD5_CTX *c, const void *data, int num) + { + const MD5_LONG *X=data; + register unsigned long A,B,C,D; + /* + * 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> + */ + + A=c->A; + B=c->B; + C=c->C; + D=c->D; + + for (;num--;X+=HASH_LBLOCK) + { + /* Round 0 */ + R0(A,B,C,D,X[ 0], 7,0xd76aa478L); + R0(D,A,B,C,X[ 1],12,0xe8c7b756L); + R0(C,D,A,B,X[ 2],17,0x242070dbL); + R0(B,C,D,A,X[ 3],22,0xc1bdceeeL); + R0(A,B,C,D,X[ 4], 7,0xf57c0fafL); + R0(D,A,B,C,X[ 5],12,0x4787c62aL); + R0(C,D,A,B,X[ 6],17,0xa8304613L); + R0(B,C,D,A,X[ 7],22,0xfd469501L); + R0(A,B,C,D,X[ 8], 7,0x698098d8L); + R0(D,A,B,C,X[ 9],12,0x8b44f7afL); + R0(C,D,A,B,X[10],17,0xffff5bb1L); + R0(B,C,D,A,X[11],22,0x895cd7beL); + R0(A,B,C,D,X[12], 7,0x6b901122L); + R0(D,A,B,C,X[13],12,0xfd987193L); + R0(C,D,A,B,X[14],17,0xa679438eL); + R0(B,C,D,A,X[15],22,0x49b40821L); + /* Round 1 */ + R1(A,B,C,D,X[ 1], 5,0xf61e2562L); + R1(D,A,B,C,X[ 6], 9,0xc040b340L); + R1(C,D,A,B,X[11],14,0x265e5a51L); + R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL); + R1(A,B,C,D,X[ 5], 5,0xd62f105dL); + R1(D,A,B,C,X[10], 9,0x02441453L); + R1(C,D,A,B,X[15],14,0xd8a1e681L); + R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L); + R1(A,B,C,D,X[ 9], 5,0x21e1cde6L); + R1(D,A,B,C,X[14], 9,0xc33707d6L); + R1(C,D,A,B,X[ 3],14,0xf4d50d87L); + R1(B,C,D,A,X[ 8],20,0x455a14edL); + R1(A,B,C,D,X[13], 5,0xa9e3e905L); + R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L); + R1(C,D,A,B,X[ 7],14,0x676f02d9L); + R1(B,C,D,A,X[12],20,0x8d2a4c8aL); + /* Round 2 */ + R2(A,B,C,D,X[ 5], 4,0xfffa3942L); + R2(D,A,B,C,X[ 8],11,0x8771f681L); + R2(C,D,A,B,X[11],16,0x6d9d6122L); + R2(B,C,D,A,X[14],23,0xfde5380cL); + R2(A,B,C,D,X[ 1], 4,0xa4beea44L); + R2(D,A,B,C,X[ 4],11,0x4bdecfa9L); + R2(C,D,A,B,X[ 7],16,0xf6bb4b60L); + R2(B,C,D,A,X[10],23,0xbebfbc70L); + R2(A,B,C,D,X[13], 4,0x289b7ec6L); + R2(D,A,B,C,X[ 0],11,0xeaa127faL); + R2(C,D,A,B,X[ 3],16,0xd4ef3085L); + R2(B,C,D,A,X[ 6],23,0x04881d05L); + R2(A,B,C,D,X[ 9], 4,0xd9d4d039L); + R2(D,A,B,C,X[12],11,0xe6db99e5L); + R2(C,D,A,B,X[15],16,0x1fa27cf8L); + R2(B,C,D,A,X[ 2],23,0xc4ac5665L); + /* Round 3 */ + R3(A,B,C,D,X[ 0], 6,0xf4292244L); + R3(D,A,B,C,X[ 7],10,0x432aff97L); + R3(C,D,A,B,X[14],15,0xab9423a7L); + R3(B,C,D,A,X[ 5],21,0xfc93a039L); + R3(A,B,C,D,X[12], 6,0x655b59c3L); + R3(D,A,B,C,X[ 3],10,0x8f0ccc92L); + R3(C,D,A,B,X[10],15,0xffeff47dL); + R3(B,C,D,A,X[ 1],21,0x85845dd1L); + R3(A,B,C,D,X[ 8], 6,0x6fa87e4fL); + R3(D,A,B,C,X[15],10,0xfe2ce6e0L); + R3(C,D,A,B,X[ 6],15,0xa3014314L); + R3(B,C,D,A,X[13],21,0x4e0811a1L); + R3(A,B,C,D,X[ 4], 6,0xf7537e82L); + R3(D,A,B,C,X[11],10,0xbd3af235L); + R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL); + R3(B,C,D,A,X[ 9],21,0xeb86d391L); + + A = c->A += A; + B = c->B += B; + C = c->C += C; + D = c->D += D; + } + } +#endif + +#ifndef md5_block_data_order +void md5_block_data_order (MD5_CTX *c, const void *data_, int num) + { + const unsigned char *data=data_; + register unsigned long A,B,C,D,l; + /* + * 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> + */ + MD5_LONG X[MD5_LBLOCK]; + /* + * In case you wonder why don't I use c->data for this. + * RISCs usually have a handful of registers and if X is + * declared as automatic array good optimizing compiler + * shall accomodate at least part of it in register bank + * instead of memory. + * + * <appro@fy.chalmers.se> + */ + + A=c->A; + B=c->B; + C=c->C; + D=c->D; + + for (;num--;) + { + HOST_c2l(data,l); X[ 0]=l; HOST_c2l(data,l); X[ 1]=l; + /* Round 0 */ + R0(A,B,C,D,X[ 0], 7,0xd76aa478L); HOST_c2l(data,l); X[ 2]=l; + R0(D,A,B,C,X[ 1],12,0xe8c7b756L); HOST_c2l(data,l); X[ 3]=l; + R0(C,D,A,B,X[ 2],17,0x242070dbL); HOST_c2l(data,l); X[ 4]=l; + R0(B,C,D,A,X[ 3],22,0xc1bdceeeL); HOST_c2l(data,l); X[ 5]=l; + R0(A,B,C,D,X[ 4], 7,0xf57c0fafL); HOST_c2l(data,l); X[ 6]=l; + R0(D,A,B,C,X[ 5],12,0x4787c62aL); HOST_c2l(data,l); X[ 7]=l; + R0(C,D,A,B,X[ 6],17,0xa8304613L); HOST_c2l(data,l); X[ 8]=l; + R0(B,C,D,A,X[ 7],22,0xfd469501L); HOST_c2l(data,l); X[ 9]=l; + R0(A,B,C,D,X[ 8], 7,0x698098d8L); HOST_c2l(data,l); X[10]=l; + R0(D,A,B,C,X[ 9],12,0x8b44f7afL); HOST_c2l(data,l); X[11]=l; + R0(C,D,A,B,X[10],17,0xffff5bb1L); HOST_c2l(data,l); X[12]=l; + R0(B,C,D,A,X[11],22,0x895cd7beL); HOST_c2l(data,l); X[13]=l; + R0(A,B,C,D,X[12], 7,0x6b901122L); HOST_c2l(data,l); X[14]=l; + R0(D,A,B,C,X[13],12,0xfd987193L); HOST_c2l(data,l); X[15]=l; + R0(C,D,A,B,X[14],17,0xa679438eL); + R0(B,C,D,A,X[15],22,0x49b40821L); + /* Round 1 */ + R1(A,B,C,D,X[ 1], 5,0xf61e2562L); + R1(D,A,B,C,X[ 6], 9,0xc040b340L); + R1(C,D,A,B,X[11],14,0x265e5a51L); + R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL); + R1(A,B,C,D,X[ 5], 5,0xd62f105dL); + R1(D,A,B,C,X[10], 9,0x02441453L); + R1(C,D,A,B,X[15],14,0xd8a1e681L); + R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L); + R1(A,B,C,D,X[ 9], 5,0x21e1cde6L); + R1(D,A,B,C,X[14], 9,0xc33707d6L); + R1(C,D,A,B,X[ 3],14,0xf4d50d87L); + R1(B,C,D,A,X[ 8],20,0x455a14edL); + R1(A,B,C,D,X[13], 5,0xa9e3e905L); + R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L); + R1(C,D,A,B,X[ 7],14,0x676f02d9L); + R1(B,C,D,A,X[12],20,0x8d2a4c8aL); + /* Round 2 */ + R2(A,B,C,D,X[ 5], 4,0xfffa3942L); + R2(D,A,B,C,X[ 8],11,0x8771f681L); + R2(C,D,A,B,X[11],16,0x6d9d6122L); + R2(B,C,D,A,X[14],23,0xfde5380cL); + R2(A,B,C,D,X[ 1], 4,0xa4beea44L); + R2(D,A,B,C,X[ 4],11,0x4bdecfa9L); + R2(C,D,A,B,X[ 7],16,0xf6bb4b60L); + R2(B,C,D,A,X[10],23,0xbebfbc70L); + R2(A,B,C,D,X[13], 4,0x289b7ec6L); + R2(D,A,B,C,X[ 0],11,0xeaa127faL); + R2(C,D,A,B,X[ 3],16,0xd4ef3085L); + R2(B,C,D,A,X[ 6],23,0x04881d05L); + R2(A,B,C,D,X[ 9], 4,0xd9d4d039L); + R2(D,A,B,C,X[12],11,0xe6db99e5L); + R2(C,D,A,B,X[15],16,0x1fa27cf8L); + R2(B,C,D,A,X[ 2],23,0xc4ac5665L); + /* Round 3 */ + R3(A,B,C,D,X[ 0], 6,0xf4292244L); + R3(D,A,B,C,X[ 7],10,0x432aff97L); + R3(C,D,A,B,X[14],15,0xab9423a7L); + R3(B,C,D,A,X[ 5],21,0xfc93a039L); + R3(A,B,C,D,X[12], 6,0x655b59c3L); + R3(D,A,B,C,X[ 3],10,0x8f0ccc92L); + R3(C,D,A,B,X[10],15,0xffeff47dL); + R3(B,C,D,A,X[ 1],21,0x85845dd1L); + R3(A,B,C,D,X[ 8], 6,0x6fa87e4fL); + R3(D,A,B,C,X[15],10,0xfe2ce6e0L); + R3(C,D,A,B,X[ 6],15,0xa3014314L); + R3(B,C,D,A,X[13],21,0x4e0811a1L); + R3(A,B,C,D,X[ 4], 6,0xf7537e82L); + R3(D,A,B,C,X[11],10,0xbd3af235L); + R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL); + R3(B,C,D,A,X[ 9],21,0xeb86d391L); + + A = c->A += A; + B = c->B += B; + C = c->C += C; + D = c->D += D; + } + } +#endif + +#ifdef undef +int printit(unsigned long *l) + { + int i,ii; + + for (i=0; i<2; i++) + { + for (ii=0; ii<8; ii++) + { + fprintf(stderr,"%08lx ",l[i*8+ii]); + } + fprintf(stderr,"\n"); + } + } +#endif diff --git a/lib/dns/sec/openssl/md5_locl.h b/lib/dns/sec/openssl/md5_locl.h new file mode 100644 index 00000000..849b7938 --- /dev/null +++ b/lib/dns/sec/openssl/md5_locl.h @@ -0,0 +1,172 @@ +/* crypto/md5/md5_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/md5.h> + +#ifndef MD5_LONG_LOG2 +#define MD5_LONG_LOG2 2 /* default to 32 bits */ +#endif + +#ifdef MD5_ASM +# if defined(__i386) || defined(WIN32) +# define md5_block_host_order md5_block_asm_host_order +# elif defined(__sparc) && defined(ULTRASPARC) + void md5_block_asm_data_order_aligned (MD5_CTX *c, const MD5_LONG *p,int num); +# define HASH_BLOCK_DATA_ORDER_ALIGNED md5_block_asm_data_order_aligned +# endif +#endif + +void md5_block_host_order (MD5_CTX *c, const void *p,int num); +void md5_block_data_order (MD5_CTX *c, const void *p,int num); + +#if defined(__i386) +/* + * *_block_host_order is expected to handle aligned data while + * *_block_data_order - unaligned. As algorithm and host (x86) + * are in this case of the same "endianess" these two are + * otherwise indistinguishable. But normally you don't want to + * call the same function because unaligned access in places + * where alignment is expected is usually a "Bad Thing". Indeed, + * on RISCs you get punished with BUS ERROR signal or *severe* + * performance degradation. Intel CPUs are in turn perfectly + * capable of loading unaligned data without such drastic side + * effect. Yes, they say it's slower than aligned load, but no + * exception is generated and therefore performance degradation + * is *incomparable* with RISCs. What we should weight here is + * costs of unaligned access against costs of aligning data. + * According to my measurements allowing unaligned access results + * in ~9% performance improvement on Pentium II operating at + * 266MHz. I won't be surprised if the difference will be higher + * on faster systems:-) + * + * <appro@fy.chalmers.se> + */ +#define md5_block_data_order md5_block_host_order +#endif + +#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_LBLOCK MD5_LBLOCK +#define HASH_UPDATE MD5_Update +#define HASH_TRANSFORM MD5_Transform +#define HASH_FINAL MD5_Final +#define HASH_BLOCK_HOST_ORDER md5_block_host_order +#if !defined(L_ENDIAN) || defined(md5_block_data_order) +#define HASH_BLOCK_DATA_ORDER md5_block_data_order +/* + * Little-endians (Intel and Alpha) feel better without this. + * It looks like memcpy does better job than generic + * md5_block_data_order on copying-n-aligning input data. + * But franlky speaking I didn't expect such result on Alpha. + * On the other hand I've got this with egcs-1.0.2 and if + * program is compiled with another (better?) compiler it + * might turn out other way around. + * + * <appro@fy.chalmers.se> + */ +#endif + +/* BEW */ +#define FLAT_INC + +#ifndef FLAT_INC +#include "../md32_common.h" +#else +#include "md32_common.h" +#endif + +/* +#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) +#define G(x,y,z) (((x) & (z)) | ((y) & (~(z)))) +*/ + +/* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be + * simplified to the code below. Wei attributes these optimisations + * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. + */ +#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c)) +#define H(b,c,d) ((b) ^ (c) ^ (d)) +#define I(b,c,d) (((~(d)) | (b)) ^ (c)) + +#define R0(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+F((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; };\ + +#define R1(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+G((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +#define R2(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+H((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +#define R3(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+I((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; diff --git a/lib/dns/sec/openssl/md_rand.c b/lib/dns/sec/openssl/md_rand.c new file mode 100644 index 00000000..6bd1960e --- /dev/null +++ b/lib/dns/sec/openssl/md_rand.c @@ -0,0 +1,429 @@ +/* crypto/rand/md_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.] + */ + +#include <stdio.h> +#include <sys/types.h> +#include <time.h> +#include <string.h> + +#include "openssl/e_os.h" + +#include <openssl/crypto.h> + +#if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND) +#if !defined(NO_SHA) && !defined(NO_SHA1) +#define USE_SHA1_RAND +#elif !defined(NO_MD5) +#define USE_MD5_RAND +#elif !defined(NO_MDC2) && !defined(NO_DES) +#define USE_MDC2_RAND +#elif !defined(NO_MD2) +#define USE_MD2_RAND +#else +#error No message digest algorithm available +#endif +#endif + +/* Changed how the state buffer used. I now attempt to 'wrap' such + * that I don't run over the same locations the next time go through + * the 1023 bytes - many thanks to + * Robert J. LeBlanc <rjl@renaissoft.com> for his comments + */ + +#if defined(USE_MD5_RAND) +#include <openssl/md5.h> +#define MD_DIGEST_LENGTH MD5_DIGEST_LENGTH +#define MD_CTX MD5_CTX +#define MD_Init(a) MD5_Init(a) +#define MD_Update(a,b,c) MD5_Update(a,b,c) +#define MD_Final(a,b) MD5_Final(a,b) +#define MD(a,b,c) MD5(a,b,c) +#elif defined(USE_SHA1_RAND) +#include <openssl/sha.h> +#define MD_DIGEST_LENGTH SHA_DIGEST_LENGTH +#define MD_CTX SHA_CTX +#define MD_Init(a) SHA1_Init(a) +#define MD_Update(a,b,c) SHA1_Update(a,b,c) +#define MD_Final(a,b) SHA1_Final(a,b) +#define MD(a,b,c) SHA1(a,b,c) +#elif defined(USE_MDC2_RAND) +#include <openssl/mdc2.h> +#define MD_DIGEST_LENGTH MDC2_DIGEST_LENGTH +#define MD_CTX MDC2_CTX +#define MD_Init(a) MDC2_Init(a) +#define MD_Update(a,b,c) MDC2_Update(a,b,c) +#define MD_Final(a,b) MDC2_Final(a,b) +#define MD(a,b,c) MDC2(a,b,c) +#elif defined(USE_MD2_RAND) +#include <openssl/md2.h> +#define MD_DIGEST_LENGTH MD2_DIGEST_LENGTH +#define MD_CTX MD2_CTX +#define MD_Init(a) MD2_Init(a) +#define MD_Update(a,b,c) MD2_Update(a,b,c) +#define MD_Final(a,b) MD2_Final(a,b) +#define MD(a,b,c) MD2(a,b,c) +#endif + +#include <openssl/rand.h> + +/* #define NORAND 1 */ +/* #define PREDICT 1 */ + +#define STATE_SIZE 1023 +static int state_num=0,state_index=0; +static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH]; +static unsigned char md[MD_DIGEST_LENGTH]; +static long md_count[2]={0,0}; + +const char *RAND_version="RAND" OPENSSL_VERSION_PTEXT; + +static void ssleay_rand_cleanup(void); +static void ssleay_rand_seed(const void *buf, int num); +static void ssleay_rand_bytes(unsigned char *buf, int num); + +RAND_METHOD rand_ssleay_meth={ + ssleay_rand_seed, + ssleay_rand_bytes, + ssleay_rand_cleanup, + }; + +RAND_METHOD *RAND_SSLeay(void) + { + return(&rand_ssleay_meth); + } + +static void ssleay_rand_cleanup(void) + { + memset(state,0,sizeof(state)); + state_num=0; + state_index=0; + memset(md,0,MD_DIGEST_LENGTH); + md_count[0]=0; + md_count[1]=0; + } + +static void ssleay_rand_seed(const void *buf, int num) + { + int i,j,k,st_idx,st_num; + MD_CTX m; + +#ifdef NORAND + return; +#endif + + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + st_idx=state_index; + st_num=state_num; + + state_index=(state_index+num); + if (state_index >= STATE_SIZE) + { + state_index%=STATE_SIZE; + state_num=STATE_SIZE; + } + else if (state_num < STATE_SIZE) + { + if (state_index > state_num) + state_num=state_index; + } + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + + for (i=0; i<num; i+=MD_DIGEST_LENGTH) + { + j=(num-i); + j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j; + + MD_Init(&m); + MD_Update(&m,md,MD_DIGEST_LENGTH); + k=(st_idx+j)-STATE_SIZE; + if (k > 0) + { + MD_Update(&m,&(state[st_idx]),j-k); + MD_Update(&m,&(state[0]),k); + } + else + MD_Update(&m,&(state[st_idx]),j); + + MD_Update(&m,buf,j); + MD_Update(&m,(unsigned char *)&(md_count[0]),sizeof(md_count)); + MD_Final(md,&m); + md_count[1]++; + + buf=(const char *)buf + j; + + for (k=0; k<j; k++) + { + state[st_idx++]^=md[k]; + if (st_idx >= STATE_SIZE) + { + st_idx=0; + st_num=STATE_SIZE; + } + } + } + memset((char *)&m,0,sizeof(m)); + } + +static void ssleay_rand_bytes(unsigned char *buf, int num) + { + int i,j,k,st_num,st_idx; + MD_CTX m; + static int init=1; + unsigned long l; +#ifdef DEVRANDOM + FILE *fh; +#endif + +#ifdef PREDICT + { + static unsigned char val=0; + + for (i=0; i<num; i++) + buf[i]=val++; + return; + } +#endif + + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + + if (init) + { + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + /* put in some default random data, we need more than + * just this */ + RAND_seed(&m,sizeof(m)); +#ifndef MSDOS + l=getpid(); + RAND_seed(&l,sizeof(l)); + l=getuid(); + RAND_seed(&l,sizeof(l)); +#endif + l=time(NULL); + RAND_seed(&l,sizeof(l)); + +/* #ifdef DEVRANDOM */ + /* + * Use a random entropy pool device. + * Linux 1.3.x and FreeBSD-Current has + * this. Use /dev/urandom if you can + * as /dev/random will block if it runs out + * of random entries. + */ + if ((fh = fopen(DEVRANDOM, "r")) != NULL) + { + unsigned char tmpbuf[32]; + + fread((unsigned char *)tmpbuf,1,32,fh); + /* we don't care how many bytes we read, + * we will just copy the 'stack' if there is + * nothing else :-) */ + fclose(fh); + RAND_seed(tmpbuf,32); + memset(tmpbuf,0,32); + } +/* #endif */ +#ifdef PURIFY + memset(state,0,STATE_SIZE); + memset(md,0,MD_DIGEST_LENGTH); +#endif + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + init=0; + } + + st_idx=state_index; + st_num=state_num; + state_index+=num; + if (state_index > state_num) + state_index=(state_index%state_num); + + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + + while (num > 0) + { + j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num; + num-=j; + MD_Init(&m); + MD_Update(&m,&(md[MD_DIGEST_LENGTH/2]),MD_DIGEST_LENGTH/2); + MD_Update(&m,(unsigned char *)&(md_count[0]),sizeof(md_count)); +#ifndef PURIFY + MD_Update(&m,buf,j); /* purify complains */ +#endif + k=(st_idx+j)-st_num; + if (k > 0) + { + MD_Update(&m,&(state[st_idx]),j-k); + MD_Update(&m,&(state[0]),k); + } + else + MD_Update(&m,&(state[st_idx]),j); + MD_Final(md,&m); + + for (i=0; i<j; i++) + { + if (st_idx >= st_num) + st_idx=0; + state[st_idx++]^=md[i]; + *(buf++)=md[i+MD_DIGEST_LENGTH/2]; + } + } + + MD_Init(&m); + MD_Update(&m,(unsigned char *)&(md_count[0]),sizeof(md_count)); + md_count[0]++; + MD_Update(&m,md,MD_DIGEST_LENGTH); + MD_Final(md,&m); + memset(&m,0,sizeof(m)); + } + +#ifdef WINDOWS +#include <windows.h> +#include <openssl/rand.h> + +/***************************************************************************** + * Initialisation function for the SSL random generator. Takes the contents + * of the screen as random seed. + * + * Created 960901 by Gertjan van Oosten, gertjan@West.NL, West Consulting B.V. + * + * Code adapted from + * <URL:http://www.microsoft.com/kb/developr/win_dk/q97193.htm>; + * the original copyright message is: + * + * (C) Copyright Microsoft Corp. 1993. All rights reserved. + * + * You have a royalty-free right to use, modify, reproduce and + * distribute the Sample Files (and/or any modified version) in + * any way you find useful, provided that you agree that + * Microsoft has no warranty obligations or liability for any + * Sample Application Files which are modified. + */ +/* + * I have modified the loading of bytes via RAND_seed() mechanism since + * the origional would have been very very CPU intensive since RAND_seed() + * does an MD5 per 16 bytes of input. The cost to digest 16 bytes is the same + * as that to digest 56 bytes. So under the old system, a screen of + * 1024*768*256 would have been CPU cost of approximatly 49,000 56 byte MD5 + * digests or digesting 2.7 mbytes. What I have put in place would + * be 48 16k MD5 digests, or efectivly 48*16+48 MD5 bytes or 816 kbytes + * or about 3.5 times as much. + * - eric + */ +void RAND_screen(void) +{ + HDC hScrDC; /* screen DC */ + HDC hMemDC; /* memory DC */ + HBITMAP hBitmap; /* handle for our bitmap */ + HBITMAP hOldBitmap; /* handle for previous bitmap */ + BITMAP bm; /* bitmap properties */ + unsigned int size; /* size of bitmap */ + char *bmbits; /* contents of bitmap */ + int w; /* screen width */ + int h; /* screen height */ + int y; /* y-coordinate of screen lines to grab */ + int n = 16; /* number of screen lines to grab at a time */ + + /* Create a screen DC and a memory DC compatible to screen DC */ + hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL); + hMemDC = CreateCompatibleDC(hScrDC); + + /* Get screen resolution */ + w = GetDeviceCaps(hScrDC, HORZRES); + h = GetDeviceCaps(hScrDC, VERTRES); + + /* Create a bitmap compatible with the screen DC */ + hBitmap = CreateCompatibleBitmap(hScrDC, w, n); + + /* Select new bitmap into memory DC */ + hOldBitmap = SelectObject(hMemDC, hBitmap); + + /* Get bitmap properties */ + GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm); + size = (unsigned int)bm.bmWidthBytes * bm.bmHeight * bm.bmPlanes; + + bmbits = Malloc(size); + if (bmbits) { + /* Now go through the whole screen, repeatedly grabbing n lines */ + for (y = 0; y < h-n; y += n) + { + unsigned char md[MD_DIGEST_LENGTH]; + + /* Bitblt screen DC to memory DC */ + BitBlt(hMemDC, 0, 0, w, n, hScrDC, 0, y, SRCCOPY); + + /* Copy bitmap bits from memory DC to bmbits */ + GetBitmapBits(hBitmap, size, bmbits); + + /* Get the MD5 of the bitmap */ + MD(bmbits,size,md); + + /* Seed the random generator with the MD5 digest */ + RAND_seed(md, MD_DIGEST_LENGTH); + } + + Free(bmbits); + } + + /* Select old bitmap back into memory DC */ + hBitmap = SelectObject(hMemDC, hOldBitmap); + + /* Clean up */ + DeleteObject(hBitmap); + DeleteDC(hMemDC); + DeleteDC(hScrDC); +} +#endif diff --git a/lib/dns/sec/openssl/mem.c b/lib/dns/sec/openssl/mem.c new file mode 100644 index 00000000..2848d1f2 --- /dev/null +++ b/lib/dns/sec/openssl/mem.c @@ -0,0 +1,382 @@ +/* crypto/mem.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 <openssl/buffer.h> +#include <openssl/bio.h> +#include <openssl/lhash.h> +#include "cryptlib.h" + +#ifdef CRYPTO_MDEBUG +static int mh_mode=CRYPTO_MEM_CHECK_ON; +#else +static int mh_mode=CRYPTO_MEM_CHECK_OFF; +#endif +static unsigned long order=0; + +static LHASH *mh=NULL; + +typedef struct mem_st + { + char *addr; + int num; + const char *file; + int line; + unsigned long order; + } MEM; + +int CRYPTO_mem_ctrl(int mode) + { + int ret=mh_mode; + + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); + switch (mode) + { + case CRYPTO_MEM_CHECK_ON: + mh_mode|=CRYPTO_MEM_CHECK_ON; + break; + case CRYPTO_MEM_CHECK_OFF: + mh_mode&= ~CRYPTO_MEM_CHECK_ON; + break; + case CRYPTO_MEM_CHECK_DISABLE: + mh_mode&= ~CRYPTO_MEM_CHECK_ENABLE; + break; + case CRYPTO_MEM_CHECK_ENABLE: + if (mh_mode&CRYPTO_MEM_CHECK_ON) + mh_mode|=CRYPTO_MEM_CHECK_ENABLE; + break; + default: + break; + } + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); + return(ret); + } + +static int mem_cmp(MEM *a, MEM *b) + { + return(a->addr - b->addr); + } + +static unsigned long mem_hash(MEM *a) + { + unsigned long ret; + + ret=(unsigned long)a->addr; + + ret=ret*17851+(ret>>14)*7+(ret>>4)*251; + return(ret); + } + +static void *(*malloc_locked_func)(int)=(void *(*)(int))malloc; +static void (*free_locked_func)(void *)=(void (*)(void *))free; +static void *(*malloc_func)(int)= (void *(*)(int))malloc; +static void *(*realloc_func)(void *, int)= (void *(*)(void *, int))realloc; +static void (*free_func)(void *)= (void (*)(void *))free; + +void CRYPTO_set_mem_functions(void *(*m)(int), void *(*r)(void *, int), + void (*f)(void *)) + { + if ((m == NULL) || (r == NULL) || (f == NULL)) return; + malloc_func=m; + realloc_func=r; + free_func=f; + malloc_locked_func=m; + free_locked_func=f; + } + +void CRYPTO_set_locked_mem_functions(void *(*m)(int), void (*f)(void *)) + { + if ((m == NULL) || (f == NULL)) return; + malloc_locked_func=m; + free_locked_func=f; + } + +void CRYPTO_get_mem_functions(void *(**m)(int), void *(**r)(void *, int), + void (**f)(void *)) + { + if (m != NULL) *m=malloc_func; + if (r != NULL) *r=realloc_func; + if (f != NULL) *f=free_func; + } + +void CRYPTO_get_locked_mem_functions(void *(**m)(), void (**f)()) + { + if (m != NULL) *m=malloc_locked_func; + if (f != NULL) *f=free_locked_func; + } + +void *CRYPTO_malloc_locked(int num) + { + return(malloc_locked_func(num)); + } + +void CRYPTO_free_locked(void *str) + { + free_locked_func(str); + } + +void *CRYPTO_malloc(int num) + { + return(malloc_func(num)); + } + +void *CRYPTO_realloc(void *str, int num) + { + return(realloc_func(str,num)); + } + +void CRYPTO_free(void *str) + { + free_func(str); + } + +static unsigned long break_order_num=0; +void *CRYPTO_dbg_malloc(int num, const char *file, int line) + { + char *ret; + MEM *m,*mm; + + if ((ret=malloc_func(num)) == NULL) + return(NULL); + + if (mh_mode & CRYPTO_MEM_CHECK_ENABLE) + { + MemCheck_off(); + if ((m=(MEM *)Malloc(sizeof(MEM))) == NULL) + { + Free(ret); + MemCheck_on(); + return(NULL); + } + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); + if (mh == NULL) + { + if ((mh=lh_new(mem_hash,mem_cmp)) == NULL) + { + Free(ret); + Free(m); + ret=NULL; + goto err; + } + } + + m->addr=ret; + m->file=file; + m->line=line; + m->num=num; + if (order == break_order_num) + { + /* BREAK HERE */ + m->order=order; + } + m->order=order++; + if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL) + { + /* Not good, but don't sweat it */ + Free(mm); + } +err: + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); + MemCheck_on(); + } + return(ret); + } + +void CRYPTO_dbg_free(void *addr) + { + MEM m,*mp; + + if ((mh_mode & CRYPTO_MEM_CHECK_ENABLE) && (mh != NULL)) + { + MemCheck_off(); + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); + m.addr=addr; + mp=(MEM *)lh_delete(mh,(char *)&m); + if (mp != NULL) + Free(mp); + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); + MemCheck_on(); + } + free_func(addr); + } + +void *CRYPTO_dbg_realloc(void *addr, int num, const char *file, int line) + { + char *ret; + MEM m,*mp; + + file = file; /* BEW - quiet the compiler */ + line = line; + + ret=realloc_func(addr,num); + if (ret == (char *)addr) return(ret); + + if (mh_mode & CRYPTO_MEM_CHECK_ENABLE) + { + MemCheck_off(); + if (ret == NULL) return(NULL); + m.addr=addr; + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); + mp=(MEM *)lh_delete(mh,(char *)&m); + if (mp != NULL) + { + mp->addr=ret; + lh_insert(mh,(char *)mp); + } + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); + MemCheck_on(); + } + return(ret); + } + +void *CRYPTO_remalloc(void *a, int n) + { + if (a != NULL) Free(a); + a=(char *)Malloc(n); + return(a); + } + +void *CRYPTO_dbg_remalloc(void *a, int n, const char *file, int line) + { + if (a != NULL) CRYPTO_dbg_free(a); + a=(char *)CRYPTO_dbg_malloc(n,file,line); + return(a); + } + +/* BEW */ +#if 0 +typedef struct mem_leak_st + { + BIO *bio; + int chunks; + long bytes; + } MEM_LEAK; + +static void print_leak(MEM *m, MEM_LEAK *l) + { + char buf[128]; + + if(m->addr == (char *)l->bio) + return; + sprintf(buf,"%5lu file=%s, line=%d, number=%d, address=%08lX\n", + m->order,m->file,m->line,m->num,(unsigned long)m->addr); + BIO_puts(l->bio,buf); + l->chunks++; + l->bytes+=m->num; + } + +void CRYPTO_mem_leaks(BIO *b) + { + MEM_LEAK ml; + char buf[80]; + + if (mh == NULL) return; + ml.bio=b; + ml.bytes=0; + ml.chunks=0; + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); + lh_doall_arg(mh,(void (*)())print_leak,(char *)&ml); + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); + if (ml.chunks != 0) + { + sprintf(buf,"%ld bytes leaked in %d chunks\n", + ml.bytes,ml.chunks); + BIO_puts(b,buf); + } + +#if 0 + lh_stats_bio(mh,b); + lh_node_stats_bio(mh,b); + lh_node_usage_stats_bio(mh,b); +#endif + } + +static void (*mem_cb)()=NULL; + +static void cb_leak(MEM *m, char *cb) + { + void (*mem_callback)()=(void (*)())cb; + mem_callback(m->order,m->file,m->line,m->num,m->addr); + } + +void CRYPTO_mem_leaks_cb(void (*cb)()) + { + if (mh == NULL) return; + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); + mem_cb=cb; + lh_doall_arg(mh,(void (*)())cb_leak,(char *)mem_cb); + mem_cb=NULL; + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); + } + +#ifndef NO_FP_API +void CRYPTO_mem_leaks_fp(FILE *fp) + { + BIO *b; + + if (mh == NULL) return; + if ((b=BIO_new(BIO_s_file())) == NULL) + return; + BIO_set_fp(b,fp,BIO_NOCLOSE); + CRYPTO_mem_leaks(b); + BIO_free(b); + } +#endif +#endif + diff --git a/lib/dns/sec/openssl/rand_lib.c b/lib/dns/sec/openssl/rand_lib.c new file mode 100644 index 00000000..34c6d5b9 --- /dev/null +++ b/lib/dns/sec/openssl/rand_lib.c @@ -0,0 +1,98 @@ +/* crypto/rand/rand_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.] + */ + +#include <stdio.h> +#include <sys/types.h> +#include <time.h> +#include <openssl/rand.h> + +#ifdef NO_RAND +static RAND_METHOD *rand_meth=NULL; +#else +extern RAND_METHOD rand_ssleay_meth; +static RAND_METHOD *rand_meth= &rand_ssleay_meth; +#endif + +void RAND_set_rand_method(RAND_METHOD *meth) + { + rand_meth=meth; + } + +RAND_METHOD *RAND_get_rand_method(void) + { + return(rand_meth); + } + +void RAND_cleanup(void) + { + if (rand_meth != NULL) + rand_meth->cleanup(); + } + +void RAND_seed(const void *buf, int num) + { + if (rand_meth != NULL) + rand_meth->seed(buf,num); + } + +void RAND_bytes(unsigned char *buf, int num) + { + if (rand_meth != NULL) + rand_meth->bytes(buf,num); + } + diff --git a/lib/dns/sec/openssl/sha1_one.c b/lib/dns/sec/openssl/sha1_one.c new file mode 100644 index 00000000..861752ea --- /dev/null +++ b/lib/dns/sec/openssl/sha1_one.c @@ -0,0 +1,76 @@ +/* crypto/sha/sha1_one.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 <string.h> +#include <openssl/sha.h> + +#ifndef NO_SHA1 +unsigned char *SHA1(const unsigned char *d, unsigned long n, unsigned char *md) + { + SHA_CTX c; + static unsigned char m[SHA_DIGEST_LENGTH]; + + if (md == NULL) md=m; + SHA1_Init(&c); + SHA1_Update(&c,d,n); + SHA1_Final(md,&c); + memset(&c,0,sizeof(c)); + return(md); + } +#endif diff --git a/lib/dns/sec/openssl/sha1dgst.c b/lib/dns/sec/openssl/sha1dgst.c new file mode 100644 index 00000000..66e885dd --- /dev/null +++ b/lib/dns/sec/openssl/sha1dgst.c @@ -0,0 +1,498 @@ +/* crypto/sha/sha1dgst.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 <string.h> +#undef SHA_0 +#define SHA_1 +#include <openssl/sha.h> +#include "sha_locl.h" +#include <openssl/opensslv.h> + +#ifndef NO_SHA1 +char *SHA1_version="SHA1" OPENSSL_VERSION_PTEXT; + +/* Implemented from SHA-1 document - The Secure Hash Algorithm + */ + +#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 + +#define K_00_19 0x5a827999UL +#define K_20_39 0x6ed9eba1UL +#define K_40_59 0x8f1bbcdcUL +#define K_60_79 0xca62c1d6UL + +#ifdef SHA1_ASM + void sha1_block_x86(SHA_CTX *c, register SHA_LONG *p, int num); +# define sha1_block(c,p,n) sha1_block_x86((c),(p),(n)*SHA_CBLOCK) +#else + static void sha1_block(SHA_CTX *c, register SHA_LONG *p, int num); +#endif + +#if !defined(B_ENDIAN) && defined(SHA1_ASM) +# define M_c2nl c2l +# define M_p_c2nl p_c2l +# define M_c2nl_p c2l_p +# define M_p_c2nl_p p_c2l_p +# define M_nl2c l2c +#else +# define M_c2nl c2nl +# define M_p_c2nl p_c2nl +# define M_c2nl_p c2nl_p +# define M_p_c2nl_p p_c2nl_p +# define M_nl2c nl2c +#endif + +void SHA1_Init(SHA_CTX *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; + c->Nl=0; + c->Nh=0; + c->num=0; + } + +void SHA1_Update(SHA_CTX *c, register const unsigned char *data, + unsigned long len) + { + register SHA_LONG *p; + int ew,ec,sw,sc; + SHA_LONG l; + + if (len == 0) return; + + l=(c->Nl+(len<<3))&0xffffffffL; + if (l < c->Nl) /* overflow */ + c->Nh++; + c->Nh+=(len>>29); + c->Nl=l; + + if (c->num != 0) + { + p=c->data; + sw=c->num>>2; + sc=c->num&0x03; + + if ((c->num+len) >= SHA_CBLOCK) + { + l= p[sw]; + M_p_c2nl(data,l,sc); + p[sw++]=l; + for (; sw<SHA_LBLOCK; sw++) + { + M_c2nl(data,l); + p[sw]=l; + } + len-=(SHA_CBLOCK-c->num); + + sha1_block(c,p,1); + c->num=0; + /* drop through and do the rest */ + } + else + { + c->num+=(int)len; + if ((sc+len) < 4) /* ugly, add char's to a word */ + { + l= p[sw]; + M_p_c2nl_p(data,l,sc,len); + p[sw]=l; + } + else + { + ew=(c->num>>2); + ec=(c->num&0x03); + l= p[sw]; + M_p_c2nl(data,l,sc); + p[sw++]=l; + for (; sw < ew; sw++) + { M_c2nl(data,l); p[sw]=l; } + if (ec) + { + M_c2nl_p(data,l,ec); + p[sw]=l; + } + } + return; + } + } + /* We can only do the following code for assember, the reason + * being that the sha1_block 'C' version changes the values + * in the 'data' array. The assember code avoids this and + * copies it to a local array. I should be able to do this for + * the C version as well.... + */ +#if SHA_LONG_LOG2==2 +#if defined(B_ENDIAN) || defined(SHA1_ASM) + if ((((unsigned long)data)%sizeof(SHA_LONG)) == 0) + { + sw=len/SHA_CBLOCK; + if (sw) + { + sha1_block(c,(SHA_LONG *)data,sw); + sw*=SHA_CBLOCK; + data+=sw; + len-=sw; + } + } +#endif +#endif + /* we now can process the input data in blocks of SHA_CBLOCK + * chars and save the leftovers to c->data. */ + p=c->data; + while (len >= SHA_CBLOCK) + { +#if SHA_LONG_LOG2==2 +#if defined(B_ENDIAN) || defined(SHA1_ASM) +#define SHA_NO_TAIL_CODE + /* + * Basically we get here only when data happens + * to be unaligned. + */ + if (p != (SHA_LONG *)data) + memcpy(p,data,SHA_CBLOCK); + data+=SHA_CBLOCK; + sha1_block(c,p=c->data,1); + len-=SHA_CBLOCK; +#elif defined(L_ENDIAN) +#define BE_COPY(dst,src,i) { \ + l = ((SHA_LONG *)src)[i]; \ + Endian_Reverse32(l); \ + dst[i] = l; \ + } + if ((((unsigned long)data)%sizeof(SHA_LONG)) == 0) + { + for (sw=(SHA_LBLOCK/4); sw; sw--) + { + BE_COPY(p,data,0); + BE_COPY(p,data,1); + BE_COPY(p,data,2); + BE_COPY(p,data,3); + p+=4; + data += 4*sizeof(SHA_LONG); + } + sha1_block(c,p=c->data,1); + len-=SHA_CBLOCK; + continue; + } +#endif +#endif +#ifndef SHA_NO_TAIL_CODE + /* + * In addition to "sizeof(SHA_LONG)!= 4" case the + * following code covers unaligned access cases on + * little-endian machines. + * <appro@fy.chalmers.se> + */ + p=c->data; + for (sw=(SHA_LBLOCK/4); sw; sw--) + { + M_c2nl(data,l); p[0]=l; + M_c2nl(data,l); p[1]=l; + M_c2nl(data,l); p[2]=l; + M_c2nl(data,l); p[3]=l; + p+=4; + } + p=c->data; + sha1_block(c,p,1); + len-=SHA_CBLOCK; +#endif + } + ec=(int)len; + c->num=ec; + ew=(ec>>2); + ec&=0x03; + + for (sw=0; sw < ew; sw++) + { M_c2nl(data,l); p[sw]=l; } + M_c2nl_p(data,l,ec); + p[sw]=l; + } + +void SHA1_Transform(SHA_CTX *c, unsigned char *b) + { + SHA_LONG p[SHA_LBLOCK]; + +#if SHA_LONG_LOG2==2 +#if defined(B_ENDIAN) || defined(SHA1_ASM) + memcpy(p,b,SHA_CBLOCK); + sha1_block(c,p,1); + return; +#elif defined(L_ENDIAN) + if (((unsigned long)b%sizeof(SHA_LONG)) == 0) + { + SHA_LONG *q; + int i; + + q=p; + for (i=(SHA_LBLOCK/4); i; i--) + { + unsigned long l; + BE_COPY(q,b,0); /* BE_COPY was defined above */ + BE_COPY(q,b,1); + BE_COPY(q,b,2); + BE_COPY(q,b,3); + q+=4; + b+=4*sizeof(SHA_LONG); + } + sha1_block(c,p,1); + return; + } +#endif +#endif +#ifndef SHA_NO_TAIL_CODE /* defined above, see comment */ + { + SHA_LONG *q; + int i; + + q=p; + for (i=(SHA_LBLOCK/4); i; i--) + { + SHA_LONG l; + c2nl(b,l); *(q++)=l; + c2nl(b,l); *(q++)=l; + c2nl(b,l); *(q++)=l; + c2nl(b,l); *(q++)=l; + } + sha1_block(c,p,1); + } +#endif + } + +#ifndef SHA1_ASM +static void sha1_block(SHA_CTX *c, register SHA_LONG *W, int num) + { + register SHA_LONG A,B,C,D,E,T; + SHA_LONG X[SHA_LBLOCK]; + + A=c->h0; + B=c->h1; + C=c->h2; + D=c->h3; + E=c->h4; + + for (;;) + { + BODY_00_15( 0,A,B,C,D,E,T,W); + BODY_00_15( 1,T,A,B,C,D,E,W); + BODY_00_15( 2,E,T,A,B,C,D,W); + BODY_00_15( 3,D,E,T,A,B,C,W); + BODY_00_15( 4,C,D,E,T,A,B,W); + BODY_00_15( 5,B,C,D,E,T,A,W); + BODY_00_15( 6,A,B,C,D,E,T,W); + BODY_00_15( 7,T,A,B,C,D,E,W); + BODY_00_15( 8,E,T,A,B,C,D,W); + BODY_00_15( 9,D,E,T,A,B,C,W); + BODY_00_15(10,C,D,E,T,A,B,W); + BODY_00_15(11,B,C,D,E,T,A,W); + BODY_00_15(12,A,B,C,D,E,T,W); + BODY_00_15(13,T,A,B,C,D,E,W); + BODY_00_15(14,E,T,A,B,C,D,W); + BODY_00_15(15,D,E,T,A,B,C,W); + BODY_16_19(16,C,D,E,T,A,B,W,W,W,W); + BODY_16_19(17,B,C,D,E,T,A,W,W,W,W); + BODY_16_19(18,A,B,C,D,E,T,W,W,W,W); + BODY_16_19(19,T,A,B,C,D,E,W,W,W,X); + + BODY_20_31(20,E,T,A,B,C,D,W,W,W,X); + BODY_20_31(21,D,E,T,A,B,C,W,W,W,X); + BODY_20_31(22,C,D,E,T,A,B,W,W,W,X); + BODY_20_31(23,B,C,D,E,T,A,W,W,W,X); + BODY_20_31(24,A,B,C,D,E,T,W,W,X,X); + BODY_20_31(25,T,A,B,C,D,E,W,W,X,X); + BODY_20_31(26,E,T,A,B,C,D,W,W,X,X); + BODY_20_31(27,D,E,T,A,B,C,W,W,X,X); + BODY_20_31(28,C,D,E,T,A,B,W,W,X,X); + BODY_20_31(29,B,C,D,E,T,A,W,W,X,X); + BODY_20_31(30,A,B,C,D,E,T,W,X,X,X); + BODY_20_31(31,T,A,B,C,D,E,W,X,X,X); + BODY_32_39(32,E,T,A,B,C,D,X); + BODY_32_39(33,D,E,T,A,B,C,X); + BODY_32_39(34,C,D,E,T,A,B,X); + BODY_32_39(35,B,C,D,E,T,A,X); + BODY_32_39(36,A,B,C,D,E,T,X); + BODY_32_39(37,T,A,B,C,D,E,X); + BODY_32_39(38,E,T,A,B,C,D,X); + BODY_32_39(39,D,E,T,A,B,C,X); + + BODY_40_59(40,C,D,E,T,A,B,X); + BODY_40_59(41,B,C,D,E,T,A,X); + BODY_40_59(42,A,B,C,D,E,T,X); + BODY_40_59(43,T,A,B,C,D,E,X); + BODY_40_59(44,E,T,A,B,C,D,X); + BODY_40_59(45,D,E,T,A,B,C,X); + BODY_40_59(46,C,D,E,T,A,B,X); + BODY_40_59(47,B,C,D,E,T,A,X); + BODY_40_59(48,A,B,C,D,E,T,X); + BODY_40_59(49,T,A,B,C,D,E,X); + BODY_40_59(50,E,T,A,B,C,D,X); + BODY_40_59(51,D,E,T,A,B,C,X); + BODY_40_59(52,C,D,E,T,A,B,X); + BODY_40_59(53,B,C,D,E,T,A,X); + BODY_40_59(54,A,B,C,D,E,T,X); + BODY_40_59(55,T,A,B,C,D,E,X); + BODY_40_59(56,E,T,A,B,C,D,X); + BODY_40_59(57,D,E,T,A,B,C,X); + BODY_40_59(58,C,D,E,T,A,B,X); + BODY_40_59(59,B,C,D,E,T,A,X); + + BODY_60_79(60,A,B,C,D,E,T,X); + BODY_60_79(61,T,A,B,C,D,E,X); + BODY_60_79(62,E,T,A,B,C,D,X); + BODY_60_79(63,D,E,T,A,B,C,X); + BODY_60_79(64,C,D,E,T,A,B,X); + BODY_60_79(65,B,C,D,E,T,A,X); + BODY_60_79(66,A,B,C,D,E,T,X); + BODY_60_79(67,T,A,B,C,D,E,X); + BODY_60_79(68,E,T,A,B,C,D,X); + BODY_60_79(69,D,E,T,A,B,C,X); + BODY_60_79(70,C,D,E,T,A,B,X); + BODY_60_79(71,B,C,D,E,T,A,X); + BODY_60_79(72,A,B,C,D,E,T,X); + BODY_60_79(73,T,A,B,C,D,E,X); + BODY_60_79(74,E,T,A,B,C,D,X); + BODY_60_79(75,D,E,T,A,B,C,X); + BODY_60_79(76,C,D,E,T,A,B,X); + BODY_60_79(77,B,C,D,E,T,A,X); + BODY_60_79(78,A,B,C,D,E,T,X); + BODY_60_79(79,T,A,B,C,D,E,X); + + 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; + + W+=SHA_LBLOCK; /* Note! This can happen only when sizeof(SHA_LONG) + * is 4. Whenever it's not the actual case this + * function is never called with num larger than 1 + * and we never advance down here. + * <appro@fy.chalmers.se> + */ + } + } +#endif + +void SHA1_Final(unsigned char *md, SHA_CTX *c) + { + register int i,j; + register SHA_LONG l; + register SHA_LONG *p; + static unsigned char end[4]={0x80,0x00,0x00,0x00}; + unsigned char *cp=end; + + /* c->num should definitly have room for at least one more byte. */ + p=c->data; + j=c->num; + i=j>>2; +#ifdef PURIFY + if ((j&0x03) == 0) p[i]=0; +#endif + l=p[i]; + M_p_c2nl(cp,l,j&0x03); + p[i]=l; + i++; + /* i is the next 'undefined word' */ + if (c->num >= SHA_LAST_BLOCK) + { + for (; i<SHA_LBLOCK; i++) + p[i]=0; + sha1_block(c,p,1); + i=0; + } + for (; i<(SHA_LBLOCK-2); i++) + p[i]=0; + p[SHA_LBLOCK-2]=c->Nh; + p[SHA_LBLOCK-1]=c->Nl; +#if SHA_LONG_LOG2==2 +#if !defined(B_ENDIAN) && defined(SHA1_ASM) + Endian_Reverse32(p[SHA_LBLOCK-2]); + Endian_Reverse32(p[SHA_LBLOCK-1]); +#endif +#endif + sha1_block(c,p,1); + cp=md; + l=c->h0; nl2c(l,cp); + l=c->h1; nl2c(l,cp); + l=c->h2; nl2c(l,cp); + l=c->h3; nl2c(l,cp); + l=c->h4; nl2c(l,cp); + + c->num=0; + /* sha_block may be leaving some stuff on the stack + * but I'm not worried :-) + memset((void *)c,0,sizeof(SHA_CTX)); + */ + } +#endif + diff --git a/lib/dns/sec/openssl/sha_locl.h b/lib/dns/sec/openssl/sha_locl.h new file mode 100644 index 00000000..ac85029a --- /dev/null +++ b/lib/dns/sec/openssl/sha_locl.h @@ -0,0 +1,288 @@ +/* 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> + +#ifdef undef +/* one or the other needs to be defined */ +#ifndef SHA_1 /* FIPE 180-1 */ +#define SHA_0 /* FIPS 180 */ +#endif +#endif + +#undef c2nl +#define c2nl(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++))) )) + +#undef p_c2nl +#define p_c2nl(c,l,n) { \ + switch (n) { \ + case 0: l =((unsigned long)(*((c)++)))<<24; \ + case 1: l|=((unsigned long)(*((c)++)))<<16; \ + case 2: l|=((unsigned long)(*((c)++)))<< 8; \ + case 3: l|=((unsigned long)(*((c)++))); \ + } \ + } + +#undef c2nl_p +/* NOTE the pointer is not incremented at the end of this */ +#define c2nl_p(c,l,n) { \ + l=0; \ + (c)+=n; \ + switch (n) { \ + case 3: l =((unsigned long)(*(--(c))))<< 8; \ + case 2: l|=((unsigned long)(*(--(c))))<<16; \ + case 1: l|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +#undef p_c2nl_p +#define p_c2nl_p(c,l,sc,len) { \ + switch (sc) \ + { \ + case 0: l =((unsigned long)(*((c)++)))<<24; \ + if (--len == 0) break; \ + case 1: l|=((unsigned long)(*((c)++)))<<16; \ + if (--len == 0) break; \ + case 2: l|=((unsigned long)(*((c)++)))<< 8; \ + } \ + } + +#undef nl2c +#define nl2c(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)) + +#undef c2l +#define c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24)) + +#undef p_c2l +#define p_c2l(c,l,n) { \ + switch (n) { \ + case 0: l =((unsigned long)(*((c)++))); \ + case 1: l|=((unsigned long)(*((c)++)))<< 8; \ + case 2: l|=((unsigned long)(*((c)++)))<<16; \ + case 3: l|=((unsigned long)(*((c)++)))<<24; \ + } \ + } + +#undef c2l_p +/* NOTE the pointer is not incremented at the end of this */ +#define c2l_p(c,l,n) { \ + l=0; \ + (c)+=n; \ + switch (n) { \ + case 3: l =((unsigned long)(*(--(c))))<<16; \ + case 2: l|=((unsigned long)(*(--(c))))<< 8; \ + case 1: l|=((unsigned long)(*(--(c)))); \ + } \ + } + +#undef p_c2l_p +#define p_c2l_p(c,l,sc,len) { \ + switch (sc) \ + { \ + case 0: l =((unsigned long)(*((c)++))); \ + if (--len == 0) break; \ + case 1: l|=((unsigned long)(*((c)++)))<< 8; \ + if (--len == 0) break; \ + case 2: l|=((unsigned long)(*((c)++)))<<16; \ + } \ + } + +#undef l2c +#define 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)) + +#ifndef SHA_LONG_LOG2 +#define SHA_LONG_LOG2 2 /* default to 32 bits */ +#endif + +#undef ROTATE +#undef Endian_Reverse32 +#if defined(WIN32) +#define ROTATE(a,n) _lrotl(a,n) +#elif defined(__GNUC__) && !defined(PEDANTIC) +/* some inline assembler templates by <appro@fy.chalmers.se> */ +#if defined(__i386) +#define ROTATE(a,n) ({ register unsigned int ret; \ + asm ("roll %1,%0" \ + : "=r"(ret) \ + : "I"(n), "0"(a) \ + : "cc"); \ + ret; \ + }) +#ifndef I386_ONLY +#define Endian_Reverse32(a) \ + { register unsigned int ltmp=(a); \ + asm ("bswapl %0" \ + : "=r"(ltmp) : "0"(ltmp)); \ + (a)=ltmp; \ + } +#endif +#elif defined(__powerpc) +#define ROTATE(a,n) ({ register unsigned int ret; \ + asm ("rlwinm %0,%1,%2,0,31" \ + : "=r"(ret) \ + : "r"(a), "I"(n)); \ + ret; \ + }) +/* Endian_Reverse32 is not needed for PowerPC */ +#endif +#endif + +/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */ +#ifdef ROTATE +#ifndef Endian_Reverse32 +/* 5 instructions with rotate instruction, else 9 */ +#define Endian_Reverse32(a) \ + { \ + unsigned long t=(a); \ + (a)=((ROTATE(t,8)&0x00FF00FF)|(ROTATE((t&0x00FF00FF),24))); \ + } +#endif +#else +#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) +#ifndef Endian_Reverse32 +/* 6 instructions with rotate instruction, else 8 */ +#define Endian_Reverse32(a) \ + { \ + unsigned long t=(a); \ + t=(((t>>8)&0x00FF00FF)|((t&0x00FF00FF)<<8)); \ + (a)=ROTATE(t,16); \ + } +#endif +/* + * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|... + * It's rewritten as above for two reasons: + * - RISCs aren't good at long constants and have to explicitely + * compose 'em with several (well, usually 2) instructions in a + * register before performing the actual operation and (as you + * already realized:-) having same constant should inspire the + * compiler to permanently allocate the only register for it; + * - most modern CPUs have two ALUs, but usually only one has + * circuitry for shifts:-( this minor tweak inspires compiler + * to schedule shift instructions in a better way... + * + * <appro@fy.chalmers.se> + */ +#endif + +/* 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) + +#undef Xupdate +#ifdef SHA_0 +#define Xupdate(a,i,ia,ib,ic,id) X[(i)&0x0f]=(a)=\ + (ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]); +#endif +#ifdef SHA_1 +#define Xupdate(a,i,ia,ib,ic,id) (a)=\ + (ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]);\ + X[(i)&0x0f]=(a)=ROTATE((a),1); +#endif + +#define BODY_00_15(i,a,b,c,d,e,f,xa) \ + (f)=xa[i]+(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,xa,xb,xc,xd) \ + Xupdate(f,i,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,xa,xb,xc,xd) \ + Xupdate(f,i,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) \ + Xupdate(f,i,xa,xa,xa,xa); \ + (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) \ + Xupdate(f,i,xa,xa,xa,xa); \ + (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) \ + Xupdate(f,i,xa,xa,xa,xa); \ + (f)=X[(i)&0x0f]+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \ + (b)=ROTATE((b),30); + diff --git a/lib/dns/sec/openssl/stack.c b/lib/dns/sec/openssl/stack.c new file mode 100644 index 00000000..bc137c43 --- /dev/null +++ b/lib/dns/sec/openssl/stack.c @@ -0,0 +1,303 @@ +/* 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 seached 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> + +#undef MIN_NODES +#define MIN_NODES 4 + +const char *STACK_version="Stack" OPENSSL_VERSION_PTEXT; + +#define FP_ICC (int (*)(const void *,const void *)) +#include <errno.h> + +int (*sk_set_cmp_func(STACK *sk, int (*c)()))(void) + { + int (*old)()=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 **)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: + return(NULL); + } + +STACK *sk_new(int (*c)()) + { + STACK *ret; + int i; + + if ((ret=(STACK *)Malloc(sizeof(STACK))) == NULL) + goto err0; + if ((ret->data=(char **)Malloc(sizeof(char *)*MIN_NODES)) == NULL) + goto err1; + 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); +err1: + Free((char *)ret); +err0: + return(NULL); + } + +int sk_insert(STACK *st, char *data, int loc) + { + char **s; + + if(st == NULL) return 0; + if (st->num_alloc <= st->num+1) + { + s=(char **)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=(char **)st->data; + t=(char **)&(st->data[1]); + for (i=st->num; i>=loc; i--) + t[i]=f[i]; + +#ifdef undef /* no memmove on sunos :-( */ + memmove( (char *)&(st->data[loc+1]), + (char *)&(st->data[loc]), + sizeof(char *)*(st->num-loc)); +#endif + st->data[loc]=data; + } + st->num++; + st->sorted=0; + return(st->num); + } + +char *sk_delete_ptr(STACK *st, char *p) + { + int i; + + for (i=0; i<st->num; i++) + if (st->data[i] == p) + return(sk_delete(st,i)); + return(NULL); + } + +char *sk_delete(STACK *st, int loc) + { + char *ret; + int i,j; + + if ((st == NULL) || (st->num == 0) || (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); + } + +int sk_find(STACK *st, char *data) + { + char **r; + int i; + int (*comp_func)(); + 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); + } + comp_func=(int (*)())st->comp; + if (!st->sorted) + { + qsort((char *)st->data,st->num,sizeof(char *),FP_ICC comp_func); + st->sorted=1; + } + if (data == NULL) return(-1); + r=(char **)bsearch(&data,(char *)st->data, + st->num,sizeof(char *),FP_ICC comp_func); + if (r == NULL) return(-1); + i=(int)(r-st->data); + for ( ; i>0; i--) + if ((*st->comp)(&(st->data[i-1]),&data) < 0) + break; + return(i); + } + +int sk_push(STACK *st, char *data) + { + return(sk_insert(st,data,st->num)); + } + +int sk_unshift(STACK *st, char *data) + { + return(sk_insert(st,data,0)); + } + +char *sk_shift(STACK *st) + { + if (st == NULL) return(NULL); + if (st->num <= 0) return(NULL); + return(sk_delete(st,0)); + } + +char *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)(char *)) + { + 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) Free((char *)st->data); + Free((char *)st); + } + +int sk_num(STACK *st) +{ + if(st == NULL) return -1; + return st->num; +} + +char *sk_value(STACK *st, int i) +{ + if(st == NULL) return NULL; + return st->data[i]; +} + +char *sk_set(STACK *st, int i, char *value) +{ + if(st == NULL) return NULL; + return (st->data[i] = value); +} diff --git a/lib/dns/sec/openssl/th-lock.c b/lib/dns/sec/openssl/th-lock.c new file mode 100644 index 00000000..ed976db3 --- /dev/null +++ b/lib/dns/sec/openssl/th-lock.c @@ -0,0 +1,373 @@ +/* crypto/threads/th-lock.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 <errno.h> +#ifdef LINUX +#include <typedefs.h> +#endif +#ifdef WIN32 +#include <windows.h> +#endif +#ifdef SOLARIS +#include <synch.h> +#include <thread.h> +#endif +#ifdef IRIX +#include <ulocks.h> +#include <sys/prctl.h> +#endif +#include <openssl/lhash.h> +#include <openssl/crypto.h> +#include <openssl/buffer.h> +#include <openssl/e_os.h> +#include <openssl/err.h> + +int CRYPTO_thread_setup(void); +void CRYPTO_thread_cleanup(void); + +#ifdef IRIX +static void irix_locking_callback(int mode,int type,char *file,int line); +static unsigned long irix_thread_id(void ); +#endif +#ifdef SOLARIS +static void solaris_locking_callback(int mode,int type,char *file,int line); +static unsigned long solaris_thread_id(void ); +#endif +#ifdef WIN32 +static void win32_locking_callback(int mode,int type,char *file,int line); +#endif +#ifdef PTHREADS +static void pthreads_locking_callback(int mode,int type,char *file,int line); +static unsigned long pthreads_thread_id(void ); +#endif + +/* usage: + * CRYPTO_thread_setup(); + * applicaion code + * CRYPTO_thread_cleanup(); + */ + +#define THREAD_STACK_SIZE (16*1024) + +#ifdef WIN32 + +static HANDLE lock_cs[CRYPTO_NUM_LOCKS]; + +int CRYPTO_thread_setup(void) + { + int i; + + for (i=0; i<CRYPTO_NUM_LOCKS; i++) + { + lock_cs[i]=CreateMutex(NULL,FALSE,NULL); + } + + CRYPTO_set_locking_callback((void (*)(int,int,char *,int))win32_locking_callback); + /* id callback defined */ + return(1); + } + +static void CRYPTO_thread_cleanup(void) + { + int i; + + CRYPTO_set_locking_callback(NULL); + for (i=0; i<CRYPTO_NUM_LOCKS; i++) + CloseHandle(lock_cs[i]); + } + +void win32_locking_callback(int mode, int type, char *file, int line) + { + if (mode & CRYPTO_LOCK) + { + WaitForSingleObject(lock_cs[type],INFINITE); + } + else + { + ReleaseMutex(lock_cs[type]); + } + } + +#endif /* WIN32 */ + +#ifdef SOLARIS + +#define USE_MUTEX + +static mutex_t lock_cs[CRYPTO_NUM_LOCKS]; +#ifdef USE_MUTEX +static long lock_count[CRYPTO_NUM_LOCKS]; +#else +static rwlock_t lock_cs[CRYPTO_NUM_LOCKS]; +#endif + +void CRYPTO_thread_setup(void) + { + int i; + + for (i=0; i<CRYPTO_NUM_LOCKS; i++) + { + lock_count[i]=0; +#ifdef USE_MUTEX + mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL); +#else + rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL); +#endif + } + + CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id); + CRYPTO_set_locking_callback((void (*)())solaris_locking_callback); + } + +void CRYPTO_thread_cleanup(void) + { + int i; + + CRYPTO_set_locking_callback(NULL); + for (i=0; i<CRYPTO_NUM_LOCKS; i++) + { +#ifdef USE_MUTEX + mutex_destroy(&(lock_cs[i])); +#else + rwlock_destroy(&(lock_cs[i])); +#endif + } + } + +void solaris_locking_callback(int mode, int type, char *file, int line) + { +#if 0 + fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n", + CRYPTO_thread_id(), + (mode&CRYPTO_LOCK)?"l":"u", + (type&CRYPTO_READ)?"r":"w",file,line); +#endif + +#if 0 + if (CRYPTO_LOCK_SSL_CERT == type) + fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n", + CRYPTO_thread_id(), + mode,file,line); +#endif + if (mode & CRYPTO_LOCK) + { +#ifdef USE_MUTEX + mutex_lock(&(lock_cs[type])); +#else + if (mode & CRYPTO_READ) + rw_rdlock(&(lock_cs[type])); + else + rw_wrlock(&(lock_cs[type])); +#endif + lock_count[type]++; + } + else + { +#ifdef USE_MUTEX + mutex_unlock(&(lock_cs[type])); +#else + rw_unlock(&(lock_cs[type])); +#endif + } + } + +unsigned long solaris_thread_id(void) + { + unsigned long ret; + + ret=(unsigned long)thr_self(); + return(ret); + } +#endif /* SOLARIS */ + +#ifdef IRIX +/* I don't think this works..... */ + +static usptr_t *arena; +static usema_t *lock_cs[CRYPTO_NUM_LOCKS]; + +void CRYPTO_thread_setup(void) + { + int i; + char filename[20]; + + strcpy(filename,"/tmp/mttest.XXXXXX"); + mktemp(filename); + + usconfig(CONF_STHREADIOOFF); + usconfig(CONF_STHREADMALLOCOFF); + usconfig(CONF_INITUSERS,100); + usconfig(CONF_LOCKTYPE,US_DEBUGPLUS); + arena=usinit(filename); + unlink(filename); + + for (i=0; i<CRYPTO_NUM_LOCKS; i++) + { + lock_cs[i]=usnewsema(arena,1); + } + + CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id); + CRYPTO_set_locking_callback((void (*)())irix_locking_callback); + } + +void CRYPTO_thread_cleanup(void) + { + int i; + + CRYPTO_set_locking_callback(NULL); + for (i=0; i<CRYPTO_NUM_LOCKS; i++) + { + char buf[10]; + + sprintf(buf,"%2d:",i); + usdumpsema(lock_cs[i],stdout,buf); + usfreesema(lock_cs[i],arena); + } + } + +void irix_locking_callback(int mode, int type, char *file, int line) + { + if (mode & CRYPTO_LOCK) + { + uspsema(lock_cs[type]); + } + else + { + usvsema(lock_cs[type]); + } + } + +unsigned long irix_thread_id(void) + { + unsigned long ret; + + ret=(unsigned long)getpid(); + return(ret); + } +#endif /* IRIX */ + +/* Linux and a few others */ +#ifdef PTHREADS + +static pthread_mutex_t lock_cs[CRYPTO_NUM_LOCKS]; +static long lock_count[CRYPTO_NUM_LOCKS]; + +void CRYPTO_thread_setup(void) + { + int i; + + for (i=0; i<CRYPTO_NUM_LOCKS; i++) + { + lock_count[i]=0; + pthread_mutex_init(&(lock_cs[i]),NULL); + } + + CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); + CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback); + } + +void thread_cleanup(void) + { + int i; + + CRYPTO_set_locking_callback(NULL); + for (i=0; i<CRYPTO_NUM_LOCKS; i++) + { + pthread_mutex_destroy(&(lock_cs[i])); + } + } + +void pthreads_locking_callback(int mode, int type, char *file, + int line) + { +#if 0 + fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n", + CRYPTO_thread_id(), + (mode&CRYPTO_LOCK)?"l":"u", + (type&CRYPTO_READ)?"r":"w",file,line); +#endif +#if 0 + if (CRYPTO_LOCK_SSL_CERT == type) + fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n", + CRYPTO_thread_id(), + mode,file,line); +#endif + if (mode & CRYPTO_LOCK) + { + pthread_mutex_lock(&(lock_cs[type])); + lock_count[type]++; + } + else + { + pthread_mutex_unlock(&(lock_cs[type])); + } + } + +unsigned long pthreads_thread_id(void) + { + unsigned long ret; + + ret=(unsigned long)pthread_self(); + return(ret); + } + +#endif /* PTHREADS */ + |