summaryrefslogtreecommitdiff
path: root/lib/libcrypto
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2006-06-27 05:05:41 +0000
committerDamien Miller <djm@cvs.openbsd.org>2006-06-27 05:05:41 +0000
commitecc645c71513728e7357c84aa8997b4dc2301936 (patch)
tree9ac84a2d60cae724af19457cc8f9f91644b23aea /lib/libcrypto
parent70ff9835c415e893131dd8dbe643c6f5e4873c53 (diff)
import of openssl-0.9.7j
Diffstat (limited to 'lib/libcrypto')
-rw-r--r--lib/libcrypto/bn/asm/ppc.pl23
-rw-r--r--lib/libcrypto/bn/bn_x931p.c282
-rwxr-xr-xlib/libcrypto/rc4/asm/rc4-x86_64.pl150
-rw-r--r--lib/libcrypto/rsa/rsa_pss.c261
-rw-r--r--lib/libcrypto/rsa/rsa_x931.c177
-rw-r--r--lib/libcrypto/util/checkhash.pl222
-rw-r--r--lib/libcrypto/util/fipslink.pl78
-rw-r--r--lib/libcrypto/util/pl/VC-32-GMAKE.pl222
8 files changed, 1402 insertions, 13 deletions
diff --git a/lib/libcrypto/bn/asm/ppc.pl b/lib/libcrypto/bn/asm/ppc.pl
index 307c7ccb358..08e00534738 100644
--- a/lib/libcrypto/bn/asm/ppc.pl
+++ b/lib/libcrypto/bn/asm/ppc.pl
@@ -116,7 +116,7 @@ if ($opf =~ /32\.s/) {
$UDIV= "divwu"; # unsigned divide
$UCMPI= "cmplwi"; # unsigned compare with immediate
$UCMP= "cmplw"; # unsigned compare
- $COUNTZ="cntlzw"; # count leading zeros
+ $CNTLZ= "cntlzw"; # count leading zeros
$SHL= "slw"; # shift left
$SHR= "srw"; # unsigned shift right
$SHRI= "srwi"; # unsigned shift right by immediate
@@ -124,6 +124,7 @@ if ($opf =~ /32\.s/) {
$CLRU= "clrlwi"; # clear upper bits
$INSR= "insrwi"; # insert right
$ROTL= "rotlwi"; # rotate left by immediate
+ $TR= "tw"; # conditional trap
} elsif ($opf =~ /64\.s/) {
$BITS= 64;
$BNSZ= $BITS/8;
@@ -139,7 +140,7 @@ if ($opf =~ /32\.s/) {
$UDIV= "divdu"; # unsigned divide
$UCMPI= "cmpldi"; # unsigned compare with immediate
$UCMP= "cmpld"; # unsigned compare
- $COUNTZ="cntlzd"; # count leading zeros
+ $CNTLZ= "cntlzd"; # count leading zeros
$SHL= "sld"; # shift left
$SHR= "srd"; # unsigned shift right
$SHRI= "srdi"; # unsigned shift right by immediate
@@ -147,6 +148,7 @@ if ($opf =~ /32\.s/) {
$CLRU= "clrldi"; # clear upper bits
$INSR= "insrdi"; # insert right
$ROTL= "rotldi"; # rotate left by immediate
+ $TR= "td"; # conditional trap
} else { die "nonsense $opf"; }
( defined shift || open STDOUT,">$opf" ) || die "can't open $opf: $!";
@@ -1710,17 +1712,12 @@ Lppcasm_add_adios:
bclr BO_ALWAYS,CR0_LT
Lppcasm_div1:
xor r0,r0,r0 #r0=0
- $COUNTZ r7,r5 #r7 = num leading 0s in d.
- subfic r8,r7,$BITS #r8 = BN_num_bits_word(d)
- cmpi 0,0,r8,$BITS #
- bc BO_IF,CR0_EQ,Lppcasm_div2 #proceed if (r8==$BITS)
- li r9,1 # r9=1
- $SHL r10,r9,r8 # r9<<=r8
- $UCMP 0,r3,r10 #
- bc BO_IF,CR0_GT,Lppcasm_div2 #or if (h > (1<<r8))
- $UDIV r3,r3,r0 #if not assert(0) divide by 0!
- #that's how we signal overflow
- bclr BO_ALWAYS,CR0_LT #return. NEVER REACHED.
+ li r8,$BITS
+ $CNTLZ. r7,r5 #r7 = num leading 0s in d.
+ bc BO_IF,CR0_EQ,Lppcasm_div2 #proceed if no leading zeros
+ subf r8,r7,r8 #r8 = BN_num_bits_word(d)
+ $SHR. r9,r3,r8 #are there any bits above r8'th?
+ $TR 16,r9,r0 #if there're, signal to dump core...
Lppcasm_div2:
$UCMP 0,r3,r5 #h>=d?
bc BO_IF,CR0_LT,Lppcasm_div3 #goto Lppcasm_div3 if not
diff --git a/lib/libcrypto/bn/bn_x931p.c b/lib/libcrypto/bn/bn_x931p.c
new file mode 100644
index 00000000000..c64410dd3ae
--- /dev/null
+++ b/lib/libcrypto/bn/bn_x931p.c
@@ -0,0 +1,282 @@
+/* bn_x931p.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+
+#ifdef OPENSSL_FIPS
+
+/* X9.31 routines for prime derivation */
+
+
+/* X9.31 prime derivation. This is used to generate the primes pi
+ * (p1, p2, q1, q2) from a parameter Xpi by checking successive odd
+ * integers.
+ */
+
+static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx,
+ void (*cb)(int, int, void *), void *cb_arg)
+ {
+ int i = 0;
+ if (!BN_copy(pi, Xpi))
+ return 0;
+ if (!BN_is_odd(pi) && !BN_add_word(pi, 1))
+ return 0;
+ for(;;)
+ {
+ i++;
+ if (cb)
+ cb(0, i, cb_arg);
+ /* NB 27 MR is specificed in X9.31 */
+ if (BN_is_prime_fasttest(pi, 27, cb, ctx, cb_arg, 1))
+ break;
+ if (!BN_add_word(pi, 2))
+ return 0;
+ }
+ if (cb)
+ cb(2, i, cb_arg);
+ return 1;
+ }
+
+/* This is the main X9.31 prime derivation function. From parameters
+ * Xp1, Xp2 and Xp derive the prime p. If the parameters p1 or p2 are
+ * not NULL they will be returned too: this is needed for testing.
+ */
+
+int BN_X931_derive_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+ void (*cb)(int, int, void *), void *cb_arg,
+ const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2,
+ const BIGNUM *e, BN_CTX *ctx)
+ {
+ int ret = 0;
+
+ BIGNUM *t, *p1p2, *pm1;
+
+ /* Only even e supported */
+ if (!BN_is_odd(e))
+ return 0;
+
+ BN_CTX_start(ctx);
+ if (!p1)
+ p1 = BN_CTX_get(ctx);
+
+ if (!p2)
+ p2 = BN_CTX_get(ctx);
+
+ t = BN_CTX_get(ctx);
+
+ p1p2 = BN_CTX_get(ctx);
+
+ pm1 = BN_CTX_get(ctx);
+
+ if (!bn_x931_derive_pi(p1, Xp1, ctx, cb, cb_arg))
+ goto err;
+
+ if (!bn_x931_derive_pi(p2, Xp2, ctx, cb, cb_arg))
+ goto err;
+
+ if (!BN_mul(p1p2, p1, p2, ctx))
+ goto err;
+
+ /* First set p to value of Rp */
+
+ if (!BN_mod_inverse(p, p2, p1, ctx))
+ goto err;
+
+ if (!BN_mul(p, p, p2, ctx))
+ goto err;
+
+ if (!BN_mod_inverse(t, p1, p2, ctx))
+ goto err;
+
+ if (!BN_mul(t, t, p1, ctx))
+ goto err;
+
+ if (!BN_sub(p, p, t))
+ goto err;
+
+ if (p->neg && !BN_add(p, p, p1p2))
+ goto err;
+
+ /* p now equals Rp */
+
+ if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
+ goto err;
+
+ if (!BN_add(p, p, Xp))
+ goto err;
+
+ /* p now equals Yp0 */
+
+ for (;;)
+ {
+ int i = 1;
+ if (cb)
+ cb(0, i++, cb_arg);
+ if (!BN_copy(pm1, p))
+ goto err;
+ if (!BN_sub_word(pm1, 1))
+ goto err;
+ if (!BN_gcd(t, pm1, e, ctx))
+ goto err;
+ if (BN_is_one(t)
+ /* X9.31 specifies 8 MR and 1 Lucas test or any prime test
+ * offering similar or better guarantees 50 MR is considerably
+ * better.
+ */
+ && BN_is_prime_fasttest(p, 50, cb, ctx, cb_arg, 1))
+ break;
+ if (!BN_add(p, p, p1p2))
+ goto err;
+ }
+
+ if (cb)
+ cb(3, 0, cb_arg);
+
+ ret = 1;
+
+ err:
+
+ BN_CTX_end(ctx);
+
+ return ret;
+ }
+
+/* Generate pair of paramters Xp, Xq for X9.31 prime generation.
+ * Note: nbits paramter is sum of number of bits in both.
+ */
+
+int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx)
+ {
+ BIGNUM *t;
+ int i;
+ /* Number of bits for each prime is of the form
+ * 512+128s for s = 0, 1, ...
+ */
+ if ((nbits < 1024) || (nbits & 0xff))
+ return 0;
+ nbits >>= 1;
+ /* The random value Xp must be between sqrt(2) * 2^(nbits-1) and
+ * 2^nbits - 1. By setting the top two bits we ensure that the lower
+ * bound is exceeded.
+ */
+ if (!BN_rand(Xp, nbits, 1, 0))
+ return 0;
+
+ BN_CTX_start(ctx);
+ t = BN_CTX_get(ctx);
+
+ for (i = 0; i < 1000; i++)
+ {
+ if (!BN_rand(Xq, nbits, 1, 0))
+ return 0;
+ /* Check that |Xp - Xq| > 2^(nbits - 100) */
+ BN_sub(t, Xp, Xq);
+ if (BN_num_bits(t) > (nbits - 100))
+ break;
+ }
+
+ BN_CTX_end(ctx);
+
+ if (i < 1000)
+ return 1;
+
+ return 0;
+
+ }
+
+/* Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1
+ * and Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL
+ * the relevant parameter will be stored in it.
+ *
+ * Due to the fact that |Xp - Xq| > 2^(nbits - 100) must be satisfied Xp and Xq
+ * are generated using the previous function and supplied as input.
+ */
+
+int BN_X931_generate_prime(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+ BIGNUM *Xp1, BIGNUM *Xp2,
+ const BIGNUM *Xp,
+ const BIGNUM *e, BN_CTX *ctx,
+ void (*cb)(int, int, void *), void *cb_arg)
+ {
+ int ret = 0;
+
+ BN_CTX_start(ctx);
+ if (!Xp1)
+ Xp1 = BN_CTX_get(ctx);
+ if (!Xp2)
+ Xp2 = BN_CTX_get(ctx);
+
+ if (!BN_rand(Xp1, 101, 0, 0))
+ goto error;
+ if (!BN_rand(Xp2, 101, 0, 0))
+ goto error;
+ if (!BN_X931_derive_prime(p, p1, p2, cb, cb_arg,
+ Xp, Xp1, Xp2, e, ctx))
+ goto error;
+
+ ret = 1;
+
+ error:
+ BN_CTX_end(ctx);
+
+ return ret;
+
+ }
+
+#endif
diff --git a/lib/libcrypto/rc4/asm/rc4-x86_64.pl b/lib/libcrypto/rc4/asm/rc4-x86_64.pl
new file mode 100755
index 00000000000..b628daca705
--- /dev/null
+++ b/lib/libcrypto/rc4/asm/rc4-x86_64.pl
@@ -0,0 +1,150 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. Rights for redistribution and usage in source and binary
+# forms are granted according to the OpenSSL license.
+# ====================================================================
+#
+# Unlike 0.9.7f this code expects RC4_CHAR back in config line! See
+# commentary section in corresponding script in development branch
+# for background information about this option carousel. For those
+# who don't have energy to figure out these gory details, here is
+# basis in form of performance matrix relative to the original
+# 0.9.7e C code-base:
+#
+# 0.9.7e 0.9.7f this
+# AMD64 1x 3.3x 2.4x
+# EM64T 1x 0.8x 1.5x
+#
+# In other words idea is to trade -25% AMD64 performance to compensate
+# for deterioration and gain +90% on EM64T core. Development branch
+# maintains best performance for either target, i.e. 3.3x for AMD64
+# and 1.5x for EM64T.
+
+$output=shift;
+
+open STDOUT,">$output" || die "can't open $output: $!";
+
+$dat="%rdi"; # arg1
+$len="%rsi"; # arg2
+$inp="%rdx"; # arg3
+$out="%rcx"; # arg4
+
+@XX=("%r8","%r10");
+@TX=("%r9","%r11");
+$YY="%r12";
+$TY="%r13";
+
+$code=<<___;;
+.text
+
+.globl RC4
+.type RC4,\@function
+.align 16
+RC4: or $len,$len
+ jne .Lentry
+ repret
+.Lentry:
+ push %r12
+ push %r13
+
+ add \$2,$dat
+ movzb -2($dat),$XX[0]#d
+ movzb -1($dat),$YY#d
+
+ add \$1,$XX[0]#b
+ movzb ($dat,$XX[0]),$TX[0]#d
+ test \$-8,$len
+ jz .Lcloop1
+ push %rbx
+.align 16 # incidentally aligned already
+.Lcloop8:
+ mov ($inp),%eax
+ mov 4($inp),%ebx
+___
+# unroll 2x4-wise, because 64-bit rotates kill Intel P4...
+for ($i=0;$i<4;$i++) {
+$code.=<<___;
+ add $TX[0]#b,$YY#b
+ lea 1($XX[0]),$XX[1]
+ movzb ($dat,$YY),$TY#d
+ movzb $XX[1]#b,$XX[1]#d
+ movzb ($dat,$XX[1]),$TX[1]#d
+ movb $TX[0]#b,($dat,$YY)
+ cmp $XX[1],$YY
+ movb $TY#b,($dat,$XX[0])
+ jne .Lcmov$i # Intel cmov is sloooow...
+ mov $TX[0],$TX[1]
+.Lcmov$i:
+ add $TX[0]#b,$TY#b
+ xor ($dat,$TY),%al
+ ror \$8,%eax
+___
+push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers
+}
+for ($i=4;$i<8;$i++) {
+$code.=<<___;
+ add $TX[0]#b,$YY#b
+ lea 1($XX[0]),$XX[1]
+ movzb ($dat,$YY),$TY#d
+ movzb $XX[1]#b,$XX[1]#d
+ movzb ($dat,$XX[1]),$TX[1]#d
+ movb $TX[0]#b,($dat,$YY)
+ cmp $XX[1],$YY
+ movb $TY#b,($dat,$XX[0])
+ jne .Lcmov$i # Intel cmov is sloooow...
+ mov $TX[0],$TX[1]
+.Lcmov$i:
+ add $TX[0]#b,$TY#b
+ xor ($dat,$TY),%bl
+ ror \$8,%ebx
+___
+push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers
+}
+$code.=<<___;
+ lea -8($len),$len
+ mov %eax,($out)
+ lea 8($inp),$inp
+ mov %ebx,4($out)
+ lea 8($out),$out
+
+ test \$-8,$len
+ jnz .Lcloop8
+ pop %rbx
+ cmp \$0,$len
+ jne .Lcloop1
+.Lexit:
+ sub \$1,$XX[0]#b
+ movb $XX[0]#b,-2($dat)
+ movb $YY#b,-1($dat)
+
+ pop %r13
+ pop %r12
+ repret
+
+.align 16
+.Lcloop1:
+ add $TX[0]#b,$YY#b
+ movzb ($dat,$YY),$TY#d
+ movb $TX[0]#b,($dat,$YY)
+ movb $TY#b,($dat,$XX[0])
+ add $TX[0]#b,$TY#b
+ add \$1,$XX[0]#b
+ movzb ($dat,$TY),$TY#d
+ movzb ($dat,$XX[0]),$TX[0]#d
+ xorb ($inp),$TY#b
+ lea 1($inp),$inp
+ movb $TY#b,($out)
+ lea 1($out),$out
+ sub \$1,$len
+ jnz .Lcloop1
+ jmp .Lexit
+.size RC4,.-RC4
+___
+
+$code =~ s/#([bwd])/$1/gm;
+
+$code =~ s/repret/.byte\t0xF3,0xC3/gm;
+
+print $code;
diff --git a/lib/libcrypto/rsa/rsa_pss.c b/lib/libcrypto/rsa/rsa_pss.c
new file mode 100644
index 00000000000..2815628f5f7
--- /dev/null
+++ b/lib/libcrypto/rsa/rsa_pss.c
@@ -0,0 +1,261 @@
+/* rsa_pss.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+const static unsigned char zeroes[] = {0,0,0,0,0,0,0,0};
+
+int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
+ const EVP_MD *Hash, const unsigned char *EM, int sLen)
+ {
+ int i;
+ int ret = 0;
+ int hLen, maskedDBLen, MSBits, emLen;
+ const unsigned char *H;
+ unsigned char *DB = NULL;
+ EVP_MD_CTX ctx;
+ unsigned char H_[EVP_MAX_MD_SIZE];
+
+ hLen = EVP_MD_size(Hash);
+ /*
+ * Negative sLen has special meanings:
+ * -1 sLen == hLen
+ * -2 salt length is autorecovered from signature
+ * -N reserved
+ */
+ if (sLen == -1) sLen = hLen;
+ else if (sLen == -2) sLen = -2;
+ else if (sLen < -2)
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
+ goto err;
+ }
+
+ MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
+ emLen = RSA_size(rsa);
+ if (EM[0] & (0xFF << MSBits))
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_FIRST_OCTET_INVALID);
+ goto err;
+ }
+ if (MSBits == 0)
+ {
+ EM++;
+ emLen--;
+ }
+ if (emLen < (hLen + sLen + 2)) /* sLen can be small negative */
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_DATA_TOO_LARGE);
+ goto err;
+ }
+ if (EM[emLen - 1] != 0xbc)
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_LAST_OCTET_INVALID);
+ goto err;
+ }
+ maskedDBLen = emLen - hLen - 1;
+ H = EM + maskedDBLen;
+ DB = OPENSSL_malloc(maskedDBLen);
+ if (!DB)
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash);
+ for (i = 0; i < maskedDBLen; i++)
+ DB[i] ^= EM[i];
+ if (MSBits)
+ DB[0] &= 0xFF >> (8 - MSBits);
+ for (i = 0; DB[i] == 0 && i < (maskedDBLen-1); i++) ;
+ if (DB[i++] != 0x1)
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_RECOVERY_FAILED);
+ goto err;
+ }
+ if (sLen >= 0 && (maskedDBLen - i) != sLen)
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
+ goto err;
+ }
+ EVP_MD_CTX_init(&ctx);
+ EVP_DigestInit_ex(&ctx, Hash, NULL);
+ EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes);
+ EVP_DigestUpdate(&ctx, mHash, hLen);
+ if (maskedDBLen - i)
+ EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i);
+ EVP_DigestFinal(&ctx, H_, NULL);
+ EVP_MD_CTX_cleanup(&ctx);
+ if (memcmp(H_, H, hLen))
+ {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, RSA_R_BAD_SIGNATURE);
+ ret = 0;
+ }
+ else
+ ret = 1;
+
+ err:
+ if (DB)
+ OPENSSL_free(DB);
+
+ return ret;
+
+ }
+
+int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
+ const unsigned char *mHash,
+ const EVP_MD *Hash, int sLen)
+ {
+ int i;
+ int ret = 0;
+ int hLen, maskedDBLen, MSBits, emLen;
+ unsigned char *H, *salt = NULL, *p;
+ EVP_MD_CTX ctx;
+
+ hLen = EVP_MD_size(Hash);
+ /*
+ * Negative sLen has special meanings:
+ * -1 sLen == hLen
+ * -2 salt length is maximized
+ * -N reserved
+ */
+ if (sLen == -1) sLen = hLen;
+ else if (sLen == -2) sLen = -2;
+ else if (sLen < -2)
+ {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS, RSA_R_SLEN_CHECK_FAILED);
+ goto err;
+ }
+
+ MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
+ emLen = RSA_size(rsa);
+ if (MSBits == 0)
+ {
+ *EM++ = 0;
+ emLen--;
+ }
+ if (sLen == -2)
+ {
+ sLen = emLen - hLen - 2;
+ }
+ else if (emLen < (hLen + sLen + 2))
+ {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS,
+ RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ goto err;
+ }
+ if (sLen > 0)
+ {
+ salt = OPENSSL_malloc(sLen);
+ if (!salt)
+ {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (!RAND_bytes(salt, sLen))
+ goto err;
+ }
+ maskedDBLen = emLen - hLen - 1;
+ H = EM + maskedDBLen;
+ EVP_MD_CTX_init(&ctx);
+ EVP_DigestInit_ex(&ctx, Hash, NULL);
+ EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes);
+ EVP_DigestUpdate(&ctx, mHash, hLen);
+ if (sLen)
+ EVP_DigestUpdate(&ctx, salt, sLen);
+ EVP_DigestFinal(&ctx, H, NULL);
+ EVP_MD_CTX_cleanup(&ctx);
+
+ /* Generate dbMask in place then perform XOR on it */
+ PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash);
+
+ p = EM;
+
+ /* Initial PS XORs with all zeroes which is a NOP so just update
+ * pointer. Note from a test above this value is guaranteed to
+ * be non-negative.
+ */
+ p += emLen - sLen - hLen - 2;
+ *p++ ^= 0x1;
+ if (sLen > 0)
+ {
+ for (i = 0; i < sLen; i++)
+ *p++ ^= salt[i];
+ }
+ if (MSBits)
+ EM[0] &= 0xFF >> (8 - MSBits);
+
+ /* H is already in place so just set final 0xbc */
+
+ EM[emLen - 1] = 0xbc;
+
+ ret = 1;
+
+ err:
+ if (salt)
+ OPENSSL_free(salt);
+
+ return ret;
+
+ }
diff --git a/lib/libcrypto/rsa/rsa_x931.c b/lib/libcrypto/rsa/rsa_x931.c
new file mode 100644
index 00000000000..df3c45f802e
--- /dev/null
+++ b/lib/libcrypto/rsa/rsa_x931.c
@@ -0,0 +1,177 @@
+/* rsa_x931.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+
+int RSA_padding_add_X931(unsigned char *to, int tlen,
+ const unsigned char *from, int flen)
+ {
+ int j;
+ unsigned char *p;
+
+ /* Absolute minimum amount of padding is 1 header nibble, 1 padding
+ * nibble and 2 trailer bytes: but 1 hash if is already in 'from'.
+ */
+
+ j = tlen - flen - 2;
+
+ if (j < 0)
+ {
+ RSAerr(RSA_F_RSA_PADDING_ADD_X931,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ return -1;
+ }
+
+ p=(unsigned char *)to;
+
+ /* If no padding start and end nibbles are in one byte */
+ if (j == 0)
+ *p++ = 0x6A;
+ else
+ {
+ *p++ = 0x6B;
+ if (j > 1)
+ {
+ memset(p, 0xBB, j - 1);
+ p += j - 1;
+ }
+ *p++ = 0xBA;
+ }
+ memcpy(p,from,(unsigned int)flen);
+ p += flen;
+ *p = 0xCC;
+ return(1);
+ }
+
+int RSA_padding_check_X931(unsigned char *to, int tlen,
+ const unsigned char *from, int flen, int num)
+ {
+ int i,j;
+ const unsigned char *p;
+
+ p=from;
+ if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B)))
+ {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_X931,RSA_R_INVALID_HEADER);
+ return -1;
+ }
+
+ if (*p++ == 0x6B)
+ {
+ j=flen-3;
+ for (i = 0; i < j; i++)
+ {
+ unsigned char c = *p++;
+ if (c == 0xBA)
+ break;
+ if (c != 0xBB)
+ {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_X931,
+ RSA_R_INVALID_PADDING);
+ return -1;
+ }
+ }
+
+ j -= i;
+
+ if (i == 0)
+ {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING);
+ return -1;
+ }
+
+ }
+ else j = flen - 2;
+
+ if (p[j] != 0xCC)
+ {
+ RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER);
+ return -1;
+ }
+
+ memcpy(to,p,(unsigned int)j);
+
+ return(j);
+ }
+
+/* Translate between X931 hash ids and NIDs */
+
+int RSA_X931_hash_id(int nid)
+ {
+ switch (nid)
+ {
+ case NID_sha1:
+ return 0x33;
+
+ case NID_sha256:
+ return 0x34;
+
+ case NID_sha384:
+ return 0x36;
+
+ case NID_sha512:
+ return 0x35;
+
+ }
+ return -1;
+ }
+
diff --git a/lib/libcrypto/util/checkhash.pl b/lib/libcrypto/util/checkhash.pl
new file mode 100644
index 00000000000..c61fa721780
--- /dev/null
+++ b/lib/libcrypto/util/checkhash.pl
@@ -0,0 +1,222 @@
+#!/usr/bin/env perl -w
+
+my $package = caller;
+
+if (!(defined $package))
+ {
+ my $retval = check_hashes(@ARGV);
+ exit $retval;
+ }
+
+1;
+
+sub check_hashes
+ {
+
+ my @args = @_;
+
+ my $change_dir = "";
+ my $check_program = "sha/fips_standalone_sha1";
+
+ my $verbose = 0;
+ my $badfiles = 0;
+ my $rebuild = 0;
+ my $force_rewrite = 0;
+ my $hash_file = "fipshashes.c";
+ my $recurse = 0;
+
+ my @fingerprint_files;
+
+ while (@args)
+ {
+ my $arg = $args[0];
+ if ($arg eq "-chdir")
+ {
+ shift @args;
+ $change_dir = shift @args;
+ }
+ elsif ($arg eq "-rebuild")
+ {
+ shift @args;
+ $rebuild = 1;
+ }
+ elsif ($arg eq "-verbose")
+ {
+ shift @args;
+ $verbose = 1;
+ }
+ elsif ($arg eq "-force-rewrite")
+ {
+ shift @args;
+ $force_rewrite = 1;
+ }
+ elsif ($arg eq "-hash_file")
+ {
+ shift @args;
+ $hash_file = shift @args;
+ }
+ elsif ($arg eq "-recurse")
+ {
+ shift @args;
+ $recurse = 1;
+ }
+ elsif ($arg eq "-program_path")
+ {
+ shift @args;
+ $check_program = shift @args;
+ }
+ else
+ {
+ print STDERR "Unknown Option $arg";
+ return 1;
+ }
+
+ }
+
+ chdir $change_dir if $change_dir ne "";
+
+ if ($recurse)
+ {
+ @fingerprint_files = ("fingerprint.sha1",
+ <*/fingerprint.sha1>);
+ }
+ else
+ {
+ push @fingerprint_files, $hash_file;
+ }
+
+ foreach $fp (@fingerprint_files)
+ {
+ if (!open(IN, "$fp"))
+ {
+ print STDERR "Can't open file $fp";
+ return 1;
+ }
+ print STDERR "Opening Fingerprint file $fp\n" if $verbose;
+ my $dir = $fp;
+ $dir =~ s/[^\/]*$//;
+ while (<IN>)
+ {
+ chomp;
+ if (!(($file, $hash) = /^\"HMAC-SHA1\((.*)\)\s*=\s*(\w*)\",$/))
+ {
+ /^\"/ || next;
+ print STDERR "FATAL: Invalid syntax in file $fp\n";
+ print STDERR "Line:\n$_\n";
+ fatal_error();
+ return 1;
+ }
+ if (!$rebuild && length($hash) != 40)
+ {
+ print STDERR "FATAL: Invalid hash length in $fp for file $file\n";
+ fatal_error();
+ return 1;
+ }
+ push @hashed_files, "$dir$file";
+ if (exists $hashes{"$dir$file"})
+ {
+ print STDERR "FATAL: Duplicate Hash file $dir$file\n";
+ fatal_error();
+ return 1;
+ }
+ if (! -r "$dir$file")
+ {
+ print STDERR "FATAL: Can't access $dir$file\n";
+ fatal_error();
+ return 1;
+ }
+ $hashes{"$dir$file"} = $hash;
+ }
+ close IN;
+ }
+
+ @checked_hashes = `$check_program @hashed_files`;
+
+ if ($? != 0)
+ {
+ print STDERR "Error running hash program $check_program\n";
+ fatal_error();
+ return 1;
+ }
+
+ if (@checked_hashes != @hashed_files)
+ {
+ print STDERR "FATAL: hash count incorrect\n";
+ fatal_error();
+ return 1;
+ }
+
+ foreach (@checked_hashes)
+ {
+ chomp;
+ if (!(($file, $hash) = /^HMAC-SHA1\((.*)\)\s*=\s*(\w*)$/))
+ {
+ print STDERR "FATAL: Invalid syntax in file $fp\n";
+ print STDERR "Line:\n$_\n";
+ fatal_error();
+ return 1;
+ }
+ if (length($hash) != 40)
+ {
+ print STDERR "FATAL: Invalid hash length for file $file\n";
+ fatal_error();
+ return 1;
+ }
+ if ($hash ne $hashes{$file})
+ {
+ if ($rebuild)
+ {
+ print STDERR "Updating hash on file $file\n";
+ $hashes{$file} = $hash;
+ }
+ else
+ {
+ print STDERR "Hash check failed for file $file\n";
+ }
+ $badfiles++;
+ }
+ elsif ($verbose)
+ { print "Hash Check OK for $file\n";}
+ }
+
+
+ if ($badfiles && !$rebuild)
+ {
+ print STDERR "FATAL: hash mismatch on $badfiles files\n";
+ fatal_error();
+ return 1;
+ }
+
+ if ($badfiles || $force_rewrite)
+ {
+ print "Updating Hash file $hash_file\n";
+ if (!open(OUT, ">$hash_file"))
+ {
+ print STDERR "Error rewriting $hash_file";
+ return 1;
+ }
+ print OUT "const char * const FIPS_source_hashes[] = {\n";
+ foreach (@hashed_files)
+ {
+ print OUT "\"HMAC-SHA1($_)= $hashes{$_}\",\n";
+ }
+ print OUT "};\n";
+ close OUT;
+ }
+
+ if (!$badfiles)
+ {
+ print "FIPS hash check successful\n";
+ }
+
+ return 0;
+
+ }
+
+
+sub fatal_error
+ {
+ print STDERR "*** Your source code does not match the FIPS validated source ***\n";
+ }
+
+
diff --git a/lib/libcrypto/util/fipslink.pl b/lib/libcrypto/util/fipslink.pl
new file mode 100644
index 00000000000..a893833c5c7
--- /dev/null
+++ b/lib/libcrypto/util/fipslink.pl
@@ -0,0 +1,78 @@
+#!/usr/bin/perl
+
+sub check_env
+ {
+ my @ret;
+ foreach (@_)
+ {
+ die "Environment variable $_ not defined!\n" unless exists $ENV{$_};
+ push @ret, $ENV{$_};
+ }
+ return @ret;
+ }
+
+
+my ($fips_cc,$fips_cc_args, $fips_link,$fips_target, $fips_libdir, $sha1_exe)
+ = check_env("FIPS_CC", "FIPS_CC_ARGS", "FIPS_LINK", "FIPS_TARGET",
+ "FIPSLIB_D", "FIPS_SHA1_EXE");
+
+
+
+if (exists $ENV{"PREMAIN_DSO_EXE"})
+ {
+ $fips_premain_dso = $ENV{"PREMAIN_DSO_EXE"};
+ }
+ else
+ {
+ $fips_premain_dso = "";
+ }
+
+check_hash($sha1_exe, "fips_premain.c");
+check_hash($sha1_exe, "fipscanister.o");
+
+
+print "Integrity check OK\n";
+
+print "$fips_cc $fips_cc_args $fips_libdir/fips_premain.c\n";
+system "$fips_cc $fips_cc_args $fips_libdir/fips_premain.c";
+die "First stage Compile failure" if $? != 0;
+
+print "$fips_link @ARGV\n";
+system "$fips_link @ARGV";
+die "First stage Link failure" if $? != 0;
+
+
+print "$fips_premain_dso $fips_target\n";
+$fips_hash=`$fips_premain_dso $fips_target`;
+chomp $fips_hash;
+die "Get hash failure" if $? != 0;
+
+
+print "$fips_cc -DHMAC_SHA1_SIG=\\\"$fips_hash\\\" $fips_cc_args $fips_libdir/fips_premain.c\n";
+system "$fips_cc -DHMAC_SHA1_SIG=\\\"$fips_hash\\\" $fips_cc_args $fips_libdir/fips_premain.c";
+die "Second stage Compile failure" if $? != 0;
+
+
+print "$fips_link @ARGV\n";
+system "$fips_link @ARGV";
+die "Second stage Link failure" if $? != 0;
+
+sub check_hash
+ {
+ my ($sha1_exe, $filename) = @_;
+ my ($hashfile, $hashval);
+
+ open(IN, "${fips_libdir}/${filename}.sha1") || die "Cannot open file hash file ${fips_libdir}/${filename}.sha1";
+ $hashfile = <IN>;
+ close IN;
+ $hashval = `$sha1_exe ${fips_libdir}/$filename`;
+ chomp $hashfile;
+ chomp $hashval;
+ $hashfile =~ s/^.*=\s+//;
+ $hashval =~ s/^.*=\s+//;
+ die "Invalid hash syntax in file" if (length($hashfile) != 40);
+ die "Invalid hash received for file" if (length($hashval) != 40);
+ die "***HASH VALUE MISMATCH FOR FILE $filename ***" if ($hashval ne $hashfile);
+ }
+
+
diff --git a/lib/libcrypto/util/pl/VC-32-GMAKE.pl b/lib/libcrypto/util/pl/VC-32-GMAKE.pl
new file mode 100644
index 00000000000..b5bbcac6c2b
--- /dev/null
+++ b/lib/libcrypto/util/pl/VC-32-GMAKE.pl
@@ -0,0 +1,222 @@
+#!/usr/local/bin/perl
+# VCw32lib.pl - the file for Visual C++ 4.[01] for windows NT, static libraries
+#
+
+
+if ($fips && !$shlib)
+ {
+ $crypto="libeayfips32";
+ $crypto_compat = "libeaycompat32.lib";
+ }
+else
+ {
+ $crypto="libeay32";
+ }
+$ssl= "ssleay32";
+
+$o='/';
+#$cp='copy nul+'; # Timestamps get stuffed otherwise
+#$rm='del';
+
+$cp='cp';
+$rm='rm';
+
+$zlib_lib="zlib1.lib";
+
+# C compiler stuff
+$cc='cl';
+$cflags=' -MD -W3 -WX -Ox -O2 -Ob2 -Gs0 -GF -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DDSO_WIN32';
+$cflags.=' -D_CRT_SECURE_NO_DEPRECATE'; # shut up VC8
+$cflags.=' -D_CRT_NONSTDC_NO_DEPRECATE'; # shut up VC8
+$lflags="-nologo -subsystem:console -machine:I386 -opt:ref";
+$mlflags='';
+
+$out_def="gmout32";
+$tmp_def="gmtmp32";
+$inc_def="gminc32";
+
+if ($debug)
+ {
+ $cflags=" -MDd -W3 -WX -Zi -Yd -Od -nologo -DOPENSSL_SYSNAME_WIN32 -D_DEBUG -DL_ENDIAN -DWIN32_LEAN_AND_MEAN -DDEBUG -DDSO_WIN32";
+ $lflags.=" -debug";
+ $mlflags.=' -debug';
+ }
+$cflags .= " -DOPENSSL_SYSNAME_WINNT" if $NT == 1;
+
+$obj='.obj';
+$ofile="-Fo";
+
+# EXE linking stuff
+$link="link";
+$efile="-out:";
+$exep='.exe';
+if ($no_sock)
+ { $ex_libs=""; }
+else { $ex_libs="wsock32.lib user32.lib gdi32.lib"; }
+
+# static library stuff
+$mklib='lib';
+$ranlib='';
+$plib="";
+$libp=".lib";
+$shlibp=($shlib)?".dll":".lib";
+$lfile='-out:';
+
+$shlib_ex_obj="";
+$app_ex_obj="setargv.obj";
+if ($nasm) {
+ $asm='nasmw -f win32';
+ $afile='-o ';
+} else {
+ $asm='ml -Cp -coff -c -Cx';
+ $asm.=" -Zi" if $debug;
+ $afile='-Fo';
+}
+
+$bn_asm_obj='';
+$bn_asm_src='';
+$des_enc_obj='';
+$des_enc_src='';
+$bf_enc_obj='';
+$bf_enc_src='';
+
+if (!$no_asm && !$fips)
+ {
+ $bn_asm_obj='crypto/bn/asm/bn_win32.obj';
+ $bn_asm_src='crypto/bn/asm/bn_win32.asm';
+ $des_enc_obj='crypto/des/asm/d_win32.obj crypto/des/asm/y_win32.obj';
+ $des_enc_src='crypto/des/asm/d_win32.asm crypto/des/asm/y_win32.asm';
+ $bf_enc_obj='crypto/bf/asm/b_win32.obj';
+ $bf_enc_src='crypto/bf/asm/b_win32.asm';
+ $cast_enc_obj='crypto/cast/asm/c_win32.obj';
+ $cast_enc_src='crypto/cast/asm/c_win32.asm';
+ $rc4_enc_obj='crypto/rc4/asm/r4_win32.obj';
+ $rc4_enc_src='crypto/rc4/asm/r4_win32.asm';
+ $rc5_enc_obj='crypto/rc5/asm/r5_win32.obj';
+ $rc5_enc_src='crypto/rc5/asm/r5_win32.asm';
+ $md5_asm_obj='crypto/md5/asm/m5_win32.obj';
+ $md5_asm_src='crypto/md5/asm/m5_win32.asm';
+ $sha1_asm_obj='crypto/sha/asm/s1_win32.obj';
+ $sha1_asm_src='crypto/sha/asm/s1_win32.asm';
+ $rmd160_asm_obj='crypto/ripemd/asm/rm_win32.obj';
+ $rmd160_asm_src='crypto/ripemd/asm/rm_win32.asm';
+ $cflags.=" -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM";
+ }
+
+if ($shlib)
+ {
+ $mlflags.=" $lflags -dll";
+# $cflags =~ s| -MD| -MT|;
+ $lib_cflag=" -D_WINDLL";
+ $out_def="gmout32dll";
+ $tmp_def="gmtmp32dll";
+ }
+
+$cflags.=" -Fd$out_def";
+
+sub do_lib_rule
+ {
+ local($objs,$target,$name,$shlib,$ign,$base_addr, $fips_get_sig, $fips_premain_src)=@_;
+ local($ret,$Name);
+
+ $taget =~ s/\//$o/g if $o ne '/';
+ ($Name=$name) =~ tr/a-z/A-Z/;
+ my $base_arg;
+ if ($base_addr ne "")
+ {
+ $base_arg= " -base:$base_addr";
+ }
+ else
+ {
+ $base_arg = "";
+ }
+
+
+# $target="\$(LIB_D)$o$target";
+ if (!$shlib)
+ {
+# $ret.="\t\$(RM) \$(O_$Name)\n";
+ $ret.="$target: $objs\n";
+ $ex =' advapi32.lib';
+ $ret.="\t\$(MKLIB) $lfile$target $objs $ex\n\n";
+ }
+ else
+ {
+ local($ex)=($target =~ /O_SSL/)?' $(L_CRYPTO)':'';
+ $ex.=' wsock32.lib gdi32.lib advapi32.lib user32.lib';
+ $ex.=" $zlib_lib" if $zlib_opt == 1 && $target =~ /O_CRYPTO/;
+ if (defined $fips_get_sig)
+ {
+ $ret.="$target: \$(O_FIPSCANISTER) $objs $fips_get_sig\n";
+ $ret.="\tFIPS_LINK=\$(LINK) ";
+ $ret.="FIPS_CC=\$(CC) ";
+ $ret.="FIPS_CC_ARGS=\"-Fo\$(OBJ_D)${o}fips_premain.obj \$(SHLIB_CFLAGS) -c\" ";
+ $ret.="FIPS_PREMAIN_DSO=$fips_get_sig ";
+ $ret.="FIPS_TARGET=$target ";
+ $ret.="FIPS_LIBDIR=\$(FIPSLIB_D) ";
+ $ret.="\$(FIPSLINK) \$(MLFLAGS) $base_arg $efile$target ";
+ $ret.="-def:ms/${Name}.def \$(SHLIB_EX_OBJ) $objs ";
+ $ret.="\$(OBJ_D)${o}fips_premain.obj $ex\n\n";
+ }
+ else
+ {
+ $ret.="$target: $objs\n";
+ $ret.="\t\$(LINK) \$(MLFLAGS) $base_arg $efile$target /def:ms/${Name}.def \$(SHLIB_EX_OBJ) $objs $ex\n\n";
+ }
+ }
+ $ret.="\n";
+ return($ret);
+ }
+
+sub do_link_rule
+ {
+ local($target,$files,$dep_libs,$libs,$standalone)=@_;
+ local($ret,$_);
+ $file =~ s/\//$o/g if $o ne '/';
+ $n=&bname($targer);
+ if ($standalone)
+ {
+ $ret.="$target: $files $dep_libs\n";
+ $ret.="\t\$(LINK) \$(LFLAGS) $efile$target ";
+ $ret.="$files $libs\n\n";
+ }
+ elsif ($fips && !$shlib)
+ {
+ $ret.="$target: \$(O_FIPSCANISTER) $files $dep_libs\n";
+ $ret.="\tFIPS_LINK=\$(LINK) ";
+ $ret.="FIPS_CC=\$(CC) ";
+ $ret.="FIPS_CC_ARGS=\"-Fo\$(OBJ_D)${o}fips_premain.obj \$(SHLIB_CFLAGS) -c\" ";
+ $ret.="FIPS_PREMAIN_DSO= ";
+ $ret.="FIPS_TARGET=$target ";
+ $ret.="FIPS_LIBDIR=\$(FIPSLIB_D) ";
+ $ret.=" \$(FIPSLINK) \$(LFLAGS) $efile$target ";
+ $ret.="\$(APP_EX_OBJ) $files \$(OBJ_D)${o}fips_premain.obj $libs\n\n";
+ }
+ else
+ {
+ $ret.="$target: $files $dep_libs\n";
+ $ret.="\t\$(LINK) \$(LFLAGS) $efile$target ";
+ $ret.="\$(APP_EX_OBJ) $files $libs\n\n";
+ }
+ $ret.="\n";
+ return($ret);
+ }
+
+sub do_rlink_rule
+ {
+ local($target,$files,$check_hash, $deps)=@_;
+ local($ret,$_);
+
+ $file =~ s/\//$o/g if $o ne '/';
+ $n=&bname($targer);
+ $ret.="$target: $check_hash $files $deps\n";
+ $ret.="\t\$(PERL) util${o}checkhash.pl -chdir fips-1.0 -program_path ..$o$check_hash\n";
+ $ret.="\t\$(MKCANISTER) $target $files\n";
+ $ret.="\t$check_hash $target > $target.sha1\n";
+ $ret.="\t\$(CP) fips-1.0${o}fips_premain.c \$(FIPSLIB_D)\n";
+ $ret.="\t$check_hash \$(FIPSLIB_D)${o}fips_premain.c > \$(FIPSLIB_D)${o}fips_premain.c.sha1\n\n";
+ return($ret);
+ }
+
+
+1;