diff options
author | Moonchild <mcwerewolf@gmail.com> | 2018-02-06 12:02:47 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-06 12:02:47 +0100 |
commit | 389c60da5e01761f4a11ef539ffa26e4c1b17875 (patch) | |
tree | c6033924a0de9be1ab140596e305898c651bf57e /security/nss/lib/freebl | |
parent | 7c9b585349c985df0cf6ace83da5dadba8b5c677 (diff) | |
parent | f017b749ea9f1586d2308504553d40bf4cc5439d (diff) | |
download | UXP-389c60da5e01761f4a11ef539ffa26e4c1b17875.tar UXP-389c60da5e01761f4a11ef539ffa26e4c1b17875.tar.gz UXP-389c60da5e01761f4a11ef539ffa26e4c1b17875.tar.lz UXP-389c60da5e01761f4a11ef539ffa26e4c1b17875.tar.xz UXP-389c60da5e01761f4a11ef539ffa26e4c1b17875.zip |
Merge pull request #13 from MoonchildProductions/ported-upstream
Ported upstream
Diffstat (limited to 'security/nss/lib/freebl')
116 files changed, 1959 insertions, 8320 deletions
diff --git a/security/nss/lib/freebl/Makefile b/security/nss/lib/freebl/Makefile index 0ce1425f1..914a0119c 100644 --- a/security/nss/lib/freebl/Makefile +++ b/security/nss/lib/freebl/Makefile @@ -110,6 +110,7 @@ endif # NSS_X86_OR_X64 means the target is either x86 or x64 ifeq (,$(filter-out i386 x386 x86 x86_64,$(CPU_ARCH))) DEFINES += -DNSS_X86_OR_X64 + CFLAGS += -mpclmul -maes ifneq (,$(USE_64)$(USE_X32)) DEFINES += -DNSS_X64 else @@ -232,8 +233,6 @@ ifeq ($(CPU_ARCH),x86) DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT DEFINES += -DMP_IS_LITTLE_ENDIAN - # The floating point ECC code doesn't work on Linux x86 (bug 311432). - #ECL_USE_FP = 1 endif ifeq ($(CPU_ARCH),arm) DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE @@ -430,7 +429,6 @@ ifeq ($(CPU_ARCH),sparc) ASFILES = mpv_sparcv8.s montmulfv8.s DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL - ECL_USE_FP = 1 endif ifdef USE_ABI64_INT # this builds for Sparc v9a pure 64-bit architecture @@ -443,7 +441,6 @@ ifeq ($(CPU_ARCH),sparc) ASFILES = mpv_sparcv9.s montmulfv9.s DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL - ECL_USE_FP = 1 endif else @@ -491,16 +488,7 @@ else endif endif endif # Solaris for non-sparc family CPUs -endif # target == SunOS - -ifndef NSS_DISABLE_ECC - ifdef ECL_USE_FP - #enable floating point ECC code - DEFINES += -DECL_USE_FP - ECL_SRCS += ecp_fp160.c ecp_fp192.c ecp_fp224.c ecp_fp.c - ECL_HDRS += ecp_fp.h - endif -endif +endif # target == SunO # poly1305-donna-x64-sse2-incremental-source.c requires __int128 support # in GCC 4.6.0. @@ -601,7 +589,7 @@ $(ECL_OBJS): $(ECL_HDRS) -$(OBJDIR)/sysrand$(OBJ_SUFFIX): sysrand.c unix_rand.c win_rand.c os2_rand.c +$(OBJDIR)/sysrand$(OBJ_SUFFIX): sysrand.c unix_rand.c win_rand.c $(OBJDIR)/$(PROG_PREFIX)mpprime$(OBJ_SUFFIX): primes.c diff --git a/security/nss/lib/freebl/aeskeywrap.c b/security/nss/lib/freebl/aeskeywrap.c index 79ff8a852..ee909dbd0 100644 --- a/security/nss/lib/freebl/aeskeywrap.c +++ b/security/nss/lib/freebl/aeskeywrap.c @@ -22,8 +22,9 @@ #include "rijndael.h" struct AESKeyWrapContextStr { - unsigned char iv[AES_KEY_WRAP_IV_BYTES]; AESContext aescx; + unsigned char iv[AES_KEY_WRAP_IV_BYTES]; + void *mem; /* Pointer to beginning of allocated memory. */ }; /******************************************/ @@ -34,8 +35,14 @@ struct AESKeyWrapContextStr { AESKeyWrapContext * AESKeyWrap_AllocateContext(void) { - AESKeyWrapContext *cx = PORT_New(AESKeyWrapContext); - return cx; + /* aligned_alloc is C11 so we have to do it the old way. */ + AESKeyWrapContext *ctx = PORT_ZAlloc(sizeof(AESKeyWrapContext) + 15); + if (ctx == NULL) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + return NULL; + } + ctx->mem = ctx; + return (AESKeyWrapContext *)(((uintptr_t)ctx + 15) & ~(uintptr_t)0x0F); } SECStatus @@ -77,7 +84,7 @@ AESKeyWrap_CreateContext(const unsigned char *key, const unsigned char *iv, return NULL; /* error is already set */ rv = AESKeyWrap_InitContext(cx, key, keylen, iv, 0, encrypt, 0); if (rv != SECSuccess) { - PORT_Free(cx); + PORT_Free(cx->mem); cx = NULL; /* error should already be set */ } return cx; @@ -94,8 +101,9 @@ AESKeyWrap_DestroyContext(AESKeyWrapContext *cx, PRBool freeit) if (cx) { AES_DestroyContext(&cx->aescx, PR_FALSE); /* memset(cx, 0, sizeof *cx); */ - if (freeit) - PORT_Free(cx); + if (freeit) { + PORT_Free(cx->mem); + } } } diff --git a/security/nss/lib/freebl/blapi.h b/security/nss/lib/freebl/blapi.h index e5a6cf30e..31e471ac4 100644 --- a/security/nss/lib/freebl/blapi.h +++ b/security/nss/lib/freebl/blapi.h @@ -801,8 +801,7 @@ SEED_Decrypt(SEEDContext *cx, unsigned char *output, ** Create a new AES context suitable for AES encryption/decryption. ** "key" raw key data ** "keylen" the number of bytes of key data (16, 24, or 32) -** "blocklen" is the blocksize to use (16, 24, or 32) -** XXX currently only blocksize==16 has been tested! +** "blocklen" is the blocksize to use. NOTE: only 16 is supported! */ extern AESContext * AES_CreateContext(const unsigned char *key, const unsigned char *iv, @@ -1429,8 +1428,6 @@ extern SECStatus RNG_RandomUpdate(const void *data, size_t bytes); */ extern SECStatus RNG_GenerateGlobalRandomBytes(void *dest, size_t len); -extern SECStatus RNG_ResetForFuzzing(void); - /* Destroy the global RNG context. After a call to RNG_RNGShutdown() ** a call to RNG_RNGInit() is required in order to use the generator again, ** along with seed data (see the comment above RNG_RNGInit()). diff --git a/security/nss/lib/freebl/blapii.h b/security/nss/lib/freebl/blapii.h index 6ad2e2892..b1be7bedf 100644 --- a/security/nss/lib/freebl/blapii.h +++ b/security/nss/lib/freebl/blapii.h @@ -9,6 +9,7 @@ #define _BLAPII_H_ #include "blapit.h" +#include "mpi.h" /* max block size of supported block ciphers */ #define MAX_BLOCK_SIZE 16 @@ -50,6 +51,18 @@ SEC_END_PROTOS #define HAVE_NO_SANITIZE_ATTR 0 #endif +/* Alignment helpers. */ +#if defined(_WINDOWS) && defined(NSS_X86_OR_X64) +#define pre_align __declspec(align(16)) +#define post_align +#elif defined(NSS_X86_OR_X64) +#define pre_align +#define post_align __attribute__((aligned(16))) +#else +#define pre_align +#define post_align +#endif + #if defined(HAVE_UNALIGNED_ACCESS) && HAVE_NO_SANITIZE_ATTR #define NO_SANITIZE_ALIGNMENT __attribute__((no_sanitize("alignment"))) #else @@ -58,4 +71,12 @@ SEC_END_PROTOS #undef HAVE_NO_SANITIZE_ATTR +SECStatus RSA_Init(); +SECStatus generate_prime(mp_int *prime, int primeLen); + +/* Freebl state. */ +PRBool aesni_support(); +PRBool clmul_support(); +PRBool avx_support(); + #endif /* _BLAPII_H_ */ diff --git a/security/nss/lib/freebl/blinit.c b/security/nss/lib/freebl/blinit.c new file mode 100644 index 000000000..d7f2ec53a --- /dev/null +++ b/security/nss/lib/freebl/blinit.c @@ -0,0 +1,119 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifdef FREEBL_NO_DEPEND +#include "stubs.h" +#endif + +#include "blapii.h" +#include "mpi.h" +#include "secerr.h" +#include "prtypes.h" +#include "prinit.h" +#include "prenv.h" + +#if defined(_MSC_VER) && !defined(_M_IX86) +#include <intrin.h> /* for _xgetbv() */ +#endif + +static PRCallOnceType coFreeblInit; + +/* State variables. */ +static PRBool aesni_support_ = PR_FALSE; +static PRBool clmul_support_ = PR_FALSE; +static PRBool avx_support_ = PR_FALSE; + +#ifdef NSS_X86_OR_X64 +/* + * Adapted from the example code in "How to detect New Instruction support in + * the 4th generation Intel Core processor family" by Max Locktyukhin. + * + * XGETBV: + * Reads an extended control register (XCR) specified by ECX into EDX:EAX. + */ +static PRBool +check_xcr0_ymm() +{ + PRUint32 xcr0; +#if defined(_MSC_VER) +#if defined(_M_IX86) + __asm { + mov ecx, 0 + xgetbv + mov xcr0, eax + } +#else + xcr0 = (PRUint32)_xgetbv(0); /* Requires VS2010 SP1 or later. */ +#endif /* _M_IX86 */ +#else /* _MSC_VER */ + /* Old OSX compilers don't support xgetbv. Use byte form. */ + __asm__(".byte 0x0F, 0x01, 0xd0" + : "=a"(xcr0) + : "c"(0) + : "%edx"); +#endif /* _MSC_VER */ + /* Check if xmm and ymm state are enabled in XCR0. */ + return (xcr0 & 6) == 6; +} + +#define ECX_AESNI (1 << 25) +#define ECX_CLMUL (1 << 1) +#define ECX_XSAVE (1 << 26) +#define ECX_OSXSAVE (1 << 27) +#define ECX_AVX (1 << 28) +#define AVX_BITS (ECX_XSAVE | ECX_OSXSAVE | ECX_AVX) + +void +CheckX86CPUSupport() +{ + unsigned long eax, ebx, ecx, edx; + char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES"); + char *disable_pclmul = PR_GetEnvSecure("NSS_DISABLE_PCLMUL"); + char *disable_avx = PR_GetEnvSecure("NSS_DISABLE_AVX"); + freebl_cpuid(1, &eax, &ebx, &ecx, &edx); + aesni_support_ = (PRBool)((ecx & ECX_AESNI) != 0 && disable_hw_aes == NULL); + clmul_support_ = (PRBool)((ecx & ECX_CLMUL) != 0 && disable_pclmul == NULL); + /* For AVX we check AVX, OSXSAVE, and XSAVE + * as well as XMM and YMM state. */ + avx_support_ = (PRBool)((ecx & AVX_BITS) == AVX_BITS) && check_xcr0_ymm() && + disable_avx == NULL; +} +#endif /* NSS_X86_OR_X64 */ + +PRBool +aesni_support() +{ + return aesni_support_; +} +PRBool +clmul_support() +{ + return clmul_support_; +} +PRBool +avx_support() +{ + return avx_support_; +} + +static PRStatus +FreeblInit(void) +{ +#ifdef NSS_X86_OR_X64 + CheckX86CPUSupport(); +#endif + return PR_SUCCESS; +} + +SECStatus +BL_Init() +{ + if (PR_CallOnce(&coFreeblInit, FreeblInit) != PR_SUCCESS) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + RSA_Init(); + + return SECSuccess; +} diff --git a/security/nss/lib/freebl/ctr.c b/security/nss/lib/freebl/ctr.c index d5715a505..b7167d4c4 100644 --- a/security/nss/lib/freebl/ctr.c +++ b/security/nss/lib/freebl/ctr.c @@ -19,30 +19,30 @@ SECStatus CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher, - const unsigned char *param, unsigned int blocksize) + const unsigned char *param) { const CK_AES_CTR_PARAMS *ctrParams = (const CK_AES_CTR_PARAMS *)param; if (ctrParams->ulCounterBits == 0 || - ctrParams->ulCounterBits > blocksize * PR_BITS_PER_BYTE) { + ctrParams->ulCounterBits > AES_BLOCK_SIZE * PR_BITS_PER_BYTE) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - /* Invariant: 0 < ctr->bufPtr <= blocksize */ + /* Invariant: 0 < ctr->bufPtr <= AES_BLOCK_SIZE */ ctr->checkWrap = PR_FALSE; - ctr->bufPtr = blocksize; /* no unused data in the buffer */ + ctr->bufPtr = AES_BLOCK_SIZE; /* no unused data in the buffer */ ctr->cipher = cipher; ctr->context = context; ctr->counterBits = ctrParams->ulCounterBits; - if (blocksize > sizeof(ctr->counter) || - blocksize > sizeof(ctrParams->cb)) { + if (AES_BLOCK_SIZE > sizeof(ctr->counter) || + AES_BLOCK_SIZE > sizeof(ctrParams->cb)) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } - PORT_Memcpy(ctr->counter, ctrParams->cb, blocksize); + PORT_Memcpy(ctr->counter, ctrParams->cb, AES_BLOCK_SIZE); if (ctr->counterBits < 64) { - PORT_Memcpy(ctr->counterFirst, ctr->counter, blocksize); + PORT_Memcpy(ctr->counterFirst, ctr->counter, AES_BLOCK_SIZE); ctr->checkWrap = PR_TRUE; } return SECSuccess; @@ -50,7 +50,7 @@ CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher, CTRContext * CTR_CreateContext(void *context, freeblCipherFunc cipher, - const unsigned char *param, unsigned int blocksize) + const unsigned char *param) { CTRContext *ctr; SECStatus rv; @@ -60,7 +60,7 @@ CTR_CreateContext(void *context, freeblCipherFunc cipher, if (ctr == NULL) { return NULL; } - rv = CTR_InitContext(ctr, context, cipher, param, blocksize); + rv = CTR_InitContext(ctr, context, cipher, param); if (rv != SECSuccess) { CTR_DestroyContext(ctr, PR_TRUE); ctr = NULL; diff --git a/security/nss/lib/freebl/ctr.h b/security/nss/lib/freebl/ctr.h index a97da144e..a397e690e 100644 --- a/security/nss/lib/freebl/ctr.h +++ b/security/nss/lib/freebl/ctr.h @@ -23,8 +23,7 @@ struct CTRContextStr { typedef struct CTRContextStr CTRContext; SECStatus CTR_InitContext(CTRContext *ctr, void *context, - freeblCipherFunc cipher, const unsigned char *param, - unsigned int blocksize); + freeblCipherFunc cipher, const unsigned char *param); /* * The context argument is the inner cipher context to use with cipher. The @@ -34,7 +33,7 @@ SECStatus CTR_InitContext(CTRContext *ctr, void *context, * The cipher argument is a block cipher in the ECB encrypt mode. */ CTRContext *CTR_CreateContext(void *context, freeblCipherFunc cipher, - const unsigned char *param, unsigned int blocksize); + const unsigned char *param); void CTR_DestroyContext(CTRContext *ctr, PRBool freeit); diff --git a/security/nss/lib/freebl/cts.c b/security/nss/lib/freebl/cts.c index 99ccebb60..774294b7a 100644 --- a/security/nss/lib/freebl/cts.c +++ b/security/nss/lib/freebl/cts.c @@ -20,19 +20,15 @@ struct CTSContextStr { CTSContext * CTS_CreateContext(void *context, freeblCipherFunc cipher, - const unsigned char *iv, unsigned int blocksize) + const unsigned char *iv) { CTSContext *cts; - if (blocksize > MAX_BLOCK_SIZE) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return NULL; - } cts = PORT_ZNew(CTSContext); if (cts == NULL) { return NULL; } - PORT_Memcpy(cts->iv, iv, blocksize); + PORT_Memcpy(cts->iv, iv, MAX_BLOCK_SIZE); cts->cipher = cipher; cts->context = context; return cts; diff --git a/security/nss/lib/freebl/cts.h b/security/nss/lib/freebl/cts.h index a3ec180af..ddd56197f 100644 --- a/security/nss/lib/freebl/cts.h +++ b/security/nss/lib/freebl/cts.h @@ -17,7 +17,7 @@ typedef struct CTSContextStr CTSContext; * The cipher argument is a block cipher in the CBC mode. */ CTSContext *CTS_CreateContext(void *context, freeblCipherFunc cipher, - const unsigned char *iv, unsigned int blocksize); + const unsigned char *iv); void CTS_DestroyContext(CTSContext *cts, PRBool freeit); diff --git a/security/nss/lib/freebl/det_rng.c b/security/nss/lib/freebl/det_rng.c index fcbf9b34a..04fce30e8 100644 --- a/security/nss/lib/freebl/det_rng.c +++ b/security/nss/lib/freebl/det_rng.c @@ -9,10 +9,32 @@ #include "seccomon.h" #include "secerr.h" +#define GLOBAL_BYTES_SIZE 100 +static PRUint8 globalBytes[GLOBAL_BYTES_SIZE]; static unsigned long globalNumCalls = 0; +static PZLock *rng_lock = NULL; SECStatus -prng_ResetForFuzzing(PZLock *rng_lock) +RNG_RNGInit(void) +{ + rng_lock = PZ_NewLock(nssILockOther); + if (!rng_lock) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + /* --- LOCKED --- */ + PZ_Lock(rng_lock); + memset(globalBytes, 0, GLOBAL_BYTES_SIZE); + PZ_Unlock(rng_lock); + /* --- UNLOCKED --- */ + + return SECSuccess; +} + +/* Take min(size, GLOBAL_BYTES_SIZE) bytes from data and use as seed and reset + * the rng state. */ +SECStatus +RNG_RandomUpdate(const void *data, size_t bytes) { /* Check for a valid RNG lock. */ PORT_Assert(rng_lock != NULL); @@ -23,7 +45,11 @@ prng_ResetForFuzzing(PZLock *rng_lock) /* --- LOCKED --- */ PZ_Lock(rng_lock); + memset(globalBytes, 0, GLOBAL_BYTES_SIZE); globalNumCalls = 0; + if (data) { + memcpy(globalBytes, (PRUint8 *)data, PR_MIN(bytes, GLOBAL_BYTES_SIZE)); + } PZ_Unlock(rng_lock); /* --- UNLOCKED --- */ @@ -31,9 +57,9 @@ prng_ResetForFuzzing(PZLock *rng_lock) } SECStatus -prng_GenerateDeterministicRandomBytes(PZLock *rng_lock, void *dest, size_t len) +RNG_GenerateGlobalRandomBytes(void *dest, size_t len) { - static const uint8_t key[32]; + static const uint8_t key[32] = { 0 }; uint8_t nonce[12] = { 0 }; /* Check for a valid RNG lock. */ @@ -58,10 +84,60 @@ prng_GenerateDeterministicRandomBytes(PZLock *rng_lock, void *dest, size_t len) } memset(dest, 0, len); + memcpy(dest, globalBytes, PR_MIN(len, GLOBAL_BYTES_SIZE)); ChaCha20XOR(dest, dest, len, key, nonce, 0); ChaCha20Poly1305_DestroyContext(cx, PR_TRUE); PZ_Unlock(rng_lock); /* --- UNLOCKED --- */ + return SECSuccess; } + +void +RNG_RNGShutdown(void) +{ + PZ_DestroyLock(rng_lock); + rng_lock = NULL; +} + +/* Test functions are not implemented! */ +SECStatus +PRNGTEST_Instantiate(const PRUint8 *entropy, unsigned int entropy_len, + const PRUint8 *nonce, unsigned int nonce_len, + const PRUint8 *personal_string, unsigned int ps_len) +{ + return SECFailure; +} + +SECStatus +PRNGTEST_Reseed(const PRUint8 *entropy, unsigned int entropy_len, + const PRUint8 *additional, unsigned int additional_len) +{ + return SECFailure; +} + +SECStatus +PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len, + const PRUint8 *additional, unsigned int additional_len) +{ + return SECFailure; +} + +SECStatus +PRNGTEST_Uninstantiate() +{ + return SECFailure; +} + +SECStatus +PRNGTEST_RunHealthTests() +{ + return SECFailure; +} + +SECStatus +PRNGTEST_Instantiate_Kat() +{ + return SECFailure; +} diff --git a/security/nss/lib/freebl/dh.c b/security/nss/lib/freebl/dh.c index 97025c7e2..6f2bafda2 100644 --- a/security/nss/lib/freebl/dh.c +++ b/security/nss/lib/freebl/dh.c @@ -14,9 +14,9 @@ #include "secerr.h" #include "blapi.h" +#include "blapii.h" #include "secitem.h" #include "mpi.h" -#include "mpprime.h" #include "secmpi.h" #define KEA_DERIVED_SECRET_LEN 128 @@ -46,9 +46,7 @@ DH_GenParam(int primeLen, DHParams **params) { PLArenaPool *arena; DHParams *dhparams; - unsigned char *pb = NULL; unsigned char *ab = NULL; - unsigned long counter = 0; mp_int p, q, a, h, psub1, test; mp_err err = MP_OKAY; SECStatus rv = SECSuccess; @@ -81,17 +79,17 @@ DH_GenParam(int primeLen, DHParams **params) CHECK_MPI_OK(mp_init(&psub1)); CHECK_MPI_OK(mp_init(&test)); /* generate prime with MPI, uses Miller-Rabin to generate strong prime. */ - pb = PORT_Alloc(primeLen); - CHECK_SEC_OK(RNG_GenerateGlobalRandomBytes(pb, primeLen)); - pb[0] |= 0x80; /* set high-order bit */ - pb[primeLen - 1] |= 0x01; /* set low-order bit */ - CHECK_MPI_OK(mp_read_unsigned_octets(&p, pb, primeLen)); - CHECK_MPI_OK(mpp_make_prime(&p, primeLen * 8, PR_TRUE, &counter)); + CHECK_SEC_OK(generate_prime(&p, primeLen)); /* construct Sophie-Germain prime q = (p-1)/2. */ CHECK_MPI_OK(mp_sub_d(&p, 1, &psub1)); CHECK_MPI_OK(mp_div_2(&psub1, &q)); /* construct a generator from the prime. */ ab = PORT_Alloc(primeLen); + if (!ab) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + rv = SECFailure; + goto cleanup; + } /* generate a candidate number a in p's field */ CHECK_SEC_OK(RNG_GenerateGlobalRandomBytes(ab, primeLen)); CHECK_MPI_OK(mp_read_unsigned_octets(&a, ab, primeLen)); @@ -121,16 +119,16 @@ cleanup: mp_clear(&h); mp_clear(&psub1); mp_clear(&test); - if (pb) - PORT_ZFree(pb, primeLen); - if (ab) + if (ab) { PORT_ZFree(ab, primeLen); + } if (err) { MP_TO_SEC_ERROR(err); rv = SECFailure; } - if (rv) + if (rv != SECSuccess) { PORT_FreeArena(arena, PR_TRUE); + } return rv; } diff --git a/security/nss/lib/freebl/drbg.c b/security/nss/lib/freebl/drbg.c index ac0bba6e0..224bbe87d 100644 --- a/security/nss/lib/freebl/drbg.c +++ b/security/nss/lib/freebl/drbg.c @@ -20,10 +20,6 @@ #include "secrng.h" /* for RNG_SystemRNG() */ #include "secmpi.h" -#ifdef UNSAFE_FUZZER_MODE -#include "det_rng.h" -#endif - /* PRNG_SEEDLEN defined in NIST SP 800-90 section 10.1 * for SHA-1, SHA-224, and SHA-256 it's 440 bits. * for SHA-384 and SHA-512 it's 888 bits */ @@ -438,10 +434,10 @@ rng_init(void) globalrng = NULL; return PR_FAILURE; } - if (rv != SECSuccess) { return PR_FAILURE; } + /* the RNG is in a valid state */ globalrng->isValid = PR_TRUE; globalrng->isKatTest = PR_FALSE; @@ -658,21 +654,7 @@ prng_GenerateGlobalRandomBytes(RNGContext *rng, SECStatus RNG_GenerateGlobalRandomBytes(void *dest, size_t len) { -#ifdef UNSAFE_FUZZER_MODE - return prng_GenerateDeterministicRandomBytes(globalrng->lock, dest, len); -#else return prng_GenerateGlobalRandomBytes(globalrng, dest, len); -#endif -} - -SECStatus -RNG_ResetForFuzzing(void) -{ -#ifdef UNSAFE_FUZZER_MODE - return prng_ResetForFuzzing(globalrng->lock); -#else - return SECFailure; -#endif } void diff --git a/security/nss/lib/freebl/ec.c b/security/nss/lib/freebl/ec.c index 12bfeed41..669c9b147 100644 --- a/security/nss/lib/freebl/ec.c +++ b/security/nss/lib/freebl/ec.c @@ -565,6 +565,15 @@ ECDH_Derive(SECItem *publicValue, return SECFailure; } + /* + * Make sure the point is on the requested curve to avoid + * certain small subgroup attacks. + */ + if (EC_ValidatePublicKey(ecParams, publicValue) != SECSuccess) { + PORT_SetError(SEC_ERROR_BAD_KEY); + return SECFailure; + } + /* Perform curve specific multiplication using ECMethod */ if (ecParams->fieldID.type == ec_field_plain) { const ECMethod *method; @@ -580,10 +589,6 @@ ECDH_Derive(SECItem *publicValue, PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); return SECFailure; } - if (method->validate(publicValue) != SECSuccess) { - PORT_SetError(SEC_ERROR_BAD_KEY); - return SECFailure; - } return method->mul(derivedSecret, privateValue, publicValue); } @@ -1001,9 +1006,14 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, } slen = signature->len / 2; + /* + * The incoming point has been verified in sftk_handlePublicKeyObject. + */ + SECITEM_AllocItem(NULL, &pointC, EC_GetPointSize(ecParams)); - if (pointC.data == NULL) + if (pointC.data == NULL) { goto cleanup; + } CHECK_MPI_OK(mp_init(&r_)); CHECK_MPI_OK(mp_init(&s_)); diff --git a/security/nss/lib/freebl/ecdecode.c b/security/nss/lib/freebl/ecdecode.c index e1f1eb8a5..54b3e111b 100644 --- a/security/nss/lib/freebl/ecdecode.c +++ b/security/nss/lib/freebl/ecdecode.c @@ -22,57 +22,6 @@ if (SECSuccess != (rv = func)) \ goto cleanup -/* - * Initializes a SECItem from a hexadecimal string - * - * Warning: This function ignores leading 00's, so any leading 00's - * in the hexadecimal string must be optional. - */ -static SECItem * -hexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str) -{ - int i = 0; - int byteval = 0; - int tmp = PORT_Strlen(str); - - PORT_Assert(arena); - PORT_Assert(item); - - if ((tmp % 2) != 0) - return NULL; - - /* skip leading 00's unless the hex string is "00" */ - while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) { - str += 2; - tmp -= 2; - } - - item->data = (unsigned char *)PORT_ArenaAlloc(arena, tmp / 2); - if (item->data == NULL) - return NULL; - item->len = tmp / 2; - - while (str[i]) { - if ((str[i] >= '0') && (str[i] <= '9')) - tmp = str[i] - '0'; - else if ((str[i] >= 'a') && (str[i] <= 'f')) - tmp = str[i] - 'a' + 10; - else if ((str[i] >= 'A') && (str[i] <= 'F')) - tmp = str[i] - 'A' + 10; - else - return NULL; - - byteval = byteval * 16 + tmp; - if ((i % 2) != 0) { - item->data[i / 2] = byteval; - byteval = 0; - } - i++; - } - - return item; -} - /* Copy all of the fields from srcParams into dstParams */ SECStatus @@ -120,12 +69,10 @@ cleanup: } static SECStatus -gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params) +gf_populate_params_bytes(ECCurveName name, ECFieldType field_type, ECParams *params) { SECStatus rv = SECFailure; - const ECCurveParams *curveParams; - /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */ - char genenc[3 + 2 * 2 * MAX_ECKEY_LEN]; + const ECCurveBytes *curveParams; if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) goto cleanup; @@ -134,26 +81,19 @@ gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params) CHECK_OK(curveParams); params->fieldID.size = curveParams->size; params->fieldID.type = field_type; - if (field_type == ec_field_GFp || - field_type == ec_field_plain) { - CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.prime, - curveParams->irr)); - } else { - CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.poly, - curveParams->irr)); + if (field_type != ec_field_GFp && field_type != ec_field_plain) { + return SECFailure; } - CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a, - curveParams->curvea)); - CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b, - curveParams->curveb)); - genenc[0] = '0'; - genenc[1] = '4'; - genenc[2] = '\0'; - strcat(genenc, curveParams->genx); - strcat(genenc, curveParams->geny); - CHECK_OK(hexString2SECItem(params->arena, ¶ms->base, genenc)); - CHECK_OK(hexString2SECItem(params->arena, ¶ms->order, - curveParams->order)); + params->fieldID.u.prime.len = curveParams->scalarSize; + params->fieldID.u.prime.data = (unsigned char *)curveParams->irr; + params->curve.a.len = curveParams->scalarSize; + params->curve.a.data = (unsigned char *)curveParams->curvea; + params->curve.b.len = curveParams->scalarSize; + params->curve.b.data = (unsigned char *)curveParams->curveb; + params->base.len = curveParams->pointSize; + params->base.data = (unsigned char *)curveParams->base; + params->order.len = curveParams->scalarSize; + params->order.data = (unsigned char *)curveParams->order; params->cofactor = curveParams->cofactor; rv = SECSuccess; @@ -216,29 +156,30 @@ EC_FillParams(PLArenaPool *arena, const SECItem *encodedParams, /* Populate params for prime256v1 aka secp256r1 * (the NIST P-256 curve) */ - CHECK_SEC_OK(gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp, - params)); + CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_X9_62_PRIME_256V1, + ec_field_GFp, params)); break; case SEC_OID_SECG_EC_SECP384R1: /* Populate params for secp384r1 * (the NIST P-384 curve) */ - CHECK_SEC_OK(gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp, - params)); + CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_SECG_PRIME_384R1, + ec_field_GFp, params)); break; case SEC_OID_SECG_EC_SECP521R1: /* Populate params for secp521r1 * (the NIST P-521 curve) */ - CHECK_SEC_OK(gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp, - params)); + CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_SECG_PRIME_521R1, + ec_field_GFp, params)); break; case SEC_OID_CURVE25519: /* Populate params for Curve25519 */ - CHECK_SEC_OK(gf_populate_params(ECCurve25519, ec_field_plain, params)); + CHECK_SEC_OK(gf_populate_params_bytes(ECCurve25519, ec_field_plain, + params)); break; default: @@ -296,16 +237,20 @@ int EC_GetPointSize(const ECParams *params) { ECCurveName name = params->name; - const ECCurveParams *curveParams; + const ECCurveBytes *curveParams; if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve) || ((curveParams = ecCurve_map[name]) == NULL)) { - /* unknown curve, calculate point size from params. assume standard curves with 2 points + /* unknown curve, calculate point size from params. assume standard curves with 2 points * and a point compression indicator byte */ int sizeInBytes = (params->fieldID.size + 7) / 8; return sizeInBytes * 2 + 1; } - return curveParams->pointSize; + if (name == ECCurve25519) { + /* Only X here */ + return curveParams->scalarSize; + } + return curveParams->pointSize - 1; } #endif /* NSS_DISABLE_ECC */ diff --git a/security/nss/lib/freebl/ecl/README b/security/nss/lib/freebl/ecl/README index 04a8b3b01..2996822c8 100644 --- a/security/nss/lib/freebl/ecl/README +++ b/security/nss/lib/freebl/ecl/README @@ -90,20 +90,6 @@ the linear coefficient in the curve defining equation). ecp_192.c and ecp_224.c provide optimized field arithmetic. -Point Arithmetic over Binary Polynomial Fields ----------------------------------------------- - -ec2_aff.c provides point arithmetic using affine coordinates. - -ec2_proj.c provides point arithmetic using projective coordinates. -(Projective coordinates represent a point (x, y) as (X, Y, Z), where -x=X/Z, y=Y/Z^2). - -ec2_mont.c provides point multiplication using Montgomery projective -coordinates. - -ec2_163.c, ec2_193.c, and ec2_233.c provide optimized field arithmetic. - Field Arithmetic ---------------- @@ -126,18 +112,6 @@ fields defined by nistp192 and nistp224 primes. ecl_gf.c provides wrappers around the basic field operations. -Binary Polynomial Field Arithmetic ----------------------------------- - -../mpi/mp_gf2m.c provides basic binary polynomial field arithmetic, -including addition, multiplication, squaring, mod, and division, as well -as conversion ob polynomial representations between bitstring and int[]. - -ec2_163.c, ec2_193.c, and ec2_233.c provide optimized field mod, mul, -and sqr operations. - -ecl_gf.c provides wrappers around the basic field operations. - Field Encoding -------------- @@ -187,81 +161,3 @@ arithmetic. Instead, they use basic field arithmetic with their optimized reduction (as in ecp_192.c and ecp_224.c). They use the same point multiplication and simultaneous point multiplication algorithms as other curves over prime fields. - -Curves over binary polynomial fields by default use generic field -arithmetic with montgomery point multiplication and basic kP + lQ -computation (multiply, multiply, and add). (Wiring in function -ECGroup_cons_GF2m in ecl.c.) - -Curves over binary polynomial fields that have optimized field -arithmetic (i.e., any 163-, 193, or 233-bit field) use their optimized -field arithmetic. They use the same point multiplication and -simultaneous point multiplication algorithms as other curves over binary -fields. - -Example -------- - -We provide an example for plugging in an optimized implementation for -the Koblitz curve nistk163. - -Suppose the file ec2_k163.c contains the optimized implementation. In -particular it contains a point multiplication function: - - mp_err ec_GF2m_nistk163_pt_mul(const mp_int *n, const mp_int *px, - const mp_int *py, mp_int *rx, mp_int *ry, const ECGroup *group); - -Since only a pt_mul function is provided, the generic pt_add function -will be used. - -There are two options for handling the optimized field arithmetic used -by the ..._pt_mul function. Say the optimized field arithmetic includes -the following functions: - - mp_err ec_GF2m_nistk163_add(const mp_int *a, const mp_int *b, - mp_int *r, const GFMethod *meth); - mp_err ec_GF2m_nistk163_mul(const mp_int *a, const mp_int *b, - mp_int *r, const GFMethod *meth); - mp_err ec_GF2m_nistk163_sqr(const mp_int *a, const mp_int *b, - mp_int *r, const GFMethod *meth); - mp_err ec_GF2m_nistk163_div(const mp_int *a, const mp_int *b, - mp_int *r, const GFMethod *meth); - -First, the optimized field arithmetic could simply be called directly -by the ..._pt_mul function. This would be accomplished by changing -the ecgroup_fromNameAndHex function in ecl.c to include the following -statements: - - if (name == ECCurve_NIST_K163) { - group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, - &geny, &order, params->cofactor); - if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } - MP_CHECKOK( ec_group_set_nistk163(group) ); - } - -and including in ec2_k163.c the following function: - - mp_err ec_group_set_nistk163(ECGroup *group) { - group->point_mul = &ec_GF2m_nistk163_pt_mul; - return MP_OKAY; - } - -As a result, ec_GF2m_pt_add and similar functions would use the -basic binary polynomial field arithmetic ec_GF2m_add, ec_GF2m_mul, -ec_GF2m_sqr, and ec_GF2m_div. - -Alternatively, the optimized field arithmetic could be wired into the -group's GFMethod. This would be accomplished by putting the following -function in ec2_k163.c: - - mp_err ec_group_set_nistk163(ECGroup *group) { - group->meth->field_add = &ec_GF2m_nistk163_add; - group->meth->field_mul = &ec_GF2m_nistk163_mul; - group->meth->field_sqr = &ec_GF2m_nistk163_sqr; - group->meth->field_div = &ec_GF2m_nistk163_div; - group->point_mul = &ec_GF2m_nistk163_pt_mul; - return MP_OKAY; - } - -For an example of functions that use special field encodings, take a -look at ecp_mont.c. diff --git a/security/nss/lib/freebl/ecl/curve25519_64.c b/security/nss/lib/freebl/ecl/curve25519_64.c index 89327ad1c..65f6bd41b 100644 --- a/security/nss/lib/freebl/ecl/curve25519_64.c +++ b/security/nss/lib/freebl/ecl/curve25519_64.c @@ -206,7 +206,7 @@ fexpand(felem *output, const u8 *in) output[1] = (*((const uint64_t *)(in + 6)) >> 3) & MASK51; output[2] = (*((const uint64_t *)(in + 12)) >> 6) & MASK51; output[3] = (*((const uint64_t *)(in + 19)) >> 1) & MASK51; - output[4] = (*((const uint64_t *)(in + 25)) >> 4) & MASK51; + output[4] = (*((const uint64_t *)(in + 24)) >> 12) & MASK51; } /* Take a fully reduced polynomial form number and contract it into a diff --git a/security/nss/lib/freebl/ecl/ecl-curve.h b/security/nss/lib/freebl/ecl/ecl-curve.h index df061396c..fc8003f5d 100644 --- a/security/nss/lib/freebl/ecl/ecl-curve.h +++ b/security/nss/lib/freebl/ecl/ecl-curve.h @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ecl-exp.h" +#include "eclt.h" #include <stdlib.h> #ifndef __ecl_curve_h_ @@ -12,52 +13,201 @@ #define KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */ #define KU_KEY_AGREEMENT (0x08) /* bit 4 */ -static const ECCurveParams ecCurve_NIST_P256 = { +static const PRUint8 irr256[32] = + { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static const PRUint8 a256[32] = + { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC }; +static const PRUint8 b256[32] = + { 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, + 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, + 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B }; +static const PRUint8 x256[32] = + { 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, + 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96 }; +static const PRUint8 y256[32] = + { 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, + 0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, + 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 }; +static const PRUint8 order256[32] = + { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, + 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 }; +static const PRUint8 base256[66] = + { 0x04, 0x00, + 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, + 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96, + 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, + 0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, + 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 }; + +static const ECCurveBytes ecCurve_NIST_P256 = { "NIST-P256", ECField_GFp, 256, - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", - "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", - "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", - "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", - "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", - 1, 128, 65, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT + irr256, a256, b256, x256, y256, order256, base256, + 1, 128, 66, 32, + KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT }; -static const ECCurveParams ecCurve_NIST_P384 = { +static const PRUint8 irr384[48] = + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }; +static const PRUint8 a384[48] = + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC }; +static const PRUint8 b384[48] = + { 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, + 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, + 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, + 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF }; +static const PRUint8 x384[48] = + { 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, + 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, + 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7 }; +static const PRUint8 y384[48] = + { 0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF, + 0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, + 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE, + 0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F }; +static const PRUint8 order384[48] = + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, + 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 }; +static const PRUint8 base384[98] = + { 0x04, 0x00, + 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, + 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, + 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7, + 0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF, + 0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, + 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE, + 0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F }; + +static const ECCurveBytes ecCurve_NIST_P384 = { "NIST-P384", ECField_GFp, 384, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", - "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", - "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", - "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", - 1, 192, 97, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT + irr384, a384, b384, x384, y384, order384, base384, + 1, 192, 98, 48, + KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT }; -static const ECCurveParams ecCurve_NIST_P521 = { +static const PRUint8 irr521[66] = + { 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static const PRUint8 a521[66] = + { 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC }; +static const PRUint8 b521[66] = + { 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, + 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, + 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, + 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, + 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, + 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00 }; +static const PRUint8 x521[66] = + { 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, + 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, + 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, + 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, + 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, + 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66 }; +static const PRUint8 y521[66] = + { 0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A, + 0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, + 0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE, + 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, + 0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE, + 0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50 }; +static const PRUint8 order521[66] = + { 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, + 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, + 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, + 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09 }; +static const PRUint8 base521[134] = + { + 0x04, 0x00, + 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, + 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, + 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, + 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, + 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, + 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66, + 0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A, + 0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, + 0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE, + 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, + 0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE, + 0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50 + }; + +static const ECCurveBytes ecCurve_NIST_P521 = { "NIST-P521", ECField_GFp, 521, - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", - "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", - "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", - "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", - 1, 256, 133, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT + irr521, a521, b521, x521, y521, order521, base521, + 1, 256, 134, 66, + KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT }; -static const ECCurveParams ecCurve25519 = { +static const PRUint8 irr25519[32] = + { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }; +static const PRUint8 a25519[32] = + { 0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static const PRUint8 b25519[32] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static const PRUint8 x25519[32] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 }; +static const PRUint8 y25519[32] = + { 0xd9, 0xd3, 0xce, 0x7e, 0xa2, 0xc5, 0xe9, 0x29, 0xb2, 0x61, 0x7c, 0x6d, + 0x7e, 0x4d, 0x3d, 0x92, 0x4c, 0xd1, 0x48, 0x77, 0x2c, 0xdd, 0x1e, 0xe0, + 0xb4, 0x86, 0xa0, 0xb8, 0xa1, 0x19, 0xae, 0x20 }; +static const PRUint8 order25519[32] = + { 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, + 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 }; +static const PRUint8 base25519[66] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0xd9, 0xd3, 0xce, 0x7e, 0xa2, 0xc5, 0xe9, 0x29, 0xb2, 0x61, 0x7c, 0x6d, + 0x7e, 0x4d, 0x3d, 0x92, 0x4c, 0xd1, 0x48, 0x77, 0x2c, 0xdd, 0x1e, 0xe0, + 0xb4, 0x86, 0xa0, 0xb8, 0xa1, 0x19, 0xae, 0x20, 0x00, 0x04 }; + +static const ECCurveBytes ecCurve_25519 = { "Curve25519", ECField_GFp, 255, - "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed", - "076D06", - "00", - "0900000000000000000000000000000000000000000000000000000000000000", - "20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9", - "1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed", - 8, 128, 32, KU_KEY_AGREEMENT + irr25519, a25519, b25519, x25519, y25519, order25519, base25519, + 8, 128, 66, 32, + KU_KEY_AGREEMENT }; /* mapping between ECCurveName enum and pointers to ECCurveParams */ -static const ECCurveParams *ecCurve_map[] = { +static const ECCurveBytes *ecCurve_map[] = { NULL, /* ECCurve_noName */ NULL, /* ECCurve_NIST_P192 */ NULL, /* ECCurve_NIST_P224 */ @@ -116,7 +266,7 @@ static const ECCurveParams *ecCurve_map[] = { NULL, /* ECCurve_WTLS_1 */ NULL, /* ECCurve_WTLS_8 */ NULL, /* ECCurve_WTLS_9 */ - &ecCurve25519, /* ECCurve25519 */ + &ecCurve_25519, /* ECCurve25519 */ NULL /* ECCurve_pastLastCurve */ }; diff --git a/security/nss/lib/freebl/ecl/ecl-priv.h b/security/nss/lib/freebl/ecl/ecl-priv.h index f43f19327..21685599d 100644 --- a/security/nss/lib/freebl/ecl/ecl-priv.h +++ b/security/nss/lib/freebl/ecl/ecl-priv.h @@ -246,12 +246,5 @@ mp_err ec_group_set_gf2m233(ECGroup *group, ECCurveName name); /* Optimized point multiplication */ mp_err ec_group_set_gfp256_32(ECGroup *group, ECCurveName name); -/* Optimized floating-point arithmetic */ -#ifdef ECL_USE_FP -mp_err ec_group_set_secp160r1_fp(ECGroup *group); -mp_err ec_group_set_nistp192_fp(ECGroup *group); -mp_err ec_group_set_nistp224_fp(ECGroup *group); -#endif - SECStatus ec_Curve25519_mul(PRUint8 *q, const PRUint8 *s, const PRUint8 *p); #endif /* __ecl_priv_h_ */ diff --git a/security/nss/lib/freebl/ecl/ecl.c b/security/nss/lib/freebl/ecl/ecl.c index 3540af781..ca87b490c 100644 --- a/security/nss/lib/freebl/ecl/ecl.c +++ b/security/nss/lib/freebl/ecl/ecl.c @@ -2,11 +2,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifdef FREEBL_NO_DEPEND +#include "../stubs.h" +#endif + #include "mpi.h" #include "mplogic.h" #include "ecl.h" #include "ecl-priv.h" #include "ecp.h" +#include "ecl-curve.h" #include <stdlib.h> #include <string.h> @@ -128,37 +133,16 @@ CLEANUP: return group; } -/* Construct ECGroup from hex parameters and name, if any. Called by - * ECGroup_fromHex and ECGroup_fromName. */ +/* Construct an ECGroup. */ ECGroup * -ecgroup_fromNameAndHex(const ECCurveName name, - const ECCurveParams *params) +construct_ecgroup(const ECCurveName name, mp_int irr, mp_int curvea, + mp_int curveb, mp_int genx, mp_int geny, mp_int order, + int cofactor, ECField field, const char *text) { - mp_int irr, curvea, curveb, genx, geny, order; int bits; ECGroup *group = NULL; mp_err res = MP_OKAY; - /* initialize values */ - MP_DIGITS(&irr) = 0; - MP_DIGITS(&curvea) = 0; - MP_DIGITS(&curveb) = 0; - MP_DIGITS(&genx) = 0; - MP_DIGITS(&geny) = 0; - MP_DIGITS(&order) = 0; - MP_CHECKOK(mp_init(&irr)); - MP_CHECKOK(mp_init(&curvea)); - MP_CHECKOK(mp_init(&curveb)); - MP_CHECKOK(mp_init(&genx)); - MP_CHECKOK(mp_init(&geny)); - MP_CHECKOK(mp_init(&order)); - MP_CHECKOK(mp_read_radix(&irr, params->irr, 16)); - MP_CHECKOK(mp_read_radix(&curvea, params->curvea, 16)); - MP_CHECKOK(mp_read_radix(&curveb, params->curveb, 16)); - MP_CHECKOK(mp_read_radix(&genx, params->genx, 16)); - MP_CHECKOK(mp_read_radix(&geny, params->geny, 16)); - MP_CHECKOK(mp_read_radix(&order, params->order, 16)); - /* determine number of bits */ bits = mpl_significant_bits(&irr) - 1; if (bits < MP_OKAY) { @@ -167,12 +151,12 @@ ecgroup_fromNameAndHex(const ECCurveName name, } /* determine which optimizations (if any) to use */ - if (params->field == ECField_GFp) { + if (field == ECField_GFp) { switch (name) { case ECCurve_SECG_PRIME_256R1: group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); + &order, cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; @@ -183,7 +167,7 @@ ecgroup_fromNameAndHex(const ECCurveName name, case ECCurve_SECG_PRIME_521R1: group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); + &order, cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; @@ -194,7 +178,7 @@ ecgroup_fromNameAndHex(const ECCurveName name, /* use generic arithmetic */ group = ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); + &order, cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; @@ -206,62 +190,95 @@ ecgroup_fromNameAndHex(const ECCurveName name, } /* set name, if any */ - if ((group != NULL) && (params->text != NULL)) { - group->text = strdup(params->text); + if ((group != NULL) && (text != NULL)) { + group->text = strdup(text); if (group->text == NULL) { res = MP_MEM; } } CLEANUP: + if (group && res != MP_OKAY) { + ECGroup_free(group); + return NULL; + } + return group; +} + +/* Construct ECGroup from parameters and name, if any. */ +ECGroup * +ecgroup_fromName(const ECCurveName name, + const ECCurveBytes *params) +{ + mp_int irr, curvea, curveb, genx, geny, order; + ECGroup *group = NULL; + mp_err res = MP_OKAY; + + /* initialize values */ + MP_DIGITS(&irr) = 0; + MP_DIGITS(&curvea) = 0; + MP_DIGITS(&curveb) = 0; + MP_DIGITS(&genx) = 0; + MP_DIGITS(&geny) = 0; + MP_DIGITS(&order) = 0; + MP_CHECKOK(mp_init(&irr)); + MP_CHECKOK(mp_init(&curvea)); + MP_CHECKOK(mp_init(&curveb)); + MP_CHECKOK(mp_init(&genx)); + MP_CHECKOK(mp_init(&geny)); + MP_CHECKOK(mp_init(&order)); + MP_CHECKOK(mp_read_unsigned_octets(&irr, params->irr, params->scalarSize)); + MP_CHECKOK(mp_read_unsigned_octets(&curvea, params->curvea, params->scalarSize)); + MP_CHECKOK(mp_read_unsigned_octets(&curveb, params->curveb, params->scalarSize)); + MP_CHECKOK(mp_read_unsigned_octets(&genx, params->genx, params->scalarSize)); + MP_CHECKOK(mp_read_unsigned_octets(&geny, params->geny, params->scalarSize)); + MP_CHECKOK(mp_read_unsigned_octets(&order, params->order, params->scalarSize)); + + group = construct_ecgroup(name, irr, curvea, curveb, genx, geny, order, + params->cofactor, params->field, params->text); + +CLEANUP: mp_clear(&irr); mp_clear(&curvea); mp_clear(&curveb); mp_clear(&genx); mp_clear(&geny); mp_clear(&order); - if (res != MP_OKAY) { + if (group && res != MP_OKAY) { ECGroup_free(group); return NULL; } return group; } -/* Construct ECGroup from hexadecimal representations of parameters. */ -ECGroup * -ECGroup_fromHex(const ECCurveParams *params) +/* Construct ECCurveBytes from an ECCurveName */ +const ECCurveBytes * +ec_GetNamedCurveParams(const ECCurveName name) { - return ecgroup_fromNameAndHex(ECCurve_noName, params); + if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name) || + (ecCurve_map[name] == NULL)) { + return NULL; + } else { + return ecCurve_map[name]; + } } /* Construct ECGroup from named parameters. */ ECGroup * ECGroup_fromName(const ECCurveName name) { - ECGroup *group = NULL; - ECCurveParams *params = NULL; - mp_err res = MP_OKAY; + const ECCurveBytes *params = NULL; - params = EC_GetNamedCurveParams(name); + /* This doesn't work with Curve25519 but it's not necessary to. */ + PORT_Assert(name != ECCurve25519); + + params = ec_GetNamedCurveParams(name); if (params == NULL) { - res = MP_UNDEF; - goto CLEANUP; + return NULL; } /* construct actual group */ - group = ecgroup_fromNameAndHex(name, params); - if (group == NULL) { - res = MP_UNDEF; - goto CLEANUP; - } - -CLEANUP: - EC_FreeCurveParams(params); - if (res != MP_OKAY) { - ECGroup_free(group); - return NULL; - } - return group; + return ecgroup_fromName(name, params); } /* Validates an EC public key as described in Section 5.2.2 of X9.62. */ diff --git a/security/nss/lib/freebl/ecl/ecl.h b/security/nss/lib/freebl/ecl/ecl.h index ddcbb1f3a..f6d5bc4ea 100644 --- a/security/nss/lib/freebl/ecl/ecl.h +++ b/security/nss/lib/freebl/ecl/ecl.h @@ -11,28 +11,17 @@ #include "blapi.h" #include "ecl-exp.h" #include "mpi.h" +#include "eclt.h" struct ECGroupStr; typedef struct ECGroupStr ECGroup; -/* Construct ECGroup from hexadecimal representations of parameters. */ -ECGroup *ECGroup_fromHex(const ECCurveParams *params); - /* Construct ECGroup from named parameters. */ ECGroup *ECGroup_fromName(const ECCurveName name); /* Free an allocated ECGroup. */ void ECGroup_free(ECGroup *group); -/* Construct ECCurveParams from an ECCurveName */ -ECCurveParams *EC_GetNamedCurveParams(const ECCurveName name); - -/* Duplicates an ECCurveParams */ -ECCurveParams *ECCurveParams_dup(const ECCurveParams *params); - -/* Free an allocated ECCurveParams */ -void EC_FreeCurveParams(ECCurveParams *params); - /* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k * P(x, * y). If x, y = NULL, then P is assumed to be the generator (base point) * of the group of points on the elliptic curve. Input and output values diff --git a/security/nss/lib/freebl/ecl/ecl_curve.c b/security/nss/lib/freebl/ecl/ecl_curve.c deleted file mode 100644 index cf090cfc3..000000000 --- a/security/nss/lib/freebl/ecl/ecl_curve.c +++ /dev/null @@ -1,93 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "ecl.h" -#include "ecl-curve.h" -#include "ecl-priv.h" -#include <stdlib.h> -#include <string.h> - -#define CHECK(func) \ - if ((func) == NULL) { \ - res = 0; \ - goto CLEANUP; \ - } - -/* Duplicates an ECCurveParams */ -ECCurveParams * -ECCurveParams_dup(const ECCurveParams *params) -{ - int res = 1; - ECCurveParams *ret = NULL; - - CHECK(ret = (ECCurveParams *)calloc(1, sizeof(ECCurveParams))); - if (params->text != NULL) { - CHECK(ret->text = strdup(params->text)); - } - ret->field = params->field; - ret->size = params->size; - if (params->irr != NULL) { - CHECK(ret->irr = strdup(params->irr)); - } - if (params->curvea != NULL) { - CHECK(ret->curvea = strdup(params->curvea)); - } - if (params->curveb != NULL) { - CHECK(ret->curveb = strdup(params->curveb)); - } - if (params->genx != NULL) { - CHECK(ret->genx = strdup(params->genx)); - } - if (params->geny != NULL) { - CHECK(ret->geny = strdup(params->geny)); - } - if (params->order != NULL) { - CHECK(ret->order = strdup(params->order)); - } - ret->cofactor = params->cofactor; - -CLEANUP: - if (res != 1) { - EC_FreeCurveParams(ret); - return NULL; - } - return ret; -} - -#undef CHECK - -/* Construct ECCurveParams from an ECCurveName */ -ECCurveParams * -EC_GetNamedCurveParams(const ECCurveName name) -{ - if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name) || - (ecCurve_map[name] == NULL)) { - return NULL; - } else { - return ECCurveParams_dup(ecCurve_map[name]); - } -} - -/* Free the memory allocated (if any) to an ECCurveParams object. */ -void -EC_FreeCurveParams(ECCurveParams *params) -{ - if (params == NULL) - return; - if (params->text != NULL) - free(params->text); - if (params->irr != NULL) - free(params->irr); - if (params->curvea != NULL) - free(params->curvea); - if (params->curveb != NULL) - free(params->curveb); - if (params->genx != NULL) - free(params->genx); - if (params->geny != NULL) - free(params->geny); - if (params->order != NULL) - free(params->order); - free(params); -} diff --git a/security/nss/lib/freebl/ecl/eclt.h b/security/nss/lib/freebl/ecl/eclt.h new file mode 100644 index 000000000..e763706f2 --- /dev/null +++ b/security/nss/lib/freebl/ecl/eclt.h @@ -0,0 +1,30 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* This header holds ECC types and must not be exported publicly. */ + +#ifndef __eclt_h_ +#define __eclt_h_ + +/* byte encoding of curve parameters */ +struct ECCurveBytesStr { + char *text; + ECField field; + size_t size; + const PRUint8 *irr; + const PRUint8 *curvea; + const PRUint8 *curveb; + const PRUint8 *genx; + const PRUint8 *geny; + const PRUint8 *order; + const PRUint8 *base; + int cofactor; + int security; + size_t pointSize; + size_t scalarSize; + unsigned int usage; +}; +typedef struct ECCurveBytesStr ECCurveBytes; + +#endif /* __ecl_h_ */ diff --git a/security/nss/lib/freebl/ecl/ecp_25519.c b/security/nss/lib/freebl/ecl/ecp_25519.c index a8d41520e..1e7875fff 100644 --- a/security/nss/lib/freebl/ecl/ecp_25519.c +++ b/security/nss/lib/freebl/ecl/ecp_25519.c @@ -79,8 +79,7 @@ ec_Curve25519_pt_validate(const SECItem *px) 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, }; - /* The point must not be longer than 32 (it can be smaller). */ - if (px->len <= 32) { + if (px->len == 32) { p = px->data; } else { return SECFailure; diff --git a/security/nss/lib/freebl/ecl/ecp_jm.c b/security/nss/lib/freebl/ecl/ecp_jm.c index a1106cea8..bd13fa050 100644 --- a/security/nss/lib/freebl/ecl/ecp_jm.c +++ b/security/nss/lib/freebl/ecl/ecp_jm.c @@ -127,6 +127,17 @@ ec_GFp_pt_add_jm_aff(const mp_int *px, const mp_int *py, const mp_int *pz, MP_CHECKOK(group->meth->field_mul(A, qx, A, group->meth)); MP_CHECKOK(group->meth->field_mul(B, qy, B, group->meth)); + /* Check P == Q */ + if (mp_cmp(A, px) == 0) { + if (mp_cmp(B, py) == 0) { + /* If Px == Qx && Py == Qy, double P. */ + return ec_GFp_pt_dbl_jm(px, py, pz, paz4, rx, ry, rz, raz4, + scratch, group); + } + /* If Px == Qx && Py != Qy, return point at infinity. */ + return ec_GFp_pt_set_inf_jac(rx, ry, rz); + } + /* C = A - px, D = B - py */ MP_CHECKOK(group->meth->field_sub(A, px, C, group->meth)); MP_CHECKOK(group->meth->field_sub(B, py, D, group->meth)); diff --git a/security/nss/lib/freebl/ecl/tests/ec_naft.c b/security/nss/lib/freebl/ecl/tests/ec_naft.c deleted file mode 100644 index 61ef15c36..000000000 --- a/security/nss/lib/freebl/ecl/tests/ec_naft.c +++ /dev/null @@ -1,121 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "mpi.h" -#include "mplogic.h" -#include "ecl.h" -#include "ecp.h" -#include "ecl-priv.h" - -#include <sys/types.h> -#include <stdio.h> -#include <time.h> -#include <sys/time.h> -#include <sys/resource.h> - -/* Returns 2^e as an integer. This is meant to be used for small powers of - * two. */ -int ec_twoTo(int e); - -/* Number of bits of scalar to test */ -#define BITSIZE 160 - -/* Time k repetitions of operation op. */ -#define M_TimeOperation(op, k) \ - { \ - double dStart, dNow, dUserTime; \ - struct rusage ru; \ - int i; \ - getrusage(RUSAGE_SELF, &ru); \ - dStart = (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec * 0.000001; \ - for (i = 0; i < k; i++) { \ - { \ - op; \ - } \ - }; \ - getrusage(RUSAGE_SELF, &ru); \ - dNow = (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec * 0.000001; \ - dUserTime = dNow - dStart; \ - if (dUserTime) \ - printf(" %-45s\n k: %6i, t: %6.2f sec\n", #op, k, dUserTime); \ - } - -/* Tests wNAF computation. Non-adjacent-form is discussed in the paper: D. - * Hankerson, J. Hernandez and A. Menezes, "Software implementation of - * elliptic curve cryptography over binary fields", Proc. CHES 2000. */ - -mp_err -main(void) -{ - signed char naf[BITSIZE + 1]; - ECGroup *group = NULL; - mp_int k; - mp_int *scalar; - int i, count; - int res; - int w = 5; - char s[1000]; - - /* Get a 160 bit scalar to compute wNAF from */ - group = ECGroup_fromName(ECCurve_SECG_PRIME_160R1); - scalar = &group->genx; - - /* Compute wNAF representation of scalar */ - ec_compute_wNAF(naf, BITSIZE, scalar, w); - - /* Verify correctness of representation */ - mp_init(&k); /* init k to 0 */ - - for (i = BITSIZE; i >= 0; i--) { - mp_add(&k, &k, &k); - /* digits in mp_???_d are unsigned */ - if (naf[i] >= 0) { - mp_add_d(&k, naf[i], &k); - } else { - mp_sub_d(&k, -naf[i], &k); - } - } - - if (mp_cmp(&k, scalar) != 0) { - printf("Error: incorrect NAF value.\n"); - MP_CHECKOK(mp_toradix(&k, s, 16)); - printf("NAF value %s\n", s); - MP_CHECKOK(mp_toradix(scalar, s, 16)); - printf("original value %s\n", s); - goto CLEANUP; - } - - /* Verify digits of representation are valid */ - for (i = 0; i <= BITSIZE; i++) { - if (naf[i] % 2 == 0 && naf[i] != 0) { - printf("Error: Even non-zero digit found.\n"); - goto CLEANUP; - } - if (naf[i] < -(ec_twoTo(w - 1)) || naf[i] >= ec_twoTo(w - 1)) { - printf("Error: Magnitude of naf digit too large.\n"); - goto CLEANUP; - } - } - - /* Verify sparsity of representation */ - count = w - 1; - for (i = 0; i <= BITSIZE; i++) { - if (naf[i] != 0) { - if (count < w - 1) { - printf("Error: Sparsity failed.\n"); - goto CLEANUP; - } - count = 0; - } else - count++; - } - - /* Check timing */ - M_TimeOperation(ec_compute_wNAF(naf, BITSIZE, scalar, w), 10000); - - printf("Test passed.\n"); -CLEANUP: - ECGroup_free(group); - return MP_OKAY; -} diff --git a/security/nss/lib/freebl/ecl/tests/ecp_test.c b/security/nss/lib/freebl/ecl/tests/ecp_test.c deleted file mode 100644 index dcec4d747..000000000 --- a/security/nss/lib/freebl/ecl/tests/ecp_test.c +++ /dev/null @@ -1,409 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "mpi.h" -#include "mplogic.h" -#include "mpprime.h" -#include "ecl.h" -#include "ecl-curve.h" -#include "ecp.h" -#include <stdio.h> -#include <strings.h> -#include <assert.h> - -#include <time.h> -#include <sys/time.h> -#include <sys/resource.h> - -/* Time k repetitions of operation op. */ -#define M_TimeOperation(op, k) \ - { \ - double dStart, dNow, dUserTime; \ - struct rusage ru; \ - int i; \ - getrusage(RUSAGE_SELF, &ru); \ - dStart = (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec * 0.000001; \ - for (i = 0; i < k; i++) { \ - { \ - op; \ - } \ - }; \ - getrusage(RUSAGE_SELF, &ru); \ - dNow = (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec * 0.000001; \ - dUserTime = dNow - dStart; \ - if (dUserTime) \ - printf(" %-45s k: %6i, t: %6.2f sec\n", #op, k, dUserTime); \ - } - -/* Test curve using generic field arithmetic. */ -#define ECTEST_GENERIC_GFP(name_c, name) \ - printf("Testing %s using generic implementation...\n", name_c); \ - params = EC_GetNamedCurveParams(name); \ - if (params == NULL) { \ - printf(" Error: could not construct params.\n"); \ - res = MP_NO; \ - goto CLEANUP; \ - } \ - ECGroup_free(group); \ - group = ECGroup_fromHex(params); \ - if (group == NULL) { \ - printf(" Error: could not construct group.\n"); \ - res = MP_NO; \ - goto CLEANUP; \ - } \ - MP_CHECKOK(ectest_curve_GFp(group, ectestPrint, ectestTime, 1)); \ - printf("... okay.\n"); - -/* Test curve using specific field arithmetic. */ -#define ECTEST_NAMED_GFP(name_c, name) \ - printf("Testing %s using specific implementation...\n", name_c); \ - ECGroup_free(group); \ - group = ECGroup_fromName(name); \ - if (group == NULL) { \ - printf(" Warning: could not construct group.\n"); \ - printf("... failed; continuing with remaining tests.\n"); \ - } else { \ - MP_CHECKOK(ectest_curve_GFp(group, ectestPrint, ectestTime, 0)); \ - printf("... okay.\n"); \ - } - -/* Performs basic tests of elliptic curve cryptography over prime fields. - * If tests fail, then it prints an error message, aborts, and returns an - * error code. Otherwise, returns 0. */ -int -ectest_curve_GFp(ECGroup *group, int ectestPrint, int ectestTime, - int generic) -{ - - mp_int one, order_1, gx, gy, rx, ry, n; - int size; - mp_err res; - char s[1000]; - - /* initialize values */ - MP_CHECKOK(mp_init(&one)); - MP_CHECKOK(mp_init(&order_1)); - MP_CHECKOK(mp_init(&gx)); - MP_CHECKOK(mp_init(&gy)); - MP_CHECKOK(mp_init(&rx)); - MP_CHECKOK(mp_init(&ry)); - MP_CHECKOK(mp_init(&n)); - - MP_CHECKOK(mp_set_int(&one, 1)); - MP_CHECKOK(mp_sub(&group->order, &one, &order_1)); - - /* encode base point */ - if (group->meth->field_dec) { - MP_CHECKOK(group->meth->field_dec(&group->genx, &gx, group->meth)); - MP_CHECKOK(group->meth->field_dec(&group->geny, &gy, group->meth)); - } else { - MP_CHECKOK(mp_copy(&group->genx, &gx)); - MP_CHECKOK(mp_copy(&group->geny, &gy)); - } - if (ectestPrint) { - /* output base point */ - printf(" base point P:\n"); - MP_CHECKOK(mp_toradix(&gx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&gy, s, 16)); - printf(" %s\n", s); - if (group->meth->field_enc) { - printf(" base point P (encoded):\n"); - MP_CHECKOK(mp_toradix(&group->genx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&group->geny, s, 16)); - printf(" %s\n", s); - } - } - -#ifdef ECL_ENABLE_GFP_PT_MUL_AFF - /* multiply base point by order - 1 and check for negative of base - * point */ - MP_CHECKOK(ec_GFp_pt_mul_aff(&order_1, &group->genx, &group->geny, &rx, &ry, group)); - if (ectestPrint) { - printf(" (order-1)*P (affine):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - MP_CHECKOK(group->meth->field_neg(&ry, &ry, group->meth)); - if ((mp_cmp(&rx, &group->genx) != 0) || (mp_cmp(&ry, &group->geny) != 0)) { - printf(" Error: invalid result (expected (- base point)).\n"); - res = MP_NO; - goto CLEANUP; - } -#endif - -#ifdef ECL_ENABLE_GFP_PT_MUL_AFF - /* multiply base point by order - 1 and check for negative of base - * point */ - MP_CHECKOK(ec_GFp_pt_mul_jac(&order_1, &group->genx, &group->geny, &rx, &ry, group)); - if (ectestPrint) { - printf(" (order-1)*P (jacobian):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - MP_CHECKOK(group->meth->field_neg(&ry, &ry, group->meth)); - if ((mp_cmp(&rx, &group->genx) != 0) || (mp_cmp(&ry, &group->geny) != 0)) { - printf(" Error: invalid result (expected (- base point)).\n"); - res = MP_NO; - goto CLEANUP; - } -#endif - - /* multiply base point by order - 1 and check for negative of base - * point */ - MP_CHECKOK(ECPoint_mul(group, &order_1, NULL, NULL, &rx, &ry)); - if (ectestPrint) { - printf(" (order-1)*P (ECPoint_mul):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - MP_CHECKOK(mp_submod(&group->meth->irr, &ry, &group->meth->irr, &ry)); - if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) { - printf(" Error: invalid result (expected (- base point)).\n"); - res = MP_NO; - goto CLEANUP; - } - - /* multiply base point by order - 1 and check for negative of base - * point */ - MP_CHECKOK(ECPoint_mul(group, &order_1, &gx, &gy, &rx, &ry)); - if (ectestPrint) { - printf(" (order-1)*P (ECPoint_mul):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - MP_CHECKOK(mp_submod(&group->meth->irr, &ry, &group->meth->irr, &ry)); - if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) { - printf(" Error: invalid result (expected (- base point)).\n"); - res = MP_NO; - goto CLEANUP; - } - -#ifdef ECL_ENABLE_GFP_PT_MUL_AFF - /* multiply base point by order and check for point at infinity */ - MP_CHECKOK(ec_GFp_pt_mul_aff(&group->order, &group->genx, &group->geny, &rx, &ry, - group)); - if (ectestPrint) { - printf(" (order)*P (affine):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { - printf(" Error: invalid result (expected point at infinity).\n"); - res = MP_NO; - goto CLEANUP; - } -#endif - -#ifdef ECL_ENABLE_GFP_PT_MUL_JAC - /* multiply base point by order and check for point at infinity */ - MP_CHECKOK(ec_GFp_pt_mul_jac(&group->order, &group->genx, &group->geny, &rx, &ry, - group)); - if (ectestPrint) { - printf(" (order)*P (jacobian):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { - printf(" Error: invalid result (expected point at infinity).\n"); - res = MP_NO; - goto CLEANUP; - } -#endif - - /* multiply base point by order and check for point at infinity */ - MP_CHECKOK(ECPoint_mul(group, &group->order, NULL, NULL, &rx, &ry)); - if (ectestPrint) { - printf(" (order)*P (ECPoint_mul):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { - printf(" Error: invalid result (expected point at infinity).\n"); - res = MP_NO; - goto CLEANUP; - } - - /* multiply base point by order and check for point at infinity */ - MP_CHECKOK(ECPoint_mul(group, &group->order, &gx, &gy, &rx, &ry)); - if (ectestPrint) { - printf(" (order)*P (ECPoint_mul):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { - printf(" Error: invalid result (expected point at infinity).\n"); - res = MP_NO; - goto CLEANUP; - } - - /* check that (order-1)P + (order-1)P + P == (order-1)P */ - MP_CHECKOK(ECPoints_mul(group, &order_1, &order_1, &gx, &gy, &rx, &ry)); - MP_CHECKOK(ECPoints_mul(group, &one, &one, &rx, &ry, &rx, &ry)); - if (ectestPrint) { - printf(" (order-1)*P + (order-1)*P + P == (order-1)*P (ECPoints_mul):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - MP_CHECKOK(mp_submod(&group->meth->irr, &ry, &group->meth->irr, &ry)); - if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) { - printf(" Error: invalid result (expected (- base point)).\n"); - res = MP_NO; - goto CLEANUP; - } - - /* test validate_point function */ - if (ECPoint_validate(group, &gx, &gy) != MP_YES) { - printf(" Error: validate point on base point failed.\n"); - res = MP_NO; - goto CLEANUP; - } - MP_CHECKOK(mp_add_d(&gy, 1, &ry)); - if (ECPoint_validate(group, &gx, &ry) != MP_NO) { - printf(" Error: validate point on invalid point passed.\n"); - res = MP_NO; - goto CLEANUP; - } - - if (ectestTime) { - /* compute random scalar */ - size = mpl_significant_bits(&group->meth->irr); - if (size < MP_OKAY) { - goto CLEANUP; - } - MP_CHECKOK(mpp_random_size(&n, (size + ECL_BITS - 1) / ECL_BITS)); - MP_CHECKOK(group->meth->field_mod(&n, &n, group->meth)); - /* timed test */ - if (generic) { -#ifdef ECL_ENABLE_GFP_PT_MUL_AFF - M_TimeOperation(MP_CHECKOK(ec_GFp_pt_mul_aff(&n, &group->genx, &group->geny, &rx, &ry, - group)), - 100); -#endif - M_TimeOperation(MP_CHECKOK(ECPoint_mul(group, &n, NULL, NULL, &rx, &ry)), - 100); - M_TimeOperation(MP_CHECKOK(ECPoints_mul(group, &n, &n, &gx, &gy, &rx, &ry)), 100); - } else { - M_TimeOperation(MP_CHECKOK(ECPoint_mul(group, &n, NULL, NULL, &rx, &ry)), - 100); - M_TimeOperation(MP_CHECKOK(ECPoint_mul(group, &n, &gx, &gy, &rx, &ry)), - 100); - M_TimeOperation(MP_CHECKOK(ECPoints_mul(group, &n, &n, &gx, &gy, &rx, &ry)), 100); - } - } - -CLEANUP: - mp_clear(&one); - mp_clear(&order_1); - mp_clear(&gx); - mp_clear(&gy); - mp_clear(&rx); - mp_clear(&ry); - mp_clear(&n); - if (res != MP_OKAY) { - printf(" Error: exiting with error value %i\n", res); - } - return res; -} - -/* Prints help information. */ -void -printUsage() -{ - printf("Usage: ecp_test [--print] [--time]\n"); - printf(" --print Print out results of each point arithmetic test.\n"); - printf(" --time Benchmark point operations and print results.\n"); -} - -/* Performs tests of elliptic curve cryptography over prime fields If - * tests fail, then it prints an error message, aborts, and returns an - * error code. Otherwise, returns 0. */ -int -main(int argv, char **argc) -{ - - int ectestTime = 0; - int ectestPrint = 0; - int i; - ECGroup *group = NULL; - ECCurveParams *params = NULL; - mp_err res; - - /* read command-line arguments */ - for (i = 1; i < argv; i++) { - if ((strcasecmp(argc[i], "time") == 0) || (strcasecmp(argc[i], "-time") == 0) || (strcasecmp(argc[i], "--time") == 0)) { - ectestTime = 1; - } else if ((strcasecmp(argc[i], "print") == 0) || (strcasecmp(argc[i], "-print") == 0) || (strcasecmp(argc[i], "--print") == 0)) { - ectestPrint = 1; - } else { - printUsage(); - return 0; - } - } - - /* generic arithmetic tests */ - ECTEST_GENERIC_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1); - - /* specific arithmetic tests */ - ECTEST_NAMED_GFP("NIST-P192", ECCurve_NIST_P192); - ECTEST_NAMED_GFP("NIST-P224", ECCurve_NIST_P224); - ECTEST_NAMED_GFP("NIST-P256", ECCurve_NIST_P256); - ECTEST_NAMED_GFP("NIST-P384", ECCurve_NIST_P384); - ECTEST_NAMED_GFP("NIST-P521", ECCurve_NIST_P521); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v1", ECCurve_X9_62_PRIME_192V1); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v2", ECCurve_X9_62_PRIME_192V2); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v3", ECCurve_X9_62_PRIME_192V3); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v1", ECCurve_X9_62_PRIME_239V1); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v2", ECCurve_X9_62_PRIME_239V2); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v3", ECCurve_X9_62_PRIME_239V3); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME256v1", ECCurve_X9_62_PRIME_256V1); - ECTEST_NAMED_GFP("SECP-112R1", ECCurve_SECG_PRIME_112R1); - ECTEST_NAMED_GFP("SECP-112R2", ECCurve_SECG_PRIME_112R2); - ECTEST_NAMED_GFP("SECP-128R1", ECCurve_SECG_PRIME_128R1); - ECTEST_NAMED_GFP("SECP-128R2", ECCurve_SECG_PRIME_128R2); - ECTEST_NAMED_GFP("SECP-160K1", ECCurve_SECG_PRIME_160K1); - ECTEST_NAMED_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1); - ECTEST_NAMED_GFP("SECP-160R2", ECCurve_SECG_PRIME_160R2); - ECTEST_NAMED_GFP("SECP-192K1", ECCurve_SECG_PRIME_192K1); - ECTEST_NAMED_GFP("SECP-192R1", ECCurve_SECG_PRIME_192R1); - ECTEST_NAMED_GFP("SECP-224K1", ECCurve_SECG_PRIME_224K1); - ECTEST_NAMED_GFP("SECP-224R1", ECCurve_SECG_PRIME_224R1); - ECTEST_NAMED_GFP("SECP-256K1", ECCurve_SECG_PRIME_256K1); - ECTEST_NAMED_GFP("SECP-256R1", ECCurve_SECG_PRIME_256R1); - ECTEST_NAMED_GFP("SECP-384R1", ECCurve_SECG_PRIME_384R1); - ECTEST_NAMED_GFP("SECP-521R1", ECCurve_SECG_PRIME_521R1); - ECTEST_NAMED_GFP("WTLS-6 (112)", ECCurve_WTLS_6); - ECTEST_NAMED_GFP("WTLS-7 (160)", ECCurve_WTLS_7); - ECTEST_NAMED_GFP("WTLS-8 (112)", ECCurve_WTLS_8); - ECTEST_NAMED_GFP("WTLS-9 (160)", ECCurve_WTLS_9); - ECTEST_NAMED_GFP("WTLS-12 (224)", ECCurve_WTLS_12); - ECTEST_NAMED_GFP("Curve25519", ECCurve25519); - -CLEANUP: - EC_FreeCurveParams(params); - ECGroup_free(group); - if (res != MP_OKAY) { - printf("Error: exiting with error value %i\n", res); - } - return res; -} diff --git a/security/nss/lib/freebl/ecl/uint128.c b/security/nss/lib/freebl/ecl/uint128.c index 22cbd023c..5465875ad 100644 --- a/security/nss/lib/freebl/ecl/uint128.c +++ b/security/nss/lib/freebl/ecl/uint128.c @@ -31,6 +31,9 @@ init128x(uint64_t x) return ret; } +#define CONSTANT_TIME_CARRY(a, b) \ + ((a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(a) * 8 - 1)) + /* arithmetic */ uint128_t @@ -38,7 +41,7 @@ add128(uint128_t a, uint128_t b) { uint128_t ret; ret.lo = a.lo + b.lo; - ret.hi = a.hi + b.hi + (ret.lo < b.lo); + ret.hi = a.hi + b.hi + CONSTANT_TIME_CARRY(ret.lo, b.lo); return ret; } diff --git a/security/nss/lib/freebl/exports.gyp b/security/nss/lib/freebl/exports.gyp index ef81685b0..aded6bfb6 100644 --- a/security/nss/lib/freebl/exports.gyp +++ b/security/nss/lib/freebl/exports.gyp @@ -33,6 +33,7 @@ 'ec.h', 'ecl/ecl-curve.h', 'ecl/ecl.h', + 'ecl/eclt.h', 'hmacct.h', 'secmpi.h', 'secrng.h' diff --git a/security/nss/lib/freebl/fipsfreebl.c b/security/nss/lib/freebl/fipsfreebl.c index b3ae6865b..094513560 100644 --- a/security/nss/lib/freebl/fipsfreebl.c +++ b/security/nss/lib/freebl/fipsfreebl.c @@ -1707,7 +1707,7 @@ BL_FIPSEntryOK(PRBool freebl_only) return SECSuccess; } /* standalone freebl can initialize */ - if (freebl_only & self_tests_freebl_success) { + if (freebl_only && self_tests_freebl_success) { return SECSuccess; } PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); diff --git a/security/nss/lib/freebl/freebl.gyp b/security/nss/lib/freebl/freebl.gyp index f5ae232ec..8c0d0dcd5 100644 --- a/security/nss/lib/freebl/freebl.gyp +++ b/security/nss/lib/freebl/freebl.gyp @@ -32,121 +32,55 @@ '<(DEPTH)/exports.gyp:nss_exports' ] }, + # For test builds, build a static freebl library so we can statically + # link it into the test build binary. This way we don't have to + # dlopen() the shared lib but can directly call freebl functions. { - 'target_name': '<(freebl_name)', - 'type': 'shared_library', - 'sources': [ - 'aeskeywrap.c', - 'alg2268.c', - 'alghmac.c', - 'arcfive.c', - 'arcfour.c', - 'camellia.c', - 'chacha20poly1305.c', - 'ctr.c', - 'cts.c', - 'des.c', - 'desblapi.c', - 'dh.c', - 'drbg.c', - 'dsa.c', - 'ec.c', - 'ecdecode.c', - 'ecl/ec_naf.c', - 'ecl/ecl.c', - 'ecl/ecl_curve.c', - 'ecl/ecl_gf.c', - 'ecl/ecl_mult.c', - 'ecl/ecp_25519.c', - 'ecl/ecp_256.c', - 'ecl/ecp_256_32.c', - 'ecl/ecp_384.c', - 'ecl/ecp_521.c', - 'ecl/ecp_aff.c', - 'ecl/ecp_jac.c', - 'ecl/ecp_jm.c', - 'ecl/ecp_mont.c', - 'fipsfreebl.c', - 'freeblver.c', - 'gcm.c', - 'hmacct.c', - 'jpake.c', - 'ldvector.c', - 'md2.c', - 'md5.c', - 'mpi/mp_gf2m.c', - 'mpi/mpcpucache.c', - 'mpi/mpi.c', - 'mpi/mplogic.c', - 'mpi/mpmontg.c', - 'mpi/mpprime.c', - 'pqg.c', - 'rawhash.c', - 'rijndael.c', - 'rsa.c', - 'rsapkcs.c', - 'seed.c', - 'sha512.c', - 'sha_fast.c', - 'shvfy.c', - 'sysrand.c', - 'tlsprfalg.c' + 'target_name': 'freebl_static', + 'type': 'static_library', + 'includes': [ + 'freebl_base.gypi', + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:nss_exports', ], 'conditions': [ [ 'OS=="linux"', { - 'sources': [ - 'nsslowhash.c', - 'stubs.c', + 'defines!': [ + 'FREEBL_NO_DEPEND', + 'FREEBL_LOWHASH', + 'USE_HW_AES', + 'INTEL_GCM', ], 'conditions': [ - [ 'test_build==1', { - 'dependencies': [ - '<(DEPTH)/lib/util/util.gyp:nssutil3', - ], - }], [ 'target_arch=="x64"', { - 'sources': [ - 'arcfour-amd64-gas.s', + # The AES assembler code doesn't work in static test builds. + # The linker complains about non-relocatable code, and I + # currently don't know how to fix this properly. + 'sources!': [ 'intel-aes.s', 'intel-gcm.s', - 'mpi/mpi_amd64.c', - 'mpi/mpi_amd64_gas.s', - 'mpi/mp_comba.c', - ], - 'dependencies': [ - 'intel-gcm-wrap_c_lib', - ], - 'conditions': [ - [ 'cc_is_clang==1', { - 'cflags': [ - '-no-integrated-as', - ], - 'cflags_mozilla': [ - '-no-integrated-as', - ], - 'asflags_mozilla': [ - '-no-integrated-as', - ], - }], - ], - }], - [ 'target_arch=="ia32"', { - 'sources': [ - 'mpi/mpi_x86.s', - ], - }], - [ 'target_arch=="arm"', { - 'sources': [ - 'mpi/mpi_arm.c', ], }], ], - }, { - # not Linux + }], + ], + }, + { + 'target_name': '<(freebl_name)', + 'type': 'shared_library', + 'includes': [ + 'freebl_base.gypi', + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:nss_exports', + ], + 'conditions': [ + [ 'OS!="linux" and OS!="android"', { 'conditions': [ [ 'moz_fold_libs==0', { 'dependencies': [ - '../util/util.gyp:nssutil3', + '<(DEPTH)/lib/util/util.gyp:nssutil3', ], }, { 'libraries': [ @@ -154,97 +88,23 @@ ], }], ], - }], - [ 'OS=="win"', { - 'sources': [ - #TODO: building with mingw should not need this. - 'ecl/uint128.c', - #TODO: clang-cl needs -msse3 here - 'intel-gcm-wrap.c', - ], - 'libraries': [ - 'advapi32.lib', - ], - 'conditions': [ - [ 'target_arch=="x64"', { - 'sources': [ - 'arcfour-amd64-masm.asm', - 'mpi/mpi_amd64.c', - 'mpi/mpi_amd64_masm.asm', - 'mpi/mp_comba_amd64_masm.asm', - 'intel-aes-x64-masm.asm', - 'intel-gcm-x64-masm.asm', - ], - }, { - # not x64 - 'sources': [ - 'mpi/mpi_x86_asm.c', - 'intel-aes-x86-masm.asm', - 'intel-gcm-x86-masm.asm', - ], - }], - ], - }], - ['target_arch=="ia32" or target_arch=="x64"', { - 'sources': [ - # All intel architectures get the 64 bit version - 'ecl/curve25519_64.c', - ], - }, { - 'sources': [ - # All non intel architectures get the generic 32 bit implementation (slow!) - 'ecl/curve25519_32.c', + }, 'target_arch=="x64"', { + 'dependencies': [ + 'intel-gcm-wrap_c_lib', ], }], - #TODO uint128.c - [ 'disable_chachapoly==0', { - 'conditions': [ - [ 'OS!="win" and target_arch=="x64"', { - 'sources': [ - 'chacha20_vec.c', - 'poly1305-donna-x64-sse2-incremental-source.c', - ], - }, { - # not x64 - 'sources': [ - 'chacha20.c', - 'poly1305.c', - ], - }], + [ 'OS=="win" and cc_is_clang==1', { + 'dependencies': [ + 'intel-gcm-wrap_c_lib', ], }], - [ 'fuzz==1', { + [ 'OS=="linux"', { 'sources': [ - 'det_rng.c', - ], - 'defines': [ - 'UNSAFE_FUZZER_MODE', - ], - }], - [ 'test_build==1', { - 'defines': [ - 'CT_VERIF', - ], - }], - [ 'OS=="mac"', { - 'conditions': [ - [ 'target_arch=="ia32"', { - 'sources': [ - 'mpi/mpi_sse2.s', - ], - 'defines': [ - 'MP_USE_UINT_DIGIT', - 'MP_ASSEMBLY_MULTIPLY', - 'MP_ASSEMBLY_SQUARE', - 'MP_ASSEMBLY_DIV_2DX1D', - ], - }], + 'nsslowhash.c', + 'stubs.c', ], }], ], - 'dependencies': [ - '<(DEPTH)/exports.gyp:nss_exports', - ], 'variables': { 'conditions': [ [ 'OS=="linux"', { @@ -254,9 +114,6 @@ }], ] }, - 'ldflags': [ - '-Wl,-Bsymbolic' - ] }, ], 'conditions': [ @@ -296,13 +153,27 @@ 'MP_API_COMPATIBLE' ], 'conditions': [ + [ 'target_arch=="ia32" or target_arch=="x64"', { + 'cflags_mozilla': [ + '-mpclmul', + '-maes', + ], + }], + [ 'OS=="mac"', { + 'xcode_settings': { + # I'm not sure since when this is supported. + # But I hope that doesn't matter. We also assume this is x86/x64. + 'OTHER_CFLAGS': [ + '-mpclmul', + '-maes', + ], + }, + }], [ 'OS=="win" and target_arch=="ia32"', { 'msvs_settings': { 'VCCLCompilerTool': { #TODO: -Ox optimize flags 'PreprocessorDefinitions': [ - 'NSS_X86_OR_X64', - 'NSS_X86', 'MP_ASSEMBLY_MULTIPLY', 'MP_ASSEMBLY_SQUARE', 'MP_ASSEMBLY_DIV_2DX1D', @@ -319,9 +190,7 @@ 'VCCLCompilerTool': { #TODO: -Ox optimize flags 'PreprocessorDefinitions': [ - 'NSS_USE_64', - 'NSS_X86_OR_X64', - 'NSS_X64', + # Should be copied to mingw defines below 'MP_IS_LITTLE_ENDIAN', 'NSS_BEVAND_ARCFOUR', 'MPI_AMD64', @@ -333,13 +202,21 @@ }, }, }], + [ 'cc_use_gnu_ld==1 and OS=="win" and target_arch=="x64"', { + 'defines': [ + 'MP_IS_LITTLE_ENDIAN', + 'NSS_BEVAND_ARCFOUR', + 'MPI_AMD64', + 'MP_ASSEMBLY_MULTIPLY', + 'NSS_USE_COMBA', + 'USE_HW_AES', + 'INTEL_GCM', + ], + }], [ 'OS!="win"', { 'conditions': [ - [ 'target_arch=="x64"', { + [ 'target_arch=="x64" or target_arch=="arm64" or target_arch=="aarch64"', { 'defines': [ - 'NSS_USE_64', - 'NSS_X86_OR_X64', - 'NSS_X64', # The Makefile does version-tests on GCC, but we're not doing that here. 'HAVE_INT128_SUPPORT', ], @@ -348,24 +225,16 @@ 'ecl/uint128.c', ], }], - [ 'target_arch=="ia32"', { - 'defines': [ - 'NSS_X86_OR_X64', - 'NSS_X86', - ], - }], ], }], [ 'OS=="linux"', { 'defines': [ 'FREEBL_LOWHASH', + 'FREEBL_NO_DEPEND', ], + }], + [ 'OS=="linux" or OS=="android"', { 'conditions': [ - [ 'test_build==0', { - 'defines': [ - 'FREEBL_NO_DEPEND', - ], - }], [ 'target_arch=="x64"', { 'defines': [ 'MP_IS_LITTLE_ENDIAN', @@ -375,7 +244,7 @@ 'NSS_USE_COMBA', ], }], - [ 'target_arch=="x64" and use_msan==0', { + [ 'target_arch=="x64"', { 'defines': [ 'USE_HW_AES', 'INTEL_GCM', @@ -390,12 +259,21 @@ 'MP_USE_UINT_DIGIT', ], }], + [ 'target_arch=="ia32" or target_arch=="x64"', { + 'cflags': [ + # enable isa option for pclmul am aes-ni; supported since gcc 4.4 + # This is only support by x84/x64. It's not needed for Windows. + '-mpclmul', + '-maes', + ], + }], [ 'target_arch=="arm"', { 'defines': [ 'MP_ASSEMBLY_MULTIPLY', 'MP_ASSEMBLY_SQUARE', 'MP_USE_UINT_DIGIT', 'SHA_NO_LONG_LONG', + 'ARMHF', ], }], ], diff --git a/security/nss/lib/freebl/freebl_base.gypi b/security/nss/lib/freebl/freebl_base.gypi new file mode 100644 index 000000000..027aa2702 --- /dev/null +++ b/security/nss/lib/freebl/freebl_base.gypi @@ -0,0 +1,201 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +{ + 'sources': [ + 'aeskeywrap.c', + 'alg2268.c', + 'alghmac.c', + 'arcfive.c', + 'arcfour.c', + 'camellia.c', + 'chacha20poly1305.c', + 'ctr.c', + 'cts.c', + 'des.c', + 'desblapi.c', + 'dh.c', + 'drbg.c', + 'dsa.c', + 'ec.c', + 'ecdecode.c', + 'ecl/ec_naf.c', + 'ecl/ecl.c', + 'ecl/ecl_gf.c', + 'ecl/ecl_mult.c', + 'ecl/ecp_25519.c', + 'ecl/ecp_256.c', + 'ecl/ecp_256_32.c', + 'ecl/ecp_384.c', + 'ecl/ecp_521.c', + 'ecl/ecp_aff.c', + 'ecl/ecp_jac.c', + 'ecl/ecp_jm.c', + 'ecl/ecp_mont.c', + 'fipsfreebl.c', + 'blinit.c', + 'freeblver.c', + 'gcm.c', + 'hmacct.c', + 'jpake.c', + 'ldvector.c', + 'md2.c', + 'md5.c', + 'mpi/mp_gf2m.c', + 'mpi/mpcpucache.c', + 'mpi/mpi.c', + 'mpi/mplogic.c', + 'mpi/mpmontg.c', + 'mpi/mpprime.c', + 'pqg.c', + 'rawhash.c', + 'rijndael.c', + 'rsa.c', + 'rsapkcs.c', + 'seed.c', + 'sha512.c', + 'sha_fast.c', + 'shvfy.c', + 'sysrand.c', + 'tlsprfalg.c' + ], + 'conditions': [ + [ 'OS=="linux" or OS=="android"', { + 'conditions': [ + [ 'target_arch=="x64"', { + 'sources': [ + 'arcfour-amd64-gas.s', + 'intel-aes.s', + 'intel-gcm.s', + 'mpi/mpi_amd64.c', + 'mpi/mpi_amd64_gas.s', + 'mpi/mp_comba.c', + ], + 'conditions': [ + [ 'cc_is_clang==1', { + 'cflags': [ + '-no-integrated-as', + ], + 'cflags_mozilla': [ + '-no-integrated-as', + ], + 'asflags_mozilla': [ + '-no-integrated-as', + ], + }], + ], + }], + [ 'target_arch=="ia32"', { + 'sources': [ + 'mpi/mpi_x86.s', + ], + }], + [ 'target_arch=="arm"', { + 'sources': [ + 'mpi/mpi_arm.c', + ], + }], + ], + }], + [ 'OS=="win"', { + 'sources': [ + #TODO: building with mingw should not need this. + 'ecl/uint128.c', + ], + 'libraries': [ + 'advapi32.lib', + ], + 'conditions': [ + [ 'cc_use_gnu_ld!=1 and target_arch=="x64"', { + 'sources': [ + 'arcfour-amd64-masm.asm', + 'mpi/mpi_amd64.c', + 'mpi/mpi_amd64_masm.asm', + 'mpi/mp_comba_amd64_masm.asm', + 'intel-aes-x64-masm.asm', + 'intel-gcm-x64-masm.asm', + ], + }], + [ 'cc_use_gnu_ld!=1 and target_arch!="x64"', { + # not x64 + 'sources': [ + 'mpi/mpi_x86_asm.c', + 'intel-aes-x86-masm.asm', + 'intel-gcm-x86-masm.asm', + ], + }], + [ 'cc_is_clang!=1', { + # MSVC + 'sources': [ + 'intel-gcm-wrap.c', + ], + }], + ], + }], + ['target_arch=="ia32" or target_arch=="x64"', { + 'sources': [ + # All intel architectures get the 64 bit version + 'ecl/curve25519_64.c', + ], + }, { + 'sources': [ + # All non intel architectures get the generic 32 bit implementation (slow!) + 'ecl/curve25519_32.c', + ], + }], + #TODO uint128.c + [ 'disable_chachapoly==0', { + 'conditions': [ + [ 'OS!="win" and target_arch=="x64"', { + 'sources': [ + 'chacha20_vec.c', + 'poly1305-donna-x64-sse2-incremental-source.c', + ], + }, { + # not x64 + 'sources': [ + 'chacha20.c', + 'poly1305.c', + ], + }], + ], + }], + [ 'fuzz==1', { + 'sources!': [ 'drbg.c' ], + 'sources': [ 'det_rng.c' ], + }], + [ 'fuzz_tls==1', { + 'defines': [ + 'UNSAFE_FUZZER_MODE', + ], + }], + [ 'ct_verif==1', { + 'defines': [ + 'CT_VERIF', + ], + }], + [ 'only_dev_random==1', { + 'defines': [ + 'SEED_ONLY_DEV_URANDOM', + ] + }], + [ 'OS=="mac"', { + 'conditions': [ + [ 'target_arch=="ia32"', { + 'sources': [ + 'mpi/mpi_sse2.s', + ], + 'defines': [ + 'MP_USE_UINT_DIGIT', + 'MP_ASSEMBLY_MULTIPLY', + 'MP_ASSEMBLY_SQUARE', + 'MP_ASSEMBLY_DIV_2DX1D', + ], + }], + ], + }], + ], + 'ldflags': [ + '-Wl,-Bsymbolic' + ], +} diff --git a/security/nss/lib/freebl/gcm.c b/security/nss/lib/freebl/gcm.c index 22121001b..0fdb0fd48 100644 --- a/security/nss/lib/freebl/gcm.c +++ b/security/nss/lib/freebl/gcm.c @@ -1,6 +1,8 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* Thanks to Thomas Pornin for the ideas how to implement the constat time + * binary multiplication. */ #ifdef FREEBL_NO_DEPEND #include "stubs.h" @@ -15,440 +17,378 @@ #include <limits.h> -/************************************************************************** - * First implement the Galois hash function of GCM (gcmHash) * - **************************************************************************/ -#define GCM_HASH_LEN_LEN 8 /* gcm hash defines lengths to be 64 bits */ - -typedef struct gcmHashContextStr gcmHashContext; - -static SECStatus gcmHash_InitContext(gcmHashContext *hash, - const unsigned char *H, - unsigned int blocksize); -static void gcmHash_DestroyContext(gcmHashContext *ghash, PRBool freeit); -static SECStatus gcmHash_Update(gcmHashContext *ghash, - const unsigned char *buf, unsigned int len, - unsigned int blocksize); -static SECStatus gcmHash_Sync(gcmHashContext *ghash, unsigned int blocksize); -static SECStatus gcmHash_Final(gcmHashContext *gcm, unsigned char *outbuf, - unsigned int *outlen, unsigned int maxout, - unsigned int blocksize); -static SECStatus gcmHash_Reset(gcmHashContext *ghash, - const unsigned char *inbuf, - unsigned int inbufLen, unsigned int blocksize); - -/* compile time defines to select how the GF2 multiply is calculated. - * There are currently 2 algorithms implemented here: MPI and ALGORITHM_1. - * - * MPI uses the GF2m implemented in mpi to support GF2 ECC. - * ALGORITHM_1 is the Algorithm 1 in both NIST SP 800-38D and - * "The Galois/Counter Mode of Operation (GCM)", McGrew & Viega. - */ -#if !defined(GCM_USE_ALGORITHM_1) && !defined(GCM_USE_MPI) -#define GCM_USE_MPI 1 /* MPI is about 5x faster with the \ - * same or less complexity. It's possible to use \ - * tables to speed things up even more */ -#endif - -/* GCM defines the bit string to be LSB first, which is exactly - * opposite everyone else, including hardware. build array - * to reverse everything. */ -static const unsigned char gcm_byte_rev[256] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff -}; - -#ifdef GCM_TRACE -#include <stdio.h> - -#define GCM_TRACE_X(ghash, label) \ - { \ - unsigned char _X[MAX_BLOCK_SIZE]; \ - int i; \ - gcm_getX(ghash, _X, blocksize); \ - printf(label, (ghash)->m); \ - for (i = 0; i < blocksize; i++) \ - printf("%02x", _X[i]); \ - printf("\n"); \ - } -#define GCM_TRACE_BLOCK(label, buf, blocksize) \ - { \ - printf(label); \ - for (i = 0; i < blocksize; i++) \ - printf("%02x", buf[i]); \ - printf("\n"); \ - } -#else -#define GCM_TRACE_X(ghash, label) -#define GCM_TRACE_BLOCK(label, buf, blocksize) +#ifdef NSS_X86_OR_X64 +#include <wmmintrin.h> /* clmul */ #endif -#ifdef GCM_USE_MPI +/* Forward declarations */ +SECStatus gcm_HashMult_hw(gcmHashContext *ghash, const unsigned char *buf, + unsigned int count); +SECStatus gcm_HashMult_sftw(gcmHashContext *ghash, const unsigned char *buf, + unsigned int count); +SECStatus gcm_HashMult_sftw32(gcmHashContext *ghash, const unsigned char *buf, + unsigned int count); -#ifdef GCM_USE_ALGORITHM_1 -#error "Only define one of GCM_USE_MPI, GCM_USE_ALGORITHM_1" -#endif -/* use the MPI functions to calculate Xn = (Xn-1^C_i)*H mod poly */ -#include "mpi.h" -#include "secmpi.h" -#include "mplogic.h" -#include "mp_gf2m.h" - -/* state needed to handle GCM Hash function */ -struct gcmHashContextStr { - mp_int H; - mp_int X; - mp_int C_i; - const unsigned int *poly; - unsigned char buffer[MAX_BLOCK_SIZE]; - unsigned int bufLen; - int m; /* XXX what is m? */ - unsigned char counterBuf[2 * GCM_HASH_LEN_LEN]; - PRUint64 cLen; -}; - -/* f = x^128 + x^7 + x^2 + x + 1 */ -static const unsigned int poly_128[] = { 128, 7, 2, 1, 0 }; - -/* sigh, GCM defines the bit strings exactly backwards from everything else */ -static void -gcm_reverse(unsigned char *target, const unsigned char *src, - unsigned int blocksize) +uint64_t +get64(const unsigned char *bytes) { - unsigned int i; - for (i = 0; i < blocksize; i++) { - target[blocksize - i - 1] = gcm_byte_rev[src[i]]; - } + return ((uint64_t)bytes[0]) << 56 | + ((uint64_t)bytes[1]) << 48 | + ((uint64_t)bytes[2]) << 40 | + ((uint64_t)bytes[3]) << 32 | + ((uint64_t)bytes[4]) << 24 | + ((uint64_t)bytes[5]) << 16 | + ((uint64_t)bytes[6]) << 8 | + ((uint64_t)bytes[7]); } /* Initialize a gcmHashContext */ -static SECStatus -gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H, - unsigned int blocksize) +SECStatus +gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H, PRBool sw) { - mp_err err = MP_OKAY; - unsigned char H_rev[MAX_BLOCK_SIZE]; - - MP_DIGITS(&ghash->H) = 0; - MP_DIGITS(&ghash->X) = 0; - MP_DIGITS(&ghash->C_i) = 0; - CHECK_MPI_OK(mp_init(&ghash->H)); - CHECK_MPI_OK(mp_init(&ghash->X)); - CHECK_MPI_OK(mp_init(&ghash->C_i)); - - mp_zero(&ghash->X); - gcm_reverse(H_rev, H, blocksize); - CHECK_MPI_OK(mp_read_unsigned_octets(&ghash->H, H_rev, blocksize)); - - /* set the irreducible polynomial. Each blocksize has its own polynomial. - * for now only blocksize 16 (=128 bits) is defined */ - switch (blocksize) { - case 16: /* 128 bits */ - ghash->poly = poly_128; - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - goto cleanup; - } ghash->cLen = 0; ghash->bufLen = 0; - ghash->m = 0; PORT_Memset(ghash->counterBuf, 0, sizeof(ghash->counterBuf)); - return SECSuccess; -cleanup: - gcmHash_DestroyContext(ghash, PR_FALSE); - return SECFailure; -} -/* Destroy a HashContext (Note we zero the digits so this function - * is idempotent if called with freeit == PR_FALSE */ -static void -gcmHash_DestroyContext(gcmHashContext *ghash, PRBool freeit) -{ - mp_clear(&ghash->H); - mp_clear(&ghash->X); - mp_clear(&ghash->C_i); - PORT_Memset(ghash, 0, sizeof(gcmHashContext)); - if (freeit) { - PORT_Free(ghash); - } -} - -static SECStatus -gcm_getX(gcmHashContext *ghash, unsigned char *T, unsigned int blocksize) -{ - int len; - mp_err err; - unsigned char tmp_buf[MAX_BLOCK_SIZE]; - unsigned char *X; - - len = mp_unsigned_octet_size(&ghash->X); - if (len <= 0) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - X = tmp_buf; - PORT_Assert((unsigned int)len <= blocksize); - if ((unsigned int)len > blocksize) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - /* zero pad the result */ - if (len != blocksize) { - PORT_Memset(X, 0, blocksize - len); - X += blocksize - len; - } - - err = mp_to_unsigned_octets(&ghash->X, X, len); - if (err < 0) { + ghash->h_low = get64(H + 8); + ghash->h_high = get64(H); + if (clmul_support() && !sw) { +#ifdef NSS_X86_OR_X64 + ghash->ghash_mul = gcm_HashMult_hw; + ghash->x = _mm_setzero_si128(); + /* MSVC requires __m64 to load epi64. */ + ghash->h = _mm_set_epi32(ghash->h_high >> 32, (uint32_t)ghash->h_high, + ghash->h_low >> 32, (uint32_t)ghash->h_low); + ghash->hw = PR_TRUE; +#else PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; +#endif /* NSS_X86_OR_X64 */ + } else { +/* We fall back to the software implementation if we can't use / don't + * want to use pclmul. */ +#ifdef HAVE_INT128_SUPPORT + ghash->ghash_mul = gcm_HashMult_sftw; +#else + ghash->ghash_mul = gcm_HashMult_sftw32; +#endif + ghash->x_high = ghash->x_low = 0; + ghash->hw = PR_FALSE; } - gcm_reverse(T, tmp_buf, blocksize); return SECSuccess; } -static SECStatus -gcm_HashMult(gcmHashContext *ghash, const unsigned char *buf, - unsigned int count, unsigned int blocksize) -{ - SECStatus rv = SECFailure; - mp_err err = MP_OKAY; - unsigned char tmp_buf[MAX_BLOCK_SIZE]; - unsigned int i; - - for (i = 0; i < count; i++, buf += blocksize) { - ghash->m++; - gcm_reverse(tmp_buf, buf, blocksize); - CHECK_MPI_OK(mp_read_unsigned_octets(&ghash->C_i, tmp_buf, blocksize)); - CHECK_MPI_OK(mp_badd(&ghash->X, &ghash->C_i, &ghash->C_i)); - /* - * Looking to speed up GCM, this the the place to do it. - * There are two areas that can be exploited to speed up this code. - * - * 1) H is a constant in this multiply. We can precompute H * (0 - 255) - * at init time and this becomes an blockize xors of our table lookup. - * - * 2) poly is a constant for each blocksize. We can calculate the - * modulo reduction by a series of adds and shifts. - * - * For now we are after functionality, so we will go ahead and use - * the builtin bmulmod from mpi - */ - CHECK_MPI_OK(mp_bmulmod(&ghash->C_i, &ghash->H, - ghash->poly, &ghash->X)); - GCM_TRACE_X(ghash, "X%d = ") - } - rv = SECSuccess; -cleanup: - PORT_Memset(tmp_buf, 0, sizeof(tmp_buf)); - if (rv != SECSuccess) { - MP_TO_SEC_ERROR(err); - } - return rv; -} - -static void -gcm_zeroX(gcmHashContext *ghash) +#ifdef HAVE_INT128_SUPPORT +/* Binary multiplication x * y = r_high << 64 | r_low. */ +void +bmul(uint64_t x, uint64_t y, uint64_t *r_high, uint64_t *r_low) { - mp_zero(&ghash->X); - ghash->m = 0; + uint128_t x1, x2, x3, x4, x5; + uint128_t y1, y2, y3, y4, y5; + uint128_t r, z; + + uint128_t m1 = (uint128_t)0x2108421084210842 << 64 | 0x1084210842108421; + uint128_t m2 = (uint128_t)0x4210842108421084 << 64 | 0x2108421084210842; + uint128_t m3 = (uint128_t)0x8421084210842108 << 64 | 0x4210842108421084; + uint128_t m4 = (uint128_t)0x0842108421084210 << 64 | 0x8421084210842108; + uint128_t m5 = (uint128_t)0x1084210842108421 << 64 | 0x0842108421084210; + + x1 = x & m1; + y1 = y & m1; + x2 = x & m2; + y2 = y & m2; + x3 = x & m3; + y3 = y & m3; + x4 = x & m4; + y4 = y & m4; + x5 = x & m5; + y5 = y & m5; + + z = (x1 * y1) ^ (x2 * y5) ^ (x3 * y4) ^ (x4 * y3) ^ (x5 * y2); + r = z & m1; + z = (x1 * y2) ^ (x2 * y1) ^ (x3 * y5) ^ (x4 * y4) ^ (x5 * y3); + r |= z & m2; + z = (x1 * y3) ^ (x2 * y2) ^ (x3 * y1) ^ (x4 * y5) ^ (x5 * y4); + r |= z & m3; + z = (x1 * y4) ^ (x2 * y3) ^ (x3 * y2) ^ (x4 * y1) ^ (x5 * y5); + r |= z & m4; + z = (x1 * y5) ^ (x2 * y4) ^ (x3 * y3) ^ (x4 * y2) ^ (x5 * y1); + r |= z & m5; + + *r_high = (uint64_t)(r >> 64); + *r_low = (uint64_t)r; } -#endif - -#ifdef GCM_USE_ALGORITHM_1 -/* use algorithm 1 of McGrew & Viega "The Galois/Counter Mode of Operation" */ - -#define GCM_ARRAY_SIZE (MAX_BLOCK_SIZE / sizeof(unsigned long)) - -struct gcmHashContextStr { - unsigned long H[GCM_ARRAY_SIZE]; - unsigned long X[GCM_ARRAY_SIZE]; - unsigned long R; - unsigned char buffer[MAX_BLOCK_SIZE]; - unsigned int bufLen; - int m; - unsigned char counterBuf[2 * GCM_HASH_LEN_LEN]; - PRUint64 cLen; -}; - -static void -gcm_bytes_to_longs(unsigned long *l, const unsigned char *c, unsigned int len) +SECStatus +gcm_HashMult_sftw(gcmHashContext *ghash, const unsigned char *buf, + unsigned int count) { - int i, j; - int array_size = len / sizeof(unsigned long); - - PORT_Assert(len % sizeof(unsigned long) == 0); - for (i = 0; i < array_size; i++) { - unsigned long tmp = 0; - int byte_offset = i * sizeof(unsigned long); - for (j = sizeof(unsigned long) - 1; j >= 0; j--) { - tmp = (tmp << PR_BITS_PER_BYTE) | gcm_byte_rev[c[byte_offset + j]]; - } - l[i] = tmp; - } + uint64_t ci_low, ci_high; + size_t i; + uint64_t z2_low, z2_high, z0_low, z0_high, z1a_low, z1a_high; + uint128_t z_high = 0, z_low = 0; + + ci_low = ghash->x_low; + ci_high = ghash->x_high; + for (i = 0; i < count; i++, buf += 16) { + ci_low ^= get64(buf + 8); + ci_high ^= get64(buf); + + /* Do binary mult ghash->X = C * ghash->H (Karatsuba). */ + bmul(ci_high, ghash->h_high, &z2_high, &z2_low); + bmul(ci_low, ghash->h_low, &z0_high, &z0_low); + bmul(ci_high ^ ci_low, ghash->h_high ^ ghash->h_low, &z1a_high, &z1a_low); + z1a_high ^= z2_high ^ z0_high; + z1a_low ^= z2_low ^ z0_low; + z_high = ((uint128_t)z2_high << 64) | (z2_low ^ z1a_high); + z_low = (((uint128_t)z0_high << 64) | z0_low) ^ (((uint128_t)z1a_low) << 64); + + /* Shift one (multiply by x) as gcm spec is stupid. */ + z_high = (z_high << 1) | (z_low >> 127); + z_low <<= 1; + + /* Reduce */ + z_low ^= (z_low << 127) ^ (z_low << 126) ^ (z_low << 121); + z_high ^= z_low ^ (z_low >> 1) ^ (z_low >> 2) ^ (z_low >> 7); + ci_low = (uint64_t)z_high; + ci_high = (uint64_t)(z_high >> 64); + } + ghash->x_low = ci_low; + ghash->x_high = ci_high; + return SECSuccess; } - -static void -gcm_longs_to_bytes(const unsigned long *l, unsigned char *c, unsigned int len) +#else +/* Binary multiplication x * y = r_high << 32 | r_low. */ +void +bmul32(uint32_t x, uint32_t y, uint32_t *r_high, uint32_t *r_low) { - int i, j; - int array_size = len / sizeof(unsigned long); - - PORT_Assert(len % sizeof(unsigned long) == 0); - for (i = 0; i < array_size; i++) { - unsigned long tmp = l[i]; - int byte_offset = i * sizeof(unsigned long); - for (j = 0; j < sizeof(unsigned long); j++) { - c[byte_offset + j] = gcm_byte_rev[tmp & 0xff]; - tmp = (tmp >> PR_BITS_PER_BYTE); - } - } + uint32_t x0, x1, x2, x3; + uint32_t y0, y1, y2, y3; + uint32_t m1 = (uint32_t)0x11111111; + uint32_t m2 = (uint32_t)0x22222222; + uint32_t m4 = (uint32_t)0x44444444; + uint32_t m8 = (uint32_t)0x88888888; + uint64_t z0, z1, z2, z3; + uint64_t z; + + x0 = x & m1; + x1 = x & m2; + x2 = x & m4; + x3 = x & m8; + y0 = y & m1; + y1 = y & m2; + y2 = y & m4; + y3 = y & m8; + z0 = ((uint64_t)x0 * y0) ^ ((uint64_t)x1 * y3) ^ + ((uint64_t)x2 * y2) ^ ((uint64_t)x3 * y1); + z1 = ((uint64_t)x0 * y1) ^ ((uint64_t)x1 * y0) ^ + ((uint64_t)x2 * y3) ^ ((uint64_t)x3 * y2); + z2 = ((uint64_t)x0 * y2) ^ ((uint64_t)x1 * y1) ^ + ((uint64_t)x2 * y0) ^ ((uint64_t)x3 * y3); + z3 = ((uint64_t)x0 * y3) ^ ((uint64_t)x1 * y2) ^ + ((uint64_t)x2 * y1) ^ ((uint64_t)x3 * y0); + z0 &= ((uint64_t)m1 << 32) | m1; + z1 &= ((uint64_t)m2 << 32) | m2; + z2 &= ((uint64_t)m4 << 32) | m4; + z3 &= ((uint64_t)m8 << 32) | m8; + z = z0 | z1 | z2 | z3; + *r_high = (uint32_t)(z >> 32); + *r_low = (uint32_t)z; } -/* Initialize a gcmHashContext */ -static SECStatus -gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H, - unsigned int blocksize) +SECStatus +gcm_HashMult_sftw32(gcmHashContext *ghash, const unsigned char *buf, + unsigned int count) { - PORT_Memset(ghash->X, 0, sizeof(ghash->X)); - PORT_Memset(ghash->H, 0, sizeof(ghash->H)); - gcm_bytes_to_longs(ghash->H, H, blocksize); - - /* set the irreducible polynomial. Each blocksize has its own polynommial - * for now only blocksize 16 (=128 bits) is defined */ - switch (blocksize) { - case 16: /* 128 bits */ - ghash->R = (unsigned long)0x87; /* x^7 + x^2 + x +1 */ - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - goto cleanup; + size_t i; + uint64_t ci_low, ci_high; + uint64_t z_high_h, z_high_l, z_low_h, z_low_l; + uint32_t ci_high_h, ci_high_l, ci_low_h, ci_low_l; + uint32_t b_a_h, b_a_l, a_a_h, a_a_l, b_b_h, b_b_l; + uint32_t a_b_h, a_b_l, b_c_h, b_c_l, a_c_h, a_c_l, c_c_h, c_c_l; + uint32_t ci_highXlow_h, ci_highXlow_l, c_a_h, c_a_l, c_b_h, c_b_l; + + uint32_t h_high_h = (uint32_t)(ghash->h_high >> 32); + uint32_t h_high_l = (uint32_t)ghash->h_high; + uint32_t h_low_h = (uint32_t)(ghash->h_low >> 32); + uint32_t h_low_l = (uint32_t)ghash->h_low; + uint32_t h_highXlow_h = h_high_h ^ h_low_h; + uint32_t h_highXlow_l = h_high_l ^ h_low_l; + uint32_t h_highX_xored = h_highXlow_h ^ h_highXlow_l; + + for (i = 0; i < count; i++, buf += 16) { + ci_low = ghash->x_low ^ get64(buf + 8); + ci_high = ghash->x_high ^ get64(buf); + ci_low_h = (uint32_t)(ci_low >> 32); + ci_low_l = (uint32_t)ci_low; + ci_high_h = (uint32_t)(ci_high >> 32); + ci_high_l = (uint32_t)ci_high; + ci_highXlow_h = ci_high_h ^ ci_low_h; + ci_highXlow_l = ci_high_l ^ ci_low_l; + + /* Do binary mult ghash->X = C * ghash->H (recursive Karatsuba). */ + bmul32(ci_high_h, h_high_h, &a_a_h, &a_a_l); + bmul32(ci_high_l, h_high_l, &a_b_h, &a_b_l); + bmul32(ci_high_h ^ ci_high_l, h_high_h ^ h_high_l, &a_c_h, &a_c_l); + a_c_h ^= a_a_h ^ a_b_h; + a_c_l ^= a_a_l ^ a_b_l; + a_a_l ^= a_c_h; + a_b_h ^= a_c_l; + /* ci_high * h_high = a_a_h:a_a_l:a_b_h:a_b_l */ + + bmul32(ci_low_h, h_low_h, &b_a_h, &b_a_l); + bmul32(ci_low_l, h_low_l, &b_b_h, &b_b_l); + bmul32(ci_low_h ^ ci_low_l, h_low_h ^ h_low_l, &b_c_h, &b_c_l); + b_c_h ^= b_a_h ^ b_b_h; + b_c_l ^= b_a_l ^ b_b_l; + b_a_l ^= b_c_h; + b_b_h ^= b_c_l; + /* ci_low * h_low = b_a_h:b_a_l:b_b_h:b_b_l */ + + bmul32(ci_highXlow_h, h_highXlow_h, &c_a_h, &c_a_l); + bmul32(ci_highXlow_l, h_highXlow_l, &c_b_h, &c_b_l); + bmul32(ci_highXlow_h ^ ci_highXlow_l, h_highX_xored, &c_c_h, &c_c_l); + c_c_h ^= c_a_h ^ c_b_h; + c_c_l ^= c_a_l ^ c_b_l; + c_a_l ^= c_c_h; + c_b_h ^= c_c_l; + /* (ci_high ^ ci_low) * (h_high ^ h_low) = c_a_h:c_a_l:c_b_h:c_b_l */ + + c_a_h ^= b_a_h ^ a_a_h; + c_a_l ^= b_a_l ^ a_a_l; + c_b_h ^= b_b_h ^ a_b_h; + c_b_l ^= b_b_l ^ a_b_l; + z_high_h = ((uint64_t)a_a_h << 32) | a_a_l; + z_high_l = (((uint64_t)a_b_h << 32) | a_b_l) ^ + (((uint64_t)c_a_h << 32) | c_a_l); + z_low_h = (((uint64_t)b_a_h << 32) | b_a_l) ^ + (((uint64_t)c_b_h << 32) | c_b_l); + z_low_l = ((uint64_t)b_b_h << 32) | b_b_l; + + /* Shift one (multiply by x) as gcm spec is stupid. */ + z_high_h = z_high_h << 1 | z_high_l >> 63; + z_high_l = z_high_l << 1 | z_low_h >> 63; + z_low_h = z_low_h << 1 | z_low_l >> 63; + z_low_l <<= 1; + + /* Reduce */ + z_low_h ^= (z_low_l << 63) ^ (z_low_l << 62) ^ (z_low_l << 57); + z_high_h ^= z_low_h ^ (z_low_h >> 1) ^ (z_low_h >> 2) ^ (z_low_h >> 7); + z_high_l ^= z_low_l ^ (z_low_l >> 1) ^ (z_low_l >> 2) ^ (z_low_l >> 7) ^ + (z_low_h << 63) ^ (z_low_h << 62) ^ (z_low_h << 57); + ghash->x_high = z_high_h; + ghash->x_low = z_high_l; } - ghash->cLen = 0; - ghash->bufLen = 0; - ghash->m = 0; - PORT_Memset(ghash->counterBuf, 0, sizeof(ghash->counterBuf)); return SECSuccess; -cleanup: - return SECFailure; -} - -/* Destroy a HashContext (Note we zero the digits so this function - * is idempotent if called with freeit == PR_FALSE */ -static void -gcmHash_DestroyContext(gcmHashContext *ghash, PRBool freeit) -{ - PORT_Memset(ghash, 0, sizeof(gcmHashContext)); - if (freeit) { - PORT_Free(ghash); - } } +#endif /* HAVE_INT128_SUPPORT */ -static unsigned long -gcm_shift_one(unsigned long *t, unsigned int count) +SECStatus +gcm_HashMult_hw(gcmHashContext *ghash, const unsigned char *buf, + unsigned int count) { - unsigned long carry = 0; - unsigned long nextcarry = 0; - unsigned int i; - for (i = 0; i < count; i++) { - nextcarry = t[i] >> ((sizeof(unsigned long) * PR_BITS_PER_BYTE) - 1); - t[i] = (t[i] << 1) | carry; - carry = nextcarry; +#ifdef NSS_X86_OR_X64 + size_t i; + pre_align __m128i z_high post_align; + pre_align __m128i z_low post_align; + pre_align __m128i C post_align; + pre_align __m128i D post_align; + pre_align __m128i E post_align; + pre_align __m128i F post_align; + pre_align __m128i bin post_align; + pre_align __m128i Ci post_align; + pre_align __m128i tmp post_align; + + for (i = 0; i < count; i++, buf += 16) { + bin = _mm_set_epi16(((uint16_t)buf[0] << 8) | buf[1], + ((uint16_t)buf[2] << 8) | buf[3], + ((uint16_t)buf[4] << 8) | buf[5], + ((uint16_t)buf[6] << 8) | buf[7], + ((uint16_t)buf[8] << 8) | buf[9], + ((uint16_t)buf[10] << 8) | buf[11], + ((uint16_t)buf[12] << 8) | buf[13], + ((uint16_t)buf[14] << 8) | buf[15]); + Ci = _mm_xor_si128(bin, ghash->x); + + /* Do binary mult ghash->X = Ci * ghash->H. */ + C = _mm_clmulepi64_si128(Ci, ghash->h, 0x00); + D = _mm_clmulepi64_si128(Ci, ghash->h, 0x11); + E = _mm_clmulepi64_si128(Ci, ghash->h, 0x01); + F = _mm_clmulepi64_si128(Ci, ghash->h, 0x10); + tmp = _mm_xor_si128(E, F); + z_high = _mm_xor_si128(tmp, _mm_slli_si128(D, 8)); + z_high = _mm_unpackhi_epi64(z_high, D); + z_low = _mm_xor_si128(_mm_slli_si128(tmp, 8), C); + z_low = _mm_unpackhi_epi64(_mm_slli_si128(C, 8), z_low); + + /* Shift one to the left (multiply by x) as gcm spec is stupid. */ + C = _mm_slli_si128(z_low, 8); + E = _mm_srli_epi64(C, 63); + D = _mm_slli_si128(z_high, 8); + F = _mm_srli_epi64(D, 63); + /* Carry over */ + C = _mm_srli_si128(z_low, 8); + D = _mm_srli_epi64(C, 63); + z_low = _mm_or_si128(_mm_slli_epi64(z_low, 1), E); + z_high = _mm_or_si128(_mm_or_si128(_mm_slli_epi64(z_high, 1), F), D); + + /* Reduce */ + C = _mm_slli_si128(z_low, 8); + /* D = z_low << 127 */ + D = _mm_slli_epi64(C, 63); + /* E = z_low << 126 */ + E = _mm_slli_epi64(C, 62); + /* F = z_low << 121 */ + F = _mm_slli_epi64(C, 57); + /* z_low ^= (z_low << 127) ^ (z_low << 126) ^ (z_low << 121); */ + z_low = _mm_xor_si128(_mm_xor_si128(_mm_xor_si128(z_low, D), E), F); + C = _mm_srli_si128(z_low, 8); + /* D = z_low >> 1 */ + D = _mm_slli_epi64(C, 63); + D = _mm_or_si128(_mm_srli_epi64(z_low, 1), D); + /* E = z_low >> 2 */ + E = _mm_slli_epi64(C, 62); + E = _mm_or_si128(_mm_srli_epi64(z_low, 2), E); + /* F = z_low >> 7 */ + F = _mm_slli_epi64(C, 57); + F = _mm_or_si128(_mm_srli_epi64(z_low, 7), F); + /* ghash->x ^= z_low ^ (z_low >> 1) ^ (z_low >> 2) ^ (z_low >> 7); */ + ghash->x = _mm_xor_si128(_mm_xor_si128( + _mm_xor_si128(_mm_xor_si128(z_high, z_low), D), E), + F); } - return carry; -} - -static SECStatus -gcm_getX(gcmHashContext *ghash, unsigned char *T, unsigned int blocksize) -{ - gcm_longs_to_bytes(ghash->X, T, blocksize); return SECSuccess; +#else + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; +#endif /* NSS_X86_OR_X64 */ } -#define GCM_XOR(t, s, len) \ - for (l = 0; l < len; l++) \ - t[l] ^= s[l] - static SECStatus -gcm_HashMult(gcmHashContext *ghash, const unsigned char *buf, - unsigned int count, unsigned int blocksize) +gcm_zeroX(gcmHashContext *ghash) { - unsigned long C_i[GCM_ARRAY_SIZE]; - unsigned int arraysize = blocksize / sizeof(unsigned long); - unsigned int i, j, k, l; - - for (i = 0; i < count; i++, buf += blocksize) { - ghash->m++; - gcm_bytes_to_longs(C_i, buf, blocksize); - GCM_XOR(C_i, ghash->X, arraysize); - /* multiply X = C_i * H */ - PORT_Memset(ghash->X, 0, sizeof(ghash->X)); - for (j = 0; j < arraysize; j++) { - unsigned long H = ghash->H[j]; - for (k = 0; k < sizeof(unsigned long) * PR_BITS_PER_BYTE; k++) { - if (H & 1) { - GCM_XOR(ghash->X, C_i, arraysize); - } - if (gcm_shift_one(C_i, arraysize)) { - C_i[0] = C_i[0] ^ ghash->R; - } - H = H >> 1; - } - } - GCM_TRACE_X(ghash, "X%d = ") + if (ghash->hw) { +#ifdef NSS_X86_OR_X64 + ghash->x = _mm_setzero_si128(); + return SECSuccess; +#else + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; +#endif /* NSS_X86_OR_X64 */ } - PORT_Memset(C_i, 0, sizeof(C_i)); - return SECSuccess; -} -static void -gcm_zeroX(gcmHashContext *ghash) -{ - PORT_Memset(ghash->X, 0, sizeof(ghash->X)); - ghash->m = 0; + ghash->x_high = ghash->x_low = 0; + return SECSuccess; } -#endif /* * implement GCM GHASH using the freebl GHASH function. The gcm_HashMult - * function always takes blocksize lengths of data. gcmHash_Update will + * function always takes AES_BLOCK_SIZE lengths of data. gcmHash_Update will * format the data properly. */ -static SECStatus +SECStatus gcmHash_Update(gcmHashContext *ghash, const unsigned char *buf, - unsigned int len, unsigned int blocksize) + unsigned int len) { unsigned int blocks; SECStatus rv; @@ -458,7 +398,7 @@ gcmHash_Update(gcmHashContext *ghash, const unsigned char *buf, /* first deal with the current buffer of data. Try to fill it out so * we can hash it */ if (ghash->bufLen) { - unsigned int needed = PR_MIN(len, blocksize - ghash->bufLen); + unsigned int needed = PR_MIN(len, AES_BLOCK_SIZE - ghash->bufLen); if (needed != 0) { PORT_Memcpy(ghash->buffer + ghash->bufLen, buf, needed); } @@ -469,24 +409,24 @@ gcmHash_Update(gcmHashContext *ghash, const unsigned char *buf, /* didn't add enough to hash the data, nothing more do do */ return SECSuccess; } - PORT_Assert(ghash->bufLen == blocksize); + PORT_Assert(ghash->bufLen == AES_BLOCK_SIZE); /* hash the buffer and clear it */ - rv = gcm_HashMult(ghash, ghash->buffer, 1, blocksize); - PORT_Memset(ghash->buffer, 0, blocksize); + rv = ghash->ghash_mul(ghash, ghash->buffer, 1); + PORT_Memset(ghash->buffer, 0, AES_BLOCK_SIZE); ghash->bufLen = 0; if (rv != SECSuccess) { return SECFailure; } } /* now hash any full blocks remaining in the data stream */ - blocks = len / blocksize; + blocks = len / AES_BLOCK_SIZE; if (blocks) { - rv = gcm_HashMult(ghash, buf, blocks, blocksize); + rv = ghash->ghash_mul(ghash, buf, blocks); if (rv != SECSuccess) { return SECFailure; } - buf += blocks * blocksize; - len -= blocks * blocksize; + buf += blocks * AES_BLOCK_SIZE; + len -= blocks * AES_BLOCK_SIZE; } /* save any remainder in the buffer to be hashed with the next call */ @@ -502,7 +442,7 @@ gcmHash_Update(gcmHashContext *ghash, const unsigned char *buf, * save the lengths for the final completion of the hash */ static SECStatus -gcmHash_Sync(gcmHashContext *ghash, unsigned int blocksize) +gcmHash_Sync(gcmHashContext *ghash) { int i; SECStatus rv; @@ -519,9 +459,9 @@ gcmHash_Sync(gcmHashContext *ghash, unsigned int blocksize) /* now zero fill the buffer and hash the last block */ if (ghash->bufLen) { - PORT_Memset(ghash->buffer + ghash->bufLen, 0, blocksize - ghash->bufLen); - rv = gcm_HashMult(ghash, ghash->buffer, 1, blocksize); - PORT_Memset(ghash->buffer, 0, blocksize); + PORT_Memset(ghash->buffer + ghash->bufLen, 0, AES_BLOCK_SIZE - ghash->bufLen); + rv = ghash->ghash_mul(ghash, ghash->buffer, 1); + PORT_Memset(ghash->buffer, 0, AES_BLOCK_SIZE); ghash->bufLen = 0; if (rv != SECSuccess) { return SECFailure; @@ -530,38 +470,56 @@ gcmHash_Sync(gcmHashContext *ghash, unsigned int blocksize) return SECSuccess; } +#define WRITE64(x, bytes) \ + (bytes)[0] = (x) >> 56; \ + (bytes)[1] = (x) >> 48; \ + (bytes)[2] = (x) >> 40; \ + (bytes)[3] = (x) >> 32; \ + (bytes)[4] = (x) >> 24; \ + (bytes)[5] = (x) >> 16; \ + (bytes)[6] = (x) >> 8; \ + (bytes)[7] = (x); + /* * This does the final sync, hashes the lengths, then returns * "T", the hashed output. */ -static SECStatus +SECStatus gcmHash_Final(gcmHashContext *ghash, unsigned char *outbuf, - unsigned int *outlen, unsigned int maxout, - unsigned int blocksize) + unsigned int *outlen, unsigned int maxout) { unsigned char T[MAX_BLOCK_SIZE]; SECStatus rv; - rv = gcmHash_Sync(ghash, blocksize); + rv = gcmHash_Sync(ghash); if (rv != SECSuccess) { goto cleanup; } - rv = gcm_HashMult(ghash, ghash->counterBuf, (GCM_HASH_LEN_LEN * 2) / blocksize, - blocksize); + rv = ghash->ghash_mul(ghash, ghash->counterBuf, + (GCM_HASH_LEN_LEN * 2) / AES_BLOCK_SIZE); if (rv != SECSuccess) { goto cleanup; } - GCM_TRACE_X(ghash, "GHASH(H,A,C) = ") - - rv = gcm_getX(ghash, T, blocksize); - if (rv != SECSuccess) { - goto cleanup; + if (ghash->hw) { +#ifdef NSS_X86_OR_X64 + uint64_t tmp_out[2]; + _mm_storeu_si128((__m128i *)tmp_out, ghash->x); + WRITE64(tmp_out[0], T + 8); + WRITE64(tmp_out[1], T); +#else + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; +#endif /* NSS_X86_OR_X64 */ + } else { + WRITE64(ghash->x_low, T + 8); + WRITE64(ghash->x_high, T); } - if (maxout > blocksize) - maxout = blocksize; + if (maxout > AES_BLOCK_SIZE) { + maxout = AES_BLOCK_SIZE; + } PORT_Memcpy(outbuf, T, maxout); *outlen = maxout; rv = SECSuccess; @@ -573,22 +531,25 @@ cleanup: SECStatus gcmHash_Reset(gcmHashContext *ghash, const unsigned char *AAD, - unsigned int AADLen, unsigned int blocksize) + unsigned int AADLen) { SECStatus rv; ghash->cLen = 0; PORT_Memset(ghash->counterBuf, 0, GCM_HASH_LEN_LEN * 2); ghash->bufLen = 0; - gcm_zeroX(ghash); + rv = gcm_zeroX(ghash); + if (rv != SECSuccess) { + return rv; + } /* now kick things off by hashing the Additional Authenticated Data */ if (AADLen != 0) { - rv = gcmHash_Update(ghash, AAD, AADLen, blocksize); + rv = gcmHash_Update(ghash, AAD, AADLen); if (rv != SECSuccess) { return SECFailure; } - rv = gcmHash_Sync(ghash, blocksize); + rv = gcmHash_Sync(ghash); if (rv != SECSuccess) { return SECFailure; } @@ -602,7 +563,7 @@ gcmHash_Reset(gcmHashContext *ghash, const unsigned char *AAD, /* state to handle the full GCM operation (hash and counter) */ struct GCMContextStr { - gcmHashContext ghash_context; + gcmHashContext *ghash_context; CTRContext ctr_context; unsigned long tagBits; unsigned char tagKey[MAX_BLOCK_SIZE]; @@ -610,58 +571,69 @@ struct GCMContextStr { GCMContext * GCM_CreateContext(void *context, freeblCipherFunc cipher, - const unsigned char *params, unsigned int blocksize) + const unsigned char *params) { GCMContext *gcm = NULL; - gcmHashContext *ghash; + gcmHashContext *ghash = NULL; unsigned char H[MAX_BLOCK_SIZE]; unsigned int tmp; PRBool freeCtr = PR_FALSE; - PRBool freeHash = PR_FALSE; const CK_GCM_PARAMS *gcmParams = (const CK_GCM_PARAMS *)params; CK_AES_CTR_PARAMS ctrParams; SECStatus rv; +#ifdef DISABLE_HW_GCM + const PRBool sw = PR_TRUE; +#else + const PRBool sw = PR_FALSE; +#endif - if (blocksize > MAX_BLOCK_SIZE || blocksize > sizeof(ctrParams.cb)) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + if (gcmParams->ulIvLen == 0) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } gcm = PORT_ZNew(GCMContext); if (gcm == NULL) { return NULL; } - /* first fill in the ghash context */ - ghash = &gcm->ghash_context; - PORT_Memset(H, 0, blocksize); - rv = (*cipher)(context, H, &tmp, blocksize, H, blocksize, blocksize); + /* aligned_alloc is C11 so we have to do it the old way. */ + ghash = PORT_ZAlloc(sizeof(gcmHashContext) + 15); + if (ghash == NULL) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + goto loser; + } + ghash->mem = ghash; + ghash = (gcmHashContext *)(((uintptr_t)ghash + 15) & ~(uintptr_t)0x0F); + + /* first plug in the ghash context */ + gcm->ghash_context = ghash; + PORT_Memset(H, 0, AES_BLOCK_SIZE); + rv = (*cipher)(context, H, &tmp, AES_BLOCK_SIZE, H, AES_BLOCK_SIZE, AES_BLOCK_SIZE); if (rv != SECSuccess) { goto loser; } - rv = gcmHash_InitContext(ghash, H, blocksize); + rv = gcmHash_InitContext(ghash, H, sw); if (rv != SECSuccess) { goto loser; } - freeHash = PR_TRUE; /* fill in the Counter context */ ctrParams.ulCounterBits = 32; PORT_Memset(ctrParams.cb, 0, sizeof(ctrParams.cb)); - if ((blocksize == 16) && (gcmParams->ulIvLen == 12)) { + if (gcmParams->ulIvLen == 12) { PORT_Memcpy(ctrParams.cb, gcmParams->pIv, gcmParams->ulIvLen); - ctrParams.cb[blocksize - 1] = 1; + ctrParams.cb[AES_BLOCK_SIZE - 1] = 1; } else { - rv = gcmHash_Update(ghash, gcmParams->pIv, gcmParams->ulIvLen, - blocksize); + rv = gcmHash_Update(ghash, gcmParams->pIv, gcmParams->ulIvLen); if (rv != SECSuccess) { goto loser; } - rv = gcmHash_Final(ghash, ctrParams.cb, &tmp, blocksize, blocksize); + rv = gcmHash_Final(ghash, ctrParams.cb, &tmp, AES_BLOCK_SIZE); if (rv != SECSuccess) { goto loser; } } rv = CTR_InitContext(&gcm->ctr_context, context, cipher, - (unsigned char *)&ctrParams, blocksize); + (unsigned char *)&ctrParams); if (rv != SECSuccess) { goto loser; } @@ -671,14 +643,14 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher, gcm->tagBits = gcmParams->ulTagBits; /* save for final step */ /* calculate the final tag key. NOTE: gcm->tagKey is zero to start with. * if this assumption changes, we would need to explicitly clear it here */ - rv = CTR_Update(&gcm->ctr_context, gcm->tagKey, &tmp, blocksize, - gcm->tagKey, blocksize, blocksize); + rv = CTR_Update(&gcm->ctr_context, gcm->tagKey, &tmp, AES_BLOCK_SIZE, + gcm->tagKey, AES_BLOCK_SIZE, AES_BLOCK_SIZE); if (rv != SECSuccess) { goto loser; } /* finally mix in the AAD data */ - rv = gcmHash_Reset(ghash, gcmParams->pAAD, gcmParams->ulAADLen, blocksize); + rv = gcmHash_Reset(ghash, gcmParams->pAAD, gcmParams->ulAADLen); if (rv != SECSuccess) { goto loser; } @@ -689,8 +661,8 @@ loser: if (freeCtr) { CTR_DestroyContext(&gcm->ctr_context, PR_FALSE); } - if (freeHash) { - gcmHash_DestroyContext(&gcm->ghash_context, PR_FALSE); + if (ghash && ghash->mem) { + PORT_Free(ghash->mem); } if (gcm) { PORT_Free(gcm); @@ -705,7 +677,7 @@ GCM_DestroyContext(GCMContext *gcm, PRBool freeit) * gcm. call their destroy functions to free up any locally * allocated data (like mp_int's) */ CTR_DestroyContext(&gcm->ctr_context, PR_FALSE); - gcmHash_DestroyContext(&gcm->ghash_context, PR_FALSE); + PORT_Free(gcm->ghash_context->mem); PORT_Memset(&gcm->tagBits, 0, sizeof(gcm->tagBits)); PORT_Memset(gcm->tagKey, 0, sizeof(gcm->tagKey)); if (freeit) { @@ -715,8 +687,7 @@ GCM_DestroyContext(GCMContext *gcm, PRBool freeit) static SECStatus gcm_GetTag(GCMContext *gcm, unsigned char *outbuf, - unsigned int *outlen, unsigned int maxout, - unsigned int blocksize) + unsigned int *outlen, unsigned int maxout) { unsigned int tagBytes; unsigned int extra; @@ -738,18 +709,14 @@ gcm_GetTag(GCMContext *gcm, unsigned char *outbuf, return SECFailure; } maxout = tagBytes; - rv = gcmHash_Final(&gcm->ghash_context, outbuf, outlen, maxout, blocksize); + rv = gcmHash_Final(gcm->ghash_context, outbuf, outlen, maxout); if (rv != SECSuccess) { return SECFailure; } - GCM_TRACE_BLOCK("GHASH=", outbuf, blocksize); - GCM_TRACE_BLOCK("Y0=", gcm->tagKey, blocksize); for (i = 0; i < *outlen; i++) { outbuf[i] ^= gcm->tagKey[i]; } - GCM_TRACE_BLOCK("Y0=", gcm->tagKey, blocksize); - GCM_TRACE_BLOCK("T=", outbuf, blocksize); /* mask off any extra bits we got */ if (extra) { outbuf[tagBytes - 1] &= ~((1 << extra) - 1); @@ -772,6 +739,12 @@ GCM_EncryptUpdate(GCMContext *gcm, unsigned char *outbuf, unsigned int tagBytes; unsigned int len; + PORT_Assert(blocksize == AES_BLOCK_SIZE); + if (blocksize != AES_BLOCK_SIZE) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE; if (UINT_MAX - inlen < tagBytes) { PORT_SetError(SEC_ERROR_INPUT_LEN); @@ -784,17 +757,17 @@ GCM_EncryptUpdate(GCMContext *gcm, unsigned char *outbuf, } rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout, - inbuf, inlen, blocksize); + inbuf, inlen, AES_BLOCK_SIZE); if (rv != SECSuccess) { return SECFailure; } - rv = gcmHash_Update(&gcm->ghash_context, outbuf, *outlen, blocksize); + rv = gcmHash_Update(gcm->ghash_context, outbuf, *outlen); if (rv != SECSuccess) { PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */ *outlen = 0; return SECFailure; } - rv = gcm_GetTag(gcm, outbuf + *outlen, &len, maxout - *outlen, blocksize); + rv = gcm_GetTag(gcm, outbuf + *outlen, &len, maxout - *outlen); if (rv != SECSuccess) { PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */ *outlen = 0; @@ -824,6 +797,12 @@ GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf, const unsigned char *intag; unsigned int len; + PORT_Assert(blocksize == AES_BLOCK_SIZE); + if (blocksize != AES_BLOCK_SIZE) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE; /* get the authentication block */ @@ -836,11 +815,11 @@ GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf, intag = inbuf + inlen; /* verify the block */ - rv = gcmHash_Update(&gcm->ghash_context, inbuf, inlen, blocksize); + rv = gcmHash_Update(gcm->ghash_context, inbuf, inlen); if (rv != SECSuccess) { return SECFailure; } - rv = gcm_GetTag(gcm, tag, &len, blocksize, blocksize); + rv = gcm_GetTag(gcm, tag, &len, AES_BLOCK_SIZE); if (rv != SECSuccess) { return SECFailure; } @@ -856,5 +835,5 @@ GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf, PORT_Memset(tag, 0, sizeof(tag)); /* finish the decryption */ return CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout, - inbuf, inlen, blocksize); + inbuf, inlen, AES_BLOCK_SIZE); } diff --git a/security/nss/lib/freebl/gcm.h b/security/nss/lib/freebl/gcm.h index 1cdba534d..0c707a081 100644 --- a/security/nss/lib/freebl/gcm.h +++ b/security/nss/lib/freebl/gcm.h @@ -6,6 +6,17 @@ #define GCM_H 1 #include "blapii.h" +#include <stdint.h> + +#ifdef NSS_X86_OR_X64 +#include <emmintrin.h> /* __m128i */ +#endif + +SEC_BEGIN_PROTOS + +#ifdef HAVE_INT128_SUPPORT +typedef unsigned __int128 uint128_t; +#endif typedef struct GCMContextStr GCMContext; @@ -17,7 +28,7 @@ typedef struct GCMContextStr GCMContext; * The cipher argument is a block cipher in the ECB encrypt mode. */ GCMContext *GCM_CreateContext(void *context, freeblCipherFunc cipher, - const unsigned char *params, unsigned int blocksize); + const unsigned char *params); void GCM_DestroyContext(GCMContext *gcm, PRBool freeit); SECStatus GCM_EncryptUpdate(GCMContext *gcm, unsigned char *outbuf, unsigned int *outlen, unsigned int maxout, @@ -28,4 +39,34 @@ SECStatus GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf, const unsigned char *inbuf, unsigned int inlen, unsigned int blocksize); +/* These functions are here only so we can test them */ +#define GCM_HASH_LEN_LEN 8 /* gcm hash defines lengths to be 64 bits */ +typedef struct gcmHashContextStr gcmHashContext; +typedef SECStatus (*ghash_t)(gcmHashContext *, const unsigned char *, + unsigned int); +pre_align struct gcmHashContextStr { +#ifdef NSS_X86_OR_X64 + __m128i x, h; +#endif + uint64_t x_low, x_high, h_high, h_low; + unsigned char buffer[MAX_BLOCK_SIZE]; + unsigned int bufLen; + uint8_t counterBuf[16]; + uint64_t cLen; + ghash_t ghash_mul; + PRBool hw; + gcmHashContext *mem; +} post_align; + +SECStatus gcmHash_Update(gcmHashContext *ghash, const unsigned char *buf, + unsigned int len); +SECStatus gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H, + PRBool sw); +SECStatus gcmHash_Reset(gcmHashContext *ghash, const unsigned char *AAD, + unsigned int AADLen); +SECStatus gcmHash_Final(gcmHashContext *ghash, unsigned char *outbuf, + unsigned int *outlen, unsigned int maxout); + +SEC_END_PROTOS + #endif diff --git a/security/nss/lib/freebl/intel-aes-x64-masm.asm b/security/nss/lib/freebl/intel-aes-x64-masm.asm index ef5c76ba2..fe183bca0 100644 --- a/security/nss/lib/freebl/intel-aes-x64-masm.asm +++ b/security/nss/lib/freebl/intel-aes-x64-masm.asm @@ -91,8 +91,6 @@ LOCAL bail movdqu [rsp + 1*16], xmm7 movdqu [rsp + 2*16], xmm8 - lea ctx, [48+ctx] - loop8: cmp inputLen, 8*16 jb loop1 @@ -555,9 +553,7 @@ LOCAL bail movdqu [rsp + 1*16], xmm7 movdqu [rsp + 2*16], xmm8 - lea ctx, [48+ctx] - - movdqu xmm0, [-32+ctx] + movdqu xmm0, [256+ctx] movdqu xmm2, [0*16 + ctx] movdqu xmm3, [1*16 + ctx] @@ -597,7 +593,7 @@ loop1: jmp loop1 bail: - movdqu [-32+ctx], xmm0 + movdqu [256+ctx], xmm0 xor rax, rax @@ -625,8 +621,6 @@ LOCAL bail movdqu [rsp + 1*16], xmm7 movdqu [rsp + 2*16], xmm8 - lea ctx, [48+ctx] - loop8: cmp inputLen, 8*16 jb dec1 @@ -657,7 +651,7 @@ loop8: ENDM aes_dec_last_rnd rnds - movdqu xmm8, [-32 + ctx] + movdqu xmm8, [256 + ctx] pxor xmm0, xmm8 movdqu xmm8, [0*16 + input] pxor xmm1, xmm8 @@ -683,7 +677,7 @@ loop8: movdqu [5*16 + output], xmm5 movdqu [6*16 + output], xmm6 movdqu [7*16 + output], xmm7 - movdqu [-32 + ctx], xmm8 + movdqu [256 + ctx], xmm8 lea input, [8*16 + input] lea output, [8*16 + output] @@ -691,7 +685,7 @@ loop8: jmp loop8 dec1: - movdqu xmm3, [-32 + ctx] + movdqu xmm3, [256 + ctx] loop1: cmp inputLen, 1*16 @@ -721,7 +715,7 @@ loop1: jmp loop1 bail: - movdqu [-32 + ctx], xmm3 + movdqu [256 + ctx], xmm3 xor rax, rax movdqu xmm6, [rsp + 0*16] @@ -773,7 +767,6 @@ LOCAL bail mov ctrCtx, ctx mov ctx, [8+ctrCtx] - lea ctx, [48+ctx] sub rsp, 3*16 movdqu [rsp + 0*16], xmm6 diff --git a/security/nss/lib/freebl/intel-aes-x86-masm.asm b/security/nss/lib/freebl/intel-aes-x86-masm.asm index 7d805e766..790c951e7 100644 --- a/security/nss/lib/freebl/intel-aes-x86-masm.asm +++ b/security/nss/lib/freebl/intel-aes-x86-masm.asm @@ -87,8 +87,6 @@ LOCAL bail mov input, [esp + 2*4 + 4*4] mov inputLen, [esp + 2*4 + 5*4] - lea ctx, [44+ctx] - loop7: cmp inputLen, 7*16 jb loop1 @@ -557,9 +555,7 @@ LOCAL bail mov input, [esp + 2*4 + 4*4] mov inputLen, [esp + 2*4 + 5*4] - lea ctx, [44+ctx] - - movdqu xmm0, [-32+ctx] + movdqu xmm0, [252+ctx] movdqu xmm2, [0*16 + ctx] movdqu xmm3, [1*16 + ctx] @@ -597,7 +593,7 @@ loop1: jmp loop1 bail: - movdqu [-32+ctx], xmm0 + movdqu [252+ctx], xmm0 xor eax, eax pop inputLen @@ -619,8 +615,6 @@ LOCAL bail mov input, [esp + 2*4 + 4*4] mov inputLen, [esp + 2*4 + 5*4] - lea ctx, [44+ctx] - loop7: cmp inputLen, 7*16 jb dec1 @@ -649,7 +643,7 @@ loop7: ENDM aes_dec_last_rnd rnds - movdqu xmm7, [-32 + ctx] + movdqu xmm7, [252 + ctx] pxor xmm0, xmm7 movdqu xmm7, [0*16 + input] pxor xmm1, xmm7 @@ -672,7 +666,7 @@ loop7: movdqu [4*16 + output], xmm4 movdqu [5*16 + output], xmm5 movdqu [6*16 + output], xmm6 - movdqu [-32 + ctx], xmm7 + movdqu [252 + ctx], xmm7 lea input, [7*16 + input] lea output, [7*16 + output] @@ -680,7 +674,7 @@ loop7: jmp loop7 dec1: - movdqu xmm3, [-32 + ctx] + movdqu xmm3, [252 + ctx] loop1: cmp inputLen, 1*16 @@ -710,7 +704,7 @@ loop1: jmp loop1 bail: - movdqu [-32 + ctx], xmm3 + movdqu [252 + ctx], xmm3 xor eax, eax pop inputLen ret @@ -769,7 +763,6 @@ LOCAL bail mov inputLen, [esp + 4*5 + 5*4] mov ctx, [4+ctrCtx] - lea ctx, [44+ctx] mov ebp, esp sub esp, 7*16 diff --git a/security/nss/lib/freebl/intel-aes.s b/security/nss/lib/freebl/intel-aes.s index 2dfcfa15b..b242d233f 100644 --- a/security/nss/lib/freebl/intel-aes.s +++ b/security/nss/lib/freebl/intel-aes.s @@ -4,8 +4,7 @@ .text -#define IV_OFFSET 16 -#define EXPANDED_KEY_OFFSET 48 +#define IV_OFFSET 256 /* * Warning: the length values used in this module are "unsigned int" @@ -144,9 +143,6 @@ key_expansion128: .globl intel_aes_encrypt_ecb_128 .align 16 intel_aes_encrypt_ecb_128: -// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi - leaq 48(%rdi), %rdi - movdqu (%rdi), %xmm2 movdqu 160(%rdi), %xmm12 xor %eax, %eax @@ -328,9 +324,6 @@ intel_aes_encrypt_ecb_128: .globl intel_aes_decrypt_ecb_128 .align 16 intel_aes_decrypt_ecb_128: -// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi - leaq 48(%rdi), %rdi - movdqu (%rdi), %xmm2 movdqu 160(%rdi), %xmm12 xorl %eax, %eax @@ -516,9 +509,7 @@ intel_aes_encrypt_cbc_128: je 2f // leaq IV_OFFSET(%rdi), %rdx -// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi - leaq 16(%rdi), %rdx - leaq 48(%rdi), %rdi + leaq 256(%rdi), %rdx movdqu (%rdx), %xmm0 movdqu (%rdi), %xmm2 @@ -575,9 +566,7 @@ intel_aes_encrypt_cbc_128: .align 16 intel_aes_decrypt_cbc_128: // leaq IV_OFFSET(%rdi), %rdx -// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi - leaq 16(%rdi), %rdx - leaq 48(%rdi), %rdi + leaq 256(%rdi), %rdx movdqu (%rdx), %xmm0 /* iv */ movdqu (%rdi), %xmm2 /* first key block */ @@ -902,9 +891,6 @@ key_expansion192: .globl intel_aes_encrypt_ecb_192 .align 16 intel_aes_encrypt_ecb_192: -// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi - leaq 48(%rdi), %rdi - movdqu (%rdi), %xmm2 movdqu 192(%rdi), %xmm14 xorl %eax, %eax @@ -1109,9 +1095,6 @@ intel_aes_encrypt_ecb_192: .globl intel_aes_decrypt_ecb_192 .align 16 intel_aes_decrypt_ecb_192: -// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi - leaq 48(%rdi), %rdi - movdqu (%rdi), %xmm2 movdqu 192(%rdi), %xmm14 xorl %eax, %eax @@ -1320,9 +1303,7 @@ intel_aes_encrypt_cbc_192: je 2f // leaq IV_OFFSET(%rdi), %rdx -// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi - leaq 16(%rdi), %rdx - leaq 48(%rdi), %rdi + leaq 256(%rdi), %rdx movdqu (%rdx), %xmm0 movdqu (%rdi), %xmm2 @@ -1382,8 +1363,8 @@ intel_aes_encrypt_cbc_192: .globl intel_aes_decrypt_cbc_192 .align 16 intel_aes_decrypt_cbc_192: - leaq 16(%rdi), %rdx - leaq 48(%rdi), %rdi +// leaq IV_OFFSET(%rdi), %rdx + leaq 256(%rdi), %rdx movdqu (%rdx), %xmm0 movdqu (%rdi), %xmm2 @@ -1738,9 +1719,6 @@ key_expansion256: .globl intel_aes_encrypt_ecb_256 .align 16 intel_aes_encrypt_ecb_256: -// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi - leaq 48(%rdi), %rdi - movdqu (%rdi), %xmm2 movdqu 224(%rdi), %xmm15 xorl %eax, %eax @@ -1970,9 +1948,6 @@ intel_aes_encrypt_ecb_256: .globl intel_aes_decrypt_ecb_256 .align 16 intel_aes_decrypt_ecb_256: -// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi - leaq 48(%rdi), %rdi - movdqu (%rdi), %xmm2 movdqu 224(%rdi), %xmm15 xorl %eax, %eax @@ -2206,9 +2181,7 @@ intel_aes_encrypt_cbc_256: je 2f // leaq IV_OFFSET(%rdi), %rdx -// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi - leaq 16(%rdi), %rdx - leaq 48(%rdi), %rdi + leaq 256(%rdi), %rdx movdqu (%rdx), %xmm0 movdqu (%rdi), %xmm8 @@ -2274,9 +2247,7 @@ intel_aes_encrypt_cbc_256: .align 16 intel_aes_decrypt_cbc_256: // leaq IV_OFFSET(%rdi), %rdx -// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi - leaq 16(%rdi), %rdx - leaq 48(%rdi), %rdi + leaq 256(%rdi), %rdx movdqu (%rdx), %xmm0 movdqu (%rdi), %xmm2 diff --git a/security/nss/lib/freebl/intel-gcm-wrap.c b/security/nss/lib/freebl/intel-gcm-wrap.c index 8c5eaf021..37a1af765 100644 --- a/security/nss/lib/freebl/intel-gcm-wrap.c +++ b/security/nss/lib/freebl/intel-gcm-wrap.c @@ -41,8 +41,7 @@ struct intel_AES_GCMContextStr { intel_AES_GCMContext * intel_AES_GCM_CreateContext(void *context, freeblCipherFunc cipher, - const unsigned char *params, - unsigned int blocksize) + const unsigned char *params) { intel_AES_GCMContext *gcm = NULL; AESContext *aes = (AESContext *)context; @@ -59,12 +58,11 @@ intel_AES_GCM_CreateContext(void *context, unsigned int j; SECStatus rv; - if (blocksize != AES_BLOCK_SIZE) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + if (gcmParams->ulIvLen == 0) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } gcm = PORT_ZNew(intel_AES_GCMContext); - if (gcm == NULL) { return NULL; } diff --git a/security/nss/lib/freebl/intel-gcm-x64-masm.asm b/security/nss/lib/freebl/intel-gcm-x64-masm.asm index 8b68b76e5..07ddefbc1 100644 --- a/security/nss/lib/freebl/intel-gcm-x64-masm.asm +++ b/security/nss/lib/freebl/intel-gcm-x64-masm.asm @@ -496,8 +496,8 @@ LbeginENC: vmovdqu CTR0, XMMWORD PTR[16*16 + 2*16 + Gctx] vmovdqu BSWAPMASK, XMMWORD PTR[Lbswap_mask] mov KS, [16*16 + 3*16 + Gctx] - mov NR, [4 + KS] - lea KS, [48 + KS] + mov NR, [244 + KS] + lea KS, [KS] vpshufb CTR0, CTR0, BSWAPMASK @@ -994,8 +994,7 @@ LbeginDEC: vmovdqu CTR0, XMMWORD PTR[16*16 + 2*16 + Gctx] vmovdqu BSWAPMASK, XMMWORD PTR[Lbswap_mask] mov KS, [16*16 + 3*16 + Gctx] - mov NR, [4 + KS] - lea KS, [48 + KS] + mov NR, [244 + KS] vpshufb CTR0, CTR0, BSWAPMASK diff --git a/security/nss/lib/freebl/intel-gcm-x86-masm.asm b/security/nss/lib/freebl/intel-gcm-x86-masm.asm index 6362ad859..32f425788 100644 --- a/security/nss/lib/freebl/intel-gcm-x86-masm.asm +++ b/security/nss/lib/freebl/intel-gcm-x86-masm.asm @@ -390,7 +390,7 @@ Htbl textequ <edx> Gctx textequ <edx> len textequ <DWORD PTR[ebp + 5*4 + 3*4]> KS textequ <esi> -NR textequ <DWORD PTR[-40 + KS]> +NR textequ <DWORD PTR[244+KS]> aluCTR textequ <ebx> aluTMP textequ <edi> @@ -463,7 +463,6 @@ LbeginENC: mov Gctx, [ebp + 5*4 + 2*4] mov KS, [16*16 + 3*16 + Gctx] - lea KS, [44 + KS] mov aluCTR, [16*16 + 2*16 + 3*4 + Gctx] bswap aluCTR @@ -931,7 +930,6 @@ LbeginDEC: mov Gctx, [ebp + 5*4 + 2*4] mov KS, [16*16 + 3*16 + Gctx] - lea KS, [44 + KS] mov aluCTR, [16*16 + 2*16 + 3*4 + Gctx] bswap aluCTR diff --git a/security/nss/lib/freebl/intel-gcm.h b/security/nss/lib/freebl/intel-gcm.h index 566e544d8..05f52f297 100644 --- a/security/nss/lib/freebl/intel-gcm.h +++ b/security/nss/lib/freebl/intel-gcm.h @@ -27,7 +27,7 @@ typedef struct intel_AES_GCMContextStr intel_AES_GCMContext; intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context, freeblCipherFunc cipher, - const unsigned char *params, unsigned int blocksize); + const unsigned char *params); void intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit); diff --git a/security/nss/lib/freebl/intel-gcm.s b/security/nss/lib/freebl/intel-gcm.s index 1a3106091..5b5cf5d4b 100644 --- a/security/nss/lib/freebl/intel-gcm.s +++ b/security/nss/lib/freebl/intel-gcm.s @@ -467,8 +467,8 @@ intel_aes_gcmENC: vmovdqu 288(Gctx), CTR vmovdqu 272(Gctx), T mov 304(Gctx), KS - mov 4(KS), NR - lea 48(KS), KS +# AESContext->Nr + mov 244(KS), NR vpshufb .Lbswap_mask(%rip), CTR, CTR vpshufb .Lbswap_mask(%rip), T, T @@ -1001,8 +1001,8 @@ intel_aes_gcmDEC: vmovdqu 288(Gctx), CTR vmovdqu 272(Gctx), T mov 304(Gctx), KS - mov 4(KS), NR - lea 48(KS), KS +# AESContext->Nr + mov 244(KS), NR vpshufb .Lbswap_mask(%rip), CTR, CTR vpshufb .Lbswap_mask(%rip), T, T diff --git a/security/nss/lib/freebl/manifest.mn b/security/nss/lib/freebl/manifest.mn index 1ef983907..bf8144218 100644 --- a/security/nss/lib/freebl/manifest.mn +++ b/security/nss/lib/freebl/manifest.mn @@ -94,6 +94,7 @@ PRIVATE_EXPORTS = \ ec.h \ ecl.h \ ecl-curve.h \ + eclt.h \ $(NULL) MPI_HDRS = mpi-config.h mpi.h mpi-priv.h mplogic.h mpprime.h logtab.h mp_gf2m.h @@ -102,7 +103,7 @@ MPI_SRCS = mpprime.c mpmontg.c mplogic.c mpi.c mp_gf2m.c ECL_HDRS = ecl-exp.h ecl.h ecp.h ecl-priv.h ifndef NSS_DISABLE_ECC -ECL_SRCS = ecl.c ecl_curve.c ecl_mult.c ecl_gf.c \ +ECL_SRCS = ecl.c ecl_mult.c ecl_gf.c \ ecp_aff.c ecp_jac.c ecp_mont.c \ ec_naf.c ecp_jm.c ecp_256.c ecp_384.c ecp_521.c \ ecp_256_32.c ecp_25519.c @@ -131,6 +132,7 @@ CSRCS = \ chacha20poly1305.c \ cts.c \ ctr.c \ + blinit.c \ fipsfreebl.c \ gcm.c \ hmacct.c \ diff --git a/security/nss/lib/freebl/mpi/Makefile b/security/nss/lib/freebl/mpi/Makefile deleted file mode 100644 index 0dee5bed1..000000000 --- a/security/nss/lib/freebl/mpi/Makefile +++ /dev/null @@ -1,244 +0,0 @@ -# -# Makefile for MPI library - -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -## Define CC to be the C compiler you wish to use. The GNU cc -## compiler (gcc) should work, at the very least -#CC=cc -#CC=gcc - -## -## Define PERL to point to your local Perl interpreter. It -## should be Perl 5.x, although it's conceivable that Perl 4 -## might work ... I haven't tested it. -## -#PERL=/usr/bin/perl -#PERL=perl - -include target.mk - -CFLAGS+= $(XCFLAGS) - -## -## Define LIBS to include any libraries you need to link against. -## If NO_TABLE is define, LIBS should include '-lm' or whatever is -## necessary to bring in the math library. Otherwise, it can be -## left alone, unless your system has other peculiar requirements. -## -LIBS=#-lmalloc#-lefence#-lm - -## -## Define RANLIB to be the library header randomizer; you might not -## need this on some systems (just set it to 'echo' on these systems, -## such as IRIX) -## -RANLIB=echo - -## -## This is the version string used for the documentation and -## building the distribution tarball. Don't mess with it unless -## you are releasing a new version -VERS=1.7p6 - -## ---------------------------------------------------------------------- -## You probably don't need to change anything below this line... -## - -## -## This is the list of source files that need to be packed into -## the distribution file -SRCS= mpi.c mpprime.c mplogic.c mp_gf2m.c mpmontg.c mpi-test.c primes.c \ - mpcpucache.c tests/ \ - utils/gcd.c utils/invmod.c utils/lap.c \ - utils/ptab.pl utils/sieve.c utils/isprime.c\ - utils/dec2hex.c utils/hex2dec.c utils/bbs_rand.c \ - utils/bbsrand.c utils/prng.c utils/primegen.c \ - utils/basecvt.c utils/makeprime.c\ - utils/fact.c utils/exptmod.c utils/pi.c utils/metime.c \ - utils/mpi.h utils/mpprime.h mulsqr.c \ - make-test-arrays test-arrays.txt all-tests make-logtab \ - types.pl stats timetest multest - -## These are the header files that go into the distribution file -HDRS=mpi.h mpi-config.h utils/mpi.h utils/mpi-config.h mpprime.h mplogic.h mp_gf2m.h \ - mp_gf2m-priv.h utils/bbs_rand.h tests/mpi.h tests/mpprime.h - -## These are the documentation files that go into the distribution file -DOCS=README doc utils/README utils/PRIMES - -## This is the list of tools built by 'make tools' -TOOLS=gcd invmod isprime lap dec2hex hex2dec primegen prng \ - basecvt fact exptmod pi makeprime identest - -LIBOBJS = mpprime.o mpmontg.o mplogic.o mp_gf2m.o mpi.o mpcpucache.o $(AS_OBJS) -LIBHDRS = mpi-config.h mpi-priv.h mpi.h -APPHDRS = mpi-config.h mpi.h mplogic.h mp_gf2m.h mpprime.h - -help: - @ echo "" - @ echo "The following targets can be built with this Makefile:" - @ echo "" - @ echo "libmpi.a - arithmetic and prime testing library" - @ echo "mpi-test - test driver (requires MP_IOFUNC)" - @ echo "tools - command line tools" - @ echo "doc - manual pages for tools" - @ echo "clean - clean up objects and such" - @ echo "distclean - get ready for distribution" - @ echo "dist - distribution tarball" - @ echo "" - -.SUFFIXES: .c .o .i - -.c.i: - $(CC) $(CFLAGS) -E $< > $@ - -#.c.o: $*.h $*.c -# $(CC) $(CFLAGS) -c $< - -#--------------------------------------- - -$(LIBOBJS): $(LIBHDRS) - -logtab.h: make-logtab - $(PERL) make-logtab > logtab.h - -mpi.o: mpi.c logtab.h $(LIBHDRS) - -mplogic.o: mplogic.c mpi-priv.h mplogic.h $(LIBHDRS) - -mp_gf2m.o: mp_gf2m.c mpi-priv.h mp_gf2m.h mp_gf2m-priv.h $(LIBHDRS) - -mpmontg.o: mpmontg.c mpi-priv.h mplogic.h mpprime.h $(LIBHDRS) - -mpprime.o: mpprime.c mpi-priv.h mpprime.h mplogic.h primes.c $(LIBHDRS) - -mpcpucache.o: mpcpucache.c $(LIBHDRS) - -mpi_mips.o: mpi_mips.s - $(CC) -o $@ $(ASFLAGS) -c mpi_mips.s - -mpi_sparc.o : montmulf.h - -mpv_sparcv9.s: vis_64.il mpv_sparc.c - $(CC) -o $@ $(SOLARIS_FPU_FLAGS) -S vis_64.il mpv_sparc.c - -mpv_sparcv8.s: vis_64.il mpv_sparc.c - $(CC) -o $@ $(SOLARIS_FPU_FLAGS) -S vis_32.il mpv_sparc.c - -montmulfv8.o montmulfv9.o mpv_sparcv8.o mpv_sparcv9.o : %.o : %.s - $(CC) -o $@ $(SOLARIS_ASM_FLAGS) -c $< - -mpi_arm.o: mpi_arm.c $(LIBHDRS) - -# This rule is used to build the .s sources, which are then hand optimized. -#montmulfv8.s montmulfv9.s : montmulf%.s : montmulf%.il montmulf.c montmulf.h -# $(CC) -o $@ $(SOLARIS_ASM_FLAGS) -S montmulf$*.il montmulf.c - - -libmpi.a: $(LIBOBJS) - ar -cvr libmpi.a $(LIBOBJS) - $(RANLIB) libmpi.a - -lib libs: libmpi.a - -mpi.i: mpi.h - -#--------------------------------------- - -MPTESTOBJS = mptest1.o mptest2.o mptest3.o mptest3a.o mptest4.o mptest4a.o \ - mptest4b.o mptest6.o mptest7.o mptest8.o mptest9.o mptestb.o -MPTESTS = $(MPTESTOBJS:.o=) - -$(MPTESTOBJS): mptest%.o: tests/mptest-%.c $(LIBHDRS) - $(CC) $(CFLAGS) -o $@ -c $< - -$(MPTESTS): mptest%: mptest%.o libmpi.a - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) - -tests: mptest1 mptest2 mptest3 mptest3a mptest4 mptest4a mptest4b mptest6 \ - mptestb bbsrand - -utests: mptest7 mptest8 mptest9 - -#--------------------------------------- - -EXTRAOBJS = bbsrand.o bbs_rand.o prng.o -UTILOBJS = primegen.o metime.o identest.o basecvt.o fact.o exptmod.o pi.o \ - makeprime.o gcd.o invmod.o lap.o isprime.o \ - dec2hex.o hex2dec.o -UTILS = $(UTILOBJS:.o=) - -$(UTILS): % : %.o libmpi.a - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) - -$(UTILOBJS) $(EXTRAOBJS): %.o : utils/%.c $(LIBHDRS) - $(CC) $(CFLAGS) -o $@ -c $< - -prng: prng.o bbs_rand.o libmpi.a - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) - -bbsrand: bbsrand.o bbs_rand.o libmpi.a - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) - -utils: $(UTILS) prng bbsrand - -#--------------------------------------- - -test-info.c: test-arrays.txt - $(PERL) make-test-arrays test-arrays.txt > test-info.c - -mpi-test.o: mpi-test.c test-info.c $(LIBHDRS) - $(CC) $(CFLAGS) -o $@ -c $< - -mpi-test: mpi-test.o libmpi.a - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) - -mdxptest.o: mdxptest.c $(LIBHDRS) mpi-priv.h - -mdxptest: mdxptest.o libmpi.a - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) - -mulsqr.o: mulsqr.c logtab.h mpi.h mpi-config.h mpprime.h - $(CC) $(CFLAGS) -DMP_SQUARE=1 -o $@ -c mulsqr.c - -mulsqr: mulsqr.o libmpi.a - $(CC) $(CFLAGS) -o $@ $^ $(LIBS) - -#--------------------------------------- - -alltests: tests utests mpi-test - -tools: $(TOOLS) - -doc: - (cd doc; ./build) - -clean: - rm -f *.o *.a *.i - rm -f core - rm -f *~ .*~ - rm -f utils/*.o - rm -f utils/core - rm -f utils/*~ utils/.*~ - -clobber: clean - rm -f $(TOOLS) $(UTILS) - -distclean: clean - rm -f mptest? mpi-test metime mulsqr karatsuba - rm -f mptest?a mptest?b - rm -f utils/mptest? - rm -f test-info.c logtab.h - rm -f libmpi.a - rm -f $(TOOLS) - -dist: Makefile $(HDRS) $(SRCS) $(DOCS) - tar -cvf mpi-$(VERS).tar Makefile $(HDRS) $(SRCS) $(DOCS) - pgps -ab mpi-$(VERS).tar - chmod +r mpi-$(VERS).tar.asc - gzip -9 mpi-$(VERS).tar - -# END diff --git a/security/nss/lib/freebl/mpi/Makefile.os2 b/security/nss/lib/freebl/mpi/Makefile.os2 deleted file mode 100644 index fa705ee08..000000000 --- a/security/nss/lib/freebl/mpi/Makefile.os2 +++ /dev/null @@ -1,243 +0,0 @@ -# -# Makefile.win - gmake Makefile for building MPI with VACPP on OS/2 -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -## Define CC to be the C compiler you wish to use. The GNU cc -## compiler (gcc) should work, at the very least -#CC=cc -#CC=gcc -CC=icc.exe -AS=alp.exe - -## -## Define PERL to point to your local Perl interpreter. It -## should be Perl 5.x, although it's conceivable that Perl 4 -## might work ... I haven't tested it. -## -#PERL=/usr/bin/perl -#PERL=perl - -## -## Define CFLAGS to contain any local options your compiler -## setup requires. -## -## Conditional compilation options are no longer here; see -## the file 'mpi-config.h' instead. -## -MPICMN = -I. -DMP_API_COMPATIBLE -DMP_IOFUNC -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD - -#OS/2 -AS_SRCS = mpi_x86.asm -MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D -#CFLAGS= -Od -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC \ - -DDEBUG -D_DEBUG -UNDEBUG -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN) -#CFLAGS = -O2 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \ - -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN) -#CFLAGS = -Od -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \ - -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN) -CFLAGS = /Ti+ -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \ - $(MPICMN) -ASFLAGS = - -## -## Define LIBS to include any libraries you need to link against. -## If NO_TABLE is define, LIBS should include '-lm' or whatever is -## necessary to bring in the math library. Otherwise, it can be -## left alone, unless your system has other peculiar requirements. -## -LIBS=#-lmalloc#-lefence#-lm - -## -## Define RANLIB to be the library header randomizer; you might not -## need this on some systems (just set it to 'echo' on these systems, -## such as IRIX) -## -RANLIB=echo - -## -## This is the version string used for the documentation and -## building the distribution tarball. Don't mess with it unless -## you are releasing a new version -VERS=1.7p6 - -## ---------------------------------------------------------------------- -## You probably don't need to change anything below this line... -## - -## -## This is the list of source files that need to be packed into -## the distribution file -SRCS= mpi.c mpprime.c mplogic.c mpmontg.c mpi-test.c primes.c tests/ \ - utils/gcd.c utils/invmod.c utils/lap.c \ - utils/ptab.pl utils/sieve.c utils/isprime.c\ - utils/dec2hex.c utils/hex2dec.c utils/bbs_rand.c \ - utils/bbsrand.c utils/prng.c utils/primegen.c \ - utils/basecvt.c utils/makeprime.c\ - utils/fact.c utils/exptmod.c utils/pi.c utils/metime.c \ - utils/mpi.h utils/mpprime.h mulsqr.c \ - make-test-arrays test-arrays.txt all-tests make-logtab \ - types.pl stats timetest multest - -## These are the header files that go into the distribution file -HDRS=mpi.h mpi-config.h utils/mpi.h utils/mpi-config.h mpprime.h mplogic.h \ - utils/bbs_rand.h tests/mpi.h tests/mpprime.h - -## These are the documentation files that go into the distribution file -DOCS=README doc utils/README utils/PRIMES - -## This is the list of tools built by 'make tools' -TOOLS=gcd.exe invmod.exe isprime.exe lap.exe dec2hex.exe hex2dec.exe \ - primegen.exe prng.exe basecvt.exe fact.exe exptmod.exe pi.exe makeprime.exe - -AS_OBJS = $(AS_SRCS:.asm=.obj) -LIBOBJS = mpprime.obj mpmontg.obj mplogic.obj mpi.obj $(AS_OBJS) -LIBHDRS = mpi-config.h mpi-priv.h mpi.h -APPHDRS = mpi-config.h mpi.h mplogic.h mpprime.h - - -help: - @ echo "" - @ echo "The following targets can be built with this Makefile:" - @ echo "" - @ echo "mpi.lib - arithmetic and prime testing library" - @ echo "mpi-test.exe - test driver (requires MP_IOFUNC)" - @ echo "tools - command line tools" - @ echo "doc - manual pages for tools" - @ echo "clean - clean up objects and such" - @ echo "distclean - get ready for distribution" - @ echo "dist - distribution tarball" - @ echo "" - -.SUFFIXES: .c .obj .i .lib .exe .asm - -.c.i: - $(CC) $(CFLAGS) -E $< > $@ - -.c.obj: - $(CC) $(CFLAGS) -c $< - -.asm.obj: - $(AS) $(ASFLAGS) $< - -.obj.exe: - $(CC) $(CFLAGS) -Fo$@ $< - -#--------------------------------------- - -$(LIBOBJS): $(LIBHDRS) - -logtab.h: make-logtab - $(PERL) make-logtab > logtab.h - -mpi.obj: mpi.c logtab.h $(LIBHDRS) - -mplogic.obj: mplogic.c mpi-priv.h mplogic.h $(LIBHDRS) - -mpmontg.obj: mpmontg.c mpi-priv.h mplogic.h mpprime.h $(LIBHDRS) - -mpprime.obj: mpprime.c mpi-priv.h mpprime.h mplogic.h primes.c $(LIBHDRS) - -mpi_mips.obj: mpi_mips.s - $(CC) -Fo$@ $(ASFLAGS) -c mpi_mips.s - -mpi.lib: $(LIBOBJS) - ilib /out:mpi.lib $(LIBOBJS) - $(RANLIB) mpi.lib - -lib libs: mpi.lib - -#--------------------------------------- - -MPTESTOBJS = mptest1.obj mptest2.obj mptest3.obj mptest3a.obj mptest4.obj \ - mptest4a.obj mptest4b.obj mptest6.obj mptest7.obj mptest8.obj mptest9.obj -MPTESTS = $(MPTESTOBJS:.obj=.exe) - -$(MPTESTOBJS): mptest%.obj: tests/mptest-%.c $(LIBHDRS) - $(CC) $(CFLAGS) -Fo$@ -c $< - -$(MPTESTS): mptest%.exe: mptest%.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -tests: mptest1.exe mptest2.exe mptest3.exe mptest3a.exe mptest4.exe \ - mptest4a.exe mptest4b.exe mptest6.exe bbsrand.exe - -utests: mptest7.exe mptest8.exe mptest9.exe - -#--------------------------------------- - -EXTRAOBJS = bbsrand.obj bbs_rand.obj prng.obj -UTILOBJS = primegen.obj metime.obj identest.obj basecvt.obj fact.obj \ - exptmod.obj pi.obj makeprime.obj karatsuba.obj gcd.obj invmod.obj lap.obj \ - isprime.obj dec2hex.obj hex2dec.obj -UTILS = $(UTILOBJS:.obj=.exe) - -$(UTILS): %.exe : %.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -$(UTILOBJS) $(EXTRAOBJS): %.obj : utils/%.c $(LIBHDRS) - $(CC) $(CFLAGS) -Fo$@ -c $< - -prng.exe: prng.obj bbs_rand.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -bbsrand.exe: bbsrand.obj bbs_rand.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -utils: $(UTILS) prng.exe bbsrand.exe - -#--------------------------------------- - -test-info.c: test-arrays.txt - $(PERL) make-test-arrays test-arrays.txt > test-info.c - -mpi-test.obj: mpi-test.c test-info.c $(LIBHDRS) - $(CC) $(CFLAGS) -Fo$@ -c $< - -mpi-test.exe: mpi-test.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -mdxptest.obj: mdxptest.c $(LIBHDRS) mpi-priv.h - -mdxptest.exe: mdxptest.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -mulsqr.obj: mulsqr.c logtab.h mpi.h mpi-config.h mpprime.h - $(CC) $(CFLAGS) -DMP_SQUARE=1 -Fo$@ -c mulsqr.c - -mulsqr.exe: mulsqr.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -#--------------------------------------- - -alltests: tests utests mpi-test.exe - -tools: $(TOOLS) - -doc: - (cd doc; ./build) - -clean: - rm -f *.obj *.lib *.pdb *.ilk - cd utils; rm -f *.obj *.lib *.pdb *.ilk - -distclean: clean - rm -f mptest? mpi-test metime mulsqr karatsuba - rm -f mptest?a mptest?b - rm -f utils/mptest? - rm -f test-info.c logtab.h - rm -f mpi.lib - rm -f $(TOOLS) - -dist: Makefile $(HDRS) $(SRCS) $(DOCS) - tar -cvf mpi-$(VERS).tar Makefile $(HDRS) $(SRCS) $(DOCS) - pgps -ab mpi-$(VERS).tar - chmod +r mpi-$(VERS).tar.asc - gzip -9 mpi-$(VERS).tar - - -print: - @echo LIBOBJS = $(LIBOBJS) -# END diff --git a/security/nss/lib/freebl/mpi/Makefile.win b/security/nss/lib/freebl/mpi/Makefile.win deleted file mode 100644 index cd41dfab8..000000000 --- a/security/nss/lib/freebl/mpi/Makefile.win +++ /dev/null @@ -1,254 +0,0 @@ -# -# Makefile.win - gmake Makefile for building MPI with MSVC on NT - -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -## Define CC to be the C compiler you wish to use. The GNU cc -## compiler (gcc) should work, at the very least -#CC=cc -#CC=gcc -CC=cl.exe -ifeq ($(CPU_ARCH),x86_64) -AS=ml64.exe -else -AS=ml.exe -endif - -## -## Define PERL to point to your local Perl interpreter. It -## should be Perl 5.x, although it's conceivable that Perl 4 -## might work ... I haven't tested it. -## -#PERL=/usr/bin/perl -#PERL=perl - -## -## Define CFLAGS to contain any local options your compiler -## setup requires. -## -## Conditional compilation options are no longer here; see -## the file 'mpi-config.h' instead. -## -MPICMN = -I. -DMP_API_COMPATIBLE -DMP_IOFUNC - -ifeq ($(CPU_ARCH),x86_64) -AS_SRCS = mpi_x86_64.asm -CFLAGS = -O2 -Z7 -MD -W3 -nologo -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \ - -DWIN32 -D_WIN64 -D_AMD64_ -D_M_AMD64 -D_WINDOWS -DWIN95 $(MPICMN) -ASFLAGS = -Cp -Sn -Zi -I. -else -#NT -AS_SRCS = mpi_x86.asm -MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D -#CFLAGS= -Od -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC \ - -DDEBUG -D_DEBUG -UNDEBUG -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN) -#CFLAGS = -O2 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \ - -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN) -#CFLAGS = -Od -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \ - -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN) -CFLAGS = -O2 -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \ - -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN) -ASFLAGS = -Cp -Sn -Zi -coff -I. -endif - -## -## Define LIBS to include any libraries you need to link against. -## If NO_TABLE is define, LIBS should include '-lm' or whatever is -## necessary to bring in the math library. Otherwise, it can be -## left alone, unless your system has other peculiar requirements. -## -LIBS=#-lmalloc#-lefence#-lm - -## -## Define RANLIB to be the library header randomizer; you might not -## need this on some systems (just set it to 'echo' on these systems, -## such as IRIX) -## -RANLIB=echo - -## -## This is the version string used for the documentation and -## building the distribution tarball. Don't mess with it unless -## you are releasing a new version -VERS=1.7p6 - -## ---------------------------------------------------------------------- -## You probably don't need to change anything below this line... -## - -## -## This is the list of source files that need to be packed into -## the distribution file -SRCS= mpi.c mpprime.c mplogic.c mpmontg.c mpi-test.c primes.c tests/ \ - utils/gcd.c utils/invmod.c utils/lap.c \ - utils/ptab.pl utils/sieve.c utils/isprime.c\ - utils/dec2hex.c utils/hex2dec.c utils/bbs_rand.c \ - utils/bbsrand.c utils/prng.c utils/primegen.c \ - utils/basecvt.c utils/makeprime.c\ - utils/fact.c utils/exptmod.c utils/pi.c utils/metime.c \ - utils/mpi.h utils/mpprime.h mulsqr.c \ - make-test-arrays test-arrays.txt all-tests make-logtab \ - types.pl stats timetest multest - -## These are the header files that go into the distribution file -HDRS=mpi.h mpi-config.h utils/mpi.h utils/mpi-config.h mpprime.h mplogic.h \ - utils/bbs_rand.h tests/mpi.h tests/mpprime.h - -## These are the documentation files that go into the distribution file -DOCS=README doc utils/README utils/PRIMES - -## This is the list of tools built by 'make tools' -TOOLS=gcd.exe invmod.exe isprime.exe lap.exe dec2hex.exe hex2dec.exe \ - primegen.exe prng.exe basecvt.exe fact.exe exptmod.exe pi.exe makeprime.exe - -AS_OBJS = $(AS_SRCS:.asm=.obj) -LIBOBJS = mpprime.obj mpmontg.obj mplogic.obj mpi.obj $(AS_OBJS) -LIBHDRS = mpi-config.h mpi-priv.h mpi.h -APPHDRS = mpi-config.h mpi.h mplogic.h mpprime.h - - -help: - @ echo "" - @ echo "The following targets can be built with this Makefile:" - @ echo "" - @ echo "mpi.lib - arithmetic and prime testing library" - @ echo "mpi-test - test driver (requires MP_IOFUNC)" - @ echo "tools - command line tools" - @ echo "doc - manual pages for tools" - @ echo "clean - clean up objects and such" - @ echo "distclean - get ready for distribution" - @ echo "dist - distribution tarball" - @ echo "" - -.SUFFIXES: .c .obj .i .lib .exe .asm - -.c.i: - $(CC) $(CFLAGS) -E $< > $@ - -.c.obj: - $(CC) $(CFLAGS) -c $< - -.asm.obj: - $(AS) $(ASFLAGS) -c $< - -.obj.exe: - $(CC) $(CFLAGS) -Fo$@ $< - -#--------------------------------------- - -$(LIBOBJS): $(LIBHDRS) - -logtab.h: make-logtab - $(PERL) make-logtab > logtab.h - -mpi.obj: mpi.c logtab.h $(LIBHDRS) - -mplogic.obj: mplogic.c mpi-priv.h mplogic.h $(LIBHDRS) - -mpmontg.obj: mpmontg.c mpi-priv.h mplogic.h mpprime.h $(LIBHDRS) - -mpprime.obj: mpprime.c mpi-priv.h mpprime.h mplogic.h primes.c $(LIBHDRS) - -mpi_mips.obj: mpi_mips.s - $(CC) -Fo$@ $(ASFLAGS) -c mpi_mips.s - -mpi.lib: $(LIBOBJS) - ar -cvr mpi.lib $(LIBOBJS) - $(RANLIB) mpi.lib - -lib libs: mpi.lib - -#--------------------------------------- - -MPTESTOBJS = mptest1.obj mptest2.obj mptest3.obj mptest3a.obj mptest4.obj \ - mptest4a.obj mptest4b.obj mptest6.obj mptest7.obj mptest8.obj mptest9.obj -MPTESTS = $(MPTESTOBJS:.obj=.exe) - -$(MPTESTOBJS): mptest%.obj: tests/mptest-%.c $(LIBHDRS) - $(CC) $(CFLAGS) -Fo$@ -c $< - -$(MPTESTS): mptest%.exe: mptest%.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -tests: mptest1.exe mptest2.exe mptest3.exe mptest3a.exe mptest4.exe \ - mptest4a.exe mptest4b.exe mptest6.exe bbsrand.exe - -utests: mptest7.exe mptest8.exe mptest9.exe - -#--------------------------------------- - -EXTRAOBJS = bbsrand.obj bbs_rand.obj prng.obj -UTILOBJS = primegen.obj metime.obj identest.obj basecvt.obj fact.obj \ - exptmod.obj pi.obj makeprime.obj karatsuba.obj gcd.obj invmod.obj lap.obj \ - isprime.obj dec2hex.obj hex2dec.obj -UTILS = $(UTILOBJS:.obj=.exe) - -$(UTILS): %.exe : %.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -$(UTILOBJS) $(EXTRAOBJS): %.obj : utils/%.c $(LIBHDRS) - $(CC) $(CFLAGS) -Fo$@ -c $< - -prng.exe: prng.obj bbs_rand.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -bbsrand.exe: bbsrand.obj bbs_rand.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -utils: $(UTILS) prng.exe bbsrand.exe - -#--------------------------------------- - -test-info.c: test-arrays.txt - $(PERL) make-test-arrays test-arrays.txt > test-info.c - -mpi-test.obj: mpi-test.c test-info.c $(LIBHDRS) - $(CC) $(CFLAGS) -Fo$@ -c $< - -mpi-test.exe: mpi-test.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -mdxptest.obj: mdxptest.c $(LIBHDRS) mpi-priv.h - -mdxptest.exe: mdxptest.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -mulsqr.obj: mulsqr.c logtab.h mpi.h mpi-config.h mpprime.h - $(CC) $(CFLAGS) -DMP_SQUARE=1 -Fo$@ -c mulsqr.c - -mulsqr.exe: mulsqr.obj mpi.lib $(LIBS) - $(CC) $(CFLAGS) -Fo$@ $^ - -#--------------------------------------- - -alltests: tests utests mpi-test.exe - -tools: $(TOOLS) - -doc: - (cd doc; ./build) - -clean: - rm -f *.obj *.lib *.pdb *.ilk - cd utils; rm -f *.obj *.lib *.pdb *.ilk - -distclean: clean - rm -f mptest? mpi-test metime mulsqr karatsuba - rm -f mptest?a mptest?b - rm -f utils/mptest? - rm -f test-info.c logtab.h - rm -f mpi.lib - rm -f $(TOOLS) - -dist: Makefile $(HDRS) $(SRCS) $(DOCS) - tar -cvf mpi-$(VERS).tar Makefile $(HDRS) $(SRCS) $(DOCS) - pgps -ab mpi-$(VERS).tar - chmod +r mpi-$(VERS).tar.asc - gzip -9 mpi-$(VERS).tar - - -print: - @echo LIBOBJS = $(LIBOBJS) -# END diff --git a/security/nss/lib/freebl/mpi/README b/security/nss/lib/freebl/mpi/README index 475549bad..776ba713a 100644 --- a/security/nss/lib/freebl/mpi/README +++ b/security/nss/lib/freebl/mpi/README @@ -67,14 +67,6 @@ assumptions about the sizes of things, but there is little if any reason to change the other parameters, so I would recommend you leave them as you found them. -The library comes with a Perl script, 'types.pl', which will scan your -current Makefile settings, and attempt to find good definitions for -these types. It relies on a Unix sort of build environment, so it -probably won't work under MacOS or Windows, but it can be convenient -if you're porting to a new flavour of Unix. Just run 'types.pl' at -the command line, and it will spit out its results to the standard -output. - Conventions ----------- @@ -503,9 +495,6 @@ MP_MODARITH - Define true to include the modular arithmetic in your application, you can set this to zero to leave out all the modular routines. -MP_NUMTH - Define true to include number theoretic functions - such as mp_gcd(), mp_lcm(), and mp_invmod(). - MP_LOGTAB - If true, the file "logtab.h" is included, which is basically a static table of base 2 logarithms. These are used to compute how big the buffers for @@ -633,92 +622,6 @@ Most of these can be built from the Makefile that comes with the library. Try 'make tools', if your environment supports it. -Testing the Library -------------------- - -Automatic test vectors are included, in the form of a program called -'mpi-test'. To build this program and run all the tests, simply -invoke the shell script 'all-tests'. If all the tests pass, you -should see a message: - - All tests passed - -If something went wrong, you'll get: - - One or more tests failed. - -If this happens, scan back through the preceding lines, to see which -test failed. Any failure indicates a bug in the library, which needs -to be fixed before it will give accurate results. If you get any such -thing, please let me know, and I'll try to fix it. Please let me know -what platform and compiler you were using, as well as which test -failed. If a reason for failure was given, please send me that text -as well. - -If you're on a system where the standard Unix build tools don't work, -you can build the 'mpi-test' program manually, and run it by hand. -This is tedious and obnoxious, sorry. - -Further manual testing can be performed by building the manual testing -programs, whose source is found in the 'tests' subdirectory. Each -test is in a source file called 'mptest-X.c'. The Makefile contains a -target to build all of them at once: - - make tests - -Read the comments at the top of each source file to see what the -driver is supposed to test. You probably don't need to do this; these -programs were only written to help me as I was developing the library. - -The relevant files are: - -mpi-test.c The source for the test driver - -make-test-arrays A Perl script to generate some of the internal - data structures used by mpi-test.c - -test-arrays.txt The source file for make-test-arrays - -all-tests A Bourne shell script which runs all the - tests in the mpi-test suite - -Running 'make mpi-test' should build the mpi-test program. If you -cannot use make, here is what needs to be done: - -(1) Use 'make-test-arrays' to generate the file 'test-info.c' from - the 'test-arrays.txt' file. Since Perl can be found everywhere, - this should be no trouble. Under Unix, this looks like: - - make-test-arrays test-arrays.txt > test-info.c - -(2) Build the MPI library: - - gcc -ansi -pedantic -Wall -c mpi.c - -(3) Build the mpi-test program: - - gcc -ansi -pedantic -Wall -o mpi-test mpi.o mpi-test.c - -When you've got mpi-test, you can use 'all-tests' to run all the tests -made available by mpi-test. If any of them fail, there should be a -diagnostic indicating what went wrong. These are fairly high-level -diagnostics, and won't really help you debug the problem; they're -simply intended to help you isolate which function caused the problem. -If you encounter a problem of this sort, feel free to e-mail me, and I -will certainly attempt to help you debug it. - -Note: Several of the tests hard-wired into 'mpi-test' operate under ----- the assumption that you are using at least a 16-bit mp_digit - type. If that is not true, several tests might fail, because - of range problems with the maximum digit value. - - If you are using an 8-bit digit, you will also need to - modify the code for mp_read_raw(), which assumes that - multiplication by 256 can be done with mp_mul_d(), a - fact that fails when DIGIT_MAX is 255. You can replace - the call with s_mp_lshd(), which will give you the same - effect, and without doing as much work. :) - Acknowledgements: ---------------- diff --git a/security/nss/lib/freebl/mpi/all-tests b/security/nss/lib/freebl/mpi/all-tests deleted file mode 100755 index 3429a15c0..000000000 --- a/security/nss/lib/freebl/mpi/all-tests +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/sh -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -ECHO=/bin/echo -MAKE=gmake - -$ECHO "\n** Running unit tests for MPI library\n" - -# Build the mpi-test program, which comprises all the unit tests for -# the MPI library... - -$ECHO "Bringing mpi-test up to date ... " -if $MAKE mpi-test ; then - : -else - $ECHO " " - $ECHO "Make failed to build mpi-test." - $ECHO " " - exit 1 -fi - -if [ ! -x mpi-test ] ; then - $ECHO " " - $ECHO "Cannot find 'mpi-test' program, testing cannot continue." - $ECHO " " - exit 1 -fi - -# Get the list of available test suites... -tests=`./mpi-test list | awk '{print $1}'` -errs=0 - -# Run each test suite and check the result code of mpi-test -for test in $tests ; do - $ECHO "$test ... \c" - if ./mpi-test $test ; then - $ECHO "passed" - else - $ECHO "FAILED" - errs=1 - fi -done - -# If any tests failed, we'll stop at this point -if [ "$errs" = "0" ] ; then - $ECHO "All unit tests passed" -else - $ECHO "One or more tests failed" - exit 1 -fi - -# Now try to build the 'pi' program, and see if it can compute the -# first thousand digits of pi correctly -$ECHO "\n** Running other tests\n" - -$ECHO "Bringing 'pi' up to date ... " -if $MAKE pi ; then - : -else - $ECHO "\nMake failed to build pi.\n" - exit 1 -fi - -if [ ! -x pi ] ; then - $ECHO "\nCannot find 'pi' program; testing cannot continue.\n" - exit 1 -fi - -./pi 2000 > /tmp/pi.tmp.$$ -if cmp tests/pi2k.txt /tmp/pi.tmp.$$ ; then - $ECHO "Okay! The pi test passes." -else - $ECHO "Oops! The pi test failed. :(" - exit 1 -fi - -rm -f /tmp/pi.tmp.$$ - -exit 0 - -# Here there be dragons diff --git a/security/nss/lib/freebl/mpi/hppatch.adb b/security/nss/lib/freebl/mpi/hppatch.adb deleted file mode 100644 index 6875032ef..000000000 --- a/security/nss/lib/freebl/mpi/hppatch.adb +++ /dev/null @@ -1,21 +0,0 @@ -#/bin/sh -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# script to change the system id in an object file from PA-RISC 2.0 to 1.1 - -adb -w $1 << EOF -?m 0 -1 0 -0x0?X -0x0?W (@0x0&~0x40000)|(~@0x0&0x40000) - -0?"change checksum" -0x7c?X -0x7c?W (@0x7c&~0x40000)|(~@0x7c&0x40000) -$q -EOF - -exit 0 - diff --git a/security/nss/lib/freebl/mpi/make-logtab b/security/nss/lib/freebl/mpi/make-logtab deleted file mode 100755 index fadba1c86..000000000 --- a/security/nss/lib/freebl/mpi/make-logtab +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/perl - -# -# make-logtab -# -# Generate a table of logarithms of 2 in various bases, for use in -# estimating the output sizes of various bases. - -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -$ARRAYNAME = $ENV{'ARRAYNAME'} || "s_logv_2"; -$ARRAYTYPE = $ENV{'ARRAYTYPE'} || "float"; - -printf("const %s %s[] = {\n %0.9ff, %0.9ff, ", - $ARRAYTYPE, $ARRAYNAME, 0, 0); -$brk = 2; -for($ix = 2; $ix < 64; $ix++) { - printf("%0.9ff, ", (log(2)/log($ix))); - $brk = ($brk + 1) & 3; - if(!$brk) { - printf(" /* %2d %2d %2d %2d */\n ", - $ix - 3, $ix - 2, $ix - 1, $ix); - } -} -printf("%0.9ff\n};\n\n", (log(2)/log($ix))); - -exit 0; diff --git a/security/nss/lib/freebl/mpi/make-test-arrays b/security/nss/lib/freebl/mpi/make-test-arrays deleted file mode 100755 index ecdd55202..000000000 --- a/security/nss/lib/freebl/mpi/make-test-arrays +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/perl - -# -# make-test-arrays -# -# Given a test-arrays file, which specifies the test suite names, the -# names of the functions which perform those test suites, and -# descriptive comments, this script generates C structures for the -# mpi-test program. The input consists of lines of the form: -# -# suite-name:function-name:comment -# -# The output is written to the standard output. Blank lines are -# ignored, and comments beginning with '#' are stripped. - -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Read parameters from the environment, if available -$NAMEVAR = $ENV{'NAMEVAR'} || "g_names"; -$COUNTVAR = $ENV{'COUNTVAR'} || "g_count"; -$FUNCVAR = $ENV{'FUNCVAR'} || "g_tests"; -$DESCVAR = $ENV{'DESCVAR'} || "g_descs"; -$FUNCLEN = 13; -$NAMELEN = 18; -$DESCLEN = 45; - -#------------------------------------------------------------------------ -# Suck in input from the files on the command line, or standard input -while(<>) { - chomp; - s/\#.*$//; - next if /^\s*$/; - - ($suite, $func, $desc) = split(/:/, $_); - - $tmp = { "suite" => $suite, - "func" => $func, - "desc" => $desc }; - - push(@item, $tmp); -} -$count = scalar(@item); -$last = pop(@item); - -#------------------------------------------------------------------------ -# Output the table of names -print "/* Table mapping test suite names to index numbers */\n"; -printf("const int %s = %d;\n", $COUNTVAR, $count); -printf("const char *%s[] = {\n", $NAMEVAR); - -foreach $elt (@item) { - printf(" \"%s\",%s/* %s%s */\n", $elt->{"suite"}, - " " x ($NAMELEN - length($elt->{"suite"})), - $elt->{"desc"}, - " " x ($DESCLEN - length($elt->{"desc"}))); -} -printf(" \"%s\" %s/* %s%s */\n", $last->{"suite"}, - " " x ($NAMELEN - length($last->{"suite"})), - $last->{"desc"}, - " " x ($DESCLEN - length($last->{"desc"}))); -print "};\n\n"; - -#------------------------------------------------------------------------ -# Output the driver function prototypes -print "/* Test function prototypes */\n"; -foreach $elt (@item, $last) { - printf("int %s(void);\n", $elt->{"func"}); -} -print "\n"; - -#------------------------------------------------------------------------ -# Output the table of functions -print "/* Table mapping index numbers to functions */\n"; -printf("int (*%s[])(void) = {\n ", $FUNCVAR); -$brk = 0; - -foreach $elt (@item) { - print($elt->{"func"}, ", ", - " " x ($FUNCLEN - length($elt->{"func"}))); - $brk = ($brk + 1) & 3; - print "\n " unless($brk); -} -print $last->{"func"}, "\n};\n\n"; - -#------------------------------------------------------------------------ -# Output the table of descriptions -print "/* Table mapping index numbers to descriptions */\n"; -printf("const char *%s[] = {\n", $DESCVAR); - -foreach $elt (@item) { - printf(" \"%s\",\n", $elt->{"desc"}); -} -printf(" \"%s\"\n};\n\n", $last->{"desc"}); - -exit 0; - diff --git a/security/nss/lib/freebl/mpi/mdxptest.c b/security/nss/lib/freebl/mpi/mdxptest.c deleted file mode 100644 index adbcfc3d1..000000000 --- a/security/nss/lib/freebl/mpi/mdxptest.c +++ /dev/null @@ -1,306 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include "mpi.h" -#include "mpi-priv.h" - -/* #define OLD_WAY 1 */ - -/* This key is the 1024-bit test key used for speed testing of RSA private -** key ops. -*/ - -#define CONST const - -static CONST unsigned char default_n[128] = { - 0xc2, 0xae, 0x96, 0x89, 0xaf, 0xce, 0xd0, 0x7b, 0x3b, 0x35, 0xfd, 0x0f, 0xb1, 0xf4, 0x7a, 0xd1, - 0x3c, 0x7d, 0xb5, 0x86, 0xf2, 0x68, 0x36, 0xc9, 0x97, 0xe6, 0x82, 0x94, 0x86, 0xaa, 0x05, 0x39, - 0xec, 0x11, 0x51, 0xcc, 0x5c, 0xa1, 0x59, 0xba, 0x29, 0x18, 0xf3, 0x28, 0xf1, 0x9d, 0xe3, 0xae, - 0x96, 0x5d, 0x6d, 0x87, 0x73, 0xf6, 0xf6, 0x1f, 0xd0, 0x2d, 0xfb, 0x2f, 0x7a, 0x13, 0x7f, 0xc8, - 0x0c, 0x7a, 0xe9, 0x85, 0xfb, 0xce, 0x74, 0x86, 0xf8, 0xef, 0x2f, 0x85, 0x37, 0x73, 0x0f, 0x62, - 0x4e, 0x93, 0x17, 0xb7, 0x7e, 0x84, 0x9a, 0x94, 0x11, 0x05, 0xca, 0x0d, 0x31, 0x4b, 0x2a, 0xc8, - 0xdf, 0xfe, 0xe9, 0x0c, 0x13, 0xc7, 0xf2, 0xad, 0x19, 0x64, 0x28, 0x3c, 0xb5, 0x6a, 0xc8, 0x4b, - 0x79, 0xea, 0x7c, 0xce, 0x75, 0x92, 0x45, 0x3e, 0xa3, 0x9d, 0x64, 0x6f, 0x04, 0x69, 0x19, 0x17 -}; - -static CONST unsigned char default_d[128] = { - 0x13, 0xcb, 0xbc, 0xf2, 0xf3, 0x35, 0x8c, 0x6d, 0x7b, 0x6f, 0xd9, 0xf3, 0xa6, 0x9c, 0xbd, 0x80, - 0x59, 0x2e, 0x4f, 0x2f, 0x11, 0xa7, 0x17, 0x2b, 0x18, 0x8f, 0x0f, 0xe8, 0x1a, 0x69, 0x5f, 0x6e, - 0xac, 0x5a, 0x76, 0x7e, 0xd9, 0x4c, 0x6e, 0xdb, 0x47, 0x22, 0x8a, 0x57, 0x37, 0x7a, 0x5e, 0x94, - 0x7a, 0x25, 0xb5, 0xe5, 0x78, 0x1d, 0x3c, 0x99, 0xaf, 0x89, 0x7d, 0x69, 0x2e, 0x78, 0x9d, 0x1d, - 0x84, 0xc8, 0xc1, 0xd7, 0x1a, 0xb2, 0x6d, 0x2d, 0x8a, 0xd9, 0xab, 0x6b, 0xce, 0xae, 0xb0, 0xa0, - 0x58, 0x55, 0xad, 0x5c, 0x40, 0x8a, 0xd6, 0x96, 0x08, 0x8a, 0xe8, 0x63, 0xe6, 0x3d, 0x6c, 0x20, - 0x49, 0xc7, 0xaf, 0x0f, 0x25, 0x73, 0xd3, 0x69, 0x43, 0x3b, 0xf2, 0x32, 0xf8, 0x3d, 0x5e, 0xee, - 0x7a, 0xca, 0xd6, 0x94, 0x55, 0xe5, 0xbd, 0x25, 0x34, 0x8d, 0x63, 0x40, 0xb5, 0x8a, 0xc3, 0x01 -}; - -#define DEFAULT_ITERS 50 - -typedef clock_t timetype; -#define gettime(x) *(x) = clock() -#define subtime(a, b) a -= b -#define msec(x) ((clock_t)((double)x * 1000.0 / CLOCKS_PER_SEC)) -#define sec(x) (x / CLOCKS_PER_SEC) - -struct TimingContextStr { - timetype start; - timetype end; - timetype interval; - - int minutes; - int seconds; - int millisecs; -}; - -typedef struct TimingContextStr TimingContext; - -TimingContext * -CreateTimingContext(void) -{ - return (TimingContext *)malloc(sizeof(TimingContext)); -} - -void -DestroyTimingContext(TimingContext *ctx) -{ - free(ctx); -} - -void -TimingBegin(TimingContext *ctx) -{ - gettime(&ctx->start); -} - -static void -timingUpdate(TimingContext *ctx) -{ - - ctx->millisecs = msec(ctx->interval) % 1000; - ctx->seconds = sec(ctx->interval); - ctx->minutes = ctx->seconds / 60; - ctx->seconds %= 60; -} - -void -TimingEnd(TimingContext *ctx) -{ - gettime(&ctx->end); - ctx->interval = ctx->end; - subtime(ctx->interval, ctx->start); - timingUpdate(ctx); -} - -char * -TimingGenerateString(TimingContext *ctx) -{ - static char sBuf[4096]; - - sprintf(sBuf, "%d minutes, %d.%03d seconds", ctx->minutes, - ctx->seconds, ctx->millisecs); - return sBuf; -} - -static void -dumpBytes(unsigned char *b, int l) -{ - int i; - if (l <= 0) - return; - for (i = 0; i < l; ++i) { - if (i % 16 == 0) - printf("\t"); - printf(" %02x", b[i]); - if (i % 16 == 15) - printf("\n"); - } - if ((i % 16) != 0) - printf("\n"); - printf("\n"); -} - -static mp_err -testNewFuncs(const unsigned char *modulusBytes, int modulus_len) -{ - mp_err mperr = MP_OKAY; - mp_int modulus; - unsigned char buf[512]; - - mperr = mp_init(&modulus); - mperr = mp_read_unsigned_octets(&modulus, modulusBytes, modulus_len); - mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len); - mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len + 1); - mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len + 4); - mperr = mp_to_unsigned_octets(&modulus, buf, modulus_len); - mperr = mp_to_signed_octets(&modulus, buf, modulus_len + 1); - mp_clear(&modulus); - return mperr; -} - -int -testModExp(const unsigned char *modulusBytes, - const unsigned int expo, - const unsigned char *input, - unsigned char *output, - int modulus_len) -{ - mp_err mperr = MP_OKAY; - mp_int modulus; - mp_int base; - mp_int exponent; - mp_int result; - - mperr = mp_init(&modulus); - mperr += mp_init(&base); - mperr += mp_init(&exponent); - mperr += mp_init(&result); - /* we initialize all mp_ints unconditionally, even if some fail. - ** This guarantees that the DIGITS pointer is valid (even if null). - ** So, mp_clear will do the right thing below. - */ - if (mperr == MP_OKAY) { - mperr = mp_read_unsigned_octets(&modulus, - modulusBytes + (sizeof default_n - modulus_len), modulus_len); - mperr += mp_read_unsigned_octets(&base, input, modulus_len); - mp_set(&exponent, expo); - if (mperr == MP_OKAY) { -#if OLD_WAY - mperr = s_mp_exptmod(&base, &exponent, &modulus, &result); -#else - mperr = mp_exptmod(&base, &exponent, &modulus, &result); -#endif - if (mperr == MP_OKAY) { - mperr = mp_to_fixlen_octets(&result, output, modulus_len); - } - } - } - mp_clear(&base); - mp_clear(&result); - - mp_clear(&modulus); - mp_clear(&exponent); - - return (int)mperr; -} - -int -doModExp(const unsigned char *modulusBytes, - const unsigned char *exponentBytes, - const unsigned char *input, - unsigned char *output, - int modulus_len) -{ - mp_err mperr = MP_OKAY; - mp_int modulus; - mp_int base; - mp_int exponent; - mp_int result; - - mperr = mp_init(&modulus); - mperr += mp_init(&base); - mperr += mp_init(&exponent); - mperr += mp_init(&result); - /* we initialize all mp_ints unconditionally, even if some fail. - ** This guarantees that the DIGITS pointer is valid (even if null). - ** So, mp_clear will do the right thing below. - */ - if (mperr == MP_OKAY) { - mperr = mp_read_unsigned_octets(&modulus, - modulusBytes + (sizeof default_n - modulus_len), modulus_len); - mperr += mp_read_unsigned_octets(&exponent, exponentBytes, modulus_len); - mperr += mp_read_unsigned_octets(&base, input, modulus_len); - if (mperr == MP_OKAY) { -#if OLD_WAY - mperr = s_mp_exptmod(&base, &exponent, &modulus, &result); -#else - mperr = mp_exptmod(&base, &exponent, &modulus, &result); -#endif - if (mperr == MP_OKAY) { - mperr = mp_to_fixlen_octets(&result, output, modulus_len); - } - } - } - mp_clear(&base); - mp_clear(&result); - - mp_clear(&modulus); - mp_clear(&exponent); - - return (int)mperr; -} - -int -main(int argc, char **argv) -{ - TimingContext *timeCtx; - char *progName; - long iters = DEFAULT_ITERS; - unsigned int modulus_len; - int i; - int rv; - unsigned char buf[1024]; - unsigned char buf2[1024]; - - progName = strrchr(argv[0], '/'); - if (!progName) - progName = strrchr(argv[0], '\\'); - progName = progName ? progName + 1 : argv[0]; - - if (argc >= 2) { - iters = atol(argv[1]); - } - - if (argc >= 3) { - modulus_len = atol(argv[2]); - } else - modulus_len = sizeof default_n; - - /* no library init function !? */ - - memset(buf, 0x41, sizeof buf); - - if (iters < 2) { - testNewFuncs(default_n, modulus_len); - testNewFuncs(default_n + 1, modulus_len - 1); - testNewFuncs(default_n + 2, modulus_len - 2); - testNewFuncs(default_n + 3, modulus_len - 3); - - rv = testModExp(default_n, 0, buf, buf2, modulus_len); - dumpBytes((unsigned char *)buf2, modulus_len); - - rv = testModExp(default_n, 1, buf, buf2, modulus_len); - dumpBytes((unsigned char *)buf2, modulus_len); - - rv = testModExp(default_n, 2, buf, buf2, modulus_len); - dumpBytes((unsigned char *)buf2, modulus_len); - - rv = testModExp(default_n, 3, buf, buf2, modulus_len); - dumpBytes((unsigned char *)buf2, modulus_len); - } - rv = doModExp(default_n, default_d, buf, buf2, modulus_len); - if (rv != 0) { - fprintf(stderr, "Error in modexp operation:\n"); - exit(1); - } - dumpBytes((unsigned char *)buf2, modulus_len); - - timeCtx = CreateTimingContext(); - TimingBegin(timeCtx); - i = iters; - while (i--) { - rv = doModExp(default_n, default_d, buf, buf2, modulus_len); - if (rv != 0) { - fprintf(stderr, "Error in modexp operation\n"); - exit(1); - } - } - TimingEnd(timeCtx); - printf("%ld iterations in %s\n", iters, TimingGenerateString(timeCtx)); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/mpcpucache.c b/security/nss/lib/freebl/mpi/mpcpucache.c index 6fed35239..336b4cc55 100644 --- a/security/nss/lib/freebl/mpi/mpcpucache.c +++ b/security/nss/lib/freebl/mpi/mpcpucache.c @@ -17,7 +17,7 @@ * * Currently the file returns good data for most modern x86 processors, and * reasonable data on 64-bit ppc processors. All other processors are assumed - * to have a cache line size of 32 bytes unless modified by target.mk. + * to have a cache line size of 32 bytes. * */ @@ -775,18 +775,6 @@ s_mpi_getProcessorLineSize() * */ -/* target.mk can define MPI_CACHE_LINE_SIZE if it's common for the family or - * OS */ -#if defined(MPI_CACHE_LINE_SIZE) && !defined(MPI_GET_PROCESSOR_LINE_SIZE_DEFINED) - -unsigned long -s_mpi_getProcessorLineSize() -{ - return MPI_CACHE_LINE_SIZE; -} -#define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1 -#endif - /* If no way to get the processor cache line size has been defined, assume * it's 32 bytes (most common value, does not significantly impact performance) */ @@ -797,12 +785,3 @@ s_mpi_getProcessorLineSize() return 32; } #endif - -#ifdef TEST_IT -#include <stdio.h> - -main() -{ - printf("line size = %d\n", s_mpi_getProcessorLineSize()); -} -#endif diff --git a/security/nss/lib/freebl/mpi/mpi-config.h b/security/nss/lib/freebl/mpi/mpi-config.h index f365592a4..c6f72b206 100644 --- a/security/nss/lib/freebl/mpi/mpi-config.h +++ b/security/nss/lib/freebl/mpi/mpi-config.h @@ -24,10 +24,6 @@ #define MP_MODARITH 1 /* include modular arithmetic ? */ #endif -#ifndef MP_NUMTH -#define MP_NUMTH 1 /* include number theoretic functions? */ -#endif - #ifndef MP_LOGTAB #define MP_LOGTAB 1 /* use table of logs instead of log()? */ #endif diff --git a/security/nss/lib/freebl/mpi/mpi.c b/security/nss/lib/freebl/mpi/mpi.c index f6f75439c..f7784c8d9 100644 --- a/security/nss/lib/freebl/mpi/mpi.c +++ b/security/nss/lib/freebl/mpi/mpi.c @@ -1695,7 +1695,6 @@ mp_iseven(const mp_int *a) /*------------------------------------------------------------------------*/ /* {{{ Number theoretic functions */ -#if MP_NUMTH /* {{{ mp_gcd(a, b, c) */ /* @@ -2376,7 +2375,6 @@ mp_invmod(const mp_int *a, const mp_int *m, mp_int *c) } /* end mp_invmod() */ /* }}} */ -#endif /* if MP_NUMTH */ /* }}} */ @@ -2861,6 +2859,9 @@ void s_mp_exch(mp_int *a, mp_int *b) { mp_int tmp; + if (!a || !b) { + return; + } tmp = *a; *a = *b; @@ -4088,7 +4089,7 @@ s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps) } #endif -#if (defined(MP_NO_MP_WORD) || defined(MP_NO_DIV_WORD)) && !defined(MP_ASSEMBLY_DIV_2DX1D) +#if !defined(MP_ASSEMBLY_DIV_2DX1D) /* ** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized ** so its high bit is 1. This code is from NSPR. @@ -4166,11 +4167,7 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ mp_int *quot) /* i: 0; o: quotient */ { mp_int part, t; -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD) - mp_word q_msd; -#else mp_digit q_msd; -#endif mp_err res; mp_digit d; mp_digit div_msd; @@ -4215,7 +4212,7 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ MP_USED(&part) = MP_USED(div); /* We have now truncated the part of the remainder to the same length as - * the divisor. If part is smaller than div, extend part by one digit. */ + * the divisor. If part is smaller than div, extend part by one digit. */ if (s_mp_cmp(&part, div) < 0) { --unusedRem; #if MP_ARGCHK == 2 @@ -4232,18 +4229,12 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ div_msd = MP_DIGIT(div, MP_USED(div) - 1); if (!partExtended) { /* In this case, q_msd /= div_msd is always 1. First, since div_msd is - * normalized to have the high bit set, 2*div_msd > MP_DIGIT_MAX. Since - * we didn't extend part, q_msd >= div_msd. Therefore we know that - * div_msd <= q_msd <= MP_DIGIT_MAX < 2*div_msd. Dividing by div_msd we - * get 1 <= q_msd/div_msd < 2. So q_msd /= div_msd must be 1. */ + * normalized to have the high bit set, 2*div_msd > MP_DIGIT_MAX. Since + * we didn't extend part, q_msd >= div_msd. Therefore we know that + * div_msd <= q_msd <= MP_DIGIT_MAX < 2*div_msd. Dividing by div_msd we + * get 1 <= q_msd/div_msd < 2. So q_msd /= div_msd must be 1. */ q_msd = 1; } else { -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD) - q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2); - q_msd /= div_msd; - if (q_msd == RADIX) - --q_msd; -#else if (q_msd == div_msd) { q_msd = MP_DIGIT_MAX; } else { @@ -4251,7 +4242,6 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ MP_CHECKOK(s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2), div_msd, &q_msd, &r)); } -#endif } #if MP_ARGCHK == 2 assert(q_msd > 0); /* This case should never occur any more. */ @@ -4261,15 +4251,15 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ /* See what that multiplies out to */ mp_copy(div, &t); - MP_CHECKOK(s_mp_mul_d(&t, (mp_digit)q_msd)); + MP_CHECKOK(s_mp_mul_d(&t, q_msd)); /* - If it's too big, back it off. We should not have to do this - more than once, or, in rare cases, twice. Knuth describes a - method by which this could be reduced to a maximum of once, but - I didn't implement that here. - * When using s_mpv_div_2dx1d, we may have to do this 3 times. - */ + If it's too big, back it off. We should not have to do this + more than once, or, in rare cases, twice. Knuth describes a + method by which this could be reduced to a maximum of once, but + I didn't implement that here. + When using s_mpv_div_2dx1d, we may have to do this 3 times. + */ for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) { --q_msd; MP_CHECKOK(s_mp_sub(&t, div)); /* t -= div */ @@ -4284,11 +4274,11 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ s_mp_clamp(rem); /* - Include the digit in the quotient. We allocated enough memory - for any quotient we could ever possibly get, so we should not - have to check for failures here - */ - MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd; + Include the digit in the quotient. We allocated enough memory + for any quotient we could ever possibly get, so we should not + have to check for failures here + */ + MP_DIGIT(quot, unusedRem) = q_msd; } /* Denormalize remainder */ diff --git a/security/nss/lib/freebl/mpi/mpi.h b/security/nss/lib/freebl/mpi/mpi.h index 64ffe75d5..97af0f069 100644 --- a/security/nss/lib/freebl/mpi/mpi.h +++ b/security/nss/lib/freebl/mpi/mpi.h @@ -225,13 +225,11 @@ int mp_isodd(const mp_int *a); int mp_iseven(const mp_int *a); /* Number theoretic */ -#if MP_NUMTH mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c); mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c); mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y); mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c); mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c); -#endif /* end MP_NUMTH */ /* Input and output */ #if MP_IOFUNC diff --git a/security/nss/lib/freebl/mpi/mpmontg.c b/security/nss/lib/freebl/mpi/mpmontg.c index 06fd41b3a..3acdc9fef 100644 --- a/security/nss/lib/freebl/mpi/mpmontg.c +++ b/security/nss/lib/freebl/mpi/mpmontg.c @@ -205,7 +205,11 @@ mp_exptmod_f(const mp_int *montBase, dTmpSize = 2 * oddPowSize; dSize = sizeof(double) * (nLen * 4 + 1 + ((odd_ints + 1) * oddPowSize) + dTmpSize); - dBuf = (double *)malloc(dSize); + dBuf = malloc(dSize); + if (!dBuf) { + res = MP_MEM; + goto CLEANUP; + } dm1 = dBuf; /* array of d32 */ dn = dBuf + nLen; /* array of d32 */ dSqr = dn + nLen; /* array of d32 */ diff --git a/security/nss/lib/freebl/mpi/mpprime.c b/security/nss/lib/freebl/mpi/mpprime.c index 58287192e..9d6232c29 100644 --- a/security/nss/lib/freebl/mpi/mpprime.c +++ b/security/nss/lib/freebl/mpi/mpprime.c @@ -402,8 +402,7 @@ mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes, #define SIEVE_SIZE 32 * 1024 mp_err -mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong, - unsigned long *nTries) +mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong) { mp_digit np; mp_err res; @@ -548,8 +547,6 @@ mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong, CLEANUP: mp_clear(&trial); mp_clear(&q); - if (nTries) - *nTries += i; if (sieve != NULL) { memset(sieve, 0, SIEVE_SIZE); free(sieve); diff --git a/security/nss/lib/freebl/mpi/mpprime.h b/security/nss/lib/freebl/mpi/mpprime.h index c47c61836..acd888d4a 100644 --- a/security/nss/lib/freebl/mpi/mpprime.h +++ b/security/nss/lib/freebl/mpi/mpprime.h @@ -13,6 +13,8 @@ #include "mpi.h" +SEC_BEGIN_PROTOS + extern const int prime_tab_size; /* number of primes available */ extern const mp_digit prime_tab[]; @@ -32,7 +34,8 @@ mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes); mp_err mpp_pprime(mp_int *a, int nt); mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes, unsigned char *sieve, mp_size nSieve); -mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong, - unsigned long *nTries); +mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong); + +SEC_END_PROTOS #endif /* end _H_MP_PRIME_ */ diff --git a/security/nss/lib/freebl/mpi/multest b/security/nss/lib/freebl/mpi/multest deleted file mode 100755 index 24752e019..000000000 --- a/security/nss/lib/freebl/mpi/multest +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/sh -# -# multest -# -# Run multiply and square timing tests, to compute a chart for the -# current processor and compiler combination. - -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -ECHO=/bin/echo -MAKE=gmake - -$ECHO "\n** Running multiply and square timing tests\n" - -$ECHO "Bringing 'mulsqr' up to date ... " -if $MAKE mulsqr ; then - : -else - $ECHO "\nMake failed to build mulsqr.\n" - exit 1 -fi - -if [ ! -x ./mulsqr ] ; then - $ECHO "\nCannot find 'mulsqr' program, testing cannot continue.\n" - exit 1 -fi - -sizes='64 128 192 256 320 384 448 512 640 768 896 1024 1536 2048' -ntests=500000 - -$ECHO "Running timing tests, please wait ... " - -trap 'echo "oop!";rm -f tt*.tmp;exit 0' INT HUP - -touch tt$$.tmp -$ECHO $ntests tests >> tt$$.tmp -for size in $sizes ; do - $ECHO "$size bits ... \c" - set -A res `./mulsqr $ntests $size|head -3|tr -d '%'|awk '{print $2}'` - $ECHO $size"\t"${res[0]}"\t"${res[1]}"\t"${res[2]} >> tt$$.tmp - $ECHO "(done)" -done -mv tt$$.tmp mulsqr-results.txt -rm -f tt$$.tmp - -$ECHO "\n** Running Karatsuba-Ofman multiplication tests\n" - -$ECHO "Brining 'karatsuba' up to date ... " -if $MAKE karatsuba ; then - : -else - $ECHO "\nMake failed to build karatsuba.\n" - exit 1 -fi - -if [ ! -x ./karatsuba ] ; then - $ECHO "\nCannot find 'karatsuba' program, testing cannot continue.\n" - exit 1 -fi - -ntests=100000 - -trap 'echo "oop!";rm -f tt*.tmp;exit 0' INT HUP - -touch tt$$.tmp -for size in $sizes ; do - $ECHO "$size bits ... " - ./karatsuba $ntests $size >> tt$$.tmp - tail -2 tt$$.tmp -done -mv tt$$.tmp karatsuba-results.txt -rm -f tt$$.tmp - -exit 0 diff --git a/security/nss/lib/freebl/mpi/stats b/security/nss/lib/freebl/mpi/stats deleted file mode 100755 index a5deb94c0..000000000 --- a/security/nss/lib/freebl/mpi/stats +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/perl - -# -# Treat each line as a sequence of comma and/or space delimited -# floating point numbers, and compute basic statistics on them. -# These are written to standard output - -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -$min = 1.7976931348623157E+308; -$max = 2.2250738585072014E-308; -$sum = $num = 0; - -while(<>) { - chomp; - - @nums = split(/[\s,]+/, $_); - next if($#nums < 0); - - $num += scalar @nums; - foreach (@nums) { - $min = $_ if($_ < $min); - $max = $_ if($_ > $max); - $sum += $_; - } -} - -if($num) { - $avg = $sum / $num; -} else { - $min = $max = 0; -} - -printf "%d\tmin=%.2f, avg=%.2f, max=%.2f, sum=%.2f\n", - $num, $min, $avg, $max, $sum; - -# end diff --git a/security/nss/lib/freebl/mpi/target.mk b/security/nss/lib/freebl/mpi/target.mk deleted file mode 100644 index dd74564b1..000000000 --- a/security/nss/lib/freebl/mpi/target.mk +++ /dev/null @@ -1,233 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -## -## Define CFLAGS to contain any local options your compiler -## setup requires. -## -## Conditional compilation options are no longer here; see -## the file 'mpi-config.h' instead. -## -MPICMN = -I. -DMP_API_COMPATIBLE -DMP_IOFUNC -CFLAGS= -O $(MPICMN) -#CFLAGS=-ansi -fullwarn -woff 1521 -O3 $(MPICMN) -#CFLAGS=-ansi -pedantic -Wall -O3 $(MPICMN) -#CFLAGS=-ansi -pedantic -Wall -g -O2 -DMP_DEBUG=1 $(MPICMN) - -ifeq ($(TARGET),mipsIRIX) -#IRIX -#MPICMN += -DMP_MONT_USE_MP_MUL -MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -MPICMN += -DMP_USE_UINT_DIGIT -#MPICMN += -DMP_NO_MP_WORD -AS_OBJS = mpi_mips.o -#ASFLAGS = -O -OPT:Olimit=4000 -dollar -fullwarn -xansi -n32 -mips3 -exceptions -ASFLAGS = -O -OPT:Olimit=4000 -dollar -fullwarn -xansi -n32 -mips3 -#CFLAGS=-ansi -n32 -O3 -fullwarn -woff 1429 -D_SGI_SOURCE $(MPICMN) -CFLAGS=-ansi -n32 -O2 -fullwarn -woff 1429 -D_SGI_SOURCE $(MPICMN) -#CFLAGS=-ansi -n32 -g -fullwarn -woff 1429 -D_SGI_SOURCE $(MPICMN) -#CFLAGS=-ansi -64 -O2 -fullwarn -woff 1429 -D_SGI_SOURCE -DMP_NO_MP_WORD \ - $(MPICMN) -endif - -ifeq ($(TARGET),alphaOSF1) -#Alpha/OSF1 -MPICMN += -DMP_ASSEMBLY_MULTIPLY -AS_OBJS+= mpvalpha.o -#CFLAGS= -O -Olimit 4000 -ieee_with_inexact -std1 -DOSF1 -D_REENTRANT $(MPICMN) -CFLAGS= -O -Olimit 4000 -ieee_with_inexact -std1 -DOSF1 -D_REENTRANT \ - -DMP_NO_MP_WORD $(MPICMN) -endif - -ifeq ($(TARGET),v9SOLARIS) -#Solaris 64 -SOLARIS_FPU_FLAGS = -fast -xO5 -xrestrict=%all -xchip=ultra -xarch=v9a -KPIC -mt -#SOLARIS_FPU_FLAGS = -fast -xO5 -xrestrict=%all -xdepend -xchip=ultra -xarch=v9a -KPIC -mt -SOLARIS_ASM_FLAGS = -xchip=ultra -xarch=v9a -KPIC -mt -AS_OBJS += montmulfv9.o -AS_OBJS += mpi_sparc.o mpv_sparcv9.o -MPICMN += -DMP_USE_UINT_DIGIT -#MPICMN += -DMP_NO_MP_WORD -MPICMN += -DMP_ASSEMBLY_MULTIPLY -MPICMN += -DMP_USING_MONT_MULF -CFLAGS= -O -KPIC -DSVR4 -DSYSV -D__svr4 -D__svr4__ -DSOLARIS -D_REENTRANT \ - -DSOLARIS2_8 -xarch=v9 -DXP_UNIX $(MPICMN) -#CFLAGS= -g -KPIC -DSVR4 -DSYSV -D__svr4 -D__svr4__ -DSOLARIS -D_REENTRANT \ - -DSOLARIS2_8 -xarch=v9 -DXP_UNIX $(MPICMN) -endif - -ifeq ($(TARGET),v8plusSOLARIS) -#Solaris 32 -SOLARIS_FPU_FLAGS = -fast -xO5 -xrestrict=%all -xdepend -xchip=ultra -xarch=v8plusa -KPIC -mt -SOLARIS_ASM_FLAGS = -xchip=ultra -xarch=v8plusa -KPIC -mt -AS_OBJS += montmulfv8.o -AS_OBJS += mpi_sparc.o mpv_sparcv8.o -#AS_OBJS = montmulf.o -MPICMN += -DMP_ASSEMBLY_MULTIPLY -MPICMN += -DMP_USING_MONT_MULF -MPICMN += -DMP_USE_UINT_DIGIT -MPICMN += -DMP_NO_MP_WORD -CFLAGS=-O -KPIC -DSVR4 -DSYSV -D__svr4 -D__svr4__ -DSOLARIS -D_REENTRANT \ - -DSOLARIS2_6 -xarch=v8plus -DXP_UNIX $(MPICMN) -endif - -ifeq ($(TARGET),v8SOLARIS) -#Solaris 32 -#SOLARIS_FPU_FLAGS = -fast -xO5 -xrestrict=%all -xdepend -xchip=ultra -xarch=v8 -KPIC -mt -#SOLARIS_ASM_FLAGS = -xchip=ultra -xarch=v8plusa -KPIC -mt -#AS_OBJS = montmulfv8.o mpi_sparc.o mpv_sparcv8.o -#AS_OBJS = montmulf.o -#MPICMN += -DMP_USING_MONT_MULF -#MPICMN += -DMP_ASSEMBLY_MULTIPLY -MPICMN += -DMP_USE_LONG_LONG_MULTIPLY -DMP_USE_UINT_DIGIT -MPICMN += -DMP_NO_MP_WORD -CFLAGS=-O -KPIC -DSVR4 -DSYSV -D__svr4 -D__svr4__ -DSOLARIS -D_REENTRANT \ - -DSOLARIS2_6 -xarch=v8 -DXP_UNIX $(MPICMN) -endif - -ifeq ($(TARGET),ia64HPUX) -#HPUX 32 on ia64 -- 64 bit digits SCREAM. -# This one is for DD32 which is the 32-bit ABI with 64-bit registers. -CFLAGS= +O3 -DHPUX10 -D_POSIX_C_SOURCE=199506L -Aa +Z -DHPUX -Dhppa \ - -D_HPUX_SOURCE -Aa +e -z +p +DD32 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN) -#CFLAGS= -O -DHPUX10 -D_POSIX_C_SOURCE=199506L -Aa +Z -DHPUX -Dhppa \ - -D_HPUX_SOURCE -Aa +e -z +p +DD32 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN) -#CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \ - -D_HPUX_SOURCE -Aa +e -z +p +DD32 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN) -endif - -ifeq ($(TARGET),ia64HPUX64) -#HPUX 32 on ia64 -# This one is for DD64 which is the 64-bit ABI -CFLAGS= +O3 -DHPUX10 -D_POSIX_C_SOURCE=199506L -Aa +Z -DHPUX -Dhppa \ - -D_HPUX_SOURCE -Aa +e -z +p +DD64 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN) -#CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \ - -D_HPUX_SOURCE -Aa +e -z +p +DD64 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN) -endif - -ifeq ($(TARGET),PA2.0WHPUX) -#HPUX64 (HP PA 2.0 Wide) using MAXPY and 64-bit digits -MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -AS_OBJS = mpi_hp.o hpma512.o hppa20.o -CFLAGS= -O -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \ - -D_HPUX_SOURCE -Aa +e -z +DA2.0W +DS2.0 +O3 +DChpux -DHPUX11 -DXP_UNIX \ - $(MPICMN) -#CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \ - -D_HPUX_SOURCE -Aa +e -z +DA2.0W +DS2.0 +DChpux -DHPUX11 -DXP_UNIX \ - $(MPICMN) -AS = $(CC) $(CFLAGS) -c -endif - -ifeq ($(TARGET),PA2.0NHPUX) -#HPUX32 (HP PA 2.0 Narrow) hybrid model, using 32-bit digits -# This one is for DA2.0 (N) which is the 32-bit ABI with 64-bit registers. -MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -AS_OBJS = mpi_hp.o hpma512.o hppa20.o -CFLAGS= +O3 -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \ - -D_HPUX_SOURCE -Aa +e -z +DA2.0 +DS2.0 +DChpux -DHPUX11 -DXP_UNIX \ - -Wl,+k $(MPICMN) -#CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \ - -D_HPUX_SOURCE -Aa +e -z +DA2.0 +DS2.0 +DChpux -DHPUX11 -DXP_UNIX \ - -Wl,+k $(MPICMN) -AS = $(CC) $(CFLAGS) -c -endif - -ifeq ($(TARGET),PA1.1HPUX) -#HPUX32 (HP PA 1.1) Pure 32 bit -MPICMN += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD -#MPICMN += -DMP_USE_LONG_LONG_MULTIPLY -CFLAGS= -O -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \ - -D_HPUX_SOURCE +DAportable +DS1.1 -DHPUX11 -DXP_UNIX $(MPICMN) -##CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \ -# -D_HPUX_SOURCE +DAportable +DS1.1 -DHPUX11 -DXP_UNIX $(MPICMN) -endif - -ifeq ($(TARGET),32AIX) -# -CC = xlC_r -MPICMN += -DMP_USE_UINT_DIGIT -MPICMN += -DMP_NO_DIV_WORD -#MPICMN += -DMP_NO_MUL_WORD -MPICMN += -DMP_NO_ADD_WORD -MPICMN += -DMP_NO_SUB_WORD -#MPICMN += -DMP_NO_MP_WORD -#MPICMN += -DMP_USE_LONG_LONG_MULTIPLY -CFLAGS = -O -DAIX -DSYSV -qarch=com -DAIX4_3 -DXP_UNIX -UDEBUG -DNDEBUG $(MPICMN) -#CFLAGS = -g -DAIX -DSYSV -qarch=com -DAIX4_3 -DXP_UNIX -UDEBUG -DNDEBUG $(MPICMN) -#CFLAGS += -pg -endif - -ifeq ($(TARGET),64AIX) -# -CC = xlC_r -MPICMN += -DMP_USE_UINT_DIGIT -CFLAGS = -O -O2 -DAIX -DSYSV -qarch=com -DAIX_64BIT -DAIX4_3 -DXP_UNIX -UDEBUG -DNDEBUG $(MPICMN) -OBJECT_MODE=64 -export OBJECT_MODE -endif - -ifeq ($(TARGET),x86LINUX) -#Linux -AS_OBJS = mpi_x86.o -MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D -MPICMN += -DMP_MONT_USE_MP_MUL -DMP_IS_LITTLE_ENDIAN -CFLAGS= -O2 -fPIC -DLINUX1_2 -Di386 -D_XOPEN_SOURCE -DLINUX2_1 -ansi -Wall \ - -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR \ - -DXP_UNIX -UDEBUG -DNDEBUG -D_REENTRANT $(MPICMN) -#CFLAGS= -g -fPIC -DLINUX1_2 -Di386 -D_XOPEN_SOURCE -DLINUX2_1 -ansi -Wall \ - -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR \ - -DXP_UNIX -DDEBUG -UNDEBUG -D_REENTRANT $(MPICMN) -#CFLAGS= -g -fPIC -DLINUX1_2 -Di386 -D_XOPEN_SOURCE -DLINUX2_1 -ansi -Wall \ - -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR \ - -DXP_UNIX -UDEBUG -DNDEBUG -D_REENTRANT $(MPICMN) -endif - -ifeq ($(TARGET),armLINUX) -MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -MPICMN += -DMP_USE_UINT_DIGIT -AS_OBJS += mpi_arm.o -endif - -ifeq ($(TARGET),AMD64SOLARIS) -ASFLAGS += -xarch=generic64 -AS_OBJS = mpi_amd64.o mpi_amd64_sun.o -MP_CONFIG = -DMP_ASSEMBLY_MULTIPLY -DMPI_AMD64 -MP_CONFIG += -DMP_IS_LITTLE_ENDIAN -CFLAGS = -xarch=generic64 -xO4 -I. -DMP_API_COMPATIBLE -DMP_IOFUNC $(MP_CONFIG) -MPICMN += $(MP_CONFIG) - -mpi_amd64_asm.o: mpi_amd64_sun.s - $(AS) -xarch=generic64 -P -D_ASM mpi_amd64_sun.s -endif - -ifeq ($(TARGET),WIN32) -ifeq ($(CPU_ARCH),x86_64) -AS_OBJS = mpi_amd64.obj mpi_amd64_masm.obj mp_comba_amd64_masm.asm -CFLAGS = -Od -Z7 -MDd -W3 -nologo -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USER) -CFLAGS += -DWIN32 -DWIN64 -D_WINDOWS -D_AMD_64_ -D_M_AMD64 -DWIN95 -DXP_PC -CFLAGS += $(MPICMN) - -$(AS_OBJS): %.obj : %.asm - ml64 -Cp -Sn -Zi -coff -nologo -c $< - -$(LIBOBJS): %.obj : %.c - cl $(CFLAGS) -Fo$@ -c $< -else -AS_OBJS = mpi_x86.obj -MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D -MPICMN += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD -DMP_API_COMPATIBLE -MPICMN += -DMP_MONT_USE_MP_MUL -MPICMN += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN -CFLAGS = -Od -Z7 -MDd -W3 -nologo -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USER) -CFLAGS += -DWIN32 -D_WINDOWS -D_X86_ -DWIN95 -DXP_PC -CFLAGS += $(MPICMN) - -$(AS_OBJS): %.obj : %.asm - ml -Cp -Sn -Zi -coff -nologo -c $< - -$(LIBOBJS): %.obj : %.c - cl $(CFLAGS) -Fo$@ -c $< - -endif -endif diff --git a/security/nss/lib/freebl/mpi/test-arrays.txt b/security/nss/lib/freebl/mpi/test-arrays.txt deleted file mode 100644 index 6c8908c1a..000000000 --- a/security/nss/lib/freebl/mpi/test-arrays.txt +++ /dev/null @@ -1,55 +0,0 @@ -# -# Test suite table for MPI library -# -# Format of entries: -# suite-name:function-name:description -# -# suite-name The name used to identify this test in mpi-test -# function-name The function called to perform this test in mpi-test.c -# description A brief description of what the suite tests - -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -list:test_list:print out a list of the available test suites -copy:test_copy:test assignment of mp-int structures -exchange:test_exch:test exchange of mp-int structures -zero:test_zero:test zeroing of an mp-int -set:test_set:test setting an mp-int to a small constant -absolute-value:test_abs:test the absolute value function -negate:test_neg:test the arithmetic negation function -add-digit:test_add_d:test digit addition -add:test_add:test full addition -subtract-digit:test_sub_d:test digit subtraction -subtract:test_sub:test full subtraction -multiply-digit:test_mul_d:test digit multiplication -multiply:test_mul:test full multiplication -square:test_sqr:test full squaring function -divide-digit:test_div_d:test digit division -divide-2:test_div_2:test division by two -divide-2d:test_div_2d:test division & remainder by 2^d -divide:test_div:test full division -expt-digit:test_expt_d:test digit exponentiation -expt:test_expt:test full exponentiation -expt-2:test_2expt:test power-of-two exponentiation -modulo-digit:test_mod_d:test digit modular reduction -modulo:test_mod:test full modular reduction -mod-add:test_addmod:test modular addition -mod-subtract:test_submod:test modular subtraction -mod-multiply:test_mulmod:test modular multiplication -mod-square:test_sqrmod:test modular squaring function -mod-expt:test_exptmod:test full modular exponentiation -mod-expt-digit:test_exptmod_d:test digit modular exponentiation -mod-inverse:test_invmod:test modular inverse function -compare-digit:test_cmp_d:test digit comparison function -compare-zero:test_cmp_z:test zero comparison function -compare:test_cmp:test general signed comparison -compare-magnitude:test_cmp_mag:test general magnitude comparison -parity:test_parity:test parity comparison functions -gcd:test_gcd:test greatest common divisor functions -lcm:test_lcm:test least common multiple function -conversion:test_convert:test general radix conversion facilities -binary:test_raw:test raw output format -pprime:test_pprime:test probabilistic primality tester -fermat:test_fermat:test Fermat pseudoprimality tester diff --git a/security/nss/lib/freebl/mpi/tests/LICENSE b/security/nss/lib/freebl/mpi/tests/LICENSE deleted file mode 100644 index c2c5d0190..000000000 --- a/security/nss/lib/freebl/mpi/tests/LICENSE +++ /dev/null @@ -1,6 +0,0 @@ -Within this directory, each of the file listed below is licensed under -the terms given in the file LICENSE-MPL, also in this directory. - -pi1k.txt -pi2k.txt -pi5k.txt diff --git a/security/nss/lib/freebl/mpi/tests/LICENSE-MPL b/security/nss/lib/freebl/mpi/tests/LICENSE-MPL deleted file mode 100644 index 41dc2327f..000000000 --- a/security/nss/lib/freebl/mpi/tests/LICENSE-MPL +++ /dev/null @@ -1,3 +0,0 @@ -This Source Code Form is subject to the terms of the Mozilla Public -License, v. 2.0. If a copy of the MPL was not distributed with this -file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/security/nss/lib/freebl/mpi/tests/mptest-1.c b/security/nss/lib/freebl/mpi/tests/mptest-1.c deleted file mode 100644 index 449134668..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-1.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Simple test driver for MPI library - * - * Test 1: Simple input test (drives single-digit multiply and add, - * as well as I/O routines) - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> - -#ifdef MAC_CW_SIOUX -#include <console.h> -#endif - -#include "mpi.h" - -int -main(int argc, char *argv[]) -{ - int ix; - mp_int mp; - -#ifdef MAC_CW_SIOUX - argc = ccommand(&argv); -#endif - - mp_init(&mp); - - for (ix = 1; ix < argc; ix++) { - mp_read_radix(&mp, argv[ix], 10); - mp_print(&mp, stdout); - fputc('\n', stdout); - } - - mp_clear(&mp); - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/mptest-2.c b/security/nss/lib/freebl/mpi/tests/mptest-2.c deleted file mode 100644 index 1505e6afd..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-2.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Simple test driver for MPI library - * - * Test 2: Basic addition and subtraction test - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> - -#include "mpi.h" - -int -main(int argc, char *argv[]) -{ - mp_int a, b, c; - - if (argc < 3) { - fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); - return 1; - } - - printf("Test 2: Basic addition and subtraction\n\n"); - - mp_init(&a); - mp_init(&b); - - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&b, argv[2], 10); - printf("a = "); - mp_print(&a, stdout); - fputc('\n', stdout); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - - mp_init(&c); - printf("c = a + b\n"); - - mp_add(&a, &b, &c); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - printf("c = a - b\n"); - - mp_sub(&a, &b, &c); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - mp_clear(&c); - mp_clear(&b); - mp_clear(&a); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/mptest-3.c b/security/nss/lib/freebl/mpi/tests/mptest-3.c deleted file mode 100644 index 86fb24654..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-3.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Simple test driver for MPI library - * - * Test 3: Multiplication, division, and exponentiation test - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> - -#include <time.h> - -#include "mpi.h" - -#define EXPT 0 /* define nonzero to get exponentiate test */ - -int -main(int argc, char *argv[]) -{ - int ix; - mp_int a, b, c, d; - mp_digit r; - mp_err res; - - if (argc < 3) { - fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); - return 1; - } - - printf("Test 3: Multiplication and division\n\n"); - srand(time(NULL)); - - mp_init(&a); - mp_init(&b); - - mp_read_variable_radix(&a, argv[1], 10); - mp_read_variable_radix(&b, argv[2], 10); - printf("a = "); - mp_print(&a, stdout); - fputc('\n', stdout); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - - mp_init(&c); - printf("\nc = a * b\n"); - - mp_mul(&a, &b, &c); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - printf("\nc = b * 32523\n"); - - mp_mul_d(&b, 32523, &c); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - mp_init(&d); - printf("\nc = a / b, d = a mod b\n"); - - mp_div(&a, &b, &c, &d); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - printf("d = "); - mp_print(&d, stdout); - fputc('\n', stdout); - - ix = rand() % 256; - printf("\nc = a / %d, r = a mod %d\n", ix, ix); - mp_div_d(&a, (mp_digit)ix, &c, &r); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - printf("r = %04X\n", r); - -#if EXPT - printf("\nc = a ** b\n"); - mp_expt(&a, &b, &c); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); -#endif - - ix = rand() % 256; - printf("\nc = 2^%d\n", ix); - mp_2expt(&c, ix); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - mp_clear(&d); - mp_clear(&c); - mp_clear(&b); - mp_clear(&a); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/mptest-3a.c b/security/nss/lib/freebl/mpi/tests/mptest-3a.c deleted file mode 100644 index c6cea7046..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-3a.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Simple test driver for MPI library - * - * Test 3a: Multiplication vs. squaring timing test - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> - -#include <time.h> - -#include "mpi.h" -#include "mpprime.h" - -int -main(int argc, char *argv[]) -{ - int ix, num, prec = 8; - double d1, d2; - clock_t start, finish; - time_t seed; - mp_int a, c, d; - - seed = time(NULL); - - if (argc < 2) { - fprintf(stderr, "Usage: %s <num-tests> [<precision>]\n", argv[0]); - return 1; - } - - if ((num = atoi(argv[1])) < 0) - num = -num; - - if (!num) { - fprintf(stderr, "%s: must perform at least 1 test\n", argv[0]); - return 1; - } - - if (argc > 2) { - if ((prec = atoi(argv[2])) <= 0) - prec = 8; - else - prec = (prec + (DIGIT_BIT - 1)) / DIGIT_BIT; - } - - printf("Test 3a: Multiplication vs squaring timing test\n" - "Precision: %d digits (%u bits)\n" - "# of tests: %d\n\n", - prec, prec * DIGIT_BIT, num); - - mp_init_size(&a, prec); - - mp_init(&c); - mp_init(&d); - - printf("Verifying accuracy ... \n"); - srand((unsigned int)seed); - for (ix = 0; ix < num; ix++) { - mpp_random_size(&a, prec); - mp_mul(&a, &a, &c); - mp_sqr(&a, &d); - - if (mp_cmp(&c, &d) != 0) { - printf("Error! Results not accurate:\n"); - printf("a = "); - mp_print(&a, stdout); - fputc('\n', stdout); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - printf("d = "); - mp_print(&d, stdout); - fputc('\n', stdout); - mp_sub(&c, &d, &d); - printf("dif "); - mp_print(&d, stdout); - fputc('\n', stdout); - mp_clear(&c); - mp_clear(&d); - mp_clear(&a); - return 1; - } - } - printf("Accuracy is confirmed for the %d test samples\n", num); - mp_clear(&d); - - printf("Testing squaring ... \n"); - srand((unsigned int)seed); - start = clock(); - for (ix = 0; ix < num; ix++) { - mpp_random_size(&a, prec); - mp_sqr(&a, &c); - } - finish = clock(); - - d2 = (double)(finish - start) / CLOCKS_PER_SEC; - - printf("Testing multiplication ... \n"); - srand((unsigned int)seed); - start = clock(); - for (ix = 0; ix < num; ix++) { - mpp_random(&a); - mp_mul(&a, &a, &c); - } - finish = clock(); - - d1 = (double)(finish - start) / CLOCKS_PER_SEC; - - printf("Multiplication time: %.3f sec (%.3f each)\n", d1, d1 / num); - printf("Squaring time: %.3f sec (%.3f each)\n", d2, d2 / num); - printf("Improvement: %.2f%%\n", (1.0 - (d2 / d1)) * 100.0); - - mp_clear(&c); - mp_clear(&a); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/mptest-4.c b/security/nss/lib/freebl/mpi/tests/mptest-4.c deleted file mode 100644 index 0f326ac2c..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-4.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Simple test driver for MPI library - * - * Test 4: Modular arithmetic tests - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> - -#include "mpi.h" - -int -main(int argc, char *argv[]) -{ - int ix; - mp_int a, b, c, m; - mp_digit r; - - if (argc < 4) { - fprintf(stderr, "Usage: %s <a> <b> <m>\n", argv[0]); - return 1; - } - - printf("Test 4: Modular arithmetic\n\n"); - - mp_init(&a); - mp_init(&b); - mp_init(&m); - - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&b, argv[2], 10); - mp_read_radix(&m, argv[3], 10); - printf("a = "); - mp_print(&a, stdout); - fputc('\n', stdout); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - printf("m = "); - mp_print(&m, stdout); - fputc('\n', stdout); - - mp_init(&c); - printf("\nc = a (mod m)\n"); - - mp_mod(&a, &m, &c); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - printf("\nc = b (mod m)\n"); - - mp_mod(&b, &m, &c); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - printf("\nc = b (mod 1853)\n"); - - mp_mod_d(&b, 1853, &r); - printf("c = %04X\n", r); - - printf("\nc = (a + b) mod m\n"); - - mp_addmod(&a, &b, &m, &c); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - printf("\nc = (a - b) mod m\n"); - - mp_submod(&a, &b, &m, &c); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - printf("\nc = (a * b) mod m\n"); - - mp_mulmod(&a, &b, &m, &c); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - printf("\nc = (a ** b) mod m\n"); - - mp_exptmod(&a, &b, &m, &c); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - printf("\nIn-place modular squaring test:\n"); - for (ix = 0; ix < 5; ix++) { - printf("a = (a * a) mod m a = "); - mp_sqrmod(&a, &m, &a); - mp_print(&a, stdout); - fputc('\n', stdout); - } - - mp_clear(&c); - mp_clear(&m); - mp_clear(&b); - mp_clear(&a); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/mptest-4a.c b/security/nss/lib/freebl/mpi/tests/mptest-4a.c deleted file mode 100644 index 0c8e18872..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-4a.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * mptest4a - modular exponentiation speed test - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <time.h> - -#include <sys/time.h> - -#include "mpi.h" -#include "mpprime.h" - -typedef struct { - unsigned int sec; - unsigned int usec; -} instant_t; - -instant_t -now(void) -{ - struct timeval clk; - instant_t res; - - res.sec = res.usec = 0; - - if (gettimeofday(&clk, NULL) != 0) - return res; - - res.sec = clk.tv_sec; - res.usec = clk.tv_usec; - - return res; -} - -extern mp_err s_mp_pad(); - -int -main(int argc, char *argv[]) -{ - int ix, num, prec = 8; - unsigned int d; - instant_t start, finish; - time_t seed; - mp_int a, m, c; - - seed = time(NULL); - - if (argc < 2) { - fprintf(stderr, "Usage: %s <num-tests> [<precision>]\n", argv[0]); - return 1; - } - - if ((num = atoi(argv[1])) < 0) - num = -num; - - if (!num) { - fprintf(stderr, "%s: must perform at least 1 test\n", argv[0]); - return 1; - } - - if (argc > 2) { - if ((prec = atoi(argv[2])) <= 0) - prec = 8; - } - - printf("Test 3a: Modular exponentiation timing test\n" - "Precision: %d digits (%d bits)\n" - "# of tests: %d\n\n", - prec, prec * DIGIT_BIT, num); - - mp_init_size(&a, prec); - mp_init_size(&m, prec); - mp_init_size(&c, prec); - s_mp_pad(&a, prec); - s_mp_pad(&m, prec); - s_mp_pad(&c, prec); - - printf("Testing modular exponentiation ... \n"); - srand((unsigned int)seed); - - start = now(); - for (ix = 0; ix < num; ix++) { - mpp_random(&a); - mpp_random(&c); - mpp_random(&m); - mp_exptmod(&a, &c, &m, &c); - } - finish = now(); - - d = (finish.sec - start.sec) * 1000000; - d -= start.usec; - d += finish.usec; - - printf("Total time elapsed: %u usec\n", d); - printf("Time per exponentiation: %u usec (%.3f sec)\n", - (d / num), (double)(d / num) / 1000000); - - mp_clear(&c); - mp_clear(&a); - mp_clear(&m); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/mptest-4b.c b/security/nss/lib/freebl/mpi/tests/mptest-4b.c deleted file mode 100644 index 1bb2f911f..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-4b.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * mptest-4b.c - * - * Test speed of a large modular exponentiation of a primitive element - * modulo a prime. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <time.h> - -#include <sys/time.h> - -#include "mpi.h" -#include "mpprime.h" - -char *g_prime = - "34BD53C07350E817CCD49721020F1754527959C421C1533244769D4CF060A8B1C3DA" - "25094BE723FB1E2369B55FEEBBE0FAC16425161BF82684062B5EC5D7D47D1B23C117" - "0FA19745E44A55E148314E582EB813AC9EE5126295E2E380CACC2F6D206B293E5ED9" - "23B54EE961A8C69CD625CE4EC38B70C649D7F014432AEF3A1C93"; -char *g_gen = "5"; - -typedef struct { - unsigned int sec; - unsigned int usec; -} instant_t; - -instant_t -now(void) -{ - struct timeval clk; - instant_t res; - - res.sec = res.usec = 0; - - if (gettimeofday(&clk, NULL) != 0) - return res; - - res.sec = clk.tv_sec; - res.usec = clk.tv_usec; - - return res; -} - -extern mp_err s_mp_pad(); - -int -main(int argc, char *argv[]) -{ - instant_t start, finish; - mp_int prime, gen, expt, res; - unsigned int ix, diff; - int num; - - srand(time(NULL)); - - if (argc < 2) { - fprintf(stderr, "Usage: %s <num-tests>\n", argv[0]); - return 1; - } - - if ((num = atoi(argv[1])) < 0) - num = -num; - - if (num == 0) - ++num; - - mp_init(&prime); - mp_init(&gen); - mp_init(&res); - mp_read_radix(&prime, g_prime, 16); - mp_read_radix(&gen, g_gen, 16); - - mp_init_size(&expt, USED(&prime) - 1); - s_mp_pad(&expt, USED(&prime) - 1); - - printf("Testing %d modular exponentations ... \n", num); - - start = now(); - for (ix = 0; ix < num; ix++) { - mpp_random(&expt); - mp_exptmod(&gen, &expt, &prime, &res); - } - finish = now(); - - diff = (finish.sec - start.sec) * 1000000; - diff += finish.usec; - diff -= start.usec; - - printf("%d operations took %u usec (%.3f sec)\n", - num, diff, (double)diff / 1000000.0); - printf("That is %.3f sec per operation.\n", - ((double)diff / 1000000.0) / num); - - mp_clear(&expt); - mp_clear(&res); - mp_clear(&gen); - mp_clear(&prime); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/mptest-5.c b/security/nss/lib/freebl/mpi/tests/mptest-5.c deleted file mode 100644 index dff3ed470..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-5.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Simple test driver for MPI library - * - * Test 5: Other number theoretic functions - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> - -#include "mpi.h" - -int -main(int argc, char *argv[]) -{ - mp_int a, b, c, x, y; - - if (argc < 3) { - fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); - return 1; - } - - printf("Test 5: Number theoretic functions\n\n"); - - mp_init(&a); - mp_init(&b); - - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&b, argv[2], 10); - - printf("a = "); - mp_print(&a, stdout); - fputc('\n', stdout); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - - mp_init(&c); - printf("\nc = (a, b)\n"); - - mp_gcd(&a, &b, &c); - printf("Euclid: c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - /* - mp_bgcd(&a, &b, &c); - printf("Binary: c = "); mp_print(&c, stdout); fputc('\n', stdout); - */ - mp_init(&x); - mp_init(&y); - printf("\nc = (a, b) = ax + by\n"); - - mp_xgcd(&a, &b, &c, &x, &y); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - printf("x = "); - mp_print(&x, stdout); - fputc('\n', stdout); - printf("y = "); - mp_print(&y, stdout); - fputc('\n', stdout); - - printf("\nc = a^-1 (mod b)\n"); - if (mp_invmod(&a, &b, &c) == MP_UNDEF) { - printf("a has no inverse mod b\n"); - } else { - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - } - - mp_clear(&y); - mp_clear(&x); - mp_clear(&c); - mp_clear(&b); - mp_clear(&a); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/mptest-5a.c b/security/nss/lib/freebl/mpi/tests/mptest-5a.c deleted file mode 100644 index c410a6a84..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-5a.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Simple test driver for MPI library - * - * Test 5a: Greatest common divisor speed test, binary vs. Euclid - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> -#include <time.h> - -#include <sys/time.h> - -#include "mpi.h" -#include "mpprime.h" - -typedef struct { - unsigned int sec; - unsigned int usec; -} instant_t; - -instant_t -now(void) -{ - struct timeval clk; - instant_t res; - - res.sec = res.usec = 0; - - if (gettimeofday(&clk, NULL) != 0) - return res; - - res.sec = clk.tv_sec; - res.usec = clk.tv_usec; - - return res; -} - -#define PRECISION 16 - -int -main(int argc, char *argv[]) -{ - int ix, num, prec = PRECISION; - mp_int a, b, c, d; - instant_t start, finish; - time_t seed; - unsigned int d1, d2; - - seed = time(NULL); - - if (argc < 2) { - fprintf(stderr, "Usage: %s <num-tests>\n", argv[0]); - return 1; - } - - if ((num = atoi(argv[1])) < 0) - num = -num; - - printf("Test 5a: Euclid vs. Binary, a GCD speed test\n\n" - "Number of tests: %d\n" - "Precision: %d digits\n\n", - num, prec); - - mp_init_size(&a, prec); - mp_init_size(&b, prec); - mp_init(&c); - mp_init(&d); - - printf("Verifying accuracy ... \n"); - srand((unsigned int)seed); - for (ix = 0; ix < num; ix++) { - mpp_random_size(&a, prec); - mpp_random_size(&b, prec); - - mp_gcd(&a, &b, &c); - mp_bgcd(&a, &b, &d); - - if (mp_cmp(&c, &d) != 0) { - printf("Error! Results not accurate:\n"); - printf("a = "); - mp_print(&a, stdout); - fputc('\n', stdout); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - printf("d = "); - mp_print(&d, stdout); - fputc('\n', stdout); - - mp_clear(&a); - mp_clear(&b); - mp_clear(&c); - mp_clear(&d); - return 1; - } - } - mp_clear(&d); - printf("Accuracy confirmed for the %d test samples\n", num); - - printf("Testing Euclid ... \n"); - srand((unsigned int)seed); - start = now(); - for (ix = 0; ix < num; ix++) { - mpp_random_size(&a, prec); - mpp_random_size(&b, prec); - mp_gcd(&a, &b, &c); - } - finish = now(); - - d1 = (finish.sec - start.sec) * 1000000; - d1 -= start.usec; - d1 += finish.usec; - - printf("Testing binary ... \n"); - srand((unsigned int)seed); - start = now(); - for (ix = 0; ix < num; ix++) { - mpp_random_size(&a, prec); - mpp_random_size(&b, prec); - mp_bgcd(&a, &b, &c); - } - finish = now(); - - d2 = (finish.sec - start.sec) * 1000000; - d2 -= start.usec; - d2 += finish.usec; - - printf("Euclidean algorithm time: %u usec\n", d1); - printf("Binary algorithm time: %u usec\n", d2); - printf("Improvement: %.2f%%\n", - (1.0 - ((double)d2 / (double)d1)) * 100.0); - - mp_clear(&c); - mp_clear(&b); - mp_clear(&a); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/mptest-6.c b/security/nss/lib/freebl/mpi/tests/mptest-6.c deleted file mode 100644 index 4febf39c5..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-6.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Simple test driver for MPI library - * - * Test 6: Output functions - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> - -#include "mpi.h" - -void -print_buf(FILE *ofp, char *buf, int len) -{ - int ix, brk = 0; - - for (ix = 0; ix < len; ix++) { - fprintf(ofp, "%02X ", buf[ix]); - - brk = (brk + 1) & 0xF; - if (!brk) - fputc('\n', ofp); - } - - if (brk) - fputc('\n', ofp); -} - -int -main(int argc, char *argv[]) -{ - int ix, size; - mp_int a; - char *buf; - - if (argc < 2) { - fprintf(stderr, "Usage: %s <a>\n", argv[0]); - return 1; - } - - printf("Test 6: Output functions\n\n"); - - mp_init(&a); - - mp_read_radix(&a, argv[1], 10); - - printf("\nConverting to a string:\n"); - - printf("Rx Size Representation\n"); - for (ix = 2; ix <= MAX_RADIX; ix++) { - size = mp_radix_size(&a, ix); - - buf = calloc(size, sizeof(char)); - mp_toradix(&a, buf, ix); - printf("%2d: %3d: %s\n", ix, size, buf); - free(buf); - } - - printf("\nRaw output:\n"); - size = mp_raw_size(&a); - buf = calloc(size, sizeof(char)); - - printf("Size: %d bytes\n", size); - - mp_toraw(&a, buf); - print_buf(stdout, buf, size); - free(buf); - - mp_clear(&a); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/mptest-7.c b/security/nss/lib/freebl/mpi/tests/mptest-7.c deleted file mode 100644 index 1e83fbf96..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-7.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Simple test driver for MPI library - * - * Test 7: Random and divisibility tests - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> -#include <time.h> - -#define MP_IOFUNC 1 -#include "mpi.h" - -#include "mpprime.h" - -int -main(int argc, char *argv[]) -{ - mp_digit num; - mp_int a, b; - - srand(time(NULL)); - - if (argc < 3) { - fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); - return 1; - } - - printf("Test 7: Random & divisibility tests\n\n"); - - mp_init(&a); - mp_init(&b); - - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&b, argv[2], 10); - - printf("a = "); - mp_print(&a, stdout); - fputc('\n', stdout); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - - if (mpp_divis(&a, &b) == MP_YES) - printf("a is divisible by b\n"); - else - printf("a is not divisible by b\n"); - - if (mpp_divis(&b, &a) == MP_YES) - printf("b is divisible by a\n"); - else - printf("b is not divisible by a\n"); - - printf("\nb = mpp_random()\n"); - mpp_random(&b); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - mpp_random(&b); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - mpp_random(&b); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - - printf("\nTesting a for divisibility by first 170 primes\n"); - num = 170; - if (mpp_divis_primes(&a, &num) == MP_YES) - printf("It is divisible by at least one of them\n"); - else - printf("It is not divisible by any of them\n"); - - mp_clear(&b); - mp_clear(&a); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/mptest-8.c b/security/nss/lib/freebl/mpi/tests/mptest-8.c deleted file mode 100644 index a9d3afff9..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-8.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Simple test driver for MPI library - * - * Test 8: Probabilistic primality tester - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> -#include <time.h> - -#define MP_IOFUNC 1 -#include "mpi.h" - -#include "mpprime.h" - -int -main(int argc, char *argv[]) -{ - int ix; - mp_digit num; - mp_int a; - - srand(time(NULL)); - - if (argc < 2) { - fprintf(stderr, "Usage: %s <a>\n", argv[0]); - return 1; - } - - printf("Test 8: Probabilistic primality testing\n\n"); - - mp_init(&a); - - mp_read_radix(&a, argv[1], 10); - - printf("a = "); - mp_print(&a, stdout); - fputc('\n', stdout); - - printf("\nChecking for divisibility by small primes ... \n"); - num = 170; - if (mpp_divis_primes(&a, &num) == MP_YES) { - printf("it is not prime\n"); - goto CLEANUP; - } - printf("Passed that test (not divisible by any small primes).\n"); - - for (ix = 0; ix < 10; ix++) { - printf("\nPerforming Rabin-Miller test, iteration %d\n", ix + 1); - - if (mpp_pprime(&a, 5) == MP_NO) { - printf("it is not prime\n"); - goto CLEANUP; - } - } - printf("All tests passed; a is probably prime\n"); - -CLEANUP: - mp_clear(&a); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/mptest-9.c b/security/nss/lib/freebl/mpi/tests/mptest-9.c deleted file mode 100644 index 133264e89..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-9.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * mptest-9.c - * - * Test logical functions - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> -#include <time.h> - -#include "mpi.h" -#include "mplogic.h" - -int -main(int argc, char *argv[]) -{ - mp_int a, b, c; - int pco; - mp_err res; - - printf("Test 9: Logical functions\n\n"); - - if (argc < 3) { - fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]); - return 1; - } - - mp_init(&a); - mp_init(&b); - mp_init(&c); - mp_read_radix(&a, argv[1], 16); - mp_read_radix(&b, argv[2], 16); - - printf("a = "); - mp_print(&a, stdout); - fputc('\n', stdout); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - - mpl_not(&a, &c); - printf("~a = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - mpl_and(&a, &b, &c); - printf("a & b = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - mpl_or(&a, &b, &c); - printf("a | b = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - mpl_xor(&a, &b, &c); - printf("a ^ b = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - mpl_rsh(&a, &c, 1); - printf("a >> 1 = "); - mp_print(&c, stdout); - fputc('\n', stdout); - mpl_rsh(&a, &c, 5); - printf("a >> 5 = "); - mp_print(&c, stdout); - fputc('\n', stdout); - mpl_rsh(&a, &c, 16); - printf("a >> 16 = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - mpl_lsh(&a, &c, 1); - printf("a << 1 = "); - mp_print(&c, stdout); - fputc('\n', stdout); - mpl_lsh(&a, &c, 5); - printf("a << 5 = "); - mp_print(&c, stdout); - fputc('\n', stdout); - mpl_lsh(&a, &c, 16); - printf("a << 16 = "); - mp_print(&c, stdout); - fputc('\n', stdout); - - mpl_num_set(&a, &pco); - printf("population(a) = %d\n", pco); - mpl_num_set(&b, &pco); - printf("population(b) = %d\n", pco); - - res = mpl_parity(&a); - if (res == MP_EVEN) - printf("a has even parity\n"); - else - printf("a has odd parity\n"); - - mp_clear(&c); - mp_clear(&b); - mp_clear(&a); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/mptest-b.c b/security/nss/lib/freebl/mpi/tests/mptest-b.c deleted file mode 100644 index 07f30eaf8..000000000 --- a/security/nss/lib/freebl/mpi/tests/mptest-b.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Simple test driver for MPI library - * - * Test GF2m: Binary Polynomial Arithmetic - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> - -#include "mp_gf2m.h" - -int -main(int argc, char *argv[]) -{ - int ix; - mp_int pp, a, b, x, y, order; - mp_int c, d, e; - mp_digit r; - mp_err res; - unsigned int p[] = { 163, 7, 6, 3, 0 }; - unsigned int ptemp[10]; - - printf("Test b: Binary Polynomial Arithmetic\n\n"); - - mp_init(&pp); - mp_init(&a); - mp_init(&b); - mp_init(&x); - mp_init(&y); - mp_init(&order); - - mp_read_radix(&pp, "0800000000000000000000000000000000000000C9", 16); - mp_read_radix(&a, "1", 16); - mp_read_radix(&b, "020A601907B8C953CA1481EB10512F78744A3205FD", 16); - mp_read_radix(&x, "03F0EBA16286A2D57EA0991168D4994637E8343E36", 16); - mp_read_radix(&y, "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", 16); - mp_read_radix(&order, "040000000000000000000292FE77E70C12A4234C33", 16); - printf("pp = "); - mp_print(&pp, stdout); - fputc('\n', stdout); - printf("a = "); - mp_print(&a, stdout); - fputc('\n', stdout); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - printf("x = "); - mp_print(&x, stdout); - fputc('\n', stdout); - printf("y = "); - mp_print(&y, stdout); - fputc('\n', stdout); - printf("order = "); - mp_print(&order, stdout); - fputc('\n', stdout); - - mp_init(&c); - mp_init(&d); - mp_init(&e); - - /* Test polynomial conversion */ - ix = mp_bpoly2arr(&pp, ptemp, 10); - if ( - (ix != 5) || - (ptemp[0] != p[0]) || - (ptemp[1] != p[1]) || - (ptemp[2] != p[2]) || - (ptemp[3] != p[3]) || - (ptemp[4] != p[4])) { - printf("Polynomial to array conversion not correct\n"); - return -1; - } - - printf("Polynomial conversion test #1 successful.\n"); - MP_CHECKOK(mp_barr2poly(p, &c)); - if (mp_cmp(&pp, &c) != 0) { - printf("Array to polynomial conversion not correct\n"); - return -1; - } - printf("Polynomial conversion test #2 successful.\n"); - - /* Test addition */ - MP_CHECKOK(mp_badd(&a, &a, &c)); - if (mp_cmp_z(&c) != 0) { - printf("a+a should equal zero\n"); - return -1; - } - printf("Addition test #1 successful.\n"); - MP_CHECKOK(mp_badd(&a, &b, &c)); - MP_CHECKOK(mp_badd(&b, &c, &c)); - if (mp_cmp(&c, &a) != 0) { - printf("c = (a + b) + b should equal a\n"); - printf("a = "); - mp_print(&a, stdout); - fputc('\n', stdout); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - return -1; - } - printf("Addition test #2 successful.\n"); - - /* Test multiplication */ - mp_set(&c, 2); - MP_CHECKOK(mp_bmul(&b, &c, &c)); - MP_CHECKOK(mp_badd(&b, &c, &c)); - mp_set(&d, 3); - MP_CHECKOK(mp_bmul(&b, &d, &d)); - if (mp_cmp(&c, &d) != 0) { - printf("c = (2 * b) + b should equal c = 3 * b\n"); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - printf("d = "); - mp_print(&d, stdout); - fputc('\n', stdout); - return -1; - } - printf("Multiplication test #1 successful.\n"); - - /* Test modular reduction */ - MP_CHECKOK(mp_bmod(&b, p, &c)); - if (mp_cmp(&b, &c) != 0) { - printf("c = b mod p should equal b\n"); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - return -1; - } - printf("Modular reduction test #1 successful.\n"); - MP_CHECKOK(mp_badd(&b, &pp, &c)); - MP_CHECKOK(mp_bmod(&c, p, &c)); - if (mp_cmp(&b, &c) != 0) { - printf("c = (b + p) mod p should equal b\n"); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - return -1; - } - printf("Modular reduction test #2 successful.\n"); - MP_CHECKOK(mp_bmul(&b, &pp, &c)); - MP_CHECKOK(mp_bmod(&c, p, &c)); - if (mp_cmp_z(&c) != 0) { - printf("c = (b * p) mod p should equal 0\n"); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - return -1; - } - printf("Modular reduction test #3 successful.\n"); - - /* Test modular multiplication */ - MP_CHECKOK(mp_bmulmod(&b, &pp, p, &c)); - if (mp_cmp_z(&c) != 0) { - printf("c = (b * p) mod p should equal 0\n"); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - return -1; - } - printf("Modular multiplication test #1 successful.\n"); - mp_set(&c, 1); - MP_CHECKOK(mp_badd(&pp, &c, &c)); - MP_CHECKOK(mp_bmulmod(&b, &c, p, &c)); - if (mp_cmp(&b, &c) != 0) { - printf("c = (b * (p + 1)) mod p should equal b\n"); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - return -1; - } - printf("Modular multiplication test #2 successful.\n"); - - /* Test modular squaring */ - MP_CHECKOK(mp_copy(&b, &c)); - MP_CHECKOK(mp_bmulmod(&b, &c, p, &c)); - MP_CHECKOK(mp_bsqrmod(&b, p, &d)); - if (mp_cmp(&c, &d) != 0) { - printf("c = (b * b) mod p should equal d = b^2 mod p\n"); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - printf("d = "); - mp_print(&d, stdout); - fputc('\n', stdout); - return -1; - } - printf("Modular squaring test #1 successful.\n"); - - /* Test modular division */ - MP_CHECKOK(mp_bdivmod(&b, &x, &pp, p, &c)); - MP_CHECKOK(mp_bmulmod(&c, &x, p, &c)); - if (mp_cmp(&b, &c) != 0) { - printf("c = (b / x) * x mod p should equal b\n"); - printf("b = "); - mp_print(&b, stdout); - fputc('\n', stdout); - printf("c = "); - mp_print(&c, stdout); - fputc('\n', stdout); - return -1; - } - printf("Modular division test #1 successful.\n"); - -CLEANUP: - - mp_clear(&order); - mp_clear(&y); - mp_clear(&x); - mp_clear(&b); - mp_clear(&a); - mp_clear(&pp); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/tests/pi1k.txt b/security/nss/lib/freebl/mpi/tests/pi1k.txt deleted file mode 100644 index 5ff6209ff..000000000 --- a/security/nss/lib/freebl/mpi/tests/pi1k.txt +++ /dev/null @@ -1 +0,0 @@ -31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989 diff --git a/security/nss/lib/freebl/mpi/tests/pi2k.txt b/security/nss/lib/freebl/mpi/tests/pi2k.txt deleted file mode 100644 index 9ce82acd1..000000000 --- a/security/nss/lib/freebl/mpi/tests/pi2k.txt +++ /dev/null @@ -1 +0,0 @@ -314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783744944825537977472684710404753464620804668425906949129331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992458631503028618297455570674983850549458858692699569092721079750930295532116534498720275596023648066549911988183479775356636980742654252786255181841757467289097777279380008164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179049460165346680498862723279178608578438382796797668145410095388378636095068006422512520511739298489608412848862694560424196528502221066118630674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759010 diff --git a/security/nss/lib/freebl/mpi/tests/pi5k.txt b/security/nss/lib/freebl/mpi/tests/pi5k.txt deleted file mode 100644 index 901fac2ea..000000000 --- a/security/nss/lib/freebl/mpi/tests/pi5k.txt +++ /dev/null @@ -1 +0,0 @@ -314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783744944825537977472684710404753464620804668425906949129331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992458631503028618297455570674983850549458858692699569092721079750930295532116534498720275596023648066549911988183479775356636980742654252786255181841757467289097777279380008164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179049460165346680498862723279178608578438382796797668145410095388378636095068006422512520511739298489608412848862694560424196528502221066118630674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759009946576407895126946839835259570982582262052248940772671947826848260147699090264013639443745530506820349625245174939965143142980919065925093722169646151570985838741059788595977297549893016175392846813826868386894277415599185592524595395943104997252468084598727364469584865383673622262609912460805124388439045124413654976278079771569143599770012961608944169486855584840635342207222582848864815845602850601684273945226746767889525213852254995466672782398645659611635488623057745649803559363456817432411251507606947945109659609402522887971089314566913686722874894056010150330861792868092087476091782493858900971490967598526136554978189312978482168299894872265880485756401427047755513237964145152374623436454285844479526586782105114135473573952311342716610213596953623144295248493718711014576540359027993440374200731057853906219838744780847848968332144571386875194350643021845319104848100537061468067491927819119793995206141966342875444064374512371819217999839101591956181467514269123974894090718649423196156794520809514655022523160388193014209376213785595663893778708303906979207734672218256259966150142150306803844773454920260541466592520149744285073251866600213243408819071048633173464965145390579626856100550810665879699816357473638405257145910289706414011097120628043903975951567715770042033786993600723055876317635942187312514712053292819182618612586732157919841484882916447060957527069572209175671167229109816909152801735067127485832228718352093539657251210835791513698820914442100675103346711031412671113699086585163983150197016515116851714376576183515565088490998985998238734552833163550764791853589322618548963213293308985706420467525907091548141654985946163718027098199430992448895757128289059232332609729971208443357326548938239119325974636673058360414281388303203824903758985243744170291327656180937734440307074692112019130203303801976211011004492932151608424448596376698389522868478312355265821314495768572624334418930396864262434107732269780280731891544110104468232527162010526522721116603966655730925471105578537634668206531098965269186205647693125705863566201855810072936065987648611791045334885034611365768675324944166803962657978771855608455296541266540853061434443185867697514566140680070023787765913440171274947042056223053899456131407112700040785473326993908145466464588079727082668306343285878569830523580893306575740679545716377525420211495576158140025012622859413021647155097925923099079654737612551765675135751782966645477917450112996148903046399471329621073404375189573596145890193897131117904297828564750320319869151402870808599048010941214722131794764777262241425485454033215718530614228813758504306332175182979866223717215916077166925474873898665494945011465406284336639379003976926567214638530673609657120918076383271664162748888007869256029022847210403172118608204190004229661711963779213375751149595015660496318629472654736425230817703675159067350235072835405670403867435136222247715891504953098444893330963408780769325993978054193414473774418426312986080998886874132604721 diff --git a/security/nss/lib/freebl/mpi/timetest b/security/nss/lib/freebl/mpi/timetest deleted file mode 100755 index c6f07bb30..000000000 --- a/security/nss/lib/freebl/mpi/timetest +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/sh - -# Simple timing test for the MPI library. Basically, we use prime -# generation as a timing test, since it exercises most of the pathways -# of the library fairly heavily. The 'primegen' tool outputs a line -# summarizing timing results. We gather these and process them for -# statistical information, which is collected into a file. - -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Avoid using built-in shell echoes -ECHO=/bin/echo -MAKE=gmake -PERL=perl - -# Use a fixed seed so timings will be more consistent -# This one is the 11th-18th decimal digits of 'e' -#export SEED=45904523 -SEED=45904523; export SEED - -#------------------------------------------------------------------------ - -$ECHO "\n** Running timing tests for MPI library\n" - -$ECHO "Bringing 'metime' up to date ... " -if $MAKE metime ; then - : -else - $ECHO "\nMake failed to build metime.\n" - exit 1 -fi - -if [ ! -x ./metime ] ; then - $ECHO "\nCannot find 'metime' program, testing cannot continue.\n" - exit 1 -fi - -#------------------------------------------------------------------------ - -$ECHO "Bringing 'primegen' up to date ... " -if $MAKE primegen ; then - : -else - $ECHO "\nMake failed to build primegen.\n" - exit 1 -fi - -if [ ! -x ./primegen ] ; then - $ECHO "\nCannot find 'primegen' program, testing cannot continue.\n" - exit 1 -fi - -#------------------------------------------------------------------------ - -rm -f timing-results.txt -touch timing-results.txt - -sizes="256 512 1024 2048" -ntests=10 - -trap 'echo "oop!";rm -f tt*.tmp timing-results.txt;exit 0' INT HUP - -$ECHO "\n-- Modular exponentiation\n" -$ECHO "Modular exponentiation:" >> timing-results.txt - -$ECHO "Running $ntests modular exponentiations per test:" -for size in $sizes ; do - $ECHO "- Gathering statistics for $size bits ... " - secs=`./metime $ntests $size | tail -1 | awk '{print $2}'` - $ECHO "$size: " $secs " seconds per op" >> timing-results.txt - tail -1 timing-results.txt -done - -$ECHO "<done>"; - -sizes="256 512 1024" -ntests=1 - -$ECHO "\n-- Prime generation\n" -$ECHO "Prime generation:" >> timing-results.txt - -$ECHO "Generating $ntests prime values per test:" -for size in $sizes ; do - $ECHO "- Gathering statistics for $size bits ... " - ./primegen $size $ntests | grep ticks | awk '{print $7}' | tr -d '(' > tt$$.tmp - $ECHO "$size:" >> timing-results.txt - $PERL stats tt$$.tmp >> timing-results.txt - tail -1 timing-results.txt - rm -f tt$$.tmp -done - -$ECHO "<done>" - -trap 'rm -f tt*.tmp timing-results.txt' INT HUP - -exit 0 - diff --git a/security/nss/lib/freebl/mpi/types.pl b/security/nss/lib/freebl/mpi/types.pl deleted file mode 100755 index c5f38afa5..000000000 --- a/security/nss/lib/freebl/mpi/types.pl +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/perl - -# -# types.pl - find recommended type definitions for digits and words -# -# This script scans the Makefile for the C compiler and compilation -# flags currently in use, and using this combination, attempts to -# compile a simple test program that outputs the sizes of the various -# unsigned integer types, in bytes. Armed with these, it finds all -# the "viable" type combinations for mp_digit and mp_word, where -# viability is defined by the requirement that mp_word be at least two -# times the precision of mp_digit. -# -# Of these, the one with the largest digit size is chosen, and -# appropriate typedef statements are written to standard output. - -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -@_=split(/\//,$0);chomp($prog=pop(@_)); - -# The array of integer types to be considered... -@TYPES = ( - "unsigned char", - "unsigned short", - "unsigned int", - "unsigned long" -); - -# Macro names for the maximum unsigned value of each type -%TMAX = ( - "unsigned char" => "UCHAR_MAX", - "unsigned short" => "USHRT_MAX", - "unsigned int" => "UINT_MAX", - "unsigned long" => "ULONG_MAX" -); - -# Read the Makefile to find out which C compiler to use -open(MFP, "<Makefile") or die "$prog: Makefile: $!\n"; -while(<MFP>) { - chomp; - if(/^CC=(.*)$/) { - $cc = $1; - last if $cflags; - } elsif(/^CFLAGS=(.*)$/) { - $cflags = $1; - last if $cc; - } -} -close(MFP); - -# If we couldn't find that, use 'cc' by default -$cc = "cc" unless $cc; - -printf STDERR "Using '%s' as the C compiler.\n", $cc; - -print STDERR "Determining type sizes ... \n"; -open(OFP, ">tc$$.c") or die "$prog: tc$$.c: $!\n"; -print OFP "#include <stdio.h>\n\nint main(void)\n{\n"; -foreach $type (@TYPES) { - printf OFP "\tprintf(\"%%d\\n\", (int)sizeof(%s));\n", $type; -} -print OFP "\n\treturn 0;\n}\n"; -close(OFP); - -system("$cc $cflags -o tc$$ tc$$.c"); - -die "$prog: unable to build test program\n" unless(-x "tc$$"); - -open(IFP, "./tc$$|") or die "$prog: can't execute test program\n"; -$ix = 0; -while(<IFP>) { - chomp; - $size{$TYPES[$ix++]} = $_; -} -close(IFP); - -unlink("tc$$"); -unlink("tc$$.c"); - -print STDERR "Selecting viable combinations ... \n"; -while(($type, $size) = each(%size)) { - push(@ts, [ $size, $type ]); -} - -# Sort them ascending by size -@ts = sort { $a->[0] <=> $b->[0] } @ts; - -# Try all possible combinations, finding pairs in which the word size -# is twice the digit size. The number of possible pairs is too small -# to bother doing this more efficiently than by brute force -for($ix = 0; $ix <= $#ts; $ix++) { - $w = $ts[$ix]; - - for($jx = 0; $jx <= $#ts; $jx++) { - $d = $ts[$jx]; - - if($w->[0] == 2 * $d->[0]) { - push(@valid, [ $d, $w ]); - } - } -} - -# Sort descending by digit size -@valid = sort { $b->[0]->[0] <=> $a->[0]->[0] } @valid; - -# Select the maximum as the recommended combination -$rec = shift(@valid); - -printf("typedef %-18s mp_sign;\n", "char"); -printf("typedef %-18s mp_digit; /* %d byte type */\n", - $rec->[0]->[1], $rec->[0]->[0]); -printf("typedef %-18s mp_word; /* %d byte type */\n", - $rec->[1]->[1], $rec->[1]->[0]); -printf("typedef %-18s mp_size;\n", "unsigned int"); -printf("typedef %-18s mp_err;\n\n", "int"); - -printf("#define %-18s (CHAR_BIT*sizeof(mp_digit))\n", "DIGIT_BIT"); -printf("#define %-18s %s\n", "DIGIT_MAX", $TMAX{$rec->[0]->[1]}); -printf("#define %-18s (CHAR_BIT*sizeof(mp_word))\n", "MP_WORD_BIT"); -printf("#define %-18s %s\n\n", "MP_WORD_MAX", $TMAX{$rec->[1]->[1]}); -printf("#define %-18s (DIGIT_MAX+1)\n\n", "RADIX"); - -printf("#define %-18s \"%%0%dX\"\n", "DIGIT_FMT", (2 * $rec->[0]->[0])); - -exit 0; diff --git a/security/nss/lib/freebl/mpi/utils/LICENSE b/security/nss/lib/freebl/mpi/utils/LICENSE deleted file mode 100644 index 5f96df7ab..000000000 --- a/security/nss/lib/freebl/mpi/utils/LICENSE +++ /dev/null @@ -1,4 +0,0 @@ -Within this directory, each of the file listed below is licensed under -the terms given in the file LICENSE-MPL, also in this directory. - -PRIMES diff --git a/security/nss/lib/freebl/mpi/utils/LICENSE-MPL b/security/nss/lib/freebl/mpi/utils/LICENSE-MPL deleted file mode 100644 index 41dc2327f..000000000 --- a/security/nss/lib/freebl/mpi/utils/LICENSE-MPL +++ /dev/null @@ -1,3 +0,0 @@ -This Source Code Form is subject to the terms of the Mozilla Public -License, v. 2.0. If a copy of the MPL was not distributed with this -file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/security/nss/lib/freebl/mpi/utils/PRIMES b/security/nss/lib/freebl/mpi/utils/PRIMES deleted file mode 100644 index ed65703ff..000000000 --- a/security/nss/lib/freebl/mpi/utils/PRIMES +++ /dev/null @@ -1,41 +0,0 @@ -Probable primes (sorted by number of significant bits) - - 128: 81386202757205669562183851789305348631 - - 128: 180241813863264101444573802809858694397 - - 128: 245274683055224433281596312431122059021 - - 128: 187522309397665259809392608791686659539 - - 256: 83252422946206411852330647237287722547866360773229941071371588246436\ - 513990159 - - 256: 79132571131322331023736933767063051273085304521895229780914612117520\ - 058517909 - - 256: 72081815425552909748220041100909735706208853818662000557743644603407\ - 965465527 - - 256: 87504602391905701494845474079163412737334477797316409702279059573654\ - 274811271 - - 512: 12233064210800062190450937494718705259777386009095453001870729392786\ - 63450255179083524798507997690270500580265258111668148238355016411719\ - 9168737693316468563 - - 512: 12003639081420725322369909586347545220275253633035565716386136197501\ - 88208318984400479275215620499883521216480724155582768193682335576385\ - 2069481074929084063 - -1024: 16467877625718912296741904171202513097057724053648819680815842057593\ - 20371835940722471475475803725455063836431454757000451907612224427007\ - 63984592414360595161051906727075047683803534852982766542661204179549\ - 77327573530800542562611753617736693359790119074768292178493884576587\ - 0230450429880021317876149636714743053 - -1024: 16602953991090311275234291158294516471009930684624948451178742895360\ - 86073703307475884280944414508444679430090561246728195735962931545473\ - 40743240318558456247740186704660778277799687988031119436541068736925\ - 20563780233711166724859277827382391527748470939542560819625727876091\ - 5372193745283891895989104479029844957 diff --git a/security/nss/lib/freebl/mpi/utils/README b/security/nss/lib/freebl/mpi/utils/README deleted file mode 100644 index 61c8e2efa..000000000 --- a/security/nss/lib/freebl/mpi/utils/README +++ /dev/null @@ -1,206 +0,0 @@ -This Source Code Form is subject to the terms of the Mozilla Public -License, v. 2.0. If a copy of the MPL was not distributed with this -file, You can obtain one at http://mozilla.org/MPL/2.0/. - -Additional MPI utilities ------------------------- - -The files 'mpprime.h' and 'mpprime.c' define some useful extensions to -the MPI library for dealing with prime numbers (in particular, testing -for divisbility, and the Rabin-Miller probabilistic primality test). - -The files 'mplogic.h' and 'mplogic.c' define extensions to the MPI -library for doing bitwise logical operations and shifting. - -This document assumes you have read the help file for the MPI library -and understand its conventions. - -Divisibility (mpprime.h) ------------- - -To test a number for divisibility by another number: - -mpp_divis(a, b) - test if b|a -mpp_divis_d(a, d) - test if d|a - -Each of these functions returns MP_YES if its initial argument is -divisible by its second, or MP_NO if it is not. Other errors may be -returned as appropriate (such as MP_RANGE if you try to test for -divisibility by zero). - -Randomness (mpprime.h) ----------- - -To generate random data: - -mpp_random(a) - fill a with random data -mpp_random_size(a, p) - fill a with p digits of random data - -The mpp_random_size() function increases the precision of a to at -least p, then fills all those digits randomly. The mp_random() -function fills a to its current precision (as determined by the number -of significant digits, USED(a)) - -Note that these functions simply use the C library's rand() function -to fill a with random digits up to its precision. This should be -adequate for primality testing, but should not be used for -cryptographic applications where truly random values are required for -security. - -You should call srand() in your driver program in order to seed the -random generator; this function doesn't call it. - -Primality Testing (mpprime.h) ------------------ - -mpp_divis_vector(a, v, s, w) - is a divisible by any of the s values - in v, and if so, w = which. -mpp_divis_primes(a, np) - is a divisible by any of the first np primes? -mpp_fermat(a, w) - is a pseudoprime with respect to witness w? -mpp_pprime(a, nt) - run nt iterations of Rabin-Miller on a. - -The mpp_divis_vector() function tests a for divisibility by each -member of an array of digits. The array is v, the size of that array -is s. Returns MP_YES if a is divisible, and stores the index of the -offending digit in w. Returns MP_NO if a is not divisible by any of -the digits in the array. - -A small table of primes is compiled into the library (typically the -first 128 primes, although you can change this by editing the file -'primes.c' before you build). The global variable prime_tab_size -contains the number of primes in the table, and the values themselves -are in the array prime_tab[], which is an array of mp_digit. - -The mpp_divis_primes() function is basically just a wrapper around -mpp_divis_vector() that uses prime_tab[] as the test vector. The np -parameter is a pointer to an mp_digit -- on input, it should specify -the number of primes to be tested against. If a is divisible by any -of the primes, MP_YES is returned and np is given the prime value that -divided a (you can use this if you're factoring, for example). -Otherwise, MP_NO is returned and np is untouched. - -The function mpp_fermat() performs Fermat's test, using w as a -witness. This test basically relies on the fact that if a is prime, -and w is relatively prime to a, then: - - w^a = w (mod a) - -That is, - - w^(a - 1) = 1 (mod a) - -The function returns MP_YES if the test passes, MP_NO if it fails. If -w is relatively prime to a, and the test fails, a is definitely -composite. If w is relatively prime to a and the test passes, then a -is either prime, or w is a false witness (the probability of this -happening depends on the choice of w and of a ... consult a number -theory textbook for more information about this). - -Note: If (w, a) != 1, the output of this test is meaningless. ----- - -The function mpp_pprime() performs the Rabin-Miller probabilistic -primality test for nt rounds. If all the tests pass, MP_YES is -returned, and a is probably prime. The probability that an answer of -MP_YES is incorrect is no greater than 1 in 4^nt, and in fact is -usually much less than that (this is a pessimistic estimate). If any -test fails, MP_NO is returned, and a is definitely composite. - -Bruce Schneier recommends at least 5 iterations of this test for most -cryptographic applications; Knuth suggests that 25 are reasonable. -Run it as many times as you feel are necessary. - -See the programs 'makeprime.c' and 'isprime.c' for reasonable examples -of how to use these functions for primality testing. - - -Bitwise Logic (mplogic.c) -------------- - -The four commonest logical operations are implemented as: - -mpl_not(a, b) - Compute bitwise (one's) complement, b = ~a - -mpl_and(a, b, c) - Compute bitwise AND, c = a & b - -mpl_or(a, b, c) - Compute bitwise OR, c = a | b - -mpl_xor(a, b, c) - Compute bitwise XOR, c = a ^ b - -Left and right shifts are available as well. These take a number to -shift, a destination, and a shift amount. The shift amount must be a -digit value between 0 and DIGIT_BIT inclusive; if it is not, MP_RANGE -will be returned and the shift will not happen. - -mpl_rsh(a, b, d) - Compute logical right shift, b = a >> d - -mpl_lsh(a, b, d) - Compute logical left shift, b = a << d - -Since these are logical shifts, they fill with zeroes (the library -uses a signed magnitude representation, so there are no sign bits to -extend anyway). - - -Command-line Utilities ----------------------- - -A handful of interesting command-line utilities are provided. These -are: - -lap.c - Find the order of a mod m. Usage is 'lap <a> <m>'. - This uses a dumb algorithm, so don't use it for - a really big modulus. - -invmod.c - Find the inverse of a mod m, if it exists. Usage - is 'invmod <a> <m>' - -sieve.c - A simple bitmap-based implementation of the Sieve - of Eratosthenes. Used to generate the table of - primes in primes.c. Usage is 'sieve <nbits>' - -prng.c - Uses the routines in bbs_rand.{h,c} to generate - one or more 32-bit pseudo-random integers. This - is mainly an example, not intended for use in a - cryptographic application (the system time is - the only source of entropy used) - -dec2hex.c - Convert decimal to hexadecimal - -hex2dec.c - Convert hexadecimal to decimal - -basecvt.c - General radix conversion tool (supports 2-64) - -isprime.c - Probabilistically test an integer for primality - using the Rabin-Miller pseudoprime test combined - with division by small primes. - -primegen.c - Generate primes at random. - -exptmod.c - Perform modular exponentiation - -ptab.pl - A Perl script to munge the output of the sieve - program into a compilable C structure. - - -Other Files ------------ - -PRIMES - Some randomly generated numbers which are prime with - extremely high probability. - -README - You're reading me already. - - -About the Author ----------------- - -This software was written by Michael J. Fromberger. You can contact -the author as follows: - -E-mail: <sting@linguist.dartmouth.edu> - -Postal: 8000 Cummings Hall, Thayer School of Engineering - Dartmouth College, Hanover, New Hampshire, USA - -PGP key: http://linguist.dartmouth.edu/~sting/keys/mjf.html - 9736 188B 5AFA 23D6 D6AA BE0D 5856 4525 289D 9907 diff --git a/security/nss/lib/freebl/mpi/utils/basecvt.c b/security/nss/lib/freebl/mpi/utils/basecvt.c deleted file mode 100644 index 0e9915406..000000000 --- a/security/nss/lib/freebl/mpi/utils/basecvt.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * basecvt.c - * - * Convert integer values specified on the command line from one input - * base to another. Accepts input and output bases between 2 and 36 - * inclusive. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "mpi.h" - -#define IBASE 10 -#define OBASE 16 -#define USAGE "Usage: %s ibase obase [value]\n" -#define MAXBASE 64 -#define MINBASE 2 - -int -main(int argc, char *argv[]) -{ - int ix, ibase = IBASE, obase = OBASE; - mp_int val; - - ix = 1; - if (ix < argc) { - ibase = atoi(argv[ix++]); - - if (ibase < MINBASE || ibase > MAXBASE) { - fprintf(stderr, "%s: input radix must be between %d and %d inclusive\n", - argv[0], MINBASE, MAXBASE); - return 1; - } - } - if (ix < argc) { - obase = atoi(argv[ix++]); - - if (obase < MINBASE || obase > MAXBASE) { - fprintf(stderr, "%s: output radix must be between %d and %d inclusive\n", - argv[0], MINBASE, MAXBASE); - return 1; - } - } - - mp_init(&val); - while (ix < argc) { - char *out; - int outlen; - - mp_read_radix(&val, argv[ix++], ibase); - - outlen = mp_radix_size(&val, obase); - out = calloc(outlen, sizeof(char)); - mp_toradix(&val, out, obase); - - printf("%s\n", out); - free(out); - } - - mp_clear(&val); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/utils/bbs_rand.c b/security/nss/lib/freebl/mpi/utils/bbs_rand.c deleted file mode 100644 index fed2fe2e6..000000000 --- a/security/nss/lib/freebl/mpi/utils/bbs_rand.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Blum, Blum & Shub PRNG using the MPI library - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "bbs_rand.h" - -#define SEED 1 -#define MODULUS 2 - -/* This modulus is the product of two randomly generated 512-bit - prime integers, each of which is congruent to 3 (mod 4). */ -static char *bbs_modulus = - "75A2A6E1D27393B86562B9CE7279A8403CB4258A637DAB5233465373E37837383EDC" - "332282B8575927BC4172CE8C147B4894050EE9D2BDEED355C121037270CA2570D127" - "7D2390CD1002263326635CC6B259148DE3A1A03201980A925E395E646A5E9164B0EC" - "28559EBA58C87447245ADD0651EDA507056A1129E3A3E16E903D64B437"; - -static int bbs_init = 0; /* flag set when library is initialized */ -static mp_int bbs_state; /* the current state of the generator */ - -/* Suggested size of random seed data */ -int bbs_seed_size = (sizeof(bbs_modulus) / 2); - -void -bbs_srand(unsigned char *data, int len) -{ - if ((bbs_init & SEED) == 0) { - mp_init(&bbs_state); - bbs_init |= SEED; - } - - mp_read_raw(&bbs_state, (char *)data, len); - -} /* end bbs_srand() */ - -unsigned int -bbs_rand(void) -{ - static mp_int modulus; - unsigned int result = 0, ix; - - if ((bbs_init & MODULUS) == 0) { - mp_init(&modulus); - mp_read_radix(&modulus, bbs_modulus, 16); - bbs_init |= MODULUS; - } - - for (ix = 0; ix < sizeof(unsigned int); ix++) { - mp_digit d; - - mp_sqrmod(&bbs_state, &modulus, &bbs_state); - d = DIGIT(&bbs_state, 0); - - result = (result << CHAR_BIT) | (d & UCHAR_MAX); - } - - return result; - -} /* end bbs_rand() */ - -/*------------------------------------------------------------------------*/ -/* HERE THERE BE DRAGONS */ diff --git a/security/nss/lib/freebl/mpi/utils/bbs_rand.h b/security/nss/lib/freebl/mpi/utils/bbs_rand.h deleted file mode 100644 index d12269bf9..000000000 --- a/security/nss/lib/freebl/mpi/utils/bbs_rand.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * bbs_rand.h - * - * Blum, Blum & Shub PRNG using the MPI library - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _H_BBSRAND_ -#define _H_BBSRAND_ - -#include <limits.h> -#include "mpi.h" - -#define BBS_RAND_MAX UINT_MAX - -/* Suggested length of seed data */ -extern int bbs_seed_size; - -void bbs_srand(unsigned char *data, int len); -unsigned int bbs_rand(void); - -#endif /* end _H_BBSRAND_ */ diff --git a/security/nss/lib/freebl/mpi/utils/bbsrand.c b/security/nss/lib/freebl/mpi/utils/bbsrand.c deleted file mode 100644 index d9151e005..000000000 --- a/security/nss/lib/freebl/mpi/utils/bbsrand.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * bbsrand.c - * - * Test driver for routines in bbs_rand.h - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <limits.h> - -#include "bbs_rand.h" - -#define NUM_TESTS 100 - -int -main(void) -{ - unsigned int seed, result, ix; - - seed = time(NULL); - bbs_srand((unsigned char *)&seed, sizeof(seed)); - - for (ix = 0; ix < NUM_TESTS; ix++) { - result = bbs_rand(); - - printf("Test %3u: %08X\n", ix + 1, result); - } - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/utils/dec2hex.c b/security/nss/lib/freebl/mpi/utils/dec2hex.c deleted file mode 100644 index ef3a52095..000000000 --- a/security/nss/lib/freebl/mpi/utils/dec2hex.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * dec2hex.c - * - * Convert decimal integers into hexadecimal - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "mpi.h" - -int -main(int argc, char *argv[]) -{ - mp_int a; - char *buf; - int len; - - if (argc < 2) { - fprintf(stderr, "Usage: %s <a>\n", argv[0]); - return 1; - } - - mp_init(&a); - mp_read_radix(&a, argv[1], 10); - len = mp_radix_size(&a, 16); - buf = malloc(len); - mp_toradix(&a, buf, 16); - - printf("%s\n", buf); - - free(buf); - mp_clear(&a); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/utils/exptmod.c b/security/nss/lib/freebl/mpi/utils/exptmod.c deleted file mode 100644 index 3ac9078f4..000000000 --- a/security/nss/lib/freebl/mpi/utils/exptmod.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * exptmod.c - * - * Command line tool to perform modular exponentiation on arbitrary - * precision integers. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "mpi.h" - -int -main(int argc, char *argv[]) -{ - mp_int a, b, m; - mp_err res; - char *str; - int len, rval = 0; - - if (argc < 3) { - fprintf(stderr, "Usage: %s <a> <b> <m>\n", argv[0]); - return 1; - } - - mp_init(&a); - mp_init(&b); - mp_init(&m); - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&b, argv[2], 10); - mp_read_radix(&m, argv[3], 10); - - if ((res = mp_exptmod(&a, &b, &m, &a)) != MP_OKAY) { - fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); - rval = 1; - } else { - len = mp_radix_size(&a, 10); - str = calloc(len, sizeof(char)); - mp_toradix(&a, str, 10); - - printf("%s\n", str); - - free(str); - } - - mp_clear(&a); - mp_clear(&b); - mp_clear(&m); - - return rval; -} diff --git a/security/nss/lib/freebl/mpi/utils/fact.c b/security/nss/lib/freebl/mpi/utils/fact.c deleted file mode 100644 index da8e61a32..000000000 --- a/security/nss/lib/freebl/mpi/utils/fact.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * fact.c - * - * Compute factorial of input integer - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "mpi.h" - -mp_err mp_fact(mp_int *a, mp_int *b); - -int -main(int argc, char *argv[]) -{ - mp_int a; - mp_err res; - - if (argc < 2) { - fprintf(stderr, "Usage: %s <number>\n", argv[0]); - return 1; - } - - mp_init(&a); - mp_read_radix(&a, argv[1], 10); - - if ((res = mp_fact(&a, &a)) != MP_OKAY) { - fprintf(stderr, "%s: error: %s\n", argv[0], - mp_strerror(res)); - mp_clear(&a); - return 1; - } - - { - char *buf; - int len; - - len = mp_radix_size(&a, 10); - buf = malloc(len); - mp_todecimal(&a, buf); - - puts(buf); - - free(buf); - } - - mp_clear(&a); - return 0; -} - -mp_err -mp_fact(mp_int *a, mp_int *b) -{ - mp_int ix, s; - mp_err res = MP_OKAY; - - if (mp_cmp_z(a) < 0) - return MP_UNDEF; - - mp_init(&s); - mp_add_d(&s, 1, &s); /* s = 1 */ - mp_init(&ix); - mp_add_d(&ix, 1, &ix); /* ix = 1 */ - - for (/* */; mp_cmp(&ix, a) <= 0; mp_add_d(&ix, 1, &ix)) { - if ((res = mp_mul(&s, &ix, &s)) != MP_OKAY) - break; - } - - mp_clear(&ix); - - /* Copy out results if we got them */ - if (res == MP_OKAY) - mp_copy(&s, b); - - mp_clear(&s); - - return res; -} diff --git a/security/nss/lib/freebl/mpi/utils/gcd.c b/security/nss/lib/freebl/mpi/utils/gcd.c deleted file mode 100644 index 9f11a250b..000000000 --- a/security/nss/lib/freebl/mpi/utils/gcd.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * gcd.c - * - * Greatest common divisor - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "mpi.h" - -char *g_prog = NULL; - -void print_mp_int(mp_int *mp, FILE *ofp); - -int -main(int argc, char *argv[]) -{ - mp_int a, b, x, y; - mp_err res; - int ext = 0; - - g_prog = argv[0]; - - if (argc < 3) { - fprintf(stderr, "Usage: %s <a> <b>\n", g_prog); - return 1; - } - - mp_init(&a); - mp_read_radix(&a, argv[1], 10); - mp_init(&b); - mp_read_radix(&b, argv[2], 10); - - /* If we were called 'xgcd', compute x, y so that g = ax + by */ - if (strcmp(g_prog, "xgcd") == 0) { - ext = 1; - mp_init(&x); - mp_init(&y); - } - - if (ext) { - if ((res = mp_xgcd(&a, &b, &a, &x, &y)) != MP_OKAY) { - fprintf(stderr, "%s: error: %s\n", g_prog, mp_strerror(res)); - mp_clear(&a); - mp_clear(&b); - mp_clear(&x); - mp_clear(&y); - return 1; - } - } else { - if ((res = mp_gcd(&a, &b, &a)) != MP_OKAY) { - fprintf(stderr, "%s: error: %s\n", g_prog, - mp_strerror(res)); - mp_clear(&a); - mp_clear(&b); - return 1; - } - } - - print_mp_int(&a, stdout); - if (ext) { - fputs("x = ", stdout); - print_mp_int(&x, stdout); - fputs("y = ", stdout); - print_mp_int(&y, stdout); - } - - mp_clear(&a); - mp_clear(&b); - - if (ext) { - mp_clear(&x); - mp_clear(&y); - } - - return 0; -} - -void -print_mp_int(mp_int *mp, FILE *ofp) -{ - char *buf; - int len; - - len = mp_radix_size(mp, 10); - buf = calloc(len, sizeof(char)); - mp_todecimal(mp, buf); - fprintf(ofp, "%s\n", buf); - free(buf); -} diff --git a/security/nss/lib/freebl/mpi/utils/hex2dec.c b/security/nss/lib/freebl/mpi/utils/hex2dec.c deleted file mode 100644 index 9b21d22e0..000000000 --- a/security/nss/lib/freebl/mpi/utils/hex2dec.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * hex2dec.c - * - * Convert decimal integers into hexadecimal - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "mpi.h" - -int -main(int argc, char *argv[]) -{ - mp_int a; - char *buf; - int len; - - if (argc < 2) { - fprintf(stderr, "Usage: %s <a>\n", argv[0]); - return 1; - } - - mp_init(&a); - mp_read_radix(&a, argv[1], 16); - len = mp_radix_size(&a, 10); - buf = malloc(len); - mp_toradix(&a, buf, 10); - - printf("%s\n", buf); - - free(buf); - mp_clear(&a); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/utils/identest.c b/security/nss/lib/freebl/mpi/utils/identest.c deleted file mode 100644 index 321d2c2b0..000000000 --- a/security/nss/lib/freebl/mpi/utils/identest.c +++ /dev/null @@ -1,84 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include "mpi.h" -#include "mpprime.h" -#include <sys/types.h> -#include <time.h> - -#define MAX_PREC (4096 / MP_DIGIT_BIT) - -mp_err -identity_test(void) -{ - mp_size preca, precb; - mp_err res; - mp_int a, b; - mp_int t1, t2, t3, t4, t5; - - preca = (rand() % MAX_PREC) + 1; - precb = (rand() % MAX_PREC) + 1; - - MP_DIGITS(&a) = 0; - MP_DIGITS(&b) = 0; - MP_DIGITS(&t1) = 0; - MP_DIGITS(&t2) = 0; - MP_DIGITS(&t3) = 0; - MP_DIGITS(&t4) = 0; - MP_DIGITS(&t5) = 0; - - MP_CHECKOK(mp_init(&a)); - MP_CHECKOK(mp_init(&b)); - MP_CHECKOK(mp_init(&t1)); - MP_CHECKOK(mp_init(&t2)); - MP_CHECKOK(mp_init(&t3)); - MP_CHECKOK(mp_init(&t4)); - MP_CHECKOK(mp_init(&t5)); - - MP_CHECKOK(mpp_random_size(&a, preca)); - MP_CHECKOK(mpp_random_size(&b, precb)); - - if (mp_cmp(&a, &b) < 0) - mp_exch(&a, &b); - - MP_CHECKOK(mp_mod(&a, &b, &t1)); /* t1 = a%b */ - MP_CHECKOK(mp_div(&a, &b, &t2, NULL)); /* t2 = a/b */ - MP_CHECKOK(mp_mul(&b, &t2, &t3)); /* t3 = (a/b)*b */ - MP_CHECKOK(mp_add(&t1, &t3, &t4)); /* t4 = a%b + (a/b)*b */ - MP_CHECKOK(mp_sub(&t4, &a, &t5)); /* t5 = a%b + (a/b)*b - a */ - if (mp_cmp_z(&t5) != 0) { - res = MP_UNDEF; - goto CLEANUP; - } - -CLEANUP: - mp_clear(&t5); - mp_clear(&t4); - mp_clear(&t3); - mp_clear(&t2); - mp_clear(&t1); - mp_clear(&b); - mp_clear(&a); - return res; -} - -int -main(void) -{ - unsigned int seed = (unsigned int)time(NULL); - unsigned long count = 0; - mp_err res; - - srand(seed); - - while (MP_OKAY == (res = identity_test())) { - if ((++count % 100) == 0) - fputc('.', stderr); - } - - fprintf(stderr, "\ntest failed, err %d\n", res); - return res; -} diff --git a/security/nss/lib/freebl/mpi/utils/invmod.c b/security/nss/lib/freebl/mpi/utils/invmod.c deleted file mode 100644 index 9b4b04d3f..000000000 --- a/security/nss/lib/freebl/mpi/utils/invmod.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * invmod.c - * - * Compute modular inverses - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> - -#include "mpi.h" - -int -main(int argc, char *argv[]) -{ - mp_int a, m; - mp_err res; - char *buf; - int len, out = 0; - - if (argc < 3) { - fprintf(stderr, "Usage: %s <a> <m>\n", argv[0]); - return 1; - } - - mp_init(&a); - mp_init(&m); - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&m, argv[2], 10); - - if (mp_cmp(&a, &m) > 0) - mp_mod(&a, &m, &a); - - switch ((res = mp_invmod(&a, &m, &a))) { - case MP_OKAY: - len = mp_radix_size(&a, 10); - buf = malloc(len); - - mp_toradix(&a, buf, 10); - printf("%s\n", buf); - free(buf); - break; - - case MP_UNDEF: - printf("No inverse\n"); - out = 1; - break; - - default: - printf("error: %s (%d)\n", mp_strerror(res), res); - out = 2; - break; - } - - mp_clear(&a); - mp_clear(&m); - - return out; -} diff --git a/security/nss/lib/freebl/mpi/utils/isprime.c b/security/nss/lib/freebl/mpi/utils/isprime.c deleted file mode 100644 index d2d86957e..000000000 --- a/security/nss/lib/freebl/mpi/utils/isprime.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * isprime.c - * - * Probabilistic primality tester command-line tool - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "mpi.h" -#include "mpprime.h" - -#define RM_TESTS 15 /* how many iterations of Rabin-Miller? */ -#define MINIMUM 1024 /* don't bother us with a < this */ - -int g_tests = RM_TESTS; -char *g_prog = NULL; - -int -main(int argc, char *argv[]) -{ - mp_int a; - mp_digit np = prime_tab_size; /* from mpprime.h */ - int res = 0; - - g_prog = argv[0]; - - if (argc < 2) { - fprintf(stderr, "Usage: %s <a>, where <a> is a decimal integer\n" - "Use '0x' prefix for a hexadecimal value\n", - g_prog); - return 1; - } - - /* Read number of tests from environment, if present */ - { - char *tmp; - - if ((tmp = PR_GetEnvSecure("RM_TESTS")) != NULL) { - if ((g_tests = atoi(tmp)) <= 0) - g_tests = RM_TESTS; - } - } - - mp_init(&a); - if (argv[1][0] == '0' && argv[1][1] == 'x') - mp_read_radix(&a, argv[1] + 2, 16); - else - mp_read_radix(&a, argv[1], 10); - - if (mp_cmp_d(&a, MINIMUM) <= 0) { - fprintf(stderr, "%s: please use a value greater than %d\n", - g_prog, MINIMUM); - mp_clear(&a); - return 1; - } - - /* Test for divisibility by small primes */ - if (mpp_divis_primes(&a, &np) != MP_NO) { - printf("Not prime (divisible by small prime %d)\n", np); - res = 2; - goto CLEANUP; - } - - /* Test with Fermat's test, using 2 as a witness */ - if (mpp_fermat(&a, 2) != MP_YES) { - printf("Not prime (failed Fermat test)\n"); - res = 2; - goto CLEANUP; - } - - /* Test with Rabin-Miller probabilistic test */ - if (mpp_pprime(&a, g_tests) == MP_NO) { - printf("Not prime (failed pseudoprime test)\n"); - res = 2; - goto CLEANUP; - } - - printf("Probably prime, 1 in 4^%d chance of false positive\n", g_tests); - -CLEANUP: - mp_clear(&a); - - return res; -} diff --git a/security/nss/lib/freebl/mpi/utils/lap.c b/security/nss/lib/freebl/mpi/utils/lap.c deleted file mode 100644 index 501e4531d..000000000 --- a/security/nss/lib/freebl/mpi/utils/lap.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * lap.c - * - * Find least annihilating power of a mod m - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> - -#include "mpi.h" - -void sig_catch(int ign); - -int g_quit = 0; - -int -main(int argc, char *argv[]) -{ - mp_int a, m, p, k; - - if (argc < 3) { - fprintf(stderr, "Usage: %s <a> <m>\n", argv[0]); - return 1; - } - - mp_init(&a); - mp_init(&m); - mp_init(&p); - mp_add_d(&p, 1, &p); - - mp_read_radix(&a, argv[1], 10); - mp_read_radix(&m, argv[2], 10); - - mp_init_copy(&k, &a); - - signal(SIGINT, sig_catch); -#ifndef __OS2__ - signal(SIGHUP, sig_catch); -#endif - signal(SIGTERM, sig_catch); - - while (mp_cmp(&p, &m) < 0) { - if (g_quit) { - int len; - char *buf; - - len = mp_radix_size(&p, 10); - buf = malloc(len); - mp_toradix(&p, buf, 10); - - fprintf(stderr, "Terminated at: %s\n", buf); - free(buf); - return 1; - } - if (mp_cmp_d(&k, 1) == 0) { - int len; - char *buf; - - len = mp_radix_size(&p, 10); - buf = malloc(len); - mp_toradix(&p, buf, 10); - - printf("%s\n", buf); - - free(buf); - break; - } - - mp_mulmod(&k, &a, &m, &k); - mp_add_d(&p, 1, &p); - } - - if (mp_cmp(&p, &m) >= 0) - printf("No annihilating power.\n"); - - mp_clear(&p); - mp_clear(&m); - mp_clear(&a); - return 0; -} - -void -sig_catch(int ign) -{ - g_quit = 1; -} diff --git a/security/nss/lib/freebl/mpi/utils/makeprime.c b/security/nss/lib/freebl/mpi/utils/makeprime.c deleted file mode 100644 index 401b7532b..000000000 --- a/security/nss/lib/freebl/mpi/utils/makeprime.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * makeprime.c - * - * A simple prime generator function (and test driver). Prints out the - * first prime it finds greater than or equal to the starting value. - * - * Usage: makeprime <start> - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> - -/* These two must be included for make_prime() to work */ - -#include "mpi.h" -#include "mpprime.h" - -/* - make_prime(p, nr) - - Find the smallest prime integer greater than or equal to p, where - primality is verified by 'nr' iterations of the Rabin-Miller - probabilistic primality test. The caller is responsible for - generating the initial value of p. - - Returns MP_OKAY if a prime has been generated, otherwise the error - code indicates some other problem. The value of p is clobbered; the - caller should keep a copy if the value is needed. - */ -mp_err make_prime(mp_int *p, int nr); - -/* The main() is not required -- it's just a test driver */ -int -main(int argc, char *argv[]) -{ - mp_int start; - mp_err res; - - if (argc < 2) { - fprintf(stderr, "Usage: %s <start-value>\n", argv[0]); - return 1; - } - - mp_init(&start); - if (argv[1][0] == '0' && tolower(argv[1][1]) == 'x') { - mp_read_radix(&start, argv[1] + 2, 16); - } else { - mp_read_radix(&start, argv[1], 10); - } - mp_abs(&start, &start); - - if ((res = make_prime(&start, 5)) != MP_OKAY) { - fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); - mp_clear(&start); - - return 1; - - } else { - char *buf = malloc(mp_radix_size(&start, 10)); - - mp_todecimal(&start, buf); - printf("%s\n", buf); - free(buf); - - mp_clear(&start); - - return 0; - } - -} /* end main() */ - -/*------------------------------------------------------------------------*/ - -mp_err -make_prime(mp_int *p, int nr) -{ - mp_err res; - - if (mp_iseven(p)) { - mp_add_d(p, 1, p); - } - - do { - mp_digit which = prime_tab_size; - - /* First test for divisibility by a few small primes */ - if ((res = mpp_divis_primes(p, &which)) == MP_YES) - continue; - else if (res != MP_NO) - goto CLEANUP; - - /* If that passes, try one iteration of Fermat's test */ - if ((res = mpp_fermat(p, 2)) == MP_NO) - continue; - else if (res != MP_YES) - goto CLEANUP; - - /* If that passes, run Rabin-Miller as often as requested */ - if ((res = mpp_pprime(p, nr)) == MP_YES) - break; - else if (res != MP_NO) - goto CLEANUP; - - } while ((res = mp_add_d(p, 2, p)) == MP_OKAY); - -CLEANUP: - return res; - -} /* end make_prime() */ - -/*------------------------------------------------------------------------*/ -/* HERE THERE BE DRAGONS */ diff --git a/security/nss/lib/freebl/mpi/utils/metime.c b/security/nss/lib/freebl/mpi/utils/metime.c deleted file mode 100644 index 122875ee0..000000000 --- a/security/nss/lib/freebl/mpi/utils/metime.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * metime.c - * - * Modular exponentiation timing test - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <time.h> - -#include "mpi.h" -#include "mpprime.h" - -double clk_to_sec(clock_t start, clock_t stop); - -int -main(int argc, char *argv[]) -{ - int ix, num, prec = 8; - unsigned int seed; - clock_t start, stop; - double sec; - - mp_int a, m, c; - - if (PR_GetEnvSecure("SEED") != NULL) - seed = abs(atoi(PR_GetEnvSecure("SEED"))); - else - seed = (unsigned int)time(NULL); - - if (argc < 2) { - fprintf(stderr, "Usage: %s <num-tests> [<nbits>]\n", argv[0]); - return 1; - } - - if ((num = atoi(argv[1])) < 0) - num = -num; - - if (!num) { - fprintf(stderr, "%s: must perform at least 1 test\n", argv[0]); - return 1; - } - - if (argc > 2) { - if ((prec = atoi(argv[2])) <= 0) - prec = 8; - else - prec = (prec + (DIGIT_BIT - 1)) / DIGIT_BIT; - } - - printf("Modular exponentiation timing test\n" - "Precision: %d digits (%d bits)\n" - "# of tests: %d\n\n", - prec, prec * DIGIT_BIT, num); - - mp_init_size(&a, prec); - mp_init_size(&m, prec); - mp_init_size(&c, prec); - - srand(seed); - - start = clock(); - for (ix = 0; ix < num; ix++) { - - mpp_random_size(&a, prec); - mpp_random_size(&c, prec); - mpp_random_size(&m, prec); - /* set msb and lsb of m */ - DIGIT(&m, 0) |= 1; - DIGIT(&m, USED(&m) - 1) |= (mp_digit)1 << (DIGIT_BIT - 1); - if (mp_cmp(&a, &m) > 0) - mp_sub(&a, &m, &a); - - mp_exptmod(&a, &c, &m, &c); - } - stop = clock(); - - sec = clk_to_sec(start, stop); - - printf("Total: %.3f seconds\n", sec); - printf("Individual: %.3f seconds\n", sec / num); - - mp_clear(&c); - mp_clear(&a); - mp_clear(&m); - - return 0; -} - -double -clk_to_sec(clock_t start, clock_t stop) -{ - return (double)(stop - start) / CLOCKS_PER_SEC; -} - -/*------------------------------------------------------------------------*/ -/* HERE THERE BE DRAGONS */ diff --git a/security/nss/lib/freebl/mpi/utils/pi.c b/security/nss/lib/freebl/mpi/utils/pi.c deleted file mode 100644 index 7e3109786..000000000 --- a/security/nss/lib/freebl/mpi/utils/pi.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * pi.c - * - * Compute pi to an arbitrary number of digits. Uses Machin's formula, - * like everyone else on the planet: - * - * pi = 16 * arctan(1/5) - 4 * arctan(1/239) - * - * This is pretty effective for up to a few thousand digits, but it - * gets pretty slow after that. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <time.h> - -#include "mpi.h" - -mp_err arctan(mp_digit mul, mp_digit x, mp_digit prec, mp_int *sum); - -int -main(int argc, char *argv[]) -{ - mp_err res; - mp_digit ndigits; - mp_int sum1, sum2; - clock_t start, stop; - int out = 0; - - /* Make the user specify precision on the command line */ - if (argc < 2) { - fprintf(stderr, "Usage: %s <num-digits>\n", argv[0]); - return 1; - } - - if ((ndigits = abs(atoi(argv[1]))) == 0) { - fprintf(stderr, "%s: you must request at least 1 digit\n", argv[0]); - return 1; - } - - start = clock(); - mp_init(&sum1); - mp_init(&sum2); - - /* sum1 = 16 * arctan(1/5) */ - if ((res = arctan(16, 5, ndigits, &sum1)) != MP_OKAY) { - fprintf(stderr, "%s: arctan: %s\n", argv[0], mp_strerror(res)); - out = 1; - goto CLEANUP; - } - - /* sum2 = 4 * arctan(1/239) */ - if ((res = arctan(4, 239, ndigits, &sum2)) != MP_OKAY) { - fprintf(stderr, "%s: arctan: %s\n", argv[0], mp_strerror(res)); - out = 1; - goto CLEANUP; - } - - /* pi = sum1 - sum2 */ - if ((res = mp_sub(&sum1, &sum2, &sum1)) != MP_OKAY) { - fprintf(stderr, "%s: mp_sub: %s\n", argv[0], mp_strerror(res)); - out = 1; - goto CLEANUP; - } - stop = clock(); - - /* Write the output in decimal */ - { - char *buf = malloc(mp_radix_size(&sum1, 10)); - - if (buf == NULL) { - fprintf(stderr, "%s: out of memory\n", argv[0]); - out = 1; - goto CLEANUP; - } - mp_todecimal(&sum1, buf); - printf("%s\n", buf); - free(buf); - } - - fprintf(stderr, "Computation took %.2f sec.\n", - (double)(stop - start) / CLOCKS_PER_SEC); - -CLEANUP: - mp_clear(&sum1); - mp_clear(&sum2); - - return out; -} - -/* Compute sum := mul * arctan(1/x), to 'prec' digits of precision */ -mp_err -arctan(mp_digit mul, mp_digit x, mp_digit prec, mp_int *sum) -{ - mp_int t, v; - mp_digit q = 1, rd; - mp_err res; - int sign = 1; - - prec += 3; /* push inaccuracies off the end */ - - mp_init(&t); - mp_set(&t, 10); - mp_init(&v); - if ((res = mp_expt_d(&t, prec, &t)) != MP_OKAY || /* get 10^prec */ - (res = mp_mul_d(&t, mul, &t)) != MP_OKAY || /* ... times mul */ - (res = mp_mul_d(&t, x, &t)) != MP_OKAY) /* ... times x */ - goto CLEANUP; - - /* - The extra multiplication by x in the above takes care of what - would otherwise have to be a special case for 1 / x^1 during the - first loop iteration. A little sneaky, but effective. - - We compute arctan(1/x) by the formula: - - 1 1 1 1 - - - ----- + ----- - ----- + ... - x 3 x^3 5 x^5 7 x^7 - - We multiply through by 'mul' beforehand, which gives us a couple - more iterations and more precision - */ - - x *= x; /* works as long as x < sqrt(RADIX), which it is here */ - - mp_zero(sum); - - do { - if ((res = mp_div_d(&t, x, &t, &rd)) != MP_OKAY) - goto CLEANUP; - - if (sign < 0 && rd != 0) - mp_add_d(&t, 1, &t); - - if ((res = mp_div_d(&t, q, &v, &rd)) != MP_OKAY) - goto CLEANUP; - - if (sign < 0 && rd != 0) - mp_add_d(&v, 1, &v); - - if (sign > 0) - res = mp_add(sum, &v, sum); - else - res = mp_sub(sum, &v, sum); - - if (res != MP_OKAY) - goto CLEANUP; - - sign *= -1; - q += 2; - - } while (mp_cmp_z(&t) != 0); - - /* Chop off inaccurate low-order digits */ - mp_div_d(sum, 1000, sum, NULL); - -CLEANUP: - mp_clear(&v); - mp_clear(&t); - - return res; -} - -/*------------------------------------------------------------------------*/ -/* HERE THERE BE DRAGONS */ diff --git a/security/nss/lib/freebl/mpi/utils/primegen.c b/security/nss/lib/freebl/mpi/utils/primegen.c deleted file mode 100644 index f62a56a4e..000000000 --- a/security/nss/lib/freebl/mpi/utils/primegen.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * primegen.c - * - * Generates random integers which are prime with a high degree of - * probability using the Miller-Rabin probabilistic primality testing - * algorithm. - * - * Usage: - * primegen <bits> [<num>] - * - * <bits> - number of significant bits each prime should have - * <num> - number of primes to generate - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <time.h> - -#include "mpi.h" -#include "mplogic.h" -#include "mpprime.h" - -#define NUM_TESTS 5 /* Number of Rabin-Miller iterations to test with */ - -#ifdef DEBUG -#define FPUTC(x, y) fputc(x, y) -#else -#define FPUTC(x, y) -#endif - -int -main(int argc, char *argv[]) -{ - unsigned char *raw; - char *out; - unsigned long nTries; - int rawlen, bits, outlen, ngen, ix, jx; - int g_strong = 0; - mp_int testval; - mp_err res; - clock_t start, end; - - /* We'll just use the C library's rand() for now, although this - won't be good enough for cryptographic purposes */ - if ((out = PR_GetEnvSecure("SEED")) == NULL) { - srand((unsigned int)time(NULL)); - } else { - srand((unsigned int)atoi(out)); - } - - if (argc < 2) { - fprintf(stderr, "Usage: %s <bits> [<count> [strong]]\n", argv[0]); - return 1; - } - - if ((bits = abs(atoi(argv[1]))) < CHAR_BIT) { - fprintf(stderr, "%s: please request at least %d bits.\n", - argv[0], CHAR_BIT); - return 1; - } - - /* If optional third argument is given, use that as the number of - primes to generate; otherwise generate one prime only. - */ - if (argc < 3) { - ngen = 1; - } else { - ngen = abs(atoi(argv[2])); - } - - /* If fourth argument is given, and is the word "strong", we'll - generate strong (Sophie Germain) primes. - */ - if (argc > 3 && strcmp(argv[3], "strong") == 0) - g_strong = 1; - - /* testval - candidate being tested; nTries - number tried so far */ - if ((res = mp_init(&testval)) != MP_OKAY) { - fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); - return 1; - } - - if (g_strong) { - printf("Requested %d strong prime value(s) of %d bits.\n", - ngen, bits); - } else { - printf("Requested %d prime value(s) of %d bits.\n", ngen, bits); - } - - rawlen = (bits / CHAR_BIT) + ((bits % CHAR_BIT) ? 1 : 0) + 1; - - if ((raw = calloc(rawlen, sizeof(unsigned char))) == NULL) { - fprintf(stderr, "%s: out of memory, sorry.\n", argv[0]); - return 1; - } - - /* This loop is one for each prime we need to generate */ - for (jx = 0; jx < ngen; jx++) { - - raw[0] = 0; /* sign is positive */ - - /* Pack the initializer with random bytes */ - for (ix = 1; ix < rawlen; ix++) - raw[ix] = (rand() * rand()) & UCHAR_MAX; - - raw[1] |= 0x80; /* set high-order bit of test value */ - raw[rawlen - 1] |= 1; /* set low-order bit of test value */ - - /* Make an mp_int out of the initializer */ - mp_read_raw(&testval, (char *)raw, rawlen); - - /* Initialize candidate counter */ - nTries = 0; - - start = clock(); /* time generation for this prime */ - do { - res = mpp_make_prime(&testval, bits, g_strong, &nTries); - if (res != MP_NO) - break; - /* This code works whether digits are 16 or 32 bits */ - res = mp_add_d(&testval, 32 * 1024, &testval); - res = mp_add_d(&testval, 32 * 1024, &testval); - FPUTC(',', stderr); - } while (1); - end = clock(); - - if (res != MP_YES) { - break; - } - FPUTC('\n', stderr); - puts("The following value is probably prime:"); - outlen = mp_radix_size(&testval, 10); - out = calloc(outlen, sizeof(unsigned char)); - mp_toradix(&testval, (char *)out, 10); - printf("10: %s\n", out); - mp_toradix(&testval, (char *)out, 16); - printf("16: %s\n\n", out); - free(out); - - printf("Number of candidates tried: %lu\n", nTries); - printf("This computation took %ld clock ticks (%.2f seconds)\n", - (end - start), ((double)(end - start) / CLOCKS_PER_SEC)); - - FPUTC('\n', stderr); - } /* end of loop to generate all requested primes */ - - if (res != MP_OKAY) - fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); - - free(raw); - mp_clear(&testval); - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/utils/prng.c b/security/nss/lib/freebl/mpi/utils/prng.c deleted file mode 100644 index 38748d18e..000000000 --- a/security/nss/lib/freebl/mpi/utils/prng.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * prng.c - * - * Command-line pseudo-random number generator - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include <time.h> - -#ifdef __OS2__ -#include <types.h> -#include <process.h> -#else -#include <unistd.h> -#endif - -#include "bbs_rand.h" - -int -main(int argc, char *argv[]) -{ - unsigned char *seed; - unsigned int ix, num = 1; - pid_t pid; - - if (argc > 1) { - num = atoi(argv[1]); - if (num <= 0) - num = 1; - } - - pid = getpid(); - srand(time(NULL) * (unsigned int)pid); - - /* Not a perfect seed, but not bad */ - seed = malloc(bbs_seed_size); - for (ix = 0; ix < bbs_seed_size; ix++) { - seed[ix] = rand() % UCHAR_MAX; - } - - bbs_srand(seed, bbs_seed_size); - memset(seed, 0, bbs_seed_size); - free(seed); - - while (num-- > 0) { - ix = bbs_rand(); - - printf("%u\n", ix); - } - - return 0; -} diff --git a/security/nss/lib/freebl/mpi/utils/ptab.pl b/security/nss/lib/freebl/mpi/utils/ptab.pl deleted file mode 100755 index ef2e565be..000000000 --- a/security/nss/lib/freebl/mpi/utils/ptab.pl +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/perl - -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -while(<>) { - chomp; - push(@primes, $_); -} - -printf("mp_size prime_tab_size = %d;\n", ($#primes + 1)); -print "mp_digit prime_tab[] = {\n"; - -print "\t"; -$last = pop(@primes); -foreach $prime (sort {$a<=>$b} @primes) { - printf("0x%04X, ", $prime); - $brk = ($brk + 1) % 8; - print "\n\t" if(!$brk); -} -printf("0x%04X", $last); -print "\n" if($brk); -print "};\n\n"; - -exit 0; diff --git a/security/nss/lib/freebl/mpi/utils/sieve.c b/security/nss/lib/freebl/mpi/utils/sieve.c deleted file mode 100644 index 57768af9e..000000000 --- a/security/nss/lib/freebl/mpi/utils/sieve.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * sieve.c - * - * Finds prime numbers using the Sieve of Eratosthenes - * - * This implementation uses a bitmap to represent all odd integers in a - * given range. We iterate over this bitmap, crossing off the - * multiples of each prime we find. At the end, all the remaining set - * bits correspond to prime integers. - * - * Here, we make two passes -- once we have generated a sieve-ful of - * primes, we copy them out, reset the sieve using the highest - * generated prime from the first pass as a base. Then we cross out - * all the multiples of all the primes we found the first time through, - * and re-sieve. In this way, we get double use of the memory we - * allocated for the sieve the first time though. Since we also - * implicitly ignore multiples of 2, this amounts to 4 times the - * values. - * - * This could (and probably will) be generalized to re-use the sieve a - * few more times. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> - -typedef unsigned char byte; - -typedef struct { - int size; - byte *bits; - long base; - int next; - int nbits; -} sieve; - -void sieve_init(sieve *sp, long base, int nbits); -void sieve_grow(sieve *sp, int nbits); -long sieve_next(sieve *sp); -void sieve_reset(sieve *sp, long base); -void sieve_cross(sieve *sp, long val); -void sieve_clear(sieve *sp); - -#define S_ISSET(S, B) (((S)->bits[(B) / CHAR_BIT] >> ((B) % CHAR_BIT)) & 1) -#define S_SET(S, B) ((S)->bits[(B) / CHAR_BIT] |= (1 << ((B) % CHAR_BIT))) -#define S_CLR(S, B) ((S)->bits[(B) / CHAR_BIT] &= ~(1 << ((B) % CHAR_BIT))) -#define S_VAL(S, B) ((S)->base + (2 * (B))) -#define S_BIT(S, V) (((V) - ((S)->base)) / 2) - -int -main(int argc, char *argv[]) -{ - sieve s; - long pr, *p; - int c, ix, cur = 0; - - if (argc < 2) { - fprintf(stderr, "Usage: %s <width>\n", argv[0]); - return 1; - } - - c = atoi(argv[1]); - if (c < 0) - c = -c; - - fprintf(stderr, "%s: sieving to %d positions\n", argv[0], c); - - sieve_init(&s, 3, c); - - c = 0; - while ((pr = sieve_next(&s)) > 0) { - ++c; - } - - p = calloc(c, sizeof(long)); - if (!p) { - fprintf(stderr, "%s: out of memory after first half\n", argv[0]); - sieve_clear(&s); - exit(1); - } - - fprintf(stderr, "%s: half done ... \n", argv[0]); - - for (ix = 0; ix < s.nbits; ix++) { - if (S_ISSET(&s, ix)) { - p[cur] = S_VAL(&s, ix); - printf("%ld\n", p[cur]); - ++cur; - } - } - - sieve_reset(&s, p[cur - 1]); - fprintf(stderr, "%s: crossing off %d found primes ... \n", argv[0], cur); - for (ix = 0; ix < cur; ix++) { - sieve_cross(&s, p[ix]); - if (!(ix % 1000)) - fputc('.', stderr); - } - fputc('\n', stderr); - - free(p); - - fprintf(stderr, "%s: sieving again from %ld ... \n", argv[0], p[cur - 1]); - c = 0; - while ((pr = sieve_next(&s)) > 0) { - ++c; - } - - fprintf(stderr, "%s: done!\n", argv[0]); - for (ix = 0; ix < s.nbits; ix++) { - if (S_ISSET(&s, ix)) { - printf("%ld\n", S_VAL(&s, ix)); - } - } - - sieve_clear(&s); - - return 0; -} - -void -sieve_init(sieve *sp, long base, int nbits) -{ - sp->size = (nbits / CHAR_BIT); - - if (nbits % CHAR_BIT) - ++sp->size; - - sp->bits = calloc(sp->size, sizeof(byte)); - memset(sp->bits, UCHAR_MAX, sp->size); - if (!(base & 1)) - ++base; - sp->base = base; - - sp->next = 0; - sp->nbits = sp->size * CHAR_BIT; -} - -void -sieve_grow(sieve *sp, int nbits) -{ - int ns = (nbits / CHAR_BIT); - - if (nbits % CHAR_BIT) - ++ns; - - if (ns > sp->size) { - byte *tmp; - int ix; - - tmp = calloc(ns, sizeof(byte)); - if (tmp == NULL) { - fprintf(stderr, "Error: out of memory in sieve_grow\n"); - return; - } - - memcpy(tmp, sp->bits, sp->size); - for (ix = sp->size; ix < ns; ix++) { - tmp[ix] = UCHAR_MAX; - } - - free(sp->bits); - sp->bits = tmp; - sp->size = ns; - - sp->nbits = sp->size * CHAR_BIT; - } -} - -long -sieve_next(sieve *sp) -{ - long out; - int ix = 0; - long val; - - if (sp->next > sp->nbits) - return -1; - - out = S_VAL(sp, sp->next); -#ifdef DEBUG - fprintf(stderr, "Sieving %ld\n", out); -#endif - - /* Sieve out all multiples of the current prime */ - val = out; - while (ix < sp->nbits) { - val += out; - ix = S_BIT(sp, val); - if ((val & 1) && ix < sp->nbits) { /* && S_ISSET(sp, ix)) { */ - S_CLR(sp, ix); -#ifdef DEBUG - fprintf(stderr, "Crossing out %ld (bit %d)\n", val, ix); -#endif - } - } - - /* Scan ahead to the next prime */ - ++sp->next; - while (sp->next < sp->nbits && !S_ISSET(sp, sp->next)) - ++sp->next; - - return out; -} - -void -sieve_cross(sieve *sp, long val) -{ - int ix = 0; - long cur = val; - - while (cur < sp->base) - cur += val; - - ix = S_BIT(sp, cur); - while (ix < sp->nbits) { - if (cur & 1) - S_CLR(sp, ix); - cur += val; - ix = S_BIT(sp, cur); - } -} - -void -sieve_reset(sieve *sp, long base) -{ - memset(sp->bits, UCHAR_MAX, sp->size); - sp->base = base; - sp->next = 0; -} - -void -sieve_clear(sieve *sp) -{ - if (sp->bits) - free(sp->bits); - - sp->bits = NULL; -} diff --git a/security/nss/lib/freebl/os2_rand.c b/security/nss/lib/freebl/os2_rand.c deleted file mode 100644 index 407b08014..000000000 --- a/security/nss/lib/freebl/os2_rand.c +++ /dev/null @@ -1,334 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#define INCL_DOS -#define INCL_DOSERRORS -#include <os2.h> -#include "secrng.h" -#include "prerror.h" -#include <stdlib.h> -#include <time.h> -#include <stdio.h> -#include <sys/stat.h> - -static BOOL -clockTickTime(unsigned long *phigh, unsigned long *plow) -{ - APIRET rc = NO_ERROR; - QWORD qword = { 0, 0 }; - - rc = DosTmrQueryTime(&qword); - if (rc != NO_ERROR) - return FALSE; - - *phigh = qword.ulHi; - *plow = qword.ulLo; - - return TRUE; -} - -size_t -RNG_GetNoise(void *buf, size_t maxbuf) -{ - unsigned long high = 0; - unsigned long low = 0; - clock_t val = 0; - int n = 0; - int nBytes = 0; - time_t sTime; - - if (maxbuf <= 0) - return 0; - - clockTickTime(&high, &low); - - /* get the maximally changing bits first */ - nBytes = sizeof(low) > maxbuf ? maxbuf : sizeof(low); - memcpy(buf, &low, nBytes); - n += nBytes; - maxbuf -= nBytes; - - if (maxbuf <= 0) - return n; - - nBytes = sizeof(high) > maxbuf ? maxbuf : sizeof(high); - memcpy(((char *)buf) + n, &high, nBytes); - n += nBytes; - maxbuf -= nBytes; - - if (maxbuf <= 0) - return n; - - /* get the number of milliseconds that have elapsed since application started */ - val = clock(); - - nBytes = sizeof(val) > maxbuf ? maxbuf : sizeof(val); - memcpy(((char *)buf) + n, &val, nBytes); - n += nBytes; - maxbuf -= nBytes; - - if (maxbuf <= 0) - return n; - - /* get the time in seconds since midnight Jan 1, 1970 */ - time(&sTime); - nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime); - memcpy(((char *)buf) + n, &sTime, nBytes); - n += nBytes; - - return n; -} - -static BOOL -EnumSystemFiles(void (*func)(const char *)) -{ - APIRET rc; - ULONG sysInfo = 0; - char bootLetter[2]; - char sysDir[_MAX_PATH] = ""; - char filename[_MAX_PATH]; - HDIR hdir = HDIR_CREATE; - ULONG numFiles = 1; - FILEFINDBUF3 fileBuf = { 0 }; - ULONG buflen = sizeof(FILEFINDBUF3); - - if (DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, (PVOID)&sysInfo, - sizeof(ULONG)) == NO_ERROR) { - bootLetter[0] = sysInfo + 'A' - 1; - bootLetter[1] = '\0'; - strcpy(sysDir, bootLetter); - strcpy(sysDir + 1, ":\\OS2\\"); - - strcpy(filename, sysDir); - strcat(filename, "*.*"); - } - - rc = DosFindFirst(filename, &hdir, FILE_NORMAL, &fileBuf, buflen, - &numFiles, FIL_STANDARD); - if (rc == NO_ERROR) { - do { - // pass the full pathname to the callback - sprintf(filename, "%s%s", sysDir, fileBuf.achName); - (*func)(filename); - - numFiles = 1; - rc = DosFindNext(hdir, &fileBuf, buflen, &numFiles); - if (rc != NO_ERROR && rc != ERROR_NO_MORE_FILES) - printf("DosFindNext errod code = %d\n", rc); - } while (rc == NO_ERROR); - - rc = DosFindClose(hdir); - if (rc != NO_ERROR) - printf("DosFindClose error code = %d", rc); - } else - printf("DosFindFirst error code = %d", rc); - - return TRUE; -} - -static int dwNumFiles, dwReadEvery, dwFileToRead = 0; - -static void -CountFiles(const char *file) -{ - dwNumFiles++; -} - -static void -ReadFiles(const char *file) -{ - if ((dwNumFiles % dwReadEvery) == 0) - RNG_FileForRNG(file); - - dwNumFiles++; -} - -static void -ReadSingleFile(const char *filename) -{ - unsigned char buffer[1024]; - FILE *file; - - file = fopen((char *)filename, "rb"); - if (file != NULL) { - while (fread(buffer, 1, sizeof(buffer), file) > 0) - ; - fclose(file); - } -} - -static void -ReadOneFile(const char *file) -{ - if (dwNumFiles == dwFileToRead) { - ReadSingleFile(file); - } - - dwNumFiles++; -} - -static void -ReadSystemFiles(void) -{ - // first count the number of files - dwNumFiles = 0; - if (!EnumSystemFiles(CountFiles)) - return; - - RNG_RandomUpdate(&dwNumFiles, sizeof(dwNumFiles)); - - // now read 10 files - if (dwNumFiles == 0) - return; - - dwReadEvery = dwNumFiles / 10; - if (dwReadEvery == 0) - dwReadEvery = 1; // less than 10 files - - dwNumFiles = 0; - EnumSystemFiles(ReadFiles); -} - -void -RNG_SystemInfoForRNG(void) -{ - unsigned long *plong = 0; - PTIB ptib; - PPIB ppib; - APIRET rc = NO_ERROR; - DATETIME dt; - COUNTRYCODE cc = { 0 }; - COUNTRYINFO ci = { 0 }; - unsigned long actual = 0; - char path[_MAX_PATH] = ""; - char fullpath[_MAX_PATH] = ""; - unsigned long pathlength = sizeof(path); - FSALLOCATE fsallocate; - FILESTATUS3 fstatus; - unsigned long defaultdrive = 0; - unsigned long logicaldrives = 0; - unsigned long sysInfo[QSV_MAX] = { 0 }; - char buffer[20]; - int nBytes = 0; - - nBytes = RNG_GetNoise(buffer, sizeof(buffer)); - RNG_RandomUpdate(buffer, nBytes); - - /* allocate memory and use address and memory */ - plong = (unsigned long *)malloc(sizeof(*plong)); - RNG_RandomUpdate(&plong, sizeof(plong)); - RNG_RandomUpdate(plong, sizeof(*plong)); - free(plong); - - /* process info */ - rc = DosGetInfoBlocks(&ptib, &ppib); - if (rc == NO_ERROR) { - RNG_RandomUpdate(ptib, sizeof(*ptib)); - RNG_RandomUpdate(ppib, sizeof(*ppib)); - } - - /* time */ - rc = DosGetDateTime(&dt); - if (rc == NO_ERROR) { - RNG_RandomUpdate(&dt, sizeof(dt)); - } - - /* country */ - rc = DosQueryCtryInfo(sizeof(ci), &cc, &ci, &actual); - if (rc == NO_ERROR) { - RNG_RandomUpdate(&cc, sizeof(cc)); - RNG_RandomUpdate(&ci, sizeof(ci)); - RNG_RandomUpdate(&actual, sizeof(actual)); - } - - /* current directory */ - rc = DosQueryCurrentDir(0, path, &pathlength); - strcat(fullpath, "\\"); - strcat(fullpath, path); - if (rc == NO_ERROR) { - RNG_RandomUpdate(fullpath, strlen(fullpath)); - // path info - rc = DosQueryPathInfo(fullpath, FIL_STANDARD, &fstatus, sizeof(fstatus)); - if (rc == NO_ERROR) { - RNG_RandomUpdate(&fstatus, sizeof(fstatus)); - } - } - - /* file system info */ - rc = DosQueryFSInfo(0, FSIL_ALLOC, &fsallocate, sizeof(fsallocate)); - if (rc == NO_ERROR) { - RNG_RandomUpdate(&fsallocate, sizeof(fsallocate)); - } - - /* drive info */ - rc = DosQueryCurrentDisk(&defaultdrive, &logicaldrives); - if (rc == NO_ERROR) { - RNG_RandomUpdate(&defaultdrive, sizeof(defaultdrive)); - RNG_RandomUpdate(&logicaldrives, sizeof(logicaldrives)); - } - - /* system info */ - rc = DosQuerySysInfo(1L, QSV_MAX, (PVOID)&sysInfo, sizeof(ULONG) * QSV_MAX); - if (rc == NO_ERROR) { - RNG_RandomUpdate(&sysInfo, sizeof(sysInfo)); - } - - // now let's do some files - ReadSystemFiles(); - - /* more noise */ - nBytes = RNG_GetNoise(buffer, sizeof(buffer)); - RNG_RandomUpdate(buffer, nBytes); -} - -void -RNG_FileForRNG(const char *filename) -{ - struct stat stat_buf; - unsigned char buffer[1024]; - FILE *file = 0; - int nBytes = 0; - static int totalFileBytes = 0; - - if (stat((char *)filename, &stat_buf) < 0) - return; - - RNG_RandomUpdate((unsigned char *)&stat_buf, sizeof(stat_buf)); - - file = fopen((char *)filename, "r"); - if (file != NULL) { - for (;;) { - size_t bytes = fread(buffer, 1, sizeof(buffer), file); - - if (bytes == 0) - break; - - RNG_RandomUpdate(buffer, bytes); - totalFileBytes += bytes; - if (totalFileBytes > 250000) - break; - } - fclose(file); - } - - nBytes = RNG_GetNoise(buffer, 20); - RNG_RandomUpdate(buffer, nBytes); -} - -static void -rng_systemJitter(void) -{ - dwNumFiles = 0; - EnumSystemFiles(ReadOneFile); - dwFileToRead++; - if (dwFileToRead >= dwNumFiles) { - dwFileToRead = 0; - } -} - -size_t -RNG_SystemRNG(void *dest, size_t maxLen) -{ - return rng_systemFromNoise(dest, maxLen); -} diff --git a/security/nss/lib/freebl/rijndael.c b/security/nss/lib/freebl/rijndael.c index 4bb182693..e4ad60388 100644 --- a/security/nss/lib/freebl/rijndael.c +++ b/security/nss/lib/freebl/rijndael.c @@ -18,27 +18,14 @@ #include "cts.h" #include "ctr.h" #include "gcm.h" +#include "mpi.h" #ifdef USE_HW_AES #include "intel-aes.h" #endif - -#include "mpi.h" - -#ifdef USE_HW_AES -static int has_intel_aes = 0; -static PRBool use_hw_aes = PR_FALSE; - #ifdef INTEL_GCM #include "intel-gcm.h" -static int has_intel_avx = 0; -static int has_intel_clmul = 0; -static PRBool use_hw_gcm = PR_FALSE; -#if defined(_MSC_VER) && !defined(_M_IX86) -#include <intrin.h> /* for _xgetbv() */ -#endif -#endif -#endif /* USE_HW_AES */ +#endif /* INTEL_GCM */ /* * There are currently five ways to build this code, varying in performance @@ -379,7 +366,7 @@ init_rijndael_tables(void) * Nk == 8 where it happens twice in every key word, in the same positions). * For now, I'm implementing this case "dumbly", w/o any unrolling. */ -static SECStatus +static void rijndael_key_expansion7(AESContext *cx, const unsigned char *key, unsigned int Nk) { unsigned int i; @@ -400,14 +387,169 @@ rijndael_key_expansion7(AESContext *cx, const unsigned char *key, unsigned int N tmp = SUBBYTE(tmp); *pW = W[i - Nk] ^ tmp; } - return SECSuccess; +} + +#if defined(NSS_X86_OR_X64) +#define EXPAND_KEY128(k, rcon, res) \ + tmp_key = _mm_aeskeygenassist_si128(k, rcon); \ + tmp_key = _mm_shuffle_epi32(tmp_key, 0xFF); \ + tmp = _mm_xor_si128(k, _mm_slli_si128(k, 4)); \ + tmp = _mm_xor_si128(tmp, _mm_slli_si128(tmp, 4)); \ + tmp = _mm_xor_si128(tmp, _mm_slli_si128(tmp, 4)); \ + res = _mm_xor_si128(tmp, tmp_key) + +static void +native_key_expansion128(AESContext *cx, const unsigned char *key) +{ + __m128i *keySchedule = cx->keySchedule; + pre_align __m128i tmp_key post_align; + pre_align __m128i tmp post_align; + keySchedule[0] = _mm_loadu_si128((__m128i *)key); + EXPAND_KEY128(keySchedule[0], 0x01, keySchedule[1]); + EXPAND_KEY128(keySchedule[1], 0x02, keySchedule[2]); + EXPAND_KEY128(keySchedule[2], 0x04, keySchedule[3]); + EXPAND_KEY128(keySchedule[3], 0x08, keySchedule[4]); + EXPAND_KEY128(keySchedule[4], 0x10, keySchedule[5]); + EXPAND_KEY128(keySchedule[5], 0x20, keySchedule[6]); + EXPAND_KEY128(keySchedule[6], 0x40, keySchedule[7]); + EXPAND_KEY128(keySchedule[7], 0x80, keySchedule[8]); + EXPAND_KEY128(keySchedule[8], 0x1B, keySchedule[9]); + EXPAND_KEY128(keySchedule[9], 0x36, keySchedule[10]); +} + +#define EXPAND_KEY192_PART1(res, k0, kt, rcon) \ + tmp2 = _mm_slli_si128(k0, 4); \ + tmp1 = _mm_xor_si128(k0, tmp2); \ + tmp2 = _mm_slli_si128(tmp2, 4); \ + tmp1 = _mm_xor_si128(_mm_xor_si128(tmp1, tmp2), _mm_slli_si128(tmp2, 4)); \ + tmp2 = _mm_aeskeygenassist_si128(kt, rcon); \ + res = _mm_xor_si128(tmp1, _mm_shuffle_epi32(tmp2, 0x55)) + +#define EXPAND_KEY192_PART2(res, k1, k2) \ + tmp2 = _mm_xor_si128(k1, _mm_slli_si128(k1, 4)); \ + res = _mm_xor_si128(tmp2, _mm_shuffle_epi32(k2, 0xFF)) + +#define EXPAND_KEY192(k0, res1, res2, res3, carry, rcon1, rcon2) \ + EXPAND_KEY192_PART1(tmp3, k0, res1, rcon1); \ + EXPAND_KEY192_PART2(carry, res1, tmp3); \ + res1 = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(res1), \ + _mm_castsi128_pd(tmp3), 0)); \ + res2 = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(tmp3), \ + _mm_castsi128_pd(carry), 1)); \ + EXPAND_KEY192_PART1(res3, tmp3, carry, rcon2) + +static void +native_key_expansion192(AESContext *cx, const unsigned char *key) +{ + __m128i *keySchedule = cx->keySchedule; + pre_align __m128i tmp1 post_align; + pre_align __m128i tmp2 post_align; + pre_align __m128i tmp3 post_align; + pre_align __m128i carry post_align; + keySchedule[0] = _mm_loadu_si128((__m128i *)key); + keySchedule[1] = _mm_loadu_si128((__m128i *)(key + 16)); + EXPAND_KEY192(keySchedule[0], keySchedule[1], keySchedule[2], + keySchedule[3], carry, 0x1, 0x2); + EXPAND_KEY192_PART2(keySchedule[4], carry, keySchedule[3]); + EXPAND_KEY192(keySchedule[3], keySchedule[4], keySchedule[5], + keySchedule[6], carry, 0x4, 0x8); + EXPAND_KEY192_PART2(keySchedule[7], carry, keySchedule[6]); + EXPAND_KEY192(keySchedule[6], keySchedule[7], keySchedule[8], + keySchedule[9], carry, 0x10, 0x20); + EXPAND_KEY192_PART2(keySchedule[10], carry, keySchedule[9]); + EXPAND_KEY192(keySchedule[9], keySchedule[10], keySchedule[11], + keySchedule[12], carry, 0x40, 0x80); +} + +#define EXPAND_KEY256_PART(res, rconx, k1x, k2x, X) \ + tmp_key = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(k2x, rconx), X); \ + tmp2 = _mm_slli_si128(k1x, 4); \ + tmp1 = _mm_xor_si128(k1x, tmp2); \ + tmp2 = _mm_slli_si128(tmp2, 4); \ + tmp1 = _mm_xor_si128(_mm_xor_si128(tmp1, tmp2), _mm_slli_si128(tmp2, 4)); \ + res = _mm_xor_si128(tmp1, tmp_key); + +#define EXPAND_KEY256(res1, res2, k1, k2, rcon) \ + EXPAND_KEY256_PART(res1, rcon, k1, k2, 0xFF); \ + EXPAND_KEY256_PART(res2, 0x00, k2, res1, 0xAA) + +static void +native_key_expansion256(AESContext *cx, const unsigned char *key) +{ + __m128i *keySchedule = cx->keySchedule; + pre_align __m128i tmp_key post_align; + pre_align __m128i tmp1 post_align; + pre_align __m128i tmp2 post_align; + keySchedule[0] = _mm_loadu_si128((__m128i *)key); + keySchedule[1] = _mm_loadu_si128((__m128i *)(key + 16)); + EXPAND_KEY256(keySchedule[2], keySchedule[3], keySchedule[0], + keySchedule[1], 0x01); + EXPAND_KEY256(keySchedule[4], keySchedule[5], keySchedule[2], + keySchedule[3], 0x02); + EXPAND_KEY256(keySchedule[6], keySchedule[7], keySchedule[4], + keySchedule[5], 0x04); + EXPAND_KEY256(keySchedule[8], keySchedule[9], keySchedule[6], + keySchedule[7], 0x08); + EXPAND_KEY256(keySchedule[10], keySchedule[11], keySchedule[8], + keySchedule[9], 0x10); + EXPAND_KEY256(keySchedule[12], keySchedule[13], keySchedule[10], + keySchedule[11], 0x20); + EXPAND_KEY256_PART(keySchedule[14], 0x40, keySchedule[12], + keySchedule[13], 0xFF); +} + +#endif /* NSS_X86_OR_X64 */ + +/* + * AES key expansion using aes-ni instructions. + */ +static void +native_key_expansion(AESContext *cx, const unsigned char *key, unsigned int Nk) +{ +#ifdef NSS_X86_OR_X64 + switch (Nk) { + case 4: + native_key_expansion128(cx, key); + return; + case 6: + native_key_expansion192(cx, key); + return; + case 8: + native_key_expansion256(cx, key); + return; + default: + /* This shouldn't happen. */ + PORT_Assert(0); + } +#else + PORT_Assert(0); +#endif /* NSS_X86_OR_X64 */ +} + +static void +native_encryptBlock(AESContext *cx, + unsigned char *output, + const unsigned char *input) +{ +#ifdef NSS_X86_OR_X64 + int i; + pre_align __m128i m post_align = _mm_loadu_si128((__m128i *)input); + m = _mm_xor_si128(m, cx->keySchedule[0]); + for (i = 1; i < cx->Nr; ++i) { + m = _mm_aesenc_si128(m, cx->keySchedule[i]); + } + m = _mm_aesenclast_si128(m, cx->keySchedule[cx->Nr]); + _mm_storeu_si128((__m128i *)output, m); +#else + PORT_Assert(0); +#endif /* NSS_X86_OR_X64 */ } /* rijndael_key_expansion * * Generate the expanded key from the key input by the user. */ -static SECStatus +static void rijndael_key_expansion(AESContext *cx, const unsigned char *key, unsigned int Nk) { unsigned int i; @@ -415,8 +557,10 @@ rijndael_key_expansion(AESContext *cx, const unsigned char *key, unsigned int Nk PRUint32 *pW; PRUint32 tmp; unsigned int round_key_words = cx->Nb * (cx->Nr + 1); - if (Nk == 7) - return rijndael_key_expansion7(cx, key, Nk); + if (Nk == 7) { + rijndael_key_expansion7(cx, key, Nk); + return; + } W = cx->expandedKey; /* The first Nk words contain the input cipher key */ memcpy(W, key, Nk * 4); @@ -475,7 +619,6 @@ rijndael_key_expansion(AESContext *cx, const unsigned char *key, unsigned int Nk *pW = W[i - Nk] ^ tmp; } } - return SECSuccess; } /* rijndael_invkey_expansion @@ -483,7 +626,7 @@ rijndael_key_expansion(AESContext *cx, const unsigned char *key, unsigned int Nk * Generate the expanded key for the inverse cipher from the key input by * the user. */ -static SECStatus +static void rijndael_invkey_expansion(AESContext *cx, const unsigned char *key, unsigned int Nk) { unsigned int r; @@ -491,8 +634,7 @@ rijndael_invkey_expansion(AESContext *cx, const unsigned char *key, unsigned int PRUint8 *b; int Nb = cx->Nb; /* begins like usual key expansion ... */ - if (rijndael_key_expansion(cx, key, Nk) != SECSuccess) - return SECFailure; + rijndael_key_expansion(cx, key, Nk); /* ... but has the additional step of InvMixColumn, * excepting the first and last round keys. */ @@ -534,12 +676,11 @@ rijndael_invkey_expansion(AESContext *cx, const unsigned char *key, unsigned int IMXC2(b[2]) ^ IMXC3(b[3]); } } - return SECSuccess; } + /************************************************************************** * - * Stuff related to Rijndael encryption/decryption, optimized for - * a 128-bit blocksize. + * Stuff related to Rijndael encryption/decryption. * *************************************************************************/ @@ -567,7 +708,7 @@ typedef union { #define STATE_BYTE(i) state.b[i] -static SECStatus NO_SANITIZE_ALIGNMENT +static void NO_SANITIZE_ALIGNMENT rijndael_encryptBlock128(AESContext *cx, unsigned char *output, const unsigned char *input) @@ -660,7 +801,6 @@ rijndael_encryptBlock128(AESContext *cx, memcpy(output, outBuf, sizeof outBuf); } #endif - return SECSuccess; } static SECStatus NO_SANITIZE_ALIGNMENT @@ -757,104 +897,6 @@ rijndael_decryptBlock128(AESContext *cx, /************************************************************************** * - * Stuff related to general Rijndael encryption/decryption, for blocksizes - * greater than 128 bits. - * - * XXX This code is currently untested! So far, AES specs have only been - * released for 128 bit blocksizes. This will be tested, but for now - * only the code above has been tested using known values. - * - *************************************************************************/ - -#define COLUMN(array, j) *((PRUint32 *)(array + j)) - -SECStatus -rijndael_encryptBlock(AESContext *cx, - unsigned char *output, - const unsigned char *input) -{ - return SECFailure; -#ifdef rijndael_large_blocks_fixed - unsigned int j, r, Nb; - unsigned int c2 = 0, c3 = 0; - PRUint32 *roundkeyw; - PRUint8 clone[RIJNDAEL_MAX_STATE_SIZE]; - Nb = cx->Nb; - roundkeyw = cx->expandedKey; - /* Step 1: Add Round Key 0 to initial state */ - for (j = 0; j < 4 * Nb; j += 4) { - COLUMN(clone, j) = COLUMN(input, j) ^ *roundkeyw++; - } - /* Step 2: Loop over rounds [1..NR-1] */ - for (r = 1; r < cx->Nr; ++r) { - for (j = 0; j < Nb; ++j) { - COLUMN(output, j) = T0(STATE_BYTE(4 * j)) ^ - T1(STATE_BYTE(4 * ((j + 1) % Nb) + 1)) ^ - T2(STATE_BYTE(4 * ((j + c2) % Nb) + 2)) ^ - T3(STATE_BYTE(4 * ((j + c3) % Nb) + 3)); - } - for (j = 0; j < 4 * Nb; j += 4) { - COLUMN(clone, j) = COLUMN(output, j) ^ *roundkeyw++; - } - } - /* Step 3: Do the last round */ - /* Final round does not employ MixColumn */ - for (j = 0; j < Nb; ++j) { - COLUMN(output, j) = ((BYTE0WORD(T2(STATE_BYTE(4 * j)))) | - (BYTE1WORD(T3(STATE_BYTE(4 * (j + 1) % Nb) + 1))) | - (BYTE2WORD(T0(STATE_BYTE(4 * (j + c2) % Nb) + 2))) | - (BYTE3WORD(T1(STATE_BYTE(4 * (j + c3) % Nb) + 3)))) ^ - *roundkeyw++; - } - return SECSuccess; -#endif -} - -SECStatus -rijndael_decryptBlock(AESContext *cx, - unsigned char *output, - const unsigned char *input) -{ - return SECFailure; -#ifdef rijndael_large_blocks_fixed - int j, r, Nb; - int c2 = 0, c3 = 0; - PRUint32 *roundkeyw; - PRUint8 clone[RIJNDAEL_MAX_STATE_SIZE]; - Nb = cx->Nb; - roundkeyw = cx->expandedKey + cx->Nb * cx->Nr + 3; - /* reverse key addition */ - for (j = 4 * Nb; j >= 0; j -= 4) { - COLUMN(clone, j) = COLUMN(input, j) ^ *roundkeyw--; - } - /* Loop over rounds in reverse [NR..1] */ - for (r = cx->Nr; r > 1; --r) { - /* Invert the (InvByteSub*InvMixColumn)(InvShiftRow(state)) */ - for (j = 0; j < Nb; ++j) { - COLUMN(output, 4 * j) = TInv0(STATE_BYTE(4 * j)) ^ - TInv1(STATE_BYTE(4 * (j + Nb - 1) % Nb) + 1) ^ - TInv2(STATE_BYTE(4 * (j + Nb - c2) % Nb) + 2) ^ - TInv3(STATE_BYTE(4 * (j + Nb - c3) % Nb) + 3); - } - /* Invert the key addition step */ - for (j = 4 * Nb; j >= 0; j -= 4) { - COLUMN(clone, j) = COLUMN(output, j) ^ *roundkeyw--; - } - } - /* inverse sub */ - for (j = 0; j < 4 * Nb; ++j) { - output[j] = SINV(clone[j]); - } - /* final key addition */ - for (j = 4 * Nb; j >= 0; j -= 4) { - COLUMN(output, j) ^= *roundkeyw--; - } - return SECSuccess; -#endif -} - -/************************************************************************** - * * Rijndael modes of operation (ECB and CBC) * *************************************************************************/ @@ -862,22 +904,21 @@ rijndael_decryptBlock(AESContext *cx, static SECStatus rijndael_encryptECB(AESContext *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, - const unsigned char *input, unsigned int inputLen, - unsigned int blocksize) + const unsigned char *input, unsigned int inputLen) { - SECStatus rv; AESBlockFunc *encryptor; - encryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE) - ? &rijndael_encryptBlock128 - : &rijndael_encryptBlock; + if (aesni_support()) { + /* Use hardware acceleration for normal AES parameters. */ + encryptor = &native_encryptBlock; + } else { + encryptor = &rijndael_encryptBlock128; + } while (inputLen > 0) { - rv = (*encryptor)(cx, output, input); - if (rv != SECSuccess) - return rv; - output += blocksize; - input += blocksize; - inputLen -= blocksize; + (*encryptor)(cx, output, input); + output += AES_BLOCK_SIZE; + input += AES_BLOCK_SIZE; + inputLen -= AES_BLOCK_SIZE; } return SECSuccess; } @@ -885,58 +926,44 @@ rijndael_encryptECB(AESContext *cx, unsigned char *output, static SECStatus rijndael_encryptCBC(AESContext *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, - const unsigned char *input, unsigned int inputLen, - unsigned int blocksize) + const unsigned char *input, unsigned int inputLen) { unsigned int j; - SECStatus rv; - AESBlockFunc *encryptor; unsigned char *lastblock; - unsigned char inblock[RIJNDAEL_MAX_STATE_SIZE * 8]; + unsigned char inblock[AES_BLOCK_SIZE * 8]; if (!inputLen) return SECSuccess; lastblock = cx->iv; - encryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE) - ? &rijndael_encryptBlock128 - : &rijndael_encryptBlock; while (inputLen > 0) { /* XOR with the last block (IV if first block) */ - for (j = 0; j < blocksize; ++j) + for (j = 0; j < AES_BLOCK_SIZE; ++j) { inblock[j] = input[j] ^ lastblock[j]; + } /* encrypt */ - rv = (*encryptor)(cx, output, inblock); - if (rv != SECSuccess) - return rv; + rijndael_encryptBlock128(cx, output, inblock); /* move to the next block */ lastblock = output; - output += blocksize; - input += blocksize; - inputLen -= blocksize; + output += AES_BLOCK_SIZE; + input += AES_BLOCK_SIZE; + inputLen -= AES_BLOCK_SIZE; } - memcpy(cx->iv, lastblock, blocksize); + memcpy(cx->iv, lastblock, AES_BLOCK_SIZE); return SECSuccess; } static SECStatus rijndael_decryptECB(AESContext *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, - const unsigned char *input, unsigned int inputLen, - unsigned int blocksize) + const unsigned char *input, unsigned int inputLen) { - SECStatus rv; - AESBlockFunc *decryptor; - - decryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE) - ? &rijndael_decryptBlock128 - : &rijndael_decryptBlock; while (inputLen > 0) { - rv = (*decryptor)(cx, output, input); - if (rv != SECSuccess) - return rv; - output += blocksize; - input += blocksize; - inputLen -= blocksize; + if (rijndael_decryptBlock128(cx, output, input) != SECSuccess) { + return SECFailure; + } + output += AES_BLOCK_SIZE; + input += AES_BLOCK_SIZE; + inputLen -= AES_BLOCK_SIZE; } return SECSuccess; } @@ -944,43 +971,37 @@ rijndael_decryptECB(AESContext *cx, unsigned char *output, static SECStatus rijndael_decryptCBC(AESContext *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, - const unsigned char *input, unsigned int inputLen, - unsigned int blocksize) + const unsigned char *input, unsigned int inputLen) { - SECStatus rv; - AESBlockFunc *decryptor; const unsigned char *in; unsigned char *out; unsigned int j; - unsigned char newIV[RIJNDAEL_MAX_BLOCKSIZE]; + unsigned char newIV[AES_BLOCK_SIZE]; if (!inputLen) return SECSuccess; PORT_Assert(output - input >= 0 || input - output >= (int)inputLen); - decryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE) - ? &rijndael_decryptBlock128 - : &rijndael_decryptBlock; - in = input + (inputLen - blocksize); - memcpy(newIV, in, blocksize); - out = output + (inputLen - blocksize); - while (inputLen > blocksize) { - rv = (*decryptor)(cx, out, in); - if (rv != SECSuccess) - return rv; - for (j = 0; j < blocksize; ++j) - out[j] ^= in[(int)(j - blocksize)]; - out -= blocksize; - in -= blocksize; - inputLen -= blocksize; + in = input + (inputLen - AES_BLOCK_SIZE); + memcpy(newIV, in, AES_BLOCK_SIZE); + out = output + (inputLen - AES_BLOCK_SIZE); + while (inputLen > AES_BLOCK_SIZE) { + if (rijndael_decryptBlock128(cx, out, in) != SECSuccess) { + return SECFailure; + } + for (j = 0; j < AES_BLOCK_SIZE; ++j) + out[j] ^= in[(int)(j - AES_BLOCK_SIZE)]; + out -= AES_BLOCK_SIZE; + in -= AES_BLOCK_SIZE; + inputLen -= AES_BLOCK_SIZE; } if (in == input) { - rv = (*decryptor)(cx, out, in); - if (rv != SECSuccess) - return rv; - for (j = 0; j < blocksize; ++j) + if (rijndael_decryptBlock128(cx, out, in) != SECSuccess) { + return SECFailure; + } + for (j = 0; j < AES_BLOCK_SIZE; ++j) out[j] ^= cx->iv[j]; } - memcpy(cx->iv, newIV, blocksize); + memcpy(cx->iv, newIV, AES_BLOCK_SIZE); return SECSuccess; } @@ -996,41 +1017,15 @@ rijndael_decryptCBC(AESContext *cx, unsigned char *output, AESContext * AES_AllocateContext(void) { - return PORT_ZNew(AESContext); -} - -#ifdef INTEL_GCM -/* - * Adapted from the example code in "How to detect New Instruction support in - * the 4th generation Intel Core processor family" by Max Locktyukhin. - * - * XGETBV: - * Reads an extended control register (XCR) specified by ECX into EDX:EAX. - */ -static PRBool -check_xcr0_ymm() -{ - PRUint32 xcr0; -#if defined(_MSC_VER) -#if defined(_M_IX86) - __asm { - mov ecx, 0 - xgetbv - mov xcr0, eax + /* aligned_alloc is C11 so we have to do it the old way. */ + AESContext *ctx = PORT_ZAlloc(sizeof(AESContext) + 15); + if (ctx == NULL) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + return NULL; } -#else - xcr0 = (PRUint32)_xgetbv(0); /* Requires VS2010 SP1 or later. */ -#endif -#else - __asm__("xgetbv" - : "=a"(xcr0) - : "c"(0) - : "%edx"); -#endif - /* Check if xmm and ymm state are enabled in XCR0. */ - return (xcr0 & 6) == 6; + ctx->mem = ctx; + return (AESContext *)(((uintptr_t)ctx + 15) & ~(uintptr_t)0x0F); } -#endif /* ** Initialize a new AES context suitable for AES encryption/decryption in @@ -1039,21 +1034,19 @@ check_xcr0_ymm() */ static SECStatus aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, - const unsigned char *iv, int mode, unsigned int encrypt, - unsigned int blocksize) + const unsigned char *iv, int mode, unsigned int encrypt) { unsigned int Nk; - /* According to Rijndael AES Proposal, section 12.1, block and key - * lengths between 128 and 256 bits are supported, as long as the + PRBool use_hw_aes; + /* According to AES, block lengths are 128 and key lengths are 128, 192, or + * 256 bits. We support other key sizes as well [128, 256] as long as the * length in bytes is divisible by 4. */ + if (key == NULL || - keysize < RIJNDAEL_MIN_BLOCKSIZE || - keysize > RIJNDAEL_MAX_BLOCKSIZE || - keysize % 4 != 0 || - blocksize < RIJNDAEL_MIN_BLOCKSIZE || - blocksize > RIJNDAEL_MAX_BLOCKSIZE || - blocksize % 4 != 0) { + keysize < AES_BLOCK_SIZE || + keysize > 32 || + keysize % 4 != 0) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } @@ -1069,45 +1062,16 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } -#ifdef USE_HW_AES - if (has_intel_aes == 0) { - unsigned long eax, ebx, ecx, edx; - char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES"); - - if (disable_hw_aes == NULL) { - freebl_cpuid(1, &eax, &ebx, &ecx, &edx); - has_intel_aes = (ecx & (1 << 25)) != 0 ? 1 : -1; -#ifdef INTEL_GCM - has_intel_clmul = (ecx & (1 << 1)) != 0 ? 1 : -1; - if ((ecx & (1 << 27)) != 0 && (ecx & (1 << 28)) != 0 && - check_xcr0_ymm()) { - has_intel_avx = 1; - } else { - has_intel_avx = -1; - } -#endif - } else { - has_intel_aes = -1; -#ifdef INTEL_GCM - has_intel_avx = -1; - has_intel_clmul = -1; -#endif - } - } - use_hw_aes = (PRBool)(has_intel_aes > 0 && (keysize % 8) == 0 && blocksize == 16); -#ifdef INTEL_GCM - use_hw_gcm = (PRBool)(use_hw_aes && has_intel_avx > 0 && has_intel_clmul > 0); -#endif -#endif /* USE_HW_AES */ + use_hw_aes = aesni_support() && (keysize % 8) == 0; /* Nb = (block size in bits) / 32 */ - cx->Nb = blocksize / 4; + cx->Nb = AES_BLOCK_SIZE / 4; /* Nk = (key size in bits) / 32 */ Nk = keysize / 4; /* Obtain number of rounds from "table" */ cx->Nr = RIJNDAEL_NUM_ROUNDS(Nk, cx->Nb); /* copy in the iv, if neccessary */ if (mode == NSS_AES_CBC) { - memcpy(cx->iv, iv, blocksize); + memcpy(cx->iv, iv, AES_BLOCK_SIZE); #ifdef USE_HW_AES if (use_hw_aes) { cx->worker = (freeblCipherFunc) @@ -1135,7 +1099,7 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, PORT_Assert((cx->Nb * (cx->Nr + 1)) <= RIJNDAEL_MAX_EXP_KEY_SIZE); if ((cx->Nb * (cx->Nr + 1)) > RIJNDAEL_MAX_EXP_KEY_SIZE) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - goto cleanup; + return SECFailure; } #ifdef USE_HW_AES if (use_hw_aes) { @@ -1148,25 +1112,28 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, defined(RIJNDAEL_GENERATE_TABLES_MACRO) if (rijndaelTables == NULL) { if (PR_CallOnce(&coRTInit, init_rijndael_tables) != PR_SUCCESS) { - return SecFailure; + return SECFailure; } } #endif /* Generate expanded key */ if (encrypt) { - if (rijndael_key_expansion(cx, key, Nk) != SECSuccess) - goto cleanup; + if (use_hw_aes && (cx->mode == NSS_AES_GCM || cx->mode == NSS_AES || + cx->mode == NSS_AES_CTR)) { + PORT_Assert(keysize == 16 || keysize == 24 || keysize == 32); + /* Prepare hardware key for normal AES parameters. */ + native_key_expansion(cx, key, Nk); + } else { + rijndael_key_expansion(cx, key, Nk); + } } else { - if (rijndael_invkey_expansion(cx, key, Nk) != SECSuccess) - goto cleanup; + rijndael_invkey_expansion(cx, key, Nk); } } cx->worker_cx = cx; cx->destroy = NULL; cx->isBlock = PR_TRUE; return SECSuccess; -cleanup: - return SECFailure; } SECStatus @@ -1178,6 +1145,11 @@ AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, PRBool baseencrypt = encrypt; SECStatus rv; + if (blocksize != AES_BLOCK_SIZE) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + switch (mode) { case NSS_AES_CTS: basemode = NSS_AES_CBC; @@ -1188,45 +1160,47 @@ AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, baseencrypt = PR_TRUE; break; } - /* make sure enough is initializes so we can safely call Destroy */ + /* Make sure enough is initialized so we can safely call Destroy. */ cx->worker_cx = NULL; cx->destroy = NULL; - rv = aes_InitContext(cx, key, keysize, iv, basemode, - baseencrypt, blocksize); + cx->mode = mode; + rv = aes_InitContext(cx, key, keysize, iv, basemode, baseencrypt); if (rv != SECSuccess) { AES_DestroyContext(cx, PR_FALSE); return rv; } - cx->mode = mode; /* finally, set up any mode specific contexts */ switch (mode) { case NSS_AES_CTS: - cx->worker_cx = CTS_CreateContext(cx, cx->worker, iv, blocksize); + cx->worker_cx = CTS_CreateContext(cx, cx->worker, iv); cx->worker = (freeblCipherFunc)(encrypt ? CTS_EncryptUpdate : CTS_DecryptUpdate); cx->destroy = (freeblDestroyFunc)CTS_DestroyContext; cx->isBlock = PR_FALSE; break; case NSS_AES_GCM: -#ifdef INTEL_GCM - if (use_hw_gcm) { - cx->worker_cx = intel_AES_GCM_CreateContext(cx, cx->worker, iv, blocksize); - cx->worker = (freeblCipherFunc)(encrypt ? intel_AES_GCM_EncryptUpdate : intel_AES_GCM_DecryptUpdate); +#if defined(INTEL_GCM) && defined(USE_HW_AES) + if (aesni_support() && (keysize % 8) == 0 && avx_support() && + clmul_support()) { + cx->worker_cx = intel_AES_GCM_CreateContext(cx, cx->worker, iv); + cx->worker = (freeblCipherFunc)(encrypt ? intel_AES_GCM_EncryptUpdate + : intel_AES_GCM_DecryptUpdate); cx->destroy = (freeblDestroyFunc)intel_AES_GCM_DestroyContext; cx->isBlock = PR_FALSE; } else #endif { - cx->worker_cx = GCM_CreateContext(cx, cx->worker, iv, blocksize); - cx->worker = (freeblCipherFunc)(encrypt ? GCM_EncryptUpdate : GCM_DecryptUpdate); + cx->worker_cx = GCM_CreateContext(cx, cx->worker, iv); + cx->worker = (freeblCipherFunc)(encrypt ? GCM_EncryptUpdate + : GCM_DecryptUpdate); cx->destroy = (freeblDestroyFunc)GCM_DestroyContext; cx->isBlock = PR_FALSE; } break; case NSS_AES_CTR: - cx->worker_cx = CTR_CreateContext(cx, cx->worker, iv, blocksize); + cx->worker_cx = CTR_CreateContext(cx, cx->worker, iv); #if defined(USE_HW_AES) && defined(_MSC_VER) - if (use_hw_aes) { + if (aesni_support() && (keysize % 8) == 0) { cx->worker = (freeblCipherFunc)CTR_Update_HW_AES; } else #endif @@ -1238,7 +1212,7 @@ AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, break; default: /* everything has already been set up by aes_InitContext, just - * return */ + * return */ return SECSuccess; } /* check to see if we succeeded in getting the worker context */ @@ -1287,8 +1261,9 @@ AES_DestroyContext(AESContext *cx, PRBool freeit) cx->worker_cx = NULL; cx->destroy = NULL; } - if (freeit) - PORT_Free(cx); + if (freeit) { + PORT_Free(cx->mem); + } } /* @@ -1302,14 +1277,12 @@ AES_Encrypt(AESContext *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, const unsigned char *input, unsigned int inputLen) { - int blocksize; /* Check args */ if (cx == NULL || output == NULL || (input == NULL && inputLen != 0)) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - blocksize = 4 * cx->Nb; - if (cx->isBlock && (inputLen % blocksize != 0)) { + if (cx->isBlock && (inputLen % AES_BLOCK_SIZE != 0)) { PORT_SetError(SEC_ERROR_INPUT_LEN); return SECFailure; } @@ -1340,7 +1313,7 @@ AES_Encrypt(AESContext *cx, unsigned char *output, #endif return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen, - input, inputLen, blocksize); + input, inputLen, AES_BLOCK_SIZE); } /* @@ -1354,14 +1327,12 @@ AES_Decrypt(AESContext *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, const unsigned char *input, unsigned int inputLen) { - int blocksize; /* Check args */ if (cx == NULL || output == NULL || (input == NULL && inputLen != 0)) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - blocksize = 4 * cx->Nb; - if (cx->isBlock && (inputLen % blocksize != 0)) { + if (cx->isBlock && (inputLen % AES_BLOCK_SIZE != 0)) { PORT_SetError(SEC_ERROR_INPUT_LEN); return SECFailure; } @@ -1371,5 +1342,5 @@ AES_Decrypt(AESContext *cx, unsigned char *output, } *outputLen = inputLen; return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen, - input, inputLen, blocksize); + input, inputLen, AES_BLOCK_SIZE); } diff --git a/security/nss/lib/freebl/rijndael.h b/security/nss/lib/freebl/rijndael.h index 0e14ec2fc..1f4a8a9f7 100644 --- a/security/nss/lib/freebl/rijndael.h +++ b/security/nss/lib/freebl/rijndael.h @@ -6,13 +6,15 @@ #define _RIJNDAEL_H_ 1 #include "blapii.h" +#include <stdint.h> -#define RIJNDAEL_MIN_BLOCKSIZE 16 /* bytes */ -#define RIJNDAEL_MAX_BLOCKSIZE 32 /* bytes */ +#ifdef NSS_X86_OR_X64 +#include <wmmintrin.h> /* aes-ni */ +#endif -typedef SECStatus AESBlockFunc(AESContext *cx, - unsigned char *output, - const unsigned char *input); +typedef void AESBlockFunc(AESContext *cx, + unsigned char *output, + const unsigned char *input); /* RIJNDAEL_NUM_ROUNDS * @@ -23,24 +25,18 @@ typedef SECStatus AESBlockFunc(AESContext *cx, #define RIJNDAEL_NUM_ROUNDS(Nk, Nb) \ (PR_MAX(Nk, Nb) + 6) -/* RIJNDAEL_MAX_STATE_SIZE - * - * Maximum number of bytes in the state (spec includes up to 256-bit block - * size) - */ -#define RIJNDAEL_MAX_STATE_SIZE 32 - /* * This magic number is (Nb_max * (Nr_max + 1)) * where Nb_max is the maximum block size in 32-bit words, * Nr_max is the maximum number of rounds, which is Nb_max + 6 */ -#define RIJNDAEL_MAX_EXP_KEY_SIZE (8 * 15) +#define RIJNDAEL_MAX_EXP_KEY_SIZE (4 * 15) /* AESContextStr * * Values which maintain the state for Rijndael encryption/decryption. * + * keySchedule - 128-bit registers for the key-schedule * iv - initialization vector for CBC mode * Nb - the number of bytes in a block, specified by user * Nr - the number of rounds, specified by a table @@ -51,17 +47,23 @@ typedef SECStatus AESBlockFunc(AESContext *cx, * isBlock - is the mode of operation a block cipher or a stream cipher? */ struct AESContextStr { + /* NOTE: Offsets to members in this struct are hardcoded in assembly. + * Don't change the struct without updating intel-aes.s and intel-gcm.s. */ + union { +#if defined(NSS_X86_OR_X64) + __m128i keySchedule[15]; +#endif + PRUint32 expandedKey[RIJNDAEL_MAX_EXP_KEY_SIZE]; + }; unsigned int Nb; unsigned int Nr; freeblCipherFunc worker; - /* NOTE: The offsets of iv and expandedKey are hardcoded in intel-aes.s. - * Don't add new members before them without updating intel-aes.s. */ - unsigned char iv[RIJNDAEL_MAX_BLOCKSIZE]; - PRUint32 expandedKey[RIJNDAEL_MAX_EXP_KEY_SIZE]; + unsigned char iv[AES_BLOCK_SIZE]; freeblDestroyFunc destroy; void *worker_cx; PRBool isBlock; int mode; + void *mem; /* Start of the allocated memory to free. */ }; #endif /* _RIJNDAEL_H_ */ diff --git a/security/nss/lib/freebl/rsa.c b/security/nss/lib/freebl/rsa.c index ff8c40ed9..7354d9317 100644 --- a/security/nss/lib/freebl/rsa.c +++ b/security/nss/lib/freebl/rsa.c @@ -190,12 +190,12 @@ cleanup: } return rv; } -static SECStatus + +SECStatus generate_prime(mp_int *prime, int primeLen) { mp_err err = MP_OKAY; SECStatus rv = SECSuccess; - unsigned long counter = 0; int piter; unsigned char *pb = NULL; pb = PORT_Alloc(primeLen); @@ -208,7 +208,7 @@ generate_prime(mp_int *prime, int primeLen) pb[0] |= 0xC0; /* set two high-order bits */ pb[primeLen - 1] |= 0x01; /* set low-order bit */ CHECK_MPI_OK(mp_read_unsigned_octets(prime, pb, primeLen)); - err = mpp_make_prime(prime, primeLen * 8, PR_FALSE, &counter); + err = mpp_make_prime(prime, primeLen * 8, PR_FALSE); if (err != MP_NO) goto cleanup; /* keep going while err == MP_NO */ @@ -321,7 +321,6 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent) kiter = 0; max_attempts = 5 * (keySizeInBits / 2); /* FIPS 186-4 B.3.3 steps 4.7 and 5.8 */ do { - prerr = 0; PORT_SetError(0); CHECK_SEC_OK(generate_prime(&p, primeLen)); CHECK_SEC_OK(generate_prime(&q, primeLen)); @@ -348,8 +347,7 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent) kiter++; /* loop until have primes */ } while (prerr == SEC_ERROR_NEED_RANDOM && kiter < max_attempts); - if (prerr) - goto cleanup; + cleanup: mp_clear(&p); mp_clear(&q); @@ -1236,7 +1234,10 @@ get_blinding_params(RSAPrivateKey *key, mp_int *n, unsigned int modLen, * Now, search its list of ready blinding params for a usable one. */ while (0 != (bp = rsabp->bp)) { - if (--(bp->counter) > 0) { +#ifndef UNSAFE_FUZZER_MODE + if (--(bp->counter) > 0) +#endif + { /* Found a match and there are still remaining uses left */ /* Return the parameters */ CHECK_MPI_OK(mp_copy(&bp->f, f)); @@ -1548,7 +1549,7 @@ cleanup: return rv; } -static SECStatus +SECStatus RSA_Init(void) { if (PR_CallOnce(&coBPInit, init_blinding_params_list) != PR_SUCCESS) { @@ -1558,12 +1559,6 @@ RSA_Init(void) return SECSuccess; } -SECStatus -BL_Init(void) -{ - return RSA_Init(); -} - /* cleanup at shutdown */ void RSA_Cleanup(void) diff --git a/security/nss/lib/freebl/rsapkcs.c b/security/nss/lib/freebl/rsapkcs.c index 577fe1f61..ad18c8b73 100644 --- a/security/nss/lib/freebl/rsapkcs.c +++ b/security/nss/lib/freebl/rsapkcs.c @@ -85,6 +85,25 @@ rsa_modulusLen(SECItem *modulus) return modLen; } +static unsigned int +rsa_modulusBits(SECItem *modulus) +{ + unsigned char byteZero = modulus->data[0]; + unsigned int numBits = (modulus->len - 1) * 8; + + if (byteZero == 0) { + numBits -= 8; + byteZero = modulus->data[1]; + } + + while (byteZero > 0) { + numBits++; + byteZero >>= 1; + } + + return numBits; +} + /* * Format one block of data for public/private key encryption using * the rules defined in PKCS #1. @@ -271,10 +290,12 @@ MGF1(HASH_HashType hashAlg, const SECHashObject *hash; void *hashContext; unsigned char C[4]; + SECStatus rv = SECSuccess; hash = HASH_GetRawHashObject(hashAlg); - if (hash == NULL) + if (hash == NULL) { return SECFailure; + } hashContext = (*hash->create)(); rounds = (maskLen + hash->length - 1) / hash->length; @@ -295,14 +316,19 @@ MGF1(HASH_HashType hashAlg, (*hash->end)(hashContext, tempHash, &digestLen, hash->length); } else { /* we're in the last round and need to cut the hash */ temp = (unsigned char *)PORT_Alloc(hash->length); + if (!temp) { + rv = SECFailure; + goto done; + } (*hash->end)(hashContext, temp, &digestLen, hash->length); PORT_Memcpy(tempHash, temp, maskLen - counter * hash->length); PORT_Free(temp); } } - (*hash->destroy)(hashContext, PR_TRUE); - return SECSuccess; +done: + (*hash->destroy)(hashContext, PR_TRUE); + return rv; } /* XXX Doesn't set error code */ @@ -962,12 +988,11 @@ failure: * We use mHash instead of M as input. * emBits from the RFC is just modBits - 1, see section 8.1.1. * We only support MGF1 as the MGF. - * - * NOTE: this code assumes modBits is a multiple of 8. */ static SECStatus emsa_pss_encode(unsigned char *em, unsigned int emLen, + unsigned int emBits, const unsigned char *mHash, HASH_HashType hashAlg, HASH_HashType maskHashAlg, @@ -1032,7 +1057,7 @@ emsa_pss_encode(unsigned char *em, PORT_Free(dbMask); /* Step 11 */ - em[0] &= 0x7f; + em[0] &= 0xff >> (8 * emLen - emBits); /* Step 12 */ em[emLen - 1] = 0xbc; @@ -1046,13 +1071,12 @@ emsa_pss_encode(unsigned char *em, * We use mHash instead of M as input. * emBits from the RFC is just modBits - 1, see section 8.1.2. * We only support MGF1 as the MGF. - * - * NOTE: this code assumes modBits is a multiple of 8. */ static SECStatus emsa_pss_verify(const unsigned char *mHash, const unsigned char *em, unsigned int emLen, + unsigned int emBits, HASH_HashType hashAlg, HASH_HashType maskHashAlg, unsigned int saltLen) @@ -1063,15 +1087,22 @@ emsa_pss_verify(const unsigned char *mHash, unsigned char *H_; /* H' from the RFC */ unsigned int i; unsigned int dbMaskLen; + unsigned int zeroBits; SECStatus rv; hash = HASH_GetRawHashObject(hashAlg); dbMaskLen = emLen - hash->length - 1; - /* Step 3 + 4 + 6 */ + /* Step 3 + 4 */ if ((emLen < (hash->length + saltLen + 2)) || - (em[emLen - 1] != 0xbc) || - ((em[0] & 0x80) != 0)) { + (em[emLen - 1] != 0xbc)) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + return SECFailure; + } + + /* Step 6 */ + zeroBits = 8 * emLen - emBits; + if (em[0] >> (8 - zeroBits)) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); return SECFailure; } @@ -1091,7 +1122,7 @@ emsa_pss_verify(const unsigned char *mHash, } /* Step 9 */ - db[0] &= 0x7f; + db[0] &= 0xff >> zeroBits; /* Step 10 */ for (i = 0; i < (dbMaskLen - saltLen - 1); i++) { @@ -1156,7 +1187,9 @@ RSA_SignPSS(RSAPrivateKey *key, { SECStatus rv = SECSuccess; unsigned int modulusLen = rsa_modulusLen(&key->modulus); - unsigned char *pssEncoded = NULL; + unsigned int modulusBits = rsa_modulusBits(&key->modulus); + unsigned int emLen = modulusLen; + unsigned char *pssEncoded, *em; if (maxOutputLen < modulusLen) { PORT_SetError(SEC_ERROR_OUTPUT_LEN); @@ -1168,16 +1201,24 @@ RSA_SignPSS(RSAPrivateKey *key, return SECFailure; } - pssEncoded = (unsigned char *)PORT_Alloc(modulusLen); + pssEncoded = em = (unsigned char *)PORT_Alloc(modulusLen); if (pssEncoded == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; } - rv = emsa_pss_encode(pssEncoded, modulusLen, input, hashAlg, + + /* len(em) == ceil((modulusBits - 1) / 8). */ + if (modulusBits % 8 == 1) { + em[0] = 0; + emLen--; + em++; + } + rv = emsa_pss_encode(em, emLen, modulusBits - 1, input, hashAlg, maskHashAlg, salt, saltLength); if (rv != SECSuccess) goto done; + // This sets error codes upon failure. rv = RSA_PrivateKeyOpDoubleChecked(key, output, pssEncoded); *outputLen = modulusLen; @@ -1198,7 +1239,9 @@ RSA_CheckSignPSS(RSAPublicKey *key, { SECStatus rv; unsigned int modulusLen = rsa_modulusLen(&key->modulus); - unsigned char *buffer; + unsigned int modulusBits = rsa_modulusBits(&key->modulus); + unsigned int emLen = modulusLen; + unsigned char *buffer, *em; if (sigLen != modulusLen) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); @@ -1210,7 +1253,7 @@ RSA_CheckSignPSS(RSAPublicKey *key, return SECFailure; } - buffer = (unsigned char *)PORT_Alloc(modulusLen); + buffer = em = (unsigned char *)PORT_Alloc(modulusLen); if (!buffer) { PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; @@ -1223,14 +1266,18 @@ RSA_CheckSignPSS(RSAPublicKey *key, return SECFailure; } - rv = emsa_pss_verify(hash, buffer, modulusLen, hashAlg, + /* len(em) == ceil((modulusBits - 1) / 8). */ + if (modulusBits % 8 == 1) { + emLen--; + em++; + } + rv = emsa_pss_verify(hash, em, emLen, modulusBits - 1, hashAlg, maskHashAlg, saltLength); - PORT_Free(buffer); + PORT_Free(buffer); return rv; } -/* XXX Doesn't set error code */ SECStatus RSA_Sign(RSAPrivateKey *key, unsigned char *output, @@ -1239,34 +1286,34 @@ RSA_Sign(RSAPrivateKey *key, const unsigned char *input, unsigned int inputLen) { - SECStatus rv = SECSuccess; + SECStatus rv = SECFailure; unsigned int modulusLen = rsa_modulusLen(&key->modulus); - SECItem formatted; - SECItem unformatted; + SECItem formatted = { siBuffer, NULL, 0 }; + SECItem unformatted = { siBuffer, (unsigned char *)input, inputLen }; - if (maxOutputLen < modulusLen) - return SECFailure; + if (maxOutputLen < modulusLen) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); + goto done; + } - unformatted.len = inputLen; - unformatted.data = (unsigned char *)input; - formatted.data = NULL; rv = rsa_FormatBlock(&formatted, modulusLen, RSA_BlockPrivate, &unformatted); - if (rv != SECSuccess) + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); goto done; + } + // This sets error codes upon failure. rv = RSA_PrivateKeyOpDoubleChecked(key, output, formatted.data); *outputLen = modulusLen; - goto done; - done: - if (formatted.data != NULL) + if (formatted.data != NULL) { PORT_ZFree(formatted.data, modulusLen); + } return rv; } -/* XXX Doesn't set error code */ SECStatus RSA_CheckSign(RSAPublicKey *key, const unsigned char *sig, @@ -1274,60 +1321,71 @@ RSA_CheckSign(RSAPublicKey *key, const unsigned char *data, unsigned int dataLen) { - SECStatus rv; + SECStatus rv = SECFailure; unsigned int modulusLen = rsa_modulusLen(&key->modulus); unsigned int i; - unsigned char *buffer; + unsigned char *buffer = NULL; + + if (sigLen != modulusLen) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } - if (sigLen != modulusLen) - goto failure; /* * 0x00 || BT || Pad || 0x00 || ActualData * * The "3" below is the first octet + the second octet + the 0x00 * octet that always comes just before the ActualData. */ - if (dataLen > modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)) - goto failure; + if (dataLen > modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)) { + PORT_SetError(SEC_ERROR_BAD_DATA); + goto done; + } buffer = (unsigned char *)PORT_Alloc(modulusLen + 1); - if (!buffer) - goto failure; + if (!buffer) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + goto done; + } - rv = RSA_PublicKeyOp(key, buffer, sig); - if (rv != SECSuccess) - goto loser; + if (RSA_PublicKeyOp(key, buffer, sig) != SECSuccess) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } /* * check the padding that was used */ if (buffer[0] != RSA_BLOCK_FIRST_OCTET || buffer[1] != (unsigned char)RSA_BlockPrivate) { - goto loser; + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; } for (i = 2; i < modulusLen - dataLen - 1; i++) { - if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) - goto loser; + if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } + } + if (buffer[i] != RSA_BLOCK_AFTER_PAD_OCTET) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; } - if (buffer[i] != RSA_BLOCK_AFTER_PAD_OCTET) - goto loser; /* * make sure we get the same results */ - if (PORT_Memcmp(buffer + modulusLen - dataLen, data, dataLen) != 0) - goto loser; - - PORT_Free(buffer); - return SECSuccess; + if (PORT_Memcmp(buffer + modulusLen - dataLen, data, dataLen) == 0) { + rv = SECSuccess; + } -loser: - PORT_Free(buffer); -failure: - return SECFailure; +done: + if (buffer) { + PORT_Free(buffer); + } + return rv; } -/* XXX Doesn't set error code */ SECStatus RSA_CheckSignRecover(RSAPublicKey *key, unsigned char *output, @@ -1336,21 +1394,27 @@ RSA_CheckSignRecover(RSAPublicKey *key, const unsigned char *sig, unsigned int sigLen) { - SECStatus rv; + SECStatus rv = SECFailure; unsigned int modulusLen = rsa_modulusLen(&key->modulus); unsigned int i; - unsigned char *buffer; + unsigned char *buffer = NULL; - if (sigLen != modulusLen) - goto failure; + if (sigLen != modulusLen) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } buffer = (unsigned char *)PORT_Alloc(modulusLen + 1); - if (!buffer) - goto failure; + if (!buffer) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + goto done; + } + + if (RSA_PublicKeyOp(key, buffer, sig) != SECSuccess) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } - rv = RSA_PublicKeyOp(key, buffer, sig); - if (rv != SECSuccess) - goto loser; *outputLen = 0; /* @@ -1358,28 +1422,34 @@ RSA_CheckSignRecover(RSAPublicKey *key, */ if (buffer[0] != RSA_BLOCK_FIRST_OCTET || buffer[1] != (unsigned char)RSA_BlockPrivate) { - goto loser; + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; } for (i = 2; i < modulusLen; i++) { if (buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET) { *outputLen = modulusLen - i - 1; break; } - if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) - goto loser; + if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } + } + if (*outputLen == 0) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } + if (*outputLen > maxOutputLen) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); + goto done; } - if (*outputLen == 0) - goto loser; - if (*outputLen > maxOutputLen) - goto loser; PORT_Memcpy(output, buffer + modulusLen - *outputLen, *outputLen); + rv = SECSuccess; - PORT_Free(buffer); - return SECSuccess; - -loser: - PORT_Free(buffer); -failure: - return SECFailure; +done: + if (buffer) { + PORT_Free(buffer); + } + return rv; } diff --git a/security/nss/lib/freebl/shvfy.c b/security/nss/lib/freebl/shvfy.c index af4a34fb0..bd9cd1c94 100644 --- a/security/nss/lib/freebl/shvfy.c +++ b/security/nss/lib/freebl/shvfy.c @@ -12,6 +12,7 @@ #include "prio.h" #include "blapi.h" #include "seccomon.h" +#include "secerr.h" #include "stdio.h" #include "prmem.h" #include "hasht.h" @@ -233,8 +234,12 @@ static char * mkCheckFileName(const char *libName) { int ln_len = PORT_Strlen(libName); - char *output = PORT_Alloc(ln_len + sizeof(SGN_SUFFIX)); int index = ln_len + 1 - sizeof("." SHLIB_SUFFIX); + char *output = PORT_Alloc(ln_len + sizeof(SGN_SUFFIX)); + if (!output) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + return NULL; + } if ((index > 0) && (PORT_Strncmp(&libName[index], diff --git a/security/nss/lib/freebl/sysrand.c b/security/nss/lib/freebl/sysrand.c index 0128fa0ee..763f6af11 100644 --- a/security/nss/lib/freebl/sysrand.c +++ b/security/nss/lib/freebl/sysrand.c @@ -8,42 +8,11 @@ #include "seccomon.h" -#ifndef XP_WIN -static size_t rng_systemFromNoise(unsigned char *dest, size_t maxLen); -#endif - -#if defined(XP_UNIX) || defined(XP_BEOS) +#if (defined(XP_UNIX) || defined(XP_BEOS)) && defined(SEED_ONLY_DEV_URANDOM) +#include "unix_urandom.c" +#elif defined(XP_UNIX) || defined(XP_BEOS) #include "unix_rand.c" #endif #ifdef XP_WIN #include "win_rand.c" #endif -#ifdef XP_OS2 -#include "os2_rand.c" -#endif - -#ifndef XP_WIN -/* - * Normal RNG_SystemRNG() isn't available, use the system noise to collect - * the required amount of entropy. - */ -static size_t -rng_systemFromNoise(unsigned char *dest, size_t maxLen) -{ - size_t retBytes = maxLen; - - while (maxLen) { - size_t nbytes = RNG_GetNoise(dest, maxLen); - - PORT_Assert(nbytes != 0); - - dest += nbytes; - maxLen -= nbytes; - - /* some hw op to try to introduce more entropy into the next - * RNG_GetNoise call */ - rng_systemJitter(); - } - return retBytes; -} -#endif diff --git a/security/nss/lib/freebl/unix_rand.c b/security/nss/lib/freebl/unix_rand.c index ea3b6af3d..24381cb26 100644 --- a/security/nss/lib/freebl/unix_rand.c +++ b/security/nss/lib/freebl/unix_rand.c @@ -160,11 +160,9 @@ RNG_kstat(PRUint32 *fed) #endif -#if defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(FREEBSD) || defined(NETBSD) || defined(DARWIN) || defined(OPENBSD) || defined(NTO) || defined(__riscos__) +#if defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(FREEBSD) || defined(NETBSD) || defined(DARWIN) || defined(OPENBSD) || defined(NTO) || defined(__riscos__) || defined(__GNU__) || defined(__FreeBSD_kernel__) || defined(__NetBSD_kernel__) #include <sys/times.h> -#define getdtablesize() sysconf(_SC_OPEN_MAX) - static size_t GetHighResClock(void *buf, size_t maxbytes) { @@ -198,8 +196,6 @@ GiveSystemInfo(void) #if defined(__svr4) || defined(SVR4) #include <sys/systeminfo.h> -#define getdtablesize() sysconf(_SC_OPEN_MAX) - static void GiveSystemInfo(void) { @@ -255,8 +251,6 @@ GiveSystemInfo(void) #if defined(__hpux) #include <sys/unistd.h> -#define getdtablesize() sysconf(_SC_OPEN_MAX) - #if defined(__ia64) #include <ia64/sys/inline.h> @@ -376,8 +370,6 @@ GiveSystemInfo(void) #include <sys/utsname.h> #include <sys/systeminfo.h> -#define getdtablesize() sysconf(_SC_OPEN_MAX) - static size_t GetHighResClock(void *buf, size_t maxbytes) { @@ -529,8 +521,6 @@ GetHighResClock(void *buf, size_t maxbuf) #if defined(sony) #include <sys/systeminfo.h> -#define getdtablesize() sysconf(_SC_OPEN_MAX) - static size_t GetHighResClock(void *buf, size_t maxbytes) { @@ -565,8 +555,6 @@ GiveSystemInfo(void) int gettimeofday(struct timeval *, struct timezone *); int gethostname(char *, int); -#define getdtablesize() sysconf(_SC_OPEN_MAX) - static size_t GetHighResClock(void *buf, size_t maxbytes) { @@ -634,8 +622,6 @@ GiveSystemInfo(void) #if defined(nec_ews) #include <sys/systeminfo.h> -#define getdtablesize() sysconf(_SC_OPEN_MAX) - static size_t GetHighResClock(void *buf, size_t maxbytes) { @@ -682,134 +668,6 @@ RNG_GetNoise(void *buf, size_t maxbytes) return n; } -#define SAFE_POPEN_MAXARGS 10 /* must be at least 2 */ - -/* - * safe_popen is static to this module and we know what arguments it is - * called with. Note that this version only supports a single open child - * process at any time. - */ -static pid_t safe_popen_pid; -static struct sigaction oldact; - -static FILE * -safe_popen(char *cmd) -{ - int p[2], fd, argc; - pid_t pid; - char *argv[SAFE_POPEN_MAXARGS + 1]; - FILE *fp; - static char blank[] = " \t"; - static struct sigaction newact; - - if (pipe(p) < 0) - return 0; - - fp = fdopen(p[0], "r"); - if (fp == 0) { - close(p[0]); - close(p[1]); - return 0; - } - - /* Setup signals so that SIGCHLD is ignored as we want to do waitpid */ - newact.sa_handler = SIG_DFL; - newact.sa_flags = 0; - sigfillset(&newact.sa_mask); - sigaction(SIGCHLD, &newact, &oldact); - - pid = fork(); - switch (pid) { - int ndesc; - - case -1: - fclose(fp); /* this closes p[0], the fd associated with fp */ - close(p[1]); - sigaction(SIGCHLD, &oldact, NULL); - return 0; - - case 0: - /* dup write-side of pipe to stderr and stdout */ - if (p[1] != 1) - dup2(p[1], 1); - if (p[1] != 2) - dup2(p[1], 2); - - /* - * close the other file descriptors, except stdin which we - * try reassociating with /dev/null, first (bug 174993) - */ - if (!freopen("/dev/null", "r", stdin)) - close(0); - ndesc = getdtablesize(); - for (fd = PR_MIN(65536, ndesc); --fd > 2; close(fd)) - ; - - /* clean up environment in the child process */ - putenv("PATH=/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc"); - putenv("SHELL=/bin/sh"); - putenv("IFS= \t"); - - /* - * The caller may have passed us a string that is in text - * space. It may be illegal to modify the string - */ - cmd = strdup(cmd); - /* format argv */ - argv[0] = strtok(cmd, blank); - argc = 1; - while ((argv[argc] = strtok(0, blank)) != 0) { - if (++argc == SAFE_POPEN_MAXARGS) { - argv[argc] = 0; - break; - } - } - - /* and away we go */ - execvp(argv[0], argv); - exit(127); - break; - - default: - close(p[1]); - break; - } - - /* non-zero means there's a cmd running */ - safe_popen_pid = pid; - return fp; -} - -static int -safe_pclose(FILE *fp) -{ - pid_t pid; - int status = -1, rv; - - if ((pid = safe_popen_pid) == 0) - return -1; - safe_popen_pid = 0; - - fclose(fp); - - /* yield the processor so the child gets some time to exit normally */ - PR_Sleep(PR_INTERVAL_NO_WAIT); - - /* if the child hasn't exited, kill it -- we're done with its output */ - while ((rv = waitpid(pid, &status, WNOHANG)) == -1 && errno == EINTR) - ; - if (rv == 0) { - kill(pid, SIGKILL); - while ((rv = waitpid(pid, &status, 0)) == -1 && errno == EINTR) - ; - } - - /* Reset SIGCHLD signal hander before returning */ - sigaction(SIGCHLD, &oldact, NULL); - - return status; -} - #ifdef DARWIN #include <TargetConditionals.h> #if !TARGET_OS_IPHONE @@ -817,15 +675,9 @@ safe_pclose(FILE *fp) #endif #endif -/* Fork netstat to collect its output by default. Do not unset this unless - * another source of entropy is available - */ -#define DO_NETSTAT 1 - void RNG_SystemInfoForRNG(void) { - FILE *fp; char buf[BUFSIZ]; size_t bytes; const char *const *cp; @@ -860,12 +712,6 @@ RNG_SystemInfoForRNG(void) }; #endif -#if defined(BSDI) - static char netstat_ni_cmd[] = "netstat -nis"; -#else - static char netstat_ni_cmd[] = "netstat -ni"; -#endif - GiveSystemInfo(); bytes = RNG_GetNoise(buf, sizeof(buf)); @@ -890,10 +736,12 @@ RNG_SystemInfoForRNG(void) if (gethostname(buf, sizeof(buf)) == 0) { RNG_RandomUpdate(buf, strlen(buf)); } - GiveSystemInfo(); /* grab some data from system's PRNG before any other files. */ bytes = RNG_FileUpdate("/dev/urandom", SYSTEM_RNG_SEED_COUNT); + if (!bytes) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); + } /* If the user points us to a random file, pass it through the rng */ randfile = PR_GetEnvSecure("NSRANDFILE"); @@ -911,33 +759,12 @@ RNG_SystemInfoForRNG(void) for (cp = files; *cp; cp++) RNG_FileForRNG(*cp); -/* - * Bug 100447: On BSD/OS 4.2 and 4.3, we have problem calling safe_popen - * in a pthreads environment. Therefore, we call safe_popen last and on - * BSD/OS we do not call safe_popen when we succeeded in getting data - * from /dev/urandom. - * - * Bug 174993: On platforms providing /dev/urandom, don't fork netstat - * either, if data has been gathered successfully. - */ - #if defined(BSDI) || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(DARWIN) || defined(LINUX) || defined(HPUX) if (bytes) return; #endif #ifdef SOLARIS - -/* - * On Solaris, NSS may be initialized automatically from libldap in - * applications that are unaware of the use of NSS. safe_popen forks, and - * sometimes creates issues with some applications' pthread_atfork handlers. - * We always have /dev/urandom on Solaris 9 and above as an entropy source, - * and for Solaris 8 we have the libkstat interface, so we don't need to - * fork netstat. - */ - -#undef DO_NETSTAT if (!bytes) { /* On Solaris 8, /dev/urandom isn't available, so we use libkstat. */ PRUint32 kstat_bytes = 0; @@ -948,15 +775,6 @@ RNG_SystemInfoForRNG(void) PORT_Assert(bytes); } #endif - -#ifdef DO_NETSTAT - fp = safe_popen(netstat_ni_cmd); - if (fp != NULL) { - while ((bytes = fread(buf, 1, sizeof(buf), fp)) > 0) - RNG_RandomUpdate(buf, bytes); - safe_pclose(fp); - } -#endif } #define TOTAL_FILE_LIMIT 1000000 /* one million */ @@ -1022,20 +840,6 @@ RNG_FileForRNG(const char *fileName) RNG_FileUpdate(fileName, TOTAL_FILE_LIMIT); } -void -ReadSingleFile(const char *fileName) -{ - FILE *file; - unsigned char buffer[BUFSIZ]; - - file = fopen(fileName, "rb"); - if (file != NULL) { - while (fread(buffer, 1, sizeof(buffer), file) > 0) - ; - fclose(file); - } -} - #define _POSIX_PTHREAD_SEMANTICS #include <dirent.h> @@ -1055,89 +859,6 @@ ReadFileOK(char *dir, char *file) return S_ISREG(stat_buf.st_mode) ? PR_TRUE : PR_FALSE; } -/* - * read one file out of either /etc or the user's home directory. - * fileToRead tells which file to read. - * - * return 1 if it's time to reset the fileToRead (no more files to read). - */ -static int -ReadOneFile(int fileToRead) -{ - char *dir = "/etc"; - DIR *fd = opendir(dir); - int resetCount = 0; - struct dirent *entry; -#if defined(__sun) - char firstName[256]; -#else - char firstName[NAME_MAX + 1]; -#endif - const char *name = NULL; - int i; - - if (fd == NULL) { - dir = PR_GetEnvSecure("HOME"); - if (dir) { - fd = opendir(dir); - } - } - if (fd == NULL) { - return 1; - } - - firstName[0] = '\0'; - for (i = 0; i <= fileToRead; i++) { - do { - /* readdir() isn't guaranteed to be thread safe on every platform; - * this code assumes the same directory isn't read concurrently. - * This usage is confirmed safe on Linux, see bug 1254334. */ - entry = readdir(fd); - } while (entry != NULL && !ReadFileOK(dir, &entry->d_name[0])); - if (entry == NULL) { - resetCount = 1; /* read to the end, start again at the beginning */ - if (firstName[0]) { - /* ran out of entries in the directory, use the first one */ - name = firstName; - } - break; - } - name = entry->d_name; - if (i == 0) { - /* copy the name of the first in case we run out of entries */ - PORT_Assert(PORT_Strlen(name) < sizeof(firstName)); - PORT_Strncpy(firstName, name, sizeof(firstName) - 1); - firstName[sizeof(firstName) - 1] = '\0'; - } - } - - if (name) { - char filename[PATH_MAX]; - int count = snprintf(filename, sizeof(filename), "%s/%s", dir, name); - if (count >= 1) { - ReadSingleFile(filename); - } - } - - closedir(fd); - return resetCount; -} - -/* - * do something to try to introduce more noise into the 'GetNoise' call - */ -static void -rng_systemJitter(void) -{ - static int fileToRead = 1; - - if (ReadOneFile(fileToRead)) { - fileToRead = 1; - } else { - fileToRead++; - } -} - size_t RNG_SystemRNG(void *dest, size_t maxLen) { @@ -1149,7 +870,8 @@ RNG_SystemRNG(void *dest, size_t maxLen) file = fopen("/dev/urandom", "r"); if (file == NULL) { - return rng_systemFromNoise(dest, maxLen); + PORT_SetError(SEC_ERROR_NEED_RANDOM); + return 0; } /* Read from the underlying file descriptor directly to bypass stdio * buffering and avoid reading more bytes than we need from /dev/urandom. diff --git a/security/nss/lib/freebl/unix_urandom.c b/security/nss/lib/freebl/unix_urandom.c new file mode 100644 index 000000000..25e6ad91c --- /dev/null +++ b/security/nss/lib/freebl/unix_urandom.c @@ -0,0 +1,50 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <fcntl.h> +#include <unistd.h> +#include "secerr.h" +#include "secrng.h" +#include "prprf.h" + +void +RNG_SystemInfoForRNG(void) +{ + PRUint8 bytes[SYSTEM_RNG_SEED_COUNT]; + size_t numBytes = RNG_SystemRNG(bytes, SYSTEM_RNG_SEED_COUNT); + if (!numBytes) { + /* error is set */ + return; + } + RNG_RandomUpdate(bytes, numBytes); +} + +size_t +RNG_SystemRNG(void *dest, size_t maxLen) +{ + int fd; + int bytes; + size_t fileBytes = 0; + unsigned char *buffer = dest; + + fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); + return 0; + } + while (fileBytes < maxLen) { + bytes = read(fd, buffer, maxLen - fileBytes); + if (bytes <= 0) { + break; + } + fileBytes += bytes; + buffer += bytes; + } + (void)close(fd); + if (fileBytes != maxLen) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); + return 0; + } + return fileBytes; +} |