changeset 12573:fb4ef506980f

6875651 move asymmetric crypto to libsoftcrypto 6816864 collect together padding methods used by PKCS#11 6917508 bignum library needs big random number function 6249983 softtoken based RSA/DSA slow on Niagara 6917506 arcfour lint check missing from usr/src/uts/sun4v/Makefile 6917513 move softFipsDSAUtil.c to common/crypto/fips/fips_dsa_util.c 6834849 dsa_sign() produces invalid signature when pkcs11 engine is used via openssl(1) for certain keys
author Dina K Nimeh <Dina.Nimeh@Sun.COM>
date Mon, 07 Jun 2010 08:54:25 -0700
parents 069cff75d3da
children 0d8f6d488501
files usr/src/common/bignum/bignum.h usr/src/common/bignum/bignumimpl.c usr/src/common/crypto/arcfour/sun4v/arcfour_crypt.c usr/src/common/crypto/dh/Makefile usr/src/common/crypto/dh/dh_impl.c usr/src/common/crypto/dh/dh_impl.h usr/src/common/crypto/dsa/Makefile usr/src/common/crypto/dsa/dsa_impl.c usr/src/common/crypto/dsa/dsa_impl.h usr/src/common/crypto/fips/fips_dsa_util.c usr/src/common/crypto/fips/fips_post.h usr/src/common/crypto/fips/fips_rsa_util.c usr/src/common/crypto/padding/Makefile usr/src/common/crypto/padding/padding.h usr/src/common/crypto/padding/pkcs1.c usr/src/common/crypto/padding/pkcs7.c usr/src/common/crypto/rsa/rsa_impl.c usr/src/common/crypto/rsa/rsa_impl.h usr/src/lib/pkcs11/libsoftcrypto/Makefile.com usr/src/lib/pkcs11/libsoftcrypto/amd64/Makefile usr/src/lib/pkcs11/libsoftcrypto/common/llib-lsoftcrypto usr/src/lib/pkcs11/libsoftcrypto/common/mapfile-vers usr/src/lib/pkcs11/libsoftcrypto/i386/Makefile usr/src/lib/pkcs11/libsoftcrypto/i386_hwcap1/Makefile usr/src/lib/pkcs11/libsoftcrypto/sparc/Makefile usr/src/lib/pkcs11/libsoftcrypto/sparcv9/Makefile usr/src/lib/pkcs11/libsoftcrypto/sun4u/Makefile.com usr/src/lib/pkcs11/libsoftcrypto/sun4u/mapfile-vers usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparc/Makefile usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparcv9/Makefile usr/src/lib/pkcs11/libsoftcrypto/sun4v/Makefile.com usr/src/lib/pkcs11/libsoftcrypto/sun4v/mapfile-vers usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparc/Makefile usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparcv9/Makefile usr/src/lib/pkcs11/pkcs11_softtoken/Makefile.com usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.h usr/src/lib/pkcs11/pkcs11_softtoken/common/softDESCrypt.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.h usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.h usr/src/lib/pkcs11/pkcs11_softtoken/common/softDecryptUtil.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSA.h usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSAUtil.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPost.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPostUtil.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.h usr/src/lib/pkcs11/pkcs11_softtoken/common/softObjectUtil.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.h usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandUtil.c usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.h usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c usr/src/uts/common/Makefile.files usr/src/uts/common/Makefile.rules usr/src/uts/common/crypto/io/rsa.c usr/src/uts/sun4v/Makefile.rules
diffstat 62 files changed, 3332 insertions(+), 2829 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/common/bignum/bignum.h	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/common/bignum/bignum.h	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef _BIGNUM_H
@@ -63,12 +63,13 @@
 #define	BIG_CHUNK_HALF_HIGHBIT	0x80000000ULL
 #endif
 
-#define	BITLEN2BIGNUMLEN(x)	(((x) + BIG_CHUNK_SIZE - 1) / BIG_CHUNK_SIZE)
-#define	CHARLEN2BIGNUMLEN(x)	(((x) + sizeof (BIG_CHUNK_TYPE) - 1) / \
-				    sizeof (BIG_CHUNK_TYPE))
+#define	BITLEN2BIGNUMLEN(x)	((x) > 0 ? \
+				((((x) - 1) / BIG_CHUNK_SIZE) + 1) : 0)
+#define	CHARLEN2BIGNUMLEN(x)	((x) > 0 ? \
+				((((x) - 1) / sizeof (BIG_CHUNK_TYPE)) + 1) : 0)
 
 #define	BIGNUM_WORDSIZE	(BIG_CHUNK_SIZE / BITSINBYTE)  /* word size in bytes */
-#define	BIG_CHUNKS_FOR_160BITS	((160 + BIG_CHUNK_SIZE - 1) / BIG_CHUNK_SIZE)
+#define	BIG_CHUNKS_FOR_160BITS	BITLEN2BIGNUMLEN(160)
 
 
 /*
@@ -149,7 +150,7 @@
     BIGNUM *dmodqminus1, BIGNUM *p, BIGNUM *q, BIGNUM *pinvmodq,
     BIGNUM *p_rr, BIGNUM *q_rr, big_modexp_ncp_info_t *info);
 int big_cmp_abs(BIGNUM *a, BIGNUM *b);
-BIG_ERR_CODE randombignum(BIGNUM *r, int length);
+BIG_ERR_CODE big_random(BIGNUM *r, size_t length, int (*rfunc)(void *, size_t));
 BIG_ERR_CODE big_div_pos(BIGNUM *result, BIGNUM *remainder,
     BIGNUM *aa, BIGNUM *bb);
 BIG_ERR_CODE big_ext_gcd_pos(BIGNUM *gcd, BIGNUM *cm, BIGNUM *ce,
--- a/usr/src/common/bignum/bignumimpl.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/common/bignum/bignumimpl.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -3147,3 +3147,48 @@
 
 	return (err);
 }
+
+/*
+ * Get a rlen-bit random number in BIGNUM format.  Caller-supplied
+ * (*rfunc)(void *dbuf, size_t dlen) must return 0 for success and
+ * -1 for failure.  Note:  (*rfunc)() takes length in bytes, not bits.
+ */
+BIG_ERR_CODE
+big_random(BIGNUM *r, size_t rlen, int (*rfunc)(void *, size_t))
+{
+	size_t	rwords, rbytes;
+	int	shift;
+
+	if (r == NULL || rlen == 0 || rfunc == NULL)
+		return (BIG_INVALID_ARGS);
+
+	/*
+	 * Convert rlen bits to r->len words (32- or 64-bit), rbytes bytes
+	 * and extend r if it's not big enough to hold the random number.
+	 */
+	rwords = BITLEN2BIGNUMLEN(rlen);
+	rbytes = rwords * sizeof (BIG_CHUNK_TYPE);
+	if (big_extend(r, rwords) != BIG_OK)
+		return (BIG_NO_MEM);
+#ifdef BIGNUM_CHUNK_32
+	r->len = rwords;
+#else
+	r->len = (uint32_t)rwords;
+#endif
+
+	if ((*rfunc)(r->value, rbytes) < 0)
+		return (BIG_NO_RANDOM);
+
+	r->value[rwords - 1] |= BIG_CHUNK_HIGHBIT;
+
+	/*
+	 * If the bit length is not a word boundary, shift the most
+	 * significant word so that we have an exactly rlen-long number.
+	 */
+	if ((shift = rlen % BIG_CHUNK_SIZE) != 0)
+		r->value[rwords - 1] >>= (BIG_CHUNK_SIZE - shift);
+
+	r->sign = 1;	/* non-negative */
+
+	return (BIG_OK);
+}
--- a/usr/src/common/crypto/arcfour/sun4v/arcfour_crypt.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/common/crypto/arcfour/sun4v/arcfour_crypt.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include "../arcfour.h"
@@ -119,8 +119,8 @@
 			tmp0 = base[i];
 			j = j + tmp0;
 			tmp1 = base[j];
-			base[i] = tmp1;
-			base[j] = tmp0;
+			base[i] = (uchar_t)tmp1;
+			base[j] = (uchar_t)tmp0;
 			tmp0 += tmp1;
 			tmp0 = tmp0 & 0xff;
 			out[ii] = in[ii] ^ base[tmp0];
@@ -144,8 +144,8 @@
 			j = j + tmp0;
 			tmp1 = base[j];
 
-			base[i] = tmp1;
-			base[j] = tmp0;
+			base[i] = (uchar_t)tmp1;
+			base[j] = (uchar_t)tmp0;
 
 			tmp0 += tmp1;
 			tmp0 = tmp0 & 0xff;
@@ -192,7 +192,7 @@
 				 * Don't store [i] yet
 				 */
 				i_accum = tmp1;
-				base[j] = tmp0;
+				base[j] = (uchar_t)tmp0;
 
 				tmp0 += tmp1;
 				tmp0 = tmp0 & 0xff;
@@ -223,12 +223,12 @@
 				 * If alias abort speculation
 				 */
 				if ((i1 ^ j) < 2) {
-					base1[0] = i_accum;
+					base1[0] = (uchar_t)i_accum;
 
 					tmp1 = base[j];
 
-					base1[1] = tmp1;
-					base[j] = tmp0;
+					base1[1] = (uchar_t)tmp1;
+					base[j] = (uchar_t)tmp0;
 
 					tmp0 += tmp1;
 					tmp0 = tmp0 & 0xff;
@@ -242,7 +242,7 @@
 					i_accum = i_accum << 8;
 					i_accum |= tmp1;
 
-					base[j] = tmp0;
+					base[j] = (uchar_t)tmp0;
 
 					tmp0 += tmp1;
 					tmp0 = tmp0 & 0xff;
@@ -272,8 +272,8 @@
 				tmp0 = base1[2];
 				j = j + tmp0;
 				tmp1 = base[j];
-				base1[2] = tmp1;
-				base[j] = tmp0;
+				base1[2] = (uchar_t)tmp1;
+				base[j] = (uchar_t)tmp0;
 				tmp1 += tmp0;
 				tmp1 = tmp1 & 0xff;
 				merge |= (unsigned long long)(base[tmp1]) << 40;
@@ -282,8 +282,8 @@
 				tmp0 = base1[3];
 				j = j + tmp0;
 				tmp1 = base[j];
-				base1[3] = tmp1;
-				base[j] = tmp0;
+				base1[3] = (uchar_t)tmp1;
+				base[j] = (uchar_t)tmp0;
 				tmp0 += tmp1;
 				tmp0 = tmp0 & 0xff;
 				merge |= (unsigned long long)(base[tmp0]) << 32;
@@ -292,8 +292,8 @@
 				tmp0 = base1[4];
 				j = j + tmp0;
 				tmp1 = base[j];
-				base1[4] = tmp1;
-				base[j] = tmp0;
+				base1[4] = (uchar_t)tmp1;
+				base[j] = (uchar_t)tmp0;
 				tmp0 += tmp1;
 				tmp0 = tmp0 & 0xff;
 				merge |= (unsigned long long)(base[tmp0]) << 24;
@@ -302,8 +302,8 @@
 				tmp0 = base1[5];
 				j = j + tmp0;
 				tmp1 = base[j];
-				base1[5] = tmp1;
-				base[j] = tmp0;
+				base1[5] = (uchar_t)tmp1;
+				base[j] = (uchar_t)tmp0;
 				tmp0 += tmp1;
 				tmp0 = tmp0 & 0xff;
 				merge |= (unsigned long long)(base[tmp0]) << 16;
@@ -314,7 +314,7 @@
 				j = j + tmp0;
 				tmp1 = base[j];
 				i_accum = tmp1;
-				base[j] = tmp0;
+				base[j] = (uchar_t)tmp0;
 
 				tmp0 += tmp1;
 				tmp0 = tmp0 & 0xff;
@@ -337,11 +337,11 @@
 				 */
 				j = j + tmp0;
 				if ((i1 ^ j) < 2) {
-					base1[6] = i_accum;
+					base1[6] = (uchar_t)i_accum;
 					tmp1 = base[j];
 
-					base1[7] = tmp1;
-					base[j] = tmp0;
+					base1[7] = (uchar_t)tmp1;
+					base[j] = (uchar_t)tmp0;
 
 					tmp0 += tmp1;
 					tmp0 = tmp0 & 0xff;
@@ -355,7 +355,7 @@
 					i_accum = i_accum << 8;
 					i_accum |= tmp1;
 
-					base[j] = tmp0;
+					base[j] = (uchar_t)tmp0;
 
 					tmp0 += tmp1;
 					tmp0 = tmp0 & 0xff;
@@ -380,14 +380,14 @@
 
 				/* BYTE 0 */
 				i1 = (i1 + 1) & 0xff;
-				jj = i1;
+				jj = (uchar_t)i1;
 
 				tmp0 = base[i1];
 				j = j + tmp0;
 
 				tmp1 = base[j];
 				i_accum = tmp1;
-				base[j] = tmp0;
+				base[j] = (uchar_t)tmp0;
 
 				tmp0 += tmp1;
 				tmp0 = tmp0 & 0xff;
@@ -407,12 +407,12 @@
 				j = j + tmp0;
 
 				if ((jj ^ j) < 2) {
-					base[jj] = i_accum;
+					base[jj] = (uchar_t)i_accum;
 
 					tmp1 = base[j];
 
-					base[i1+1] = tmp1;
-					base[j] = tmp0;
+					base[i1+1] = (uchar_t)tmp1;
+					base[j] = (uchar_t)tmp0;
 
 					tmp0 += tmp1;
 					tmp0 = tmp0 & 0xff;
@@ -427,7 +427,7 @@
 					i_accum = i_accum << 8;
 					i_accum |= tmp1;
 
-					base[j] = tmp0;
+					base[j] = (uchar_t)tmp0;
 
 					tmp0 += tmp1;
 					tmp0 = tmp0 & 0xff;
@@ -452,8 +452,8 @@
 				tmp0 = base[i1];
 				j = j + tmp0;
 				tmp1 = base[j];
-				base[i1] = tmp1;
-				base[j] = tmp0;
+				base[i1] = (uchar_t)tmp1;
+				base[j] = (uchar_t)tmp0;
 				tmp0 += tmp1;
 				tmp0 = tmp0 & 0xff;
 				merge |= (unsigned long long)(base[tmp0]) << 40;
@@ -462,8 +462,8 @@
 				tmp0 = base[i1+1];
 				j = j + tmp0;
 				tmp1 = base[j];
-				base[i1+1] = tmp1;
-				base[j] = tmp0;
+				base[i1+1] = (uchar_t)tmp1;
+				base[j] = (uchar_t)tmp0;
 				tmp0 += tmp1;
 				tmp0 = tmp0 & 0xff;
 				merge |= (unsigned long long)(base[tmp0]) << 32;
@@ -473,8 +473,8 @@
 				tmp0 = base[i1];
 				j = j + tmp0;
 				tmp1 = base[j];
-				base[i1] = tmp1;
-				base[j] = tmp0;
+				base[i1] = (uchar_t)tmp1;
+				base[j] = (uchar_t)tmp0;
 				tmp0 += tmp1;
 				tmp0 = tmp0 & 0xff;
 				merge |= (unsigned long long)(base[tmp0]) << 24;
@@ -483,22 +483,22 @@
 				tmp0 = base[i1+1];
 				j = j + tmp0;
 				tmp1 = base[j];
-				base[i1+1] = tmp1;
-				base[j] = tmp0;
+				base[i1+1] = (uchar_t)tmp1;
+				base[j] = (uchar_t)tmp0;
 				tmp0 += tmp1;
 				tmp0 = tmp0 & 0xff;
 				merge |= (unsigned long long)(base[tmp0]) << 16;
 
 				/* BYTE 6 */
 				i1 = (i1+2) &0xff;
-				jj = i1;
+				jj = (uchar_t)i1;
 				tmp0 = base[i1];
 
 				j = j + tmp0;
 
 				tmp1 = base[j];
 				i_accum = tmp1;
-				base[j] = tmp0;
+				base[j] = (uchar_t)tmp0;
 
 
 				tmp0 += tmp1;
@@ -519,11 +519,11 @@
 
 				j = j + tmp0;
 				if ((jj ^ j) < 2) {
-					base[jj] = i_accum;
+					base[jj] = (uchar_t)i_accum;
 					tmp1 = base[j];
 
-					base[i1] = tmp1;
-					base[j] = tmp0;
+					base[i1] = (uchar_t)tmp1;
+					base[j] = (uchar_t)tmp0;
 
 					tmp0 += tmp1;
 					tmp0 = tmp0 & 0xff;
@@ -538,7 +538,7 @@
 					i_accum = i_accum << 8;
 					i_accum |= tmp1;
 
-					base[j] = tmp0;
+					base[j] = (uchar_t)tmp0;
 
 					tmp0 += tmp1;
 					tmp0 = tmp0 & 0xff;
@@ -569,7 +569,7 @@
 			*((unsigned long long *) (&out[ii])) = in0;
 		}
 
-		i = i1;
+		i = (uchar_t)i1;
 
 		/*
 		 * Handle any overrun
@@ -588,8 +588,8 @@
 			j = j + tmp0;
 			tmp1 = base[j];
 
-			base[i] = tmp1;
-			base[j] = tmp0;
+			base[i] = (uchar_t)tmp1;
+			base[j] = (uchar_t)tmp0;
 
 			tmp0 += tmp1;
 			tmp0 = tmp0 & 0xff;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/dh/Makefile	Mon Jun 07 08:54:25 2010 -0700
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# common/crypto/dh/Makefile
+#
+# include global definitions
+include $(SRC)/Makefile.master
+
+.KEEP_STATE:
+
+FRC:
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/dh/dh_impl.c	Mon Jun 07 08:54:25 2010 -0700
@@ -0,0 +1,380 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * This file contains DH helper routines common to
+ * the PKCS11 soft token code and the kernel DH code.
+ */
+
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <bignum.h>
+
+#ifdef _KERNEL
+#include <sys/param.h>
+#else
+#include <strings.h>
+#include <cryptoutil.h>
+#endif
+
+#include <sys/crypto/common.h>
+#include <des/des_impl.h>
+#include "dh_impl.h"
+
+
+static CK_RV
+convert_rv(BIG_ERR_CODE err)
+{
+	switch (err) {
+
+	case BIG_OK:
+		return (CKR_OK);
+
+	case BIG_NO_MEM:
+		return (CKR_HOST_MEMORY);
+
+	case BIG_NO_RANDOM:
+		return (CKR_DEVICE_ERROR);
+
+	case BIG_INVALID_ARGS:
+		return (CKR_ARGUMENTS_BAD);
+
+	case BIG_DIV_BY_0:
+	default:
+		return (CKR_GENERAL_ERROR);
+	}
+}
+
+/* size is in bits */
+static BIG_ERR_CODE
+DH_key_init(DHkey *key, int size)
+{
+	BIG_ERR_CODE err = BIG_OK;
+	int len;
+
+	len = BITLEN2BIGNUMLEN(size);
+	key->size = size;
+
+	if ((err = big_init(&(key->p), len)) != BIG_OK)
+		return (err);
+	if ((err = big_init(&(key->g), len)) != BIG_OK)
+		goto ret1;
+	if ((err = big_init(&(key->x), len)) != BIG_OK)
+		goto ret2;
+	if ((err = big_init(&(key->y), len)) != BIG_OK)
+		goto ret3;
+
+	return (BIG_OK);
+
+ret3:
+	big_finish(&(key->x));
+ret2:
+	big_finish(&(key->g));
+ret1:
+	big_finish(&(key->p));
+	return (err);
+}
+
+static void
+DH_key_finish(DHkey *key)
+{
+
+	big_finish(&(key->y));
+	big_finish(&(key->x));
+	big_finish(&(key->g));
+	big_finish(&(key->p));
+
+}
+
+/*
+ * Generate DH key pair x and y, given prime p and base g.
+ * Can optionally provided bit length of x, not to exceed bit length of p.
+ */
+CK_RV
+dh_genkey_pair(DHbytekey *bkey)
+{
+	CK_RV		rv = CKR_OK;
+	BIG_ERR_CODE	brv;
+	uint32_t	primebit_len;
+	DHkey		dhkey;
+	int		(*rf)(void *, size_t);
+	uint32_t	prime_bytes;
+
+	if (bkey == NULL)
+		return (CKR_ARGUMENTS_BAD);
+
+	/* Must have prime and base set, value bits can be 0 or non-0 */
+	if (bkey->prime_bits == 0 || bkey->prime == NULL ||
+	    bkey->base_bytes == 0 || bkey->base == NULL)
+		return (CKR_ARGUMENTS_BAD);
+
+	prime_bytes = CRYPTO_BITS2BYTES(bkey->prime_bits);
+
+	if ((prime_bytes < MIN_DH_KEYLENGTH_IN_BYTES) ||
+	    (prime_bytes > MAX_DH_KEYLENGTH_IN_BYTES)) {
+		return (CKR_KEY_SIZE_RANGE);
+	}
+
+	/*
+	 * Initialize the DH key.
+	 * Note: big_extend takes length in words.
+	 */
+	if ((brv = DH_key_init(&dhkey, bkey->prime_bits)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto ret;
+	}
+
+	/* Convert prime p to bignum. */
+	if ((brv = big_extend(&(dhkey.p), CHARLEN2BIGNUMLEN(prime_bytes))) !=
+	    BIG_OK) {
+		rv = convert_rv(brv);
+		goto ret;
+	}
+	bytestring2bignum(&(dhkey.p), bkey->prime, prime_bytes);
+
+	/* Convert base g to bignum. */
+	if ((brv = big_extend(&(dhkey.g),
+	    CHARLEN2BIGNUMLEN(bkey->base_bytes))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto ret;
+	}
+	bytestring2bignum(&(dhkey.g), bkey->base, bkey->base_bytes);
+
+	/* Base g cannot be greater than prime p. */
+	if (big_cmp_abs(&(dhkey.g), &(dhkey.p)) >= 0) {
+		rv = CKR_ATTRIBUTE_VALUE_INVALID;
+		goto ret;
+	}
+
+	/*
+	 * The intention of selecting a private-value length is to reduce
+	 * the computation time for key agreement, while maintaining a
+	 * given level of security.
+	 */
+
+	/* Maximum bit length for private-value x is bit length of prime p */
+	primebit_len = big_bitlength(&(dhkey.p));
+
+	if (bkey->value_bits == 0)
+		bkey->value_bits = primebit_len;
+
+	if (bkey->value_bits > primebit_len) {
+		rv = CKR_ATTRIBUTE_VALUE_INVALID;
+		goto ret;
+	}
+
+	/* Generate DH key pair private and public values. */
+	if ((brv = big_extend(&(dhkey.x), CHARLEN2BIGNUMLEN(prime_bytes)))
+	    != BIG_OK) {
+		rv = convert_rv(brv);
+		goto ret;
+	}
+
+	if ((brv = big_extend(&(dhkey.y), CHARLEN2BIGNUMLEN(prime_bytes)))
+	    != BIG_OK) {
+		rv = convert_rv(brv);
+		goto ret;
+	}
+
+	/*
+	 * The big integer of the private value shall be generated privately
+	 * and randomly.
+	 */
+	rf = bkey->rfunc;
+	if (rf == NULL) {
+#ifdef _KERNEL
+		rf = random_get_pseudo_bytes;
+#else
+		rf = pkcs11_get_urandom;
+#endif
+	}
+
+	if ((brv = big_random(&(dhkey.x), bkey->value_bits, rf)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto ret;
+	}
+
+	/*
+	 * The base g shall be raised to the private value x modulo p to
+	 * give an integer y, the integer public value, i.e. y = (g^x) mod p.
+	 */
+	if ((brv = big_modexp(&(dhkey.y), &(dhkey.g), &(dhkey.x),
+	    &(dhkey.p), NULL)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto ret;
+	}
+
+	bignum2bytestring(bkey->private_x, &(dhkey.x), prime_bytes);
+	bignum2bytestring(bkey->public_y, &(dhkey.y), prime_bytes);
+
+ret:
+	DH_key_finish(&dhkey);
+
+	return (rv);
+}
+
+/*
+ * DH key derive operation
+ */
+CK_RV
+dh_key_derive(DHbytekey *bkey, uint32_t key_type,	/* = CKK_KEY_TYPE */
+    uchar_t *secretkey, uint32_t *secretkey_len)	/* derived secret */
+{
+	CK_RV		rv = CKR_OK;
+	BIG_ERR_CODE	brv;
+	DHkey		dhkey;
+	uchar_t		*s = NULL;
+	uint32_t	s_bytes = 0;
+	uint32_t	prime_bytes;
+	uint32_t	value_bytes;
+
+	if (bkey == NULL)
+		return (CKR_ARGUMENTS_BAD);
+
+	/* Must have prime, private value and public value */
+	if (bkey->prime_bits == 0 || bkey->prime == NULL ||
+	    bkey->value_bits == 0 || bkey->private_x == NULL ||
+	    bkey->public_y == NULL)
+		return (CKR_ARGUMENTS_BAD);
+
+	if (secretkey == NULL) {
+		return (CKR_ARGUMENTS_BAD);
+	}
+
+	prime_bytes = CRYPTO_BITS2BYTES(bkey->prime_bits);
+	value_bytes = CRYPTO_BITS2BYTES(bkey->value_bits);
+
+	/*
+	 * Initialize the DH key.
+	 * Note: big_extend takes length in words.
+	 */
+	if ((brv = DH_key_init(&dhkey, bkey->prime_bits)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto ret;
+	}
+
+	/* Convert prime p to bignum. */
+	if ((brv = big_extend(&(dhkey.p), CHARLEN2BIGNUMLEN(prime_bytes))) !=
+	    BIG_OK) {
+		rv = convert_rv(brv);
+		goto ret;
+	}
+	bytestring2bignum(&(dhkey.p), bkey->prime, prime_bytes);
+
+	/* Convert private-value x to bignum. */
+	if ((brv = big_extend(&(dhkey.x), CHARLEN2BIGNUMLEN(value_bytes))) !=
+	    BIG_OK) {
+		rv = convert_rv(brv);
+		goto ret;
+	}
+	bytestring2bignum(&(dhkey.x), bkey->private_x, value_bytes);
+
+	/* Convert public-value y to bignum. */
+	if ((brv = big_extend(&(dhkey.y), CHARLEN2BIGNUMLEN(value_bytes))) !=
+	    BIG_OK) {
+		rv = convert_rv(brv);
+		goto ret;
+	}
+	bytestring2bignum(&(dhkey.y), bkey->public_y, value_bytes);
+
+	/*
+	 * Recycle base g as a temporary variable to compute the derived
+	 * secret value which is "g" = (y^x) mod p.  (Not recomputing g.)
+	 */
+	if ((brv = big_extend(&(dhkey.g), CHARLEN2BIGNUMLEN(prime_bytes))) !=
+	    BIG_OK) {
+		rv = convert_rv(brv);
+		goto ret;
+	}
+
+	if ((brv = big_modexp(&(dhkey.g), &(dhkey.y), &(dhkey.x),
+	    &(dhkey.p), NULL)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto ret;
+	}
+
+#ifdef _KERNEL
+	if ((s = kmem_alloc(P2ROUNDUP_TYPED(prime_bytes,
+	    sizeof (BIG_CHUNK_SIZE), size_t))) == NULL) {
+#else
+	if ((s = malloc(P2ROUNDUP_TYPED(prime_bytes,
+	    sizeof (BIG_CHUNK_SIZE), size_t))) == NULL) {
+#endif
+		rv = CKR_HOST_MEMORY;
+		goto ret;
+	}
+	s_bytes = dhkey.g.len * (int)sizeof (BIG_CHUNK_TYPE);
+	bignum2bytestring(s, &(dhkey.g), s_bytes);
+
+	switch (key_type) {
+
+	case CKK_DES:
+		*secretkey_len = DES_KEYSIZE;
+		break;
+	case CKK_DES2:
+		*secretkey_len = DES2_KEYSIZE;
+		break;
+	case CKK_DES3:
+		*secretkey_len = DES3_KEYSIZE;
+		break;
+	case CKK_RC4:
+	case CKK_AES:
+	case CKK_GENERIC_SECRET:
+		/* use provided secret key length, if any */
+		break;
+	default:
+		/* invalid key type */
+		rv = CKR_ATTRIBUTE_TYPE_INVALID;
+		goto ret;
+	}
+
+	if (*secretkey_len == 0) {
+		*secretkey_len = s_bytes;
+	}
+
+	if (*secretkey_len > s_bytes) {
+		rv = CKR_ATTRIBUTE_VALUE_INVALID;
+		goto ret;
+	}
+
+	/*
+	 * The truncation removes bytes from the leading end of the
+	 * secret value.
+	 */
+	(void) memcpy(secretkey, (s + s_bytes - *secretkey_len),
+	    *secretkey_len);
+
+ret:
+	if (s != NULL)
+#ifdef _KERNEL
+		kmem_free(s, sizeof (BIG_CHUNK_SIZE));
+#else
+		free(s);
+#endif
+
+	DH_key_finish(&dhkey);
+
+	return (rv);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/dh/dh_impl.h	Mon Jun 07 08:54:25 2010 -0700
@@ -0,0 +1,99 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _DH_IMPL_H
+#define	_DH_IMPL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <bignum.h>
+
+#define	MIN_DH_KEYLENGTH_IN_BYTES	8
+#define	MAX_DH_KEYLENGTH_IN_BYTES	512
+#define	DH_MIN_KEY_LEN		64
+#define	DH_MAX_KEY_LEN		4096
+
+#ifdef _KERNEL
+
+#include <sys/sunddi.h>
+#include <sys/crypto/common.h>
+
+#define	CK_RV			ulong_t
+
+#define	CKR_OK			CRYPTO_SUCCESS
+#define	CKR_ARGUMENTS_BAD	CRYPTO_ARGUMENTS_BAD
+#define	CKR_ATTRIBUTE_TYPE_INVALID	CRYPTO_ATTRIBUTE_TYPE_INVALID
+#define	CKR_ATTRIBUTE_VALUE_INVALID	CRYPTO_ATTRIBUTE_VALUE_INVALID
+#define	CKR_DEVICE_ERROR	CRYPTO_DEVICE_ERROR
+#define	CKR_GENERAL_ERROR	CRYPTO_GENERAL_ERROR
+#define	CKR_HOST_MEMORY		CRYPTO_HOST_MEMORY
+#define	CKR_KEY_SIZE_RANGE	CRYPTO_KEY_SIZE_RANGE
+
+int random_get_bytes(uint8_t *ran_out, size_t ran_len);
+int random_get_pseudo_bytes(uint8_t *ran_out, size_t ran_len);
+
+#else
+
+#include <security/cryptoki.h>
+#include <security/pkcs11t.h>
+
+#endif	/* _KERNEL */
+
+
+/* DH key using BIGNUM representations */
+typedef struct {
+	int 	size;		/* key size in bits */
+	BIGNUM	p;		/* p (prime) */
+	BIGNUM	g;		/* g (base) */
+	BIGNUM	x;		/* private value (random) */
+	BIGNUM	y;		/* public value (= g^x mod p) */
+} DHkey;
+
+/* DH key using byte string representations, useful for parameter lists */
+typedef struct {
+	uint32_t prime_bits;	/* size */
+	uchar_t	*prime;		/* p */
+	uint32_t base_bytes;
+	uchar_t *base;		/* g */
+	uint32_t value_bits;	/* for both x and y */
+	uchar_t	*private_x;	/* x */
+	uchar_t *public_y;	/* y */
+	int	(*rfunc)(void *, size_t);	/* random function */
+} DHbytekey;
+
+
+CK_RV dh_genkey_pair(DHbytekey *bkey);
+
+CK_RV dh_key_derive(DHbytekey *bkey, uint32_t key_type,
+    uchar_t *secretkey, uint32_t *secretkey_len);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _DH_IMPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/dsa/Makefile	Mon Jun 07 08:54:25 2010 -0700
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# common/crypto/dsa/Makefile
+#
+# include global definitions
+include $(SRC)/Makefile.master
+
+.KEEP_STATE:
+
+FRC:
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/dsa/dsa_impl.c	Mon Jun 07 08:54:25 2010 -0700
@@ -0,0 +1,600 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * This file contains DSA helper routines common to
+ * the PKCS11 soft token code and the kernel DSA code.
+ */
+
+#include <sys/types.h>
+#include <bignum.h>
+
+#ifdef _KERNEL
+#include <sys/param.h>
+#else
+#include <strings.h>
+#include <cryptoutil.h>
+#endif
+
+#include <sys/crypto/common.h>
+#include "dsa_impl.h"
+
+
+static CK_RV
+convert_rv(BIG_ERR_CODE err)
+{
+	switch (err) {
+
+	case BIG_OK:
+		return (CKR_OK);
+
+	case BIG_NO_MEM:
+		return (CKR_HOST_MEMORY);
+
+	case BIG_NO_RANDOM:
+		return (CKR_DEVICE_ERROR);
+
+	case BIG_INVALID_ARGS:
+		return (CKR_ARGUMENTS_BAD);
+
+	case BIG_DIV_BY_0:
+	default:
+		return (CKR_GENERAL_ERROR);
+	}
+}
+
+/* size is in bits */
+static BIG_ERR_CODE
+DSA_key_init(DSAkey *key, int size)
+{
+	BIG_ERR_CODE err = BIG_OK;
+	int len, len160;
+
+	len = BITLEN2BIGNUMLEN(size);
+	len160 = BIG_CHUNKS_FOR_160BITS;
+	key->size = size;
+	if ((err = big_init(&(key->q), len160)) != BIG_OK)
+		return (err);
+	if ((err = big_init(&(key->p), len)) != BIG_OK)
+		goto ret1;
+	if ((err = big_init(&(key->g), len)) != BIG_OK)
+		goto ret2;
+	if ((err = big_init(&(key->x), len160)) != BIG_OK)
+		goto ret3;
+	if ((err = big_init(&(key->y), len)) != BIG_OK)
+		goto ret4;
+	if ((err = big_init(&(key->k), len160)) != BIG_OK)
+		goto ret5;
+	if ((err = big_init(&(key->r), len160)) != BIG_OK)
+		goto ret6;
+	if ((err = big_init(&(key->s), len160)) != BIG_OK)
+		goto ret7;
+	if ((err = big_init(&(key->v), len160)) != BIG_OK)
+		goto ret8;
+
+	return (BIG_OK);
+
+ret8:
+	big_finish(&(key->s));
+ret7:
+	big_finish(&(key->r));
+ret6:
+	big_finish(&(key->k));
+ret5:
+	big_finish(&(key->y));
+ret4:
+	big_finish(&(key->x));
+ret3:
+	big_finish(&(key->g));
+ret2:
+	big_finish(&(key->p));
+ret1:
+	big_finish(&(key->q));
+	return (err);
+}
+
+static void
+DSA_key_finish(DSAkey *key)
+{
+
+	big_finish(&(key->v));
+	big_finish(&(key->s));
+	big_finish(&(key->r));
+	big_finish(&(key->k));
+	big_finish(&(key->y));
+	big_finish(&(key->x));
+	big_finish(&(key->g));
+	big_finish(&(key->p));
+	big_finish(&(key->q));
+
+}
+
+/*
+ * Generate DSA private x and public y from prime p, subprime q, and base g.
+ */
+static CK_RV
+generate_dsa_key(DSAkey *key, int (*rfunc)(void *, size_t))
+{
+	BIG_ERR_CODE err;
+	int (*rf)(void *, size_t);
+
+	rf = rfunc;
+	if (rf == NULL) {
+#ifdef _KERNEL
+		rf = random_get_pseudo_bytes;
+#else
+		rf = pkcs11_get_urandom;
+#endif
+	}
+	do {
+		if ((err = big_random(&(key->x), DSA_SUBPRIME_BITS, rf)) !=
+		    BIG_OK) {
+			return (convert_rv(err));
+		}
+	} while (big_cmp_abs(&(key->x), &(key->q)) > 0);
+
+	if ((err = big_modexp(&(key->y), &(key->g), (&key->x), (&key->p),
+	    NULL)) != BIG_OK)
+		return (convert_rv(err));
+
+	return (CKR_OK);
+}
+
+CK_RV
+dsa_genkey_pair(DSAbytekey *bkey)
+{
+	CK_RV rv = CKR_OK;
+	BIG_ERR_CODE brv;
+	DSAkey	dsakey;
+	uint32_t prime_bytes;
+	uint32_t subprime_bytes;
+
+	prime_bytes = CRYPTO_BITS2BYTES(bkey->prime_bits);
+
+	if ((prime_bytes < MIN_DSA_KEY_LEN) ||
+	    (prime_bytes > MAX_DSA_KEY_LEN)) {
+		return (CKR_ATTRIBUTE_VALUE_INVALID);
+	}
+
+	/*
+	 * There is no check here that prime_bits must be a multiple of 64,
+	 * and thus that prime_bytes must be a multiple of 8.
+	 */
+
+	subprime_bytes = CRYPTO_BITS2BYTES(bkey->subprime_bits);
+
+	if (subprime_bytes != DSA_SUBPRIME_BYTES) {
+		return (CKR_ATTRIBUTE_VALUE_INVALID);
+	}
+
+	if (bkey->public_y == NULL || bkey->private_x == NULL) {
+		return (CKR_ARGUMENTS_BAD);
+	}
+
+	/*
+	 * Initialize the DSA key.
+	 * Note: big_extend takes length in words.
+	 */
+	if ((brv = DSA_key_init(&dsakey, bkey->prime_bits)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto cleanexit;
+	}
+
+	/* Convert prime p to bignum. */
+	if ((brv = big_extend(&(dsakey.p),
+	    CHARLEN2BIGNUMLEN(prime_bytes))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto cleanexit;
+	}
+	bytestring2bignum(&(dsakey.p), bkey->prime, prime_bytes);
+
+	/* Convert prime q to bignum. */
+	if ((brv = big_extend(&(dsakey.q),
+	    CHARLEN2BIGNUMLEN(subprime_bytes))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto cleanexit;
+	}
+	bytestring2bignum(&(dsakey.q), bkey->subprime, subprime_bytes);
+
+	/* Convert base g to bignum. */
+	if ((brv = big_extend(&(dsakey.g),
+	    CHARLEN2BIGNUMLEN(bkey->base_bytes))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto cleanexit;
+	}
+	bytestring2bignum(&(dsakey.g), bkey->base, bkey->base_bytes);
+
+	/*
+	 * Generate DSA key pair.
+	 * Note: bignum.len is length of value in words.
+	 */
+	if ((rv = generate_dsa_key(&dsakey, bkey->rfunc)) !=
+	    CKR_OK) {
+		goto cleanexit;
+	}
+
+	bkey->public_y_bits = CRYPTO_BYTES2BITS(prime_bytes);
+	bignum2bytestring(bkey->public_y, &(dsakey.y), prime_bytes);
+
+	bkey->private_x_bits = CRYPTO_BYTES2BITS(DSA_SUBPRIME_BYTES);
+	bignum2bytestring(bkey->private_x, &(dsakey.x), DSA_SUBPRIME_BYTES);
+
+cleanexit:
+	DSA_key_finish(&dsakey);
+
+	return (rv);
+}
+
+/*
+ * DSA sign operation
+ */
+CK_RV
+dsa_sign(DSAbytekey *bkey, uchar_t *in, uint32_t inlen, uchar_t *out)
+{
+	CK_RV rv = CKR_OK;
+	BIG_ERR_CODE brv;
+	DSAkey dsakey;
+	BIGNUM msg, tmp, tmp1;
+	uint32_t prime_bytes;
+	uint32_t subprime_bytes;
+	uint32_t value_bytes;
+	int (*rf)(void *, size_t);
+
+	prime_bytes = CRYPTO_BITS2BYTES(bkey->prime_bits);
+	subprime_bytes = CRYPTO_BITS2BYTES(bkey->subprime_bits);
+
+	if (DSA_SUBPRIME_BYTES != subprime_bytes) {
+		return (CKR_KEY_SIZE_RANGE);
+	}
+
+	value_bytes = CRYPTO_BITS2BYTES(bkey->private_x_bits);	/* len of x */
+
+	if (DSA_SUBPRIME_BYTES < value_bytes) {
+		return (CKR_KEY_SIZE_RANGE);
+	}
+
+	/*
+	 * Initialize the DH key.
+	 * Note: big_extend takes length in words.
+	 */
+	if ((brv = DSA_key_init(&dsakey, bkey->prime_bits)) != BIG_OK) {
+		return (CKR_HOST_MEMORY);
+	}
+
+	if ((brv = big_extend(&(dsakey.p),
+	    CHARLEN2BIGNUMLEN(prime_bytes))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean1;
+	}
+	bytestring2bignum(&(dsakey.p), bkey->prime, prime_bytes);
+
+	if ((brv = big_extend(&(dsakey.q),
+	    CHARLEN2BIGNUMLEN(subprime_bytes))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean1;
+	}
+	bytestring2bignum(&(dsakey.q), bkey->subprime, subprime_bytes);
+
+	if ((brv = big_extend(&(dsakey.g),
+	    CHARLEN2BIGNUMLEN(bkey->base_bytes))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean1;
+	}
+	bytestring2bignum(&(dsakey.g), bkey->base, bkey->base_bytes);
+
+	if ((brv = big_extend(&(dsakey.x),
+	    CHARLEN2BIGNUMLEN(value_bytes))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean1;
+	}
+	bytestring2bignum(&(dsakey.x), bkey->private_x, value_bytes);
+
+	if ((brv = big_init(&msg, BIG_CHUNKS_FOR_160BITS)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean1;
+	}
+	bytestring2bignum(&msg, in, inlen);
+
+	/*
+	 * Compute signature.
+	 */
+	if ((brv = big_init(&tmp, CHARLEN2BIGNUMLEN(prime_bytes) +
+	    2 * BIG_CHUNKS_FOR_160BITS + 1)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean2;
+	}
+	if ((brv = big_init(&tmp1, 2 * BIG_CHUNKS_FOR_160BITS + 1)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean3;
+	}
+
+	rf = bkey->rfunc;
+	if (rf == NULL) {
+#ifdef _KERNEL
+		rf = random_get_pseudo_bytes;
+#else
+		rf = pkcs11_get_urandom;
+#endif
+	}
+	if ((brv = big_random(&(dsakey.k), DSA_SUBPRIME_BITS, rf)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean4;
+	}
+
+	if ((brv = big_div_pos(NULL, &(dsakey.k), &(dsakey.k),
+	    &(dsakey.q))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean4;
+	}
+
+	if ((brv = big_modexp(&tmp, &(dsakey.g), &(dsakey.k), &(dsakey.p),
+	    NULL)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean4;
+	}
+
+	if ((brv = big_div_pos(NULL, &(dsakey.r), &tmp, &(dsakey.q))) !=
+	    BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean4;
+	}
+
+
+	if ((brv = big_ext_gcd_pos(NULL, NULL, &tmp, &(dsakey.q),
+	    &(dsakey.k))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean4;
+	}
+
+	if (tmp.sign == -1)
+		if ((brv = big_add(&tmp, &tmp, &(dsakey.q))) != BIG_OK) {
+			rv = convert_rv(brv);
+			goto clean4;			/* tmp <- k^-1 */
+		}
+
+	if ((brv = big_mul(&tmp1, &(dsakey.x), &(dsakey.r))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean4;
+	}
+
+	if ((brv = big_add(&tmp1, &tmp1, &msg)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean4;
+	}
+
+	if ((brv = big_mul(&tmp, &tmp1, &tmp)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean4;
+	}
+
+	if ((brv = big_div_pos(NULL, &(dsakey.s), &tmp, &(dsakey.q))) !=
+	    BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean4;
+	}
+
+	/*
+	 * Signature is in DSA key r and s values, copy to out
+	 */
+	bignum2bytestring(out, &(dsakey.r), DSA_SUBPRIME_BYTES);
+	bignum2bytestring(out + DSA_SUBPRIME_BYTES, &(dsakey.s),
+	    DSA_SUBPRIME_BYTES);
+
+clean4:
+	big_finish(&tmp1);
+clean3:
+	big_finish(&tmp);
+clean2:
+	big_finish(&msg);
+clean1:
+	DSA_key_finish(&dsakey);
+
+	return (rv);
+}
+
+/*
+ * DSA verify operation
+ */
+CK_RV
+dsa_verify(DSAbytekey *bkey, uchar_t *data, uchar_t *sig)
+{
+	CK_RV rv = CKR_OK;
+	BIG_ERR_CODE brv;
+	DSAkey dsakey;
+	BIGNUM msg, tmp1, tmp2, tmp3;
+	uint32_t prime_bytes;
+	uint32_t subprime_bytes;
+	uint32_t value_bytes;
+
+	prime_bytes = CRYPTO_BITS2BYTES(bkey->prime_bits);
+	subprime_bytes = CRYPTO_BITS2BYTES(bkey->subprime_bits);
+
+	if (DSA_SUBPRIME_BYTES != subprime_bytes) {
+		return (CKR_KEY_SIZE_RANGE);
+	}
+
+	if (prime_bytes < bkey->base_bytes) {
+		return (CKR_KEY_SIZE_RANGE);
+	}
+
+	value_bytes = CRYPTO_BITS2BYTES(bkey->public_y_bits);	/* len of y */
+	if (prime_bytes < value_bytes) {
+		return (CKR_KEY_SIZE_RANGE);
+	}
+
+	/*
+	 * Initialize the DSA key.
+	 * Note: big_extend takes length in words.
+	 */
+	if (DSA_key_init(&dsakey, bkey->prime_bits) != BIG_OK) {
+		return (CKR_HOST_MEMORY);
+	}
+
+	if ((brv = big_extend(&(dsakey.p),
+	    CHARLEN2BIGNUMLEN(prime_bytes))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean1;
+	}
+	bytestring2bignum(&(dsakey.p), bkey->prime, prime_bytes);
+
+	if ((brv = big_extend(&(dsakey.q),
+	    CHARLEN2BIGNUMLEN(subprime_bytes))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean1;
+	}
+	bytestring2bignum(&(dsakey.q), bkey->subprime, subprime_bytes);
+
+	if ((brv = big_extend(&(dsakey.g),
+	    CHARLEN2BIGNUMLEN(bkey->base_bytes))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean1;
+	}
+	bytestring2bignum(&(dsakey.g), bkey->base, bkey->base_bytes);
+
+	if ((brv = big_extend(&(dsakey.y),
+	    CHARLEN2BIGNUMLEN(value_bytes))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean1;
+	}
+	bytestring2bignum(&(dsakey.y), bkey->public_y, value_bytes);
+
+	/*
+	 * Copy signature to DSA key r and s values
+	 */
+	if ((brv = big_extend(&(dsakey.r),
+	    CHARLEN2BIGNUMLEN(DSA_SUBPRIME_BYTES))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean1;
+	}
+	bytestring2bignum(&(dsakey.r), sig, DSA_SUBPRIME_BYTES);
+
+	if ((brv = big_extend(&(dsakey.s),
+	    CHARLEN2BIGNUMLEN(DSA_SUBPRIME_BYTES))) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean1;
+	}
+	bytestring2bignum(&(dsakey.s), sig + DSA_SUBPRIME_BYTES,
+	    DSA_SUBPRIME_BYTES);
+
+
+	if (big_init(&msg, BIG_CHUNKS_FOR_160BITS) != BIG_OK) {
+		rv = CKR_HOST_MEMORY;
+		goto clean1;
+	}
+	bytestring2bignum(&msg, data, DSA_SUBPRIME_BYTES);
+
+	if (big_init(&tmp1, 2 * CHARLEN2BIGNUMLEN(prime_bytes)) != BIG_OK) {
+		rv = CKR_HOST_MEMORY;
+		goto clean2;
+	}
+	if (big_init(&tmp2, CHARLEN2BIGNUMLEN(prime_bytes)) != BIG_OK) {
+		rv = CKR_HOST_MEMORY;
+		goto clean3;
+	}
+	if (big_init(&tmp3, 2 * BIG_CHUNKS_FOR_160BITS) != BIG_OK) {
+		rv = CKR_HOST_MEMORY;
+		goto clean4;
+	}
+
+	/*
+	 * Verify signature against msg.
+	 */
+	if (big_ext_gcd_pos(NULL, &tmp2, NULL, &(dsakey.s), &(dsakey.q)) !=
+	    BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean5;
+	}
+
+	if (tmp2.sign == -1)
+		if (big_add(&tmp2, &tmp2, &(dsakey.q)) != BIG_OK) {
+			rv = convert_rv(brv);
+			goto clean5;			/* tmp2 <- w */
+		}
+
+	if (big_mul(&tmp1, &msg, &tmp2) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean5;
+	}
+
+	if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.q)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean5;				/* tmp1 <- u_1 */
+	}
+
+	if (big_mul(&tmp2, &tmp2, &(dsakey.r)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean5;
+	}
+
+	if (big_div_pos(NULL, &tmp2, &tmp2, &(dsakey.q)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean5;				/* tmp2 <- u_2 */
+	}
+
+	if (big_modexp(&tmp1, &(dsakey.g), &tmp1, &(dsakey.p), NULL) !=
+	    BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean5;
+	}
+
+	if (big_modexp(&tmp2, &(dsakey.y), &tmp2, &(dsakey.p), NULL) !=
+	    BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean5;
+	}
+
+	if (big_mul(&tmp1, &tmp1, &tmp2) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean5;
+	}
+
+	if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.p)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean5;
+	}
+
+	if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.q)) != BIG_OK) {
+		rv = convert_rv(brv);
+		goto clean5;
+	}
+
+	if (big_cmp_abs(&tmp1, &(dsakey.r)) == 0)
+		rv = CKR_OK;
+	else
+		rv = CKR_SIGNATURE_INVALID;
+
+clean5:
+	big_finish(&tmp3);
+clean4:
+	big_finish(&tmp2);
+clean3:
+	big_finish(&tmp1);
+clean2:
+	big_finish(&msg);
+clean1:
+	DSA_key_finish(&dsakey);
+
+	return (rv);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/dsa/dsa_impl.h	Mon Jun 07 08:54:25 2010 -0700
@@ -0,0 +1,136 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _DSA_IMPL_H
+#define	_DSA_IMPL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <bignum.h>
+
+/* DSA Signature is always 40 bytes */
+#define	DSA_SIGNATURE_LENGTH	40
+#define	MIN_DSA_KEY_LEN		(512 >> 3)
+#define	MAX_DSA_KEY_LEN		(1024 >> 3)
+
+#define	DSA_SUBPRIME_BITS	160
+#define	DSA_SUBPRIME_BYTES	(DSA_SUBPRIME_BITS >> 3)
+
+#ifdef _KERNEL
+
+#include <sys/sunddi.h>
+#include <sys/crypto/common.h>
+
+#define	CK_RV			int
+
+#define	CKR_OK			CRYPTO_SUCCESS
+#define	CKR_ARGUMENTS_BAD	CRYPTO_ARGUMENTS_BAD
+#define	CKR_ATTRIBUTE_VALUE_INVALID	CRYPTO_ATTRIBUTE_VALUE_INVALID
+#define	CKR_DEVICE_ERROR	CRYPTO_DEVICE_ERROR
+#define	CKR_GENERAL_ERROR	CRYPTO_GENERAL_ERROR
+#define	CKR_HOST_MEMORY		CRYPTO_HOST_MEMORY
+#define	CKR_KEY_SIZE_RANGE	CRYPTO_KEY_SIZE_RANGE
+#define	CKR_SIGNATURE_INVALID	CRYPTO_SIGNATURE_INVALID
+
+int random_get_bytes(uint8_t *ran_out, size_t ran_len);
+int random_get_pseudo_bytes(uint8_t *ran_out, size_t ran_len);
+
+#else
+
+#include <security/cryptoki.h>
+#include <security/pkcs11t.h>
+
+#endif	/* _KERNEL */
+
+
+/* DSA key using BIGNUM representations */
+typedef struct {
+	int 	size;		/* key size in bits */
+	BIGNUM	p;		/* p (<size-bit> prime) */
+	BIGNUM	q;		/* q (160-bit prime) */
+	BIGNUM	g;		/* g (the base) */
+	BIGNUM	x;		/* private key (< q) */
+	BIGNUM	y;		/* = g^x mod p */
+	BIGNUM	k;		/* k (random number < q) */
+	BIGNUM	r;		/* r (signature 1st part) */
+	BIGNUM	s;		/* s (signature 2st part) */
+	BIGNUM	v;		/* v (verification value - should be = r) */
+	BIGNUM	p_rr;		/* 2^(2*(32*p->len)) mod p */
+	BIGNUM	q_rr;		/* 2^(2*(32*q->len)) mod q */
+} DSAkey;
+
+/* DSA key using byte string representations, useful for parameter lists */
+typedef struct {
+	uint32_t prime_bits;	/* size */
+	uchar_t	*prime;		/* p */
+	uint32_t subprime_bits;	/* = 160 */
+	uchar_t	*subprime;	/* q */
+	uint32_t base_bytes;
+	uchar_t	*base;		/* g */
+	uchar_t	*private_x;	/* x */
+	uint32_t private_x_bits;
+	uchar_t	*public_y;	/* y */
+	uint32_t public_y_bits;
+	uchar_t	*signature;	/* concat(r, s) */
+	int	(*rfunc)(void *, size_t);	/* random function */
+} DSAbytekey;
+
+
+CK_RV dsa_genkey_pair(DSAbytekey *bkey);
+
+CK_RV dsa_sign(DSAbytekey *bkey, uchar_t *msg, uint32_t msglen, uchar_t *sig);
+
+CK_RV dsa_verify(DSAbytekey *bkey, uchar_t *msg, uchar_t *sig);
+
+
+/*
+ * The following definitions and declarations are only used by DSA FIPS POST
+ */
+#ifdef _DSA_FIPS_POST
+
+/* DSA FIPS Declarations */
+#define	FIPS_DSA_PRIME_LENGTH		128 /* 1024-bits */
+#define	FIPS_DSA_SUBPRIME_LENGTH	20 /*  160-bits */
+#define	FIPS_DSA_BASE_LENGTH		128 /* 1024-bits */
+#define	FIPS_DSA_SEED_LENGTH		20 /*  160-bits */
+#define	FIPS_DSA_DIGEST_LENGTH		20 /*  160-bits */
+#define	FIPS_DSA_SIGNATURE_LENGTH	40 /*  320-bits */
+
+/* DSA FIPS functions */
+extern int fips_dsa_post(void);
+extern int fips_dsa_genkey_pair(DSAbytekey *);
+extern int fips_dsa_digest_sign(DSAbytekey *, uint8_t *, uint32_t, uint8_t *);
+extern int fips_dsa_verify(DSAbytekey *, uint8_t *, uint8_t *);
+
+#endif /* _DSA_FIPS_POST */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _DSA_IMPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/fips/fips_dsa_util.c	Mon Jun 07 08:54:25 2010 -0700
@@ -0,0 +1,260 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/sha1.h>
+#define	_SHA2_IMPL
+#include <sys/sha2.h>
+
+#ifdef	_KERNEL
+#include <sys/param.h>
+#include <sys/kmem.h>
+#else
+#include <strings.h>
+#include <cryptoutil.h>
+#include "softMAC.h"
+#endif
+
+#include <security/cryptoki.h>
+#include <sys/crypto/common.h>
+
+#include <sha1/sha1_impl.h>
+#define	_DSA_FIPS_POST
+#include <dsa/dsa_impl.h>
+
+
+/* DSA Known P (1024-bits), Q (160-bits), and G (1024-bits) Values. */
+static uint8_t dsa_P[] = {
+	0x80, 0xb0, 0xd1, 0x9d, 0x6e, 0xa4, 0xf3, 0x28,
+	0x9f, 0x24, 0xa9, 0x8a, 0x49, 0xd0, 0x0c, 0x63,
+	0xe8, 0x59, 0x04, 0xf9, 0x89, 0x4a, 0x5e, 0xc0,
+	0x6d, 0xd2, 0x67, 0x6b, 0x37, 0x81, 0x83, 0x0c,
+	0xfe, 0x3a, 0x8a, 0xfd, 0xa0, 0x3b, 0x08, 0x91,
+	0x1c, 0xcb, 0xb5, 0x63, 0xb0, 0x1c, 0x70, 0xd0,
+	0xae, 0xe1, 0x60, 0x2e, 0x12, 0xeb, 0x54, 0xc7,
+	0xcf, 0xc6, 0xcc, 0xae, 0x97, 0x52, 0x32, 0x63,
+	0xd3, 0xeb, 0x55, 0xea, 0x2f, 0x4c, 0xd5, 0xd7,
+	0x3f, 0xda, 0xec, 0x49, 0x27, 0x0b, 0x14, 0x56,
+	0xc5, 0x09, 0xbe, 0x4d, 0x09, 0x15, 0x75, 0x2b,
+	0xa3, 0x42, 0x0d, 0x03, 0x71, 0xdf, 0x0f, 0xf4,
+	0x0e, 0xe9, 0x0c, 0x46, 0x93, 0x3d, 0x3f, 0xa6,
+	0x6c, 0xdb, 0xca, 0xe5, 0xac, 0x96, 0xc8, 0x64,
+	0x5c, 0xec, 0x4b, 0x35, 0x65, 0xfc, 0xfb, 0x5a,
+	0x1b, 0x04, 0x1b, 0xa1, 0x0e, 0xfd, 0x88, 0x15
+};
+
+static uint8_t dsa_Q[] = {
+	0xad, 0x22, 0x59, 0xdf, 0xe5, 0xec, 0x4c, 0x6e,
+	0xf9, 0x43, 0xf0, 0x4b, 0x2d, 0x50, 0x51, 0xc6,
+	0x91, 0x99, 0x8b, 0xcf
+};
+
+static uint8_t dsa_G[] = {
+	0x78, 0x6e, 0xa9, 0xd8, 0xcd, 0x4a, 0x85, 0xa4,
+	0x45, 0xb6, 0x6e, 0x5d, 0x21, 0x50, 0x61, 0xf6,
+	0x5f, 0xdf, 0x5c, 0x7a, 0xde, 0x0d, 0x19, 0xd3,
+	0xc1, 0x3b, 0x14, 0xcc, 0x8e, 0xed, 0xdb, 0x17,
+	0xb6, 0xca, 0xba, 0x86, 0xa9, 0xea, 0x51, 0x2d,
+	0xc1, 0xa9, 0x16, 0xda, 0xf8, 0x7b, 0x59, 0x8a,
+	0xdf, 0xcb, 0xa4, 0x67, 0x00, 0x44, 0xea, 0x24,
+	0x73, 0xe5, 0xcb, 0x4b, 0xaf, 0x2a, 0x31, 0x25,
+	0x22, 0x28, 0x3f, 0x16, 0x10, 0x82, 0xf7, 0xeb,
+	0x94, 0x0d, 0xdd, 0x09, 0x22, 0x14, 0x08, 0x79,
+	0xba, 0x11, 0x0b, 0xf1, 0xff, 0x2d, 0x67, 0xac,
+	0xeb, 0xb6, 0x55, 0x51, 0x69, 0x97, 0xa7, 0x25,
+	0x6b, 0x9c, 0xa0, 0x9b, 0xd5, 0x08, 0x9b, 0x27,
+	0x42, 0x1c, 0x7a, 0x69, 0x57, 0xe6, 0x2e, 0xed,
+	0xa9, 0x5b, 0x25, 0xe8, 0x1f, 0xd2, 0xed, 0x1f,
+	0xdf, 0xe7, 0x80, 0x17, 0xba, 0x0d, 0x4d, 0x38
+};
+
+/*
+ * DSA Known Random Values (known random key block is 160-bits)
+ * and (known random signature block is 160-bits).
+ */
+static uint8_t dsa_known_random_key_block[] = {
+	"This is DSA RNG key!"
+};
+
+static uint8_t dsa_known_random_signature_block[] = {
+	"Random DSA Signature"
+};
+
+/* DSA Known Digest (160-bits) */
+static uint8_t dsa_known_digest[] = {
+	"DSA Signature Digest"
+};
+
+/* DSA Known Signature (320-bits). */
+static uint8_t dsa_known_signature[] = {
+	0x25, 0x7c, 0x3a, 0x79, 0x32, 0x45, 0xb7, 0x32,
+	0x70, 0xca, 0x62, 0x63, 0x2b, 0xf6, 0x29, 0x2c,
+	0x22, 0x2a, 0x03, 0xce, 0x65, 0x02, 0x72, 0x5a,
+	0x66, 0x29, 0xcf, 0x56, 0xe6, 0xdf, 0xb0, 0xcc,
+	0x53, 0x72, 0x56, 0x70, 0x92, 0xb5, 0x45, 0x75
+
+};
+
+
+static int
+fips_dsa_random_func(void *buf, size_t buflen)
+{
+	/* should not happen */
+	if (buflen != FIPS_DSA_SEED_LENGTH)
+		return (-1);
+
+	(void) memcpy(buf, dsa_known_random_key_block,
+	    FIPS_DSA_SEED_LENGTH);
+	return (0);
+}
+
+static int
+fips_dsa_signature_func(void *buf, size_t buflen)
+{
+	/* should not happen */
+	if (buflen != FIPS_DSA_SEED_LENGTH)
+		return (-1);
+
+	(void) memcpy(buf, dsa_known_random_signature_block,
+	    FIPS_DSA_SEED_LENGTH);
+	return (0);
+}
+
+int
+fips_dsa_genkey_pair(DSAbytekey *bkey)
+{
+	return (dsa_genkey_pair(bkey));
+}
+
+int
+fips_dsa_digest_sign(DSAbytekey *bkey,
+	uint8_t *in, uint32_t inlen, uint8_t *out)
+{
+	CK_RV rv;
+	SHA1_CTX *sha1_context;
+	uint8_t sha1_computed_digest[FIPS_DSA_DIGEST_LENGTH];
+
+	sha1_context = fips_sha1_build_context();
+	if (sha1_context == NULL)
+		return (CKR_HOST_MEMORY);
+
+	rv = fips_sha1_hash(sha1_context, in, inlen, sha1_computed_digest);
+	if (rv != CKR_OK)
+		goto clean1;
+
+	rv = dsa_sign(bkey, sha1_computed_digest, FIPS_DSA_DIGEST_LENGTH, out);
+
+clean1:
+#ifdef _KERNEL
+	kmem_free(sha1_context, sizeof (SHA1_CTX));
+#else
+	free(sha1_context);
+#endif
+	return (rv);
+}
+
+int
+fips_dsa_verify(DSAbytekey *bkey, uint8_t *data, uint8_t *sig)
+{
+	CK_RV rv;
+	SHA1_CTX *sha1_context;
+	uint8_t sha1_computed_digest[FIPS_DSA_DIGEST_LENGTH];
+
+	sha1_context = fips_sha1_build_context();
+	if (sha1_context == NULL)
+		return (CKR_HOST_MEMORY);
+
+	rv = fips_sha1_hash(sha1_context, data, FIPS_DSA_DIGEST_LENGTH,
+	    sha1_computed_digest);
+	if (rv != CKR_OK)
+		goto clean1;
+
+	rv = dsa_verify(bkey, sha1_computed_digest, sig);
+
+clean1:
+#ifdef _KERNEL
+	kmem_free(sha1_context, sizeof (SHA1_CTX));
+#else
+	free(sha1_context);
+#endif
+	return (rv);
+}
+
+/*
+ * DSA Power-On SelfTest(s).
+ */
+int
+fips_dsa_post(void)
+{
+	DSAbytekey dsa_params;
+	CK_RV rv;
+	uint8_t dsa_computed_signature[FIPS_DSA_SIGNATURE_LENGTH];
+
+	/*
+	 * Generate a DSA public/private key pair.
+	 */
+	dsa_params.prime = dsa_P;
+	dsa_params.prime_bits = CRYPTO_BYTES2BITS(FIPS_DSA_PRIME_LENGTH);
+	dsa_params.subprime = dsa_Q;
+	dsa_params.subprime_bits = CRYPTO_BYTES2BITS(FIPS_DSA_SUBPRIME_LENGTH);
+	dsa_params.base = dsa_G;
+	dsa_params.base_bytes = FIPS_DSA_BASE_LENGTH;
+
+	dsa_params.rfunc = fips_dsa_random_func;
+
+	rv = fips_dsa_genkey_pair(&dsa_params);
+	if (rv != CKR_OK)
+		return (CKR_DEVICE_ERROR);
+
+	/*
+	 * DSA Known Answer Signature Test
+	 */
+
+	dsa_params.rfunc = fips_dsa_signature_func;
+
+	/* Perform DSA signature process. */
+	rv = fips_dsa_digest_sign(&dsa_params,
+	    dsa_known_digest, FIPS_DSA_DIGEST_LENGTH, dsa_computed_signature);
+
+	if ((rv != CKR_OK) ||
+	    (memcmp(dsa_computed_signature, dsa_known_signature,
+	    FIPS_DSA_SIGNATURE_LENGTH) != 0)) {
+		goto clean;
+	}
+
+	/*
+	 * DSA Known Answer Verification Test
+	 */
+
+	/* Perform DSA verification process. */
+	rv = fips_dsa_verify(&dsa_params,
+	    dsa_known_digest, dsa_computed_signature);
+
+clean:
+	if (rv != CKR_OK)
+		return (CKR_DEVICE_ERROR);
+	else
+		return (CKR_OK);
+}
--- a/usr/src/common/crypto/fips/fips_post.h	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/common/crypto/fips/fips_post.h	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef	_FIPS_POST_H
@@ -37,6 +37,7 @@
 #define	CK_BYTE				uchar_t
 #define	CK_ULONG			ulong_t
 #define	CK_RV				int
+
 #define	CKR_OK				CRYPTO_SUCCESS
 #define	CKR_HOST_MEMORY			CRYPTO_HOST_MEMORY
 #define	CKR_DEVICE_ERROR		CRYPTO_DEVICE_ERROR
@@ -44,6 +45,7 @@
 #define	CKR_ENCRYPTED_DATA_LEN_RANGE	CRYPTO_ENCRYPTED_DATA_LEN_RANGE
 #define	CKR_ENCRYPTED_DATA_INVALID	CRYPTO_ENCRYPTED_DATA_INVALID
 #define	CKR_SIGNATURE_INVALID		CRYPTO_SIGNATURE_INVALID
+#define	CKR_SIGNATURE_LEN_RANGE		CRYPTO_SIGNATURE_LEN_RANGE
 #define	CKR_ARGUMENTS_BAD		CRYPTO_ARGUMENTS_BAD
 
 #else
--- a/usr/src/common/crypto/fips/fips_rsa_util.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/common/crypto/fips/fips_rsa_util.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,323 +18,48 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <sys/types.h>
-#include <sys/param.h>
-#include <sys/errno.h>
-#include <sys/kmem.h>
-#include <sys/systm.h>
-#include <sys/sysmacros.h>
 #include <sys/sha1.h>
 #define	_SHA2_IMPL
 #include <sys/sha2.h>
+
+#ifdef	_KERNEL
+
+#include <sys/param.h>
+#include <sys/kmem.h>
+
+#else
+
+#include <strings.h>
+#include <cryptoutil.h>
+#include "softMAC.h"
+
+#include <security/cryptoki.h>
 #include <sys/crypto/common.h>
+
+#endif
+
+#include <padding/padding.h>
+#include <sha2/sha2_impl.h>
 #define	_RSA_FIPS_POST
 #include <rsa/rsa_impl.h>
-#ifndef _KERNEL
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <stdio.h>
-#include <security/cryptoki.h>
-#include <cryptoutil.h>
-#include "softMAC.h"
-#endif
-#include <sha2/sha2_impl.h>
 
 int
-fips_rsa_encrypt(uint8_t *modulus, int modulus_len,
-	uint8_t *expo, int expo_len,
-	uint8_t *in, int in_len, uint8_t *out)
+fips_rsa_encrypt(RSAPrivateKey_t *key, uint8_t *in, int in_len, uint8_t *out)
 {
-
-	RSAkey *rsakey;
-	BIGNUM msg;
-	CK_RV rv = CKR_OK;
-
-#ifdef _KERNEL
-	if ((rsakey = kmem_zalloc(sizeof (RSAkey), KM_SLEEP)) == NULL) {
-#else
-	if ((rsakey = calloc(1, sizeof (RSAkey))) == NULL) {
-#endif
-		rv = CKR_HOST_MEMORY;
-		goto clean1;
-	}
-
-	if (RSA_key_init(rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean2;
-	}
-
-	/* Size for big_init is in (32-bit) words. */
-	if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean3;
-	}
-
-	/* Convert octet string exponent to big integer format. */
-	bytestring2bignum(&(rsakey->e), expo, expo_len);
-
-	/* Convert octet string modulus to big integer format. */
-	bytestring2bignum(&(rsakey->n), modulus, modulus_len);
-
-	/* Convert octet string input data to big integer format. */
-	bytestring2bignum(&msg, (uchar_t *)in, in_len);
-
-	if (big_cmp_abs(&msg, &(rsakey->n)) > 0) {
-		rv = CKR_DATA_LEN_RANGE;
-		goto clean4;
-	}
-
-	/* Perform RSA computation on big integer input data. */
-	if (big_modexp(&msg, &msg, &(rsakey->e), &(rsakey->n), NULL) !=
-	    BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean4;
-	}
-
-	/* Convert the big integer output data to octet string. */
-	bignum2bytestring((uchar_t *)out, &msg, modulus_len);
-
-clean4:
-	big_finish(&msg);
-clean3:
-	RSA_key_finish(rsakey);
-clean2:
-#ifndef _KERNEL
-	free(rsakey);
-#else
-	kmem_free(rsakey, sizeof (RSAkey));
-#endif
-clean1:
-
-	return (rv);
+	return (rsa_encrypt(&(key->bkey), in, in_len, out));
 }
 
 int
 fips_rsa_decrypt(RSAPrivateKey_t *key, uint8_t *in, int in_len,
 	uint8_t *out)
 {
-
-	RSAkey *rsakey;
-	BIGNUM msg;
-	CK_RV rv = CKR_OK;
-
-#ifdef _KERNEL
-	if ((rsakey = kmem_zalloc(sizeof (RSAkey), KM_SLEEP)) == NULL) {
-#else
-	if ((rsakey = calloc(1, sizeof (RSAkey))) == NULL) {
-#endif
-		rv = CKR_HOST_MEMORY;
-		goto clean1;
-	}
-
-	/* psize and qsize for RSA_key_init is in bits. */
-	if (RSA_key_init(rsakey, key->prime2_len * 8, key->prime1_len * 8)
-	    != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean2;
-	}
-
-	/* Size for big_init is in (32-bit) words. */
-	if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean3;
-	}
-
-	/* Convert octet string input data to big integer format. */
-	bytestring2bignum(&msg, (uchar_t *)in, in_len);
-
-	/* Convert octet string modulus to big integer format. */
-	bytestring2bignum(&(rsakey->n), key->modulus, key->modulus_len);
-
-	if (big_cmp_abs(&msg, &(rsakey->n)) > 0) {
-		rv = CKR_DATA_LEN_RANGE;
-		goto clean4;
-	}
-
-	/* Convert the rest of private key attributes to big integer format. */
-	bytestring2bignum(&(rsakey->dmodpminus1), key->exponent2,
-	    key->exponent2_len);
-	bytestring2bignum(&(rsakey->dmodqminus1), key->exponent1,
-	    key->exponent1_len);
-	bytestring2bignum(&(rsakey->p), key->prime2, key->prime2_len);
-	bytestring2bignum(&(rsakey->q), key->prime1, key->prime1_len);
-	bytestring2bignum(&(rsakey->pinvmodq), key->coef, key->coef_len);
-
-	if ((big_cmp_abs(&(rsakey->dmodpminus1), &(rsakey->p)) > 0) ||
-	    (big_cmp_abs(&(rsakey->dmodqminus1), &(rsakey->q)) > 0) ||
-	    (big_cmp_abs(&(rsakey->pinvmodq), &(rsakey->q)) > 0)) {
-#ifndef _KERNEL
-		rv = CKR_KEY_SIZE_RANGE;
-#else
-		rv = CRYPTO_KEY_SIZE_RANGE;
-#endif
-		goto clean4;
-	}
-
-	/* Perform RSA computation on big integer input data. */
-	if (big_modexp_crt(&msg, &msg, &(rsakey->dmodpminus1),
-	    &(rsakey->dmodqminus1), &(rsakey->p), &(rsakey->q),
-	    &(rsakey->pinvmodq), NULL, NULL) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean4;
-	}
-
-	/* Convert the big integer output data to octet string. */
-	bignum2bytestring((uchar_t *)out, &msg, key->modulus_len);
-
-clean4:
-	big_finish(&msg);
-clean3:
-	RSA_key_finish(rsakey);
-clean2:
-#ifndef _KERNEL
-	free(rsakey);
-#else
-	kmem_free(rsakey, sizeof (RSAkey));
-#endif
-clean1:
-
-	return (rv);
-
-}
-
-int
-fips_rsa_sign(RSAPrivateKey_t *rsa_params, uint8_t *in,
-	uint32_t inlen, uint8_t *out)
-{
-	BIGNUM msg;
-	RSAkey rsakey;
-	CK_RV rv = CKR_OK;
-
-	/* psize and qsize for RSA_key_init is in bits. */
-	if (RSA_key_init(&rsakey, rsa_params->prime2_len * 8,
-	    rsa_params->prime1_len * 8) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean1;
-	}
-
-	/* Size for big_init is in BIG_CHUNK_TYPE words. */
-	if (big_init(&msg, CHARLEN2BIGNUMLEN(inlen)) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean2;
-	}
-
-	/* Convert octet string input data to big integer format. */
-	bytestring2bignum(&msg, (uchar_t *)in, inlen);
-
-	/* Convert octet string modulus to big integer format. */
-	bytestring2bignum(&(rsakey.n), rsa_params->modulus,
-	    rsa_params->modulus_len);
-
-	if (big_cmp_abs(&msg, &(rsakey.n)) > 0) {
-		rv = CKR_DATA_LEN_RANGE;
-		goto clean3;
-	}
-
-	/* Convert the rest of private key attributes to big integer format. */
-	bytestring2bignum(&(rsakey.dmodpminus1), rsa_params->exponent2,
-	    rsa_params->exponent2_len);
-	bytestring2bignum(&(rsakey.dmodqminus1), rsa_params->exponent1,
-	    rsa_params->exponent1_len);
-	bytestring2bignum(&(rsakey.p), rsa_params->prime2,
-	    rsa_params->prime2_len);
-	bytestring2bignum(&(rsakey.q), rsa_params->prime1,
-	    rsa_params->prime1_len);
-	bytestring2bignum(&(rsakey.pinvmodq), rsa_params->coef,
-	    rsa_params->coef_len);
-
-	if ((big_cmp_abs(&(rsakey.dmodpminus1), &(rsakey.p)) > 0) ||
-	    (big_cmp_abs(&(rsakey.dmodqminus1), &(rsakey.q)) > 0) ||
-	    (big_cmp_abs(&(rsakey.pinvmodq), &(rsakey.q)) > 0)) {
-#ifndef _KERNEL
-		rv = CKR_KEY_SIZE_RANGE;
-#else
-		rv = CRYPTO_KEY_SIZE_RANGE;
-#endif
-		goto clean3;
-	}
-
-	/* Perform RSA computation on big integer input data. */
-	if (big_modexp_crt(&msg, &msg, &(rsakey.dmodpminus1),
-	    &(rsakey.dmodqminus1), &(rsakey.p), &(rsakey.q),
-	    &(rsakey.pinvmodq), NULL, NULL) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean3;
-	}
-
-	/* Convert the big integer output data to octet string. */
-	bignum2bytestring((uchar_t *)out, &msg, rsa_params->modulus_len);
-
-clean3:
-	big_finish(&msg);
-clean2:
-	RSA_key_finish(&rsakey);
-clean1:
-
-	return (rv);
-
-}
-
-int
-fips_rsa_verify(RSAPrivateKey_t *rsa_params, uint8_t *in, uint32_t in_len,
-    uint8_t *out)
-{
-
-	BIGNUM msg;
-	RSAkey rsakey;
-	CK_RV rv = CKR_OK;
-
-	if (RSA_key_init(&rsakey, rsa_params->modulus_len * 4,
-	    rsa_params->modulus_len * 4) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean1;
-	}
-
-	/* Size for big_init is in BIG_CHUNK_TYPE words. */
-	if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean2;
-	}
-
-	/* Convert octet string exponent to big integer format. */
-	bytestring2bignum(&(rsakey.e), rsa_params->public_expo,
-	    rsa_params->public_expo_len);
-
-	/* Convert octet string modulus to big integer format. */
-	bytestring2bignum(&(rsakey.n), rsa_params->modulus,
-	    rsa_params->modulus_len);
-
-	/* Convert octet string input data to big integer format. */
-	bytestring2bignum(&msg, (uchar_t *)in, in_len);
-
-	if (big_cmp_abs(&msg, &(rsakey.n)) > 0) {
-		rv = CKR_DATA_LEN_RANGE;
-		goto clean3;
-	}
-
-	/* Perform RSA computation on big integer input data. */
-	if (big_modexp(&msg, &msg, &(rsakey.e), &(rsakey.n), NULL) !=
-	    BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean3;
-	}
-
-	/* Convert the big integer output data to octet string. */
-	bignum2bytestring((uchar_t *)out, &msg, rsa_params->modulus_len);
-
-clean3:
-	big_finish(&msg);
-clean2:
-	RSA_key_finish(&rsakey);
-clean1:
-
-	return (rv);
+	return (rsa_decrypt(&(key->bkey), in, in_len, out));
 }
 
 static CK_RV
@@ -487,17 +212,18 @@
 	}
 	}
 
-	modulus_len = rsa_private_key->modulus_len;
+	modulus_len = CRYPTO_BITS2BYTES(rsa_private_key->bkey.modulus_bits);
 
 	if (sign) {
-		rv = soft_sign_rsa_pkcs_encode(der_data, der_data_len,
+		rv = pkcs1_encode(PKCS1_SIGN, der_data, der_data_len,
 		    plain_data, modulus_len);
 
 		if (rv != CKR_OK) {
 			return (CKR_DEVICE_ERROR);
 		}
 
-		rv = fips_rsa_sign(rsa_private_key, plain_data, modulus_len,
+		/* Sign operation uses decryption with private key */
+		rv = fips_rsa_decrypt(rsa_private_key, plain_data, modulus_len,
 			rsa_computed_signature);
 
 		if (rv != CKR_OK) {
@@ -508,7 +234,7 @@
 		 * Perform RSA decryption with the signer's RSA public key
 		 * for verification process.
 		 */
-		rv = fips_rsa_verify(rsa_private_key, rsa_computed_signature,
+		rv = fips_rsa_encrypt(rsa_private_key, rsa_computed_signature,
 		    modulus_len, plain_data);
 
 		if (rv == CKR_OK) {
@@ -518,19 +244,15 @@
 			 * recovered data, then compare the recovered data with
 			 * the original data.
 			 */
-			int data_len = modulus_len;
+			size_t data_len = modulus_len;
 
-			rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len);
+			rv = pkcs1_decode(PKCS1_VERIFY, plain_data, &data_len);
 			if (rv != CKR_OK) {
 				return (CKR_DEVICE_ERROR);
 			}
 
 			if ((CK_ULONG)data_len != der_data_len) {
-#ifdef _KERNEL
-				return (CRYPTO_SIGNATURE_LEN_RANGE);
-#else
 				return (CKR_SIGNATURE_LEN_RANGE);
-#endif
 			} else if (memcmp(der_data,
 			    &plain_data[modulus_len - data_len],
 			    data_len) != 0) {
@@ -776,16 +498,21 @@
 	CK_RV rv;
 	uint8_t rsa_computed_ciphertext[FIPS_RSA_ENCRYPT_LENGTH];
 	uint8_t rsa_computed_plaintext[FIPS_RSA_DECRYPT_LENGTH];
-	uint8_t  rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH];
+	uint8_t rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH];
 	CK_BYTE der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len];
 
 	/*
 	 * RSA Known Answer Encryption Test.
 	 */
+	rsa_private_key.bkey.modulus = rsa_modulus;
+	rsa_private_key.bkey.modulus_bits =
+	    CRYPTO_BYTES2BITS(FIPS_RSA_MODULUS_LENGTH);
+	rsa_private_key.bkey.pubexpo = rsa_public_exponent;
+	rsa_private_key.bkey.pubexpo_bytes = FIPS_RSA_PUBLIC_EXPONENT_LENGTH;
+	rsa_private_key.bkey.rfunc = NULL;
 
 	/* Perform RSA Public Key Encryption. */
-	rv = fips_rsa_encrypt(rsa_modulus, FIPS_RSA_MODULUS_LENGTH,
-	    rsa_public_exponent, FIPS_RSA_PUBLIC_EXPONENT_LENGTH,
+	rv = fips_rsa_encrypt(&rsa_private_key,
 	    rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH,
 	    rsa_computed_ciphertext);
 
@@ -799,22 +526,23 @@
 	 */
 	rsa_private_key.version = rsa_version;
 	rsa_private_key.version_len = FIPS_RSA_PRIVATE_VERSION_LENGTH;
-	rsa_private_key.modulus = rsa_modulus;
-	rsa_private_key.modulus_len = FIPS_RSA_MODULUS_LENGTH;
-	rsa_private_key.public_expo = rsa_public_exponent;
-	rsa_private_key.public_expo_len = FIPS_RSA_PUBLIC_EXPONENT_LENGTH;
-	rsa_private_key.private_expo = rsa_private_exponent;
-	rsa_private_key.private_expo_len = FIPS_RSA_PRIVATE_EXPONENT_LENGTH;
-	rsa_private_key.prime1 = rsa_prime0;
-	rsa_private_key.prime1_len = FIPS_RSA_PRIME0_LENGTH;
-	rsa_private_key.prime2 = rsa_prime1;
-	rsa_private_key.prime2_len = FIPS_RSA_PRIME1_LENGTH;
-	rsa_private_key.exponent1 = rsa_exponent0;
-	rsa_private_key.exponent1_len = FIPS_RSA_EXPONENT0_LENGTH;
-	rsa_private_key.exponent2 = rsa_exponent1;
-	rsa_private_key.exponent2_len = FIPS_RSA_EXPONENT1_LENGTH;
-	rsa_private_key.coef = rsa_coefficient;
-	rsa_private_key.coef_len = FIPS_RSA_COEFFICIENT_LENGTH;
+	rsa_private_key.bkey.modulus = rsa_modulus;
+	rsa_private_key.bkey.modulus_bits =
+	    CRYPTO_BYTES2BITS(FIPS_RSA_MODULUS_LENGTH);
+	rsa_private_key.bkey.pubexpo = rsa_public_exponent;
+	rsa_private_key.bkey.pubexpo_bytes = FIPS_RSA_PUBLIC_EXPONENT_LENGTH;
+	rsa_private_key.bkey.privexpo = rsa_private_exponent;
+	rsa_private_key.bkey.privexpo_bytes = FIPS_RSA_PRIVATE_EXPONENT_LENGTH;
+	rsa_private_key.bkey.prime1 = rsa_prime0;
+	rsa_private_key.bkey.prime1_bytes = FIPS_RSA_PRIME0_LENGTH;
+	rsa_private_key.bkey.prime2 = rsa_prime1;
+	rsa_private_key.bkey.prime2_bytes = FIPS_RSA_PRIME1_LENGTH;
+	rsa_private_key.bkey.expo1 = rsa_exponent0;
+	rsa_private_key.bkey.expo1_bytes = FIPS_RSA_EXPONENT0_LENGTH;
+	rsa_private_key.bkey.expo2 = rsa_exponent1;
+	rsa_private_key.bkey.expo2_bytes = FIPS_RSA_EXPONENT1_LENGTH;
+	rsa_private_key.bkey.coeff = rsa_coefficient;
+	rsa_private_key.bkey.coeff_bytes = FIPS_RSA_COEFFICIENT_LENGTH;
 
 	/* Perform RSA Private Key Decryption. */
 	rv = fips_rsa_decrypt(&rsa_private_key, rsa_known_ciphertext,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/padding/Makefile	Mon Jun 07 08:54:25 2010 -0700
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# common/crypto/padding/Makefile
+#
+# include global definitions
+include $(SRC)/Makefile.master
+
+.KEEP_STATE:
+
+FRC:
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/padding/padding.h	Mon Jun 07 08:54:25 2010 -0700
@@ -0,0 +1,80 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _PADDING_H
+#define	_PADDING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+
+#define	MIN_PKCS1_PADLEN	11
+
+/*
+ * Values for PKCS#1 method of encoding/decoding.
+ */
+#define	PKCS1_ENCRYPT		0x02
+#define	PKCS1_DECRYPT		0x02
+#define	PKCS1_SIGN		0x01
+#define	PKCS1_VERIFY		0x01
+
+#ifdef _KERNEL
+
+#include <sys/sunddi.h>
+#include <sys/crypto/common.h>
+
+#define	CK_BYTE			uchar_t
+#define	CK_ULONG		ulong_t
+
+#define	CKR_DATA_LEN_RANGE	CRYPTO_DATA_LEN_RANGE
+#define	CKR_DEVICE_ERROR	CRYPTO_DEVICE_ERROR
+#define	CKR_ENCRYPTED_DATA_INVALID	CRYPTO_ENCRYPTED_DATA_INVALID
+#define	CKR_SIGNATURE_INVALID	CRYPTO_SIGNATURE_INVALID
+
+int knzero_random_generator(uint8_t *ran_out, size_t ran_len);
+void kmemset(uint8_t *buf, char pattern, size_t len);
+
+#else
+
+#include <security/cryptoki.h>
+#include <security/pkcs11t.h>
+
+#endif	/* _KERNEL */
+
+int pkcs1_encode(int method, uint8_t *databuf, size_t datalen, uint8_t *padbuf,
+    size_t padbuflen);
+int pkcs1_decode(int method, uint8_t *padbuf, size_t *plen);
+
+int pkcs7_encode(uint8_t *databuf, size_t datalen, uint8_t *padbuf,
+    size_t padbuflen, uint8_t multiple);
+int pkcs7_decode(uint8_t *padbuf, size_t *plen);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _PADDING_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/padding/pkcs1.c	Mon Jun 07 08:54:25 2010 -0700
@@ -0,0 +1,146 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * This file contains padding helper routines common to
+ * the PKCS11 soft token code and the kernel crypto code.
+ */
+
+#include <sys/types.h>
+#include "padding.h"
+
+#ifdef _KERNEL
+#include <sys/param.h>
+#else
+#include <strings.h>
+#include <cryptoutil.h>
+#endif
+
+/*
+ * To create a block type "02" encryption block for RSA PKCS encryption
+ * process.
+ *
+ * This is EME-PKCS1-v1_5 encoding as described in RSA PKCS#1.
+ *
+ * The RSA PKCS Padding before encryption is in the following format:
+ * +----+----+--------------------+----+-----------------------------+
+ * |0x00|0x02| 8 bytes or more RN |0x00|       DATA                  |
+ * +----+----+--------------------+----+-----------------------------+
+ *
+ *
+ * To create a block type "01" block for RSA PKCS signature process.
+ *
+ * This EMSA-PKCS1-1_5 encoding as decribed in RSA PKCS#1.
+ *
+ * The RSA PKCS Padding before Signing is in the following format:
+ * +----+----+----------------------+----+-----------------------------+
+ * |0x00|0x01| 8 bytes of more 0xFF |0x00|          DATA               |
+ * +----+----+----------------------+----+-----------------------------+
+ *
+ */
+int
+pkcs1_encode(int method, uint8_t *databuf, size_t datalen, uint8_t *padbuf,
+    size_t padbuflen)
+{
+	size_t	padlen;
+	int	rv;
+
+	padlen = padbuflen - datalen;
+	if (padlen < MIN_PKCS1_PADLEN) {
+		return (CKR_DATA_LEN_RANGE);
+	}
+
+	rv = 0;
+
+	padbuf[0] = 0x00;
+	padbuf[1] = (method == PKCS1_ENCRYPT) ? 0x02 : 0x01;
+
+	if (method == PKCS1_ENCRYPT) {
+#ifdef _KERNEL
+		rv = knzero_random_generator(padbuf + 2, padlen - 3);
+#else
+		rv = (pkcs11_get_nzero_urandom(padbuf + 2, padlen - 3) < 0) ?
+		    CKR_DEVICE_ERROR : 0;
+#endif
+	} else if (method == PKCS1_SIGN) {
+#ifdef _KERNEL
+		kmemset(padbuf + 2, 0xFF, padlen - 3);
+#else
+		(void) memset(padbuf + 2, 0xFF, padlen - 3);
+#endif
+	}
+
+	if (rv != 0) {
+		return (rv);
+	}
+
+	padbuf[padlen - 1] = 0x00;
+
+	bcopy(databuf, padbuf + padlen, datalen);
+
+	return (0);
+}
+
+/*
+ * The RSA PKCS Padding in the following format:
+ * +----+----+-------------------------+----+------------------------+
+ * |0x00| BT | 8 bytes or more padding |0x00|       DATA             |
+ * +----+----+-+++++-------------------+----+------------------------+
+ * where BT is block type: 0x02 for encrypt/decrypt, 0x01 for sign/verify
+ *
+ * 'padbuf' points to the recovered message.  Strip off the padding and
+ * validate it as much as possible.  'plen' is changed to hold the actual
+ * data length.
+ */
+int
+pkcs1_decode(int method, uint8_t *padbuf, size_t *plen)
+{
+	int	rv = ((method == PKCS1_DECRYPT) ? CKR_ENCRYPTED_DATA_INVALID :
+	    CKR_SIGNATURE_INVALID);
+	int	i;
+
+	/* Check to see if the recovered data is padded is 0x0002 or 0x0001. */
+	if (padbuf[0] != 0x00 || padbuf[1] != (method == PKCS1_DECRYPT ?
+	    0x02 : 0x01)) {
+		return (rv);
+	}
+
+	/* Remove all the random bits up to 0x00 (= NULL char) */
+	for (i = 2; (*plen - i) > 0; i++) {
+		if (padbuf[i] == 0x00) {
+			i++;
+			if (i < MIN_PKCS1_PADLEN) {
+				return (rv);
+			}
+			*plen -= i;
+
+			return (0);
+		} else if (method == PKCS1_VERIFY && padbuf[i] != 0xFF) {
+			return (rv);
+		}
+	}
+
+	return (rv);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/common/crypto/padding/pkcs7.c	Mon Jun 07 08:54:25 2010 -0700
@@ -0,0 +1,121 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * This file contains padding helper routines common to
+ * the PKCS11 soft token code and the kernel crypto code.
+ */
+
+#include <sys/types.h>
+#include "padding.h"
+
+#ifdef _KERNEL
+#include <sys/param.h>
+#else
+#include <strings.h>
+#include <cryptoutil.h>
+#endif
+
+/*
+ * This is padding as decribed in Section 10.3 of RSA PKCS#7.
+ *
+ * The RSA PKCS Padding is in the following format:
+ * +-----------------------------+----+-------------+
+ * |       DATA                  |0x0k|0x0k|...|0x0k|
+ * +-----------------------------+----+----+---+----+
+ * where 0x0k is if data_len mod multiple = multiple - k
+ * and multiple < 256 and 1 <= k <= multiple
+ *
+ * If databuf is non NULL, padbuf must be large enough
+ * to contain both databuf and the padding.  databuf and
+ * padbuf may be the same buffer.
+ * databuf:
+ * +-----------------------------+
+ * |       DATA                  |
+ * +-----------------------------+
+ *                           datalen
+ * padbuf:
+ * +-----------------------------+----+-------------+
+ * |       DATA                  |0x0k|0x0k|...|0x0k|
+ * +-----------------------------+----+----+---+----+
+ *                           datalen          padbuflen
+ *
+ * If databuf is NULL, padbuf only needs to be large
+ * enough for the padding, and datalen must still be
+ * provided to compute the padding value:
+ *				 padbuf:
+ *                               +----+-------------+
+ *                               |0x0k|0x0k|...|0x0k|
+ *                               +----+----+---+----+
+ *                           datalen           padbuflen
+ */
+int
+pkcs7_encode(uint8_t *databuf, size_t datalen, uint8_t *padbuf,
+    size_t padbuflen, uint8_t multiple)
+{
+	size_t	padlen;
+
+	padlen = multiple - (datalen % multiple);
+	if (databuf == NULL)
+		datalen = 0;
+
+	if (padlen > padbuflen - datalen) {
+		return (CKR_DATA_LEN_RANGE);
+	}
+
+	bcopy(databuf, padbuf, datalen);
+	(void) memset(padbuf + datalen, padlen & 0xff, padlen);
+
+	return (0);
+}
+
+/*
+ * 'padbuf' points to the recovered message.  Strip off the padding and
+ * validate it as much as possible.  'plen' is changed to hold the actual
+ * data length.  'padbuf' is unchanged.
+ */
+int
+pkcs7_decode(uint8_t *padbuf, size_t *plen)
+{
+	int	i;
+	size_t	padlen;
+
+	/* Recover the padding value, even if padbuf has trailing nulls */
+	while (*plen > 0 && (padlen = padbuf[*plen - 1]) == 0)
+		(*plen)--;
+
+	/* Must have non-zero padding */
+	if (padlen == 0)
+		return (CKR_ENCRYPTED_DATA_INVALID);
+
+	/* Count back from all padding bytes; lint tag is for *plen-1-i >= 0 */
+	/* LINTED E_SUSPICIOUS_COMPARISON */
+	for (i = 0; i < padlen && (*plen - 1 - i) >= 0; i++) {
+		if (padbuf[*plen - 1 - i] != (padlen & 0xff))
+			return (CKR_ENCRYPTED_DATA_INVALID);
+	}
+	*plen -= i;
+	return (0);
+}
--- a/usr/src/common/crypto/rsa/rsa_impl.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/common/crypto/rsa/rsa_impl.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -29,16 +29,18 @@
  */
 
 #include <sys/types.h>
-#include "rsa_impl.h"
+#include <bignum.h>
 
 #ifdef _KERNEL
 #include <sys/param.h>
 #else
 #include <strings.h>
 #include <cryptoutil.h>
-#include "softRandom.h"
 #endif
 
+#include <sys/crypto/common.h>
+#include "rsa_impl.h"
+
 /*
  * DER encoding T of the DigestInfo values for MD5, SHA1, and SHA2
  * from PKCS#1 v2.1: RSA Cryptography Standard Section 9.2 Note 1
@@ -77,8 +79,32 @@
 
 const CK_BYTE DEFAULT_PUB_EXPO[DEFAULT_PUB_EXPO_Len] = { 0x01, 0x00, 0x01 };
 
+
+static CK_RV
+convert_rv(BIG_ERR_CODE err)
+{
+	switch (err) {
+
+	case BIG_OK:
+		return (CKR_OK);
+
+	case BIG_NO_MEM:
+		return (CKR_HOST_MEMORY);
+
+	case BIG_NO_RANDOM:
+		return (CKR_DEVICE_ERROR);
+
+	case BIG_INVALID_ARGS:
+		return (CKR_ARGUMENTS_BAD);
+
+	case BIG_DIV_BY_0:
+	default:
+		return (CKR_GENERAL_ERROR);
+	}
+}
+
 /* psize and qsize are in bits */
-BIG_ERR_CODE
+static BIG_ERR_CODE
 RSA_key_init(RSAkey *key, int psize, int qsize)
 {
 	BIG_ERR_CODE err = BIG_OK;
@@ -142,8 +168,7 @@
 	return (err);
 }
 
-
-void
+static void
 RSA_key_finish(RSAkey *key)
 {
 
@@ -165,162 +190,472 @@
 
 }
 
-
 /*
- * To create a block type "02" encryption block for RSA PKCS encryption
- * process.
- *
- * The RSA PKCS Padding before encryption is in the following format:
- * +------+--------------------+----+-----------------------------+
- * |0x0002| 8 bytes or more RN |0x00|       DATA                  |
- * +------+--------------------+----+-----------------------------+
- *
+ * Generate RSA key
  */
-CK_RV
-soft_encrypt_rsa_pkcs_encode(uint8_t *databuf,
-    size_t datalen, uint8_t *padbuf, size_t padbuflen)
+static CK_RV
+generate_rsa_key(RSAkey *key, int psize, int qsize, BIGNUM *pubexp,
+    int (*rfunc)(void *, size_t))
 {
+	CK_RV		rv = CKR_OK;
 
 /* EXPORT DELETE START */
 
-	size_t	padlen;
-	CK_RV	rv;
+	int		(*rf)(void *, size_t);
+	BIGNUM		a, b, c, d, e, f, g, h;
+	int		len, keylen, size;
+	BIG_ERR_CODE	brv = BIG_OK;
+
+	size = psize + qsize;
+	keylen = BITLEN2BIGNUMLEN(size);
+	len = keylen * 2 + 1;
+	key->size = size;
+
+	/*
+	 * Note: It is not really necessary to compute e, it is in pubexp:
+	 * 	(void) big_copy(&(key->e), pubexp);
+	 */
+
+	a.malloced = 0;
+	b.malloced = 0;
+	c.malloced = 0;
+	d.malloced = 0;
+	e.malloced = 0;
+	f.malloced = 0;
+	g.malloced = 0;
+	h.malloced = 0;
 
-	padlen = padbuflen - datalen;
-	if (padlen < MIN_PKCS1_PADLEN) {
-		return (CKR_DATA_LEN_RANGE);
+	if ((big_init(&a, len) != BIG_OK) ||
+	    (big_init(&b, len) != BIG_OK) ||
+	    (big_init(&c, len) != BIG_OK) ||
+	    (big_init(&d, len) != BIG_OK) ||
+	    (big_init(&e, len) != BIG_OK) ||
+	    (big_init(&f, len) != BIG_OK) ||
+	    (big_init(&g, len) != BIG_OK) ||
+	    (big_init(&h, len) != BIG_OK)) {
+		big_finish(&h);
+		big_finish(&g);
+		big_finish(&f);
+		big_finish(&e);
+		big_finish(&d);
+		big_finish(&c);
+		big_finish(&b);
+		big_finish(&a);
+
+		return (CKR_HOST_MEMORY);
+	}
+
+	rf = rfunc;
+	if (rf == NULL) {
+#ifdef _KERNEL
+		rf = (int (*)(void *, size_t))random_get_pseudo_bytes;
+#else
+		rf = pkcs11_get_urandom;
+#endif
+	}
+
+nextp:
+	if ((brv = big_random(&a, psize, rf)) != BIG_OK) {
+		goto ret;
+	}
+
+	if ((brv = big_nextprime_pos(&b, &a)) != BIG_OK) {
+		goto ret;
+	}
+	/* b now contains the potential prime p */
+
+	(void) big_sub_pos(&a, &b, &big_One);
+	if ((brv = big_ext_gcd_pos(&f, &d, &g, pubexp, &a)) != BIG_OK) {
+		goto ret;
+	}
+	if (big_cmp_abs(&f, &big_One) != 0) {
+		goto nextp;
+	}
+
+	if ((brv = big_random(&c, qsize, rf)) != BIG_OK) {
+		goto ret;
 	}
 
-	/* Pad with 0x0002+non-zero pseudorandom numbers+0x00. */
-	padbuf[0] = 0x00;
-	padbuf[1] = 0x02;
-#ifdef _KERNEL
-	rv = knzero_random_generator(padbuf + 2, padbuflen - 3);
-#else
-	rv = CKR_OK;
-	if (pkcs11_get_nzero_urandom(padbuf + 2, padbuflen - 3) < 0)
-		rv = CKR_DEVICE_ERROR;
-#endif
-	if (rv != CKR_OK) {
-		return (rv);
+nextq:
+	(void) big_add(&a, &c, &big_Two);
+
+	if (big_bitlength(&a) != qsize) {
+		goto nextp;
+	}
+	if (big_cmp_abs(&a, &b) == 0) {
+		goto nextp;
+	}
+	if ((brv = big_nextprime_pos(&c, &a)) != BIG_OK) {
+		goto ret;
+	}
+	/* c now contains the potential prime q */
+
+	if ((brv = big_mul(&g, &b, &c)) != BIG_OK) {
+		goto ret;
+	}
+	if (big_bitlength(&g) != size) {
+		goto nextp;
+	}
+	/* g now contains the potential modulus n */
+
+	(void) big_sub_pos(&a, &b, &big_One);
+	(void) big_sub_pos(&d, &c, &big_One);
+
+	if ((brv = big_mul(&a, &a, &d)) != BIG_OK) {
+		goto ret;
+	}
+	if ((brv = big_ext_gcd_pos(&f, &d, &h, pubexp, &a)) != BIG_OK) {
+		goto ret;
+	}
+	if (big_cmp_abs(&f, &big_One) != 0) {
+		goto nextq;
+	} else {
+		(void) big_copy(&e, pubexp);
+	}
+	if (d.sign == -1) {
+		if ((brv = big_add(&d, &d, &a)) != BIG_OK) {
+			goto ret;
+		}
+	}
+	(void) big_copy(&(key->p), &b);
+	(void) big_copy(&(key->q), &c);
+	(void) big_copy(&(key->n), &g);
+	(void) big_copy(&(key->d), &d);
+	(void) big_copy(&(key->e), &e);
+
+	if ((brv = big_ext_gcd_pos(&a, &f, &h, &b, &c)) != BIG_OK) {
+		goto ret;
 	}
-	padbuf[padlen - 1] = 0x00;
+	if (f.sign == -1) {
+		if ((brv = big_add(&f, &f, &c)) != BIG_OK) {
+			goto ret;
+		}
+	}
+	(void) big_copy(&(key->pinvmodq), &f);
+
+	(void) big_sub(&a, &b, &big_One);
+	if ((brv = big_div_pos(&a, &f, &d, &a)) != BIG_OK) {
+		goto ret;
+	}
+	(void) big_copy(&(key->dmodpminus1), &f);
+	(void) big_sub(&a, &c, &big_One);
+	if ((brv = big_div_pos(&a, &f, &d, &a)) != BIG_OK) {
+		goto ret;
+	}
+	(void) big_copy(&(key->dmodqminus1), &f);
 
-	bcopy(databuf, padbuf + padlen, datalen);
+	/* pairwise consistency check:  decrypt and encrypt restores value */
+	if ((brv = big_random(&h, size, rf)) != BIG_OK) {
+		goto ret;
+	}
+	if ((brv = big_div_pos(&a, &h, &h, &g)) != BIG_OK) {
+		goto ret;
+	}
+	if ((brv = big_modexp(&a, &h, &d, &g, NULL)) != BIG_OK) {
+		goto ret;
+	}
+
+	if ((brv = big_modexp(&b, &a, &e, &g, NULL)) != BIG_OK) {
+		goto ret;
+	}
+
+	if (big_cmp_abs(&b, &h) != 0) {
+		/* this should not happen */
+		rv = generate_rsa_key(key, psize, qsize, pubexp, rf);
+		goto ret1;
+	} else {
+		brv = BIG_OK;
+	}
+
+ret:
+	rv = convert_rv(brv);
+ret1:
+	big_finish(&h);
+	big_finish(&g);
+	big_finish(&f);
+	big_finish(&e);
+	big_finish(&d);
+	big_finish(&c);
+	big_finish(&b);
+	big_finish(&a);
 
 /* EXPORT DELETE END */
 
-	return (CKR_OK);
+	return (rv);
 }
 
-
-/*
- * The RSA PKCS Padding after decryption is in the following format:
- * +------+--------------------+----+-----------------------------+
- * |0x0002| 8 bytes or more RN |0x00|       DATA                  |
- * +------+--------------------+----+-----------------------------+
- *
- * 'padbuf' points to the recovered message which is the modulus
- * length. As a result, 'plen' is changed to hold the actual data length.
- */
 CK_RV
-soft_decrypt_rsa_pkcs_decode(uint8_t *padbuf, int *plen)
+rsa_genkey_pair(RSAbytekey *bkey)
 {
+	/*
+	 * NOTE:  Whomever originally wrote this function swapped p and q.
+	 * This table shows the mapping between name convention used here
+	 * versus what is used in most texts that describe RSA key generation.
+	 *	This function:			Standard convention:
+	 *	--------------			--------------------
+	 *	modulus, n			-same-
+	 *	prime 1, q			prime 1, p
+	 *	prime 2, p			prime 2, q
+	 *	private exponent, d		-same-
+	 *	public exponent, e		-same-
+	 *	exponent 1, d mod (q-1)		d mod (p-1)
+	 *	exponent 2, d mod (p-1)		d mod (q-1)
+	 *	coefficient, p^-1 mod q		q^-1 mod p
+	 *
+	 * Also notice the struct member for coefficient is named .pinvmodq
+	 * rather than .qinvmodp, reflecting the switch.
+	 *
+	 * The code here wasn't unswapped, because "it works".  Further,
+	 * p and q are interchangeable as long as exponent 1 and 2 and
+	 * the coefficient are kept straight too.  This note is here to
+	 * make the reader aware of the switcheroo.
+	 */
+	CK_RV	rv = CKR_OK;
 
 /* EXPORT DELETE START */
 
-	int	i;
+	BIGNUM	public_exponent = {0};
+	RSAkey	rsakey;
+	uint32_t modulus_bytes;
+
+	if (bkey == NULL)
+		return (CKR_ARGUMENTS_BAD);
+
+	/* Must have modulus bits set */
+	if (bkey->modulus_bits == 0)
+		return (CKR_ARGUMENTS_BAD);
+
+	/* Must have public exponent set */
+	if (bkey->pubexpo_bytes == 0 || bkey->pubexpo == NULL)
+		return (CKR_ARGUMENTS_BAD);
 
-	/* Check to see if the recovered data is padded is 0x0002. */
-	if (padbuf[0] != 0x00 || padbuf[1] != 0x02) {
-		return (CKR_ENCRYPTED_DATA_INVALID);
+	/* Note: modulus_bits may not be same as (8 * sizeof (modulus)) */
+	modulus_bytes = CRYPTO_BITS2BYTES(bkey->modulus_bits);
+
+	/* Modulus length needs to be between min key size and max key size. */
+	if ((modulus_bytes < MIN_RSA_KEYLENGTH_IN_BYTES) ||
+	    (modulus_bytes > MAX_RSA_KEYLENGTH_IN_BYTES)) {
+		return (CKR_KEY_SIZE_RANGE);
+	}
+
+	/*
+	 * Initialize the RSA key.
+	 */
+	if (RSA_key_init(&rsakey, modulus_bytes * 4, modulus_bytes * 4) !=
+	    BIG_OK) {
+		return (CKR_HOST_MEMORY);
 	}
 
-	/* Remove all the random bits up to 0x00 (= NULL char) */
-	for (i = 2; (*plen - i) > 0; i++) {
-		if (padbuf[i] == 0x00) {
-			i++;
-			if (i < MIN_PKCS1_PADLEN) {
-				return (CKR_ENCRYPTED_DATA_INVALID);
-			}
-			*plen -= i;
+	/* Create a public exponent in bignum format. */
+	if (big_init(&public_exponent,
+	    CHARLEN2BIGNUMLEN(bkey->pubexpo_bytes)) != BIG_OK) {
+		rv = CKR_HOST_MEMORY;
+		goto clean1;
+	}
+	bytestring2bignum(&public_exponent, bkey->pubexpo, bkey->pubexpo_bytes);
+
+	/* Generate RSA key pair. */
+	if ((rv = generate_rsa_key(&rsakey,
+	    modulus_bytes * 4, modulus_bytes * 4, &public_exponent,
+	    bkey->rfunc)) != CKR_OK) {
+		big_finish(&public_exponent);
+		goto clean1;
+	}
+	big_finish(&public_exponent);
+
+	/* modulus_bytes = rsakey.n.len * (int)sizeof (BIG_CHUNK_TYPE); */
+	bignum2bytestring(bkey->modulus, &(rsakey.n), modulus_bytes);
+
+	bkey->privexpo_bytes = rsakey.d.len * (int)sizeof (BIG_CHUNK_TYPE);
+	bignum2bytestring(bkey->privexpo, &(rsakey.d), bkey->privexpo_bytes);
 
-			return (CKR_OK);
-		}
-	}
+	bkey->pubexpo_bytes = rsakey.e.len * (int)sizeof (BIG_CHUNK_TYPE);
+	bignum2bytestring(bkey->pubexpo, &(rsakey.e), bkey->pubexpo_bytes);
+
+	bkey->prime1_bytes = rsakey.q.len * (int)sizeof (BIG_CHUNK_TYPE);
+	bignum2bytestring(bkey->prime1, &(rsakey.q), bkey->prime1_bytes);
+
+	bkey->prime2_bytes = rsakey.p.len * (int)sizeof (BIG_CHUNK_TYPE);
+	bignum2bytestring(bkey->prime2, &(rsakey.p), bkey->prime2_bytes);
+
+	bkey->expo1_bytes =
+	    rsakey.dmodqminus1.len * (int)sizeof (BIG_CHUNK_TYPE);
+	bignum2bytestring(bkey->expo1, &(rsakey.dmodqminus1),
+	    bkey->expo1_bytes);
+
+	bkey->expo2_bytes =
+	    rsakey.dmodpminus1.len * (int)sizeof (BIG_CHUNK_TYPE);
+	bignum2bytestring(bkey->expo2,
+	    &(rsakey.dmodpminus1), bkey->expo2_bytes);
+
+	bkey->coeff_bytes =
+	    rsakey.pinvmodq.len * (int)sizeof (BIG_CHUNK_TYPE);
+	bignum2bytestring(bkey->coeff, &(rsakey.pinvmodq), bkey->coeff_bytes);
+
+clean1:
+	RSA_key_finish(&rsakey);
 
 /* EXPORT DELETE END */
 
-	return (CKR_ENCRYPTED_DATA_INVALID);
+	return (rv);
 }
 
 /*
- * To create a block type "01" block for RSA PKCS signature process.
- *
- * The RSA PKCS Padding before Signing is in the following format:
- * +------+--------------+----+-----------------------------+
- * |0x0001| 0xFFFF.......|0x00|          DATA               |
- * +------+--------------+----+-----------------------------+
+ * RSA encrypt operation
  */
 CK_RV
-soft_sign_rsa_pkcs_encode(uint8_t *pData, size_t dataLen, uint8_t *data,
-    size_t mbit_l)
+rsa_encrypt(RSAbytekey *bkey, uchar_t *in, uint32_t in_len, uchar_t *out)
 {
+	CK_RV rv = CKR_OK;
 
 /* EXPORT DELETE START */
 
-	size_t	padlen;
+	BIGNUM msg;
+	RSAkey rsakey;
+	uint32_t modulus_bytes;
+
+	if (bkey == NULL)
+		return (CKR_ARGUMENTS_BAD);
+
+	/* Must have modulus and public exponent set */
+	if (bkey->modulus_bits == 0 || bkey->modulus == NULL ||
+	    bkey->pubexpo_bytes == 0 || bkey->pubexpo == NULL)
+		return (CKR_ARGUMENTS_BAD);
 
-	padlen = mbit_l - dataLen;
-	if (padlen < MIN_PKCS1_PADLEN) {
-		return (CKR_DATA_LEN_RANGE);
+	/* Note: modulus_bits may not be same as (8 * sizeof (modulus)) */
+	modulus_bytes = CRYPTO_BITS2BYTES(bkey->modulus_bits);
+
+	if (bkey->pubexpo_bytes > modulus_bytes) {
+		return (CKR_KEY_SIZE_RANGE);
+	}
+
+	/* psize and qsize for RSA_key_init is in bits. */
+	if (RSA_key_init(&rsakey, modulus_bytes * 4, modulus_bytes * 4) !=
+	    BIG_OK) {
+		return (CKR_HOST_MEMORY);
 	}
 
-	padlen -= 3;
-	data[0] = 0x00;
-	data[1] = 0x01;
-#ifdef _KERNEL
-	kmemset(data + 2, 0xFF, padlen);
-#else
-	(void) memset(data + 2, 0xFF, padlen);
-#endif
-	data[padlen + 2] = 0x00;
-	bcopy(pData, data + padlen + 3, dataLen);
+	/* Size for big_init is in BIG_CHUNK_TYPE words. */
+	if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
+		rv = CKR_HOST_MEMORY;
+		goto clean2;
+	}
+	bytestring2bignum(&msg, in, in_len);
+
+	/* Convert public exponent and modulus to big integer format. */
+	bytestring2bignum(&(rsakey.e), bkey->pubexpo, bkey->pubexpo_bytes);
+	bytestring2bignum(&(rsakey.n), bkey->modulus, modulus_bytes);
+
+	if (big_cmp_abs(&msg, &(rsakey.n)) > 0) {
+		rv = CKR_DATA_LEN_RANGE;
+		goto clean3;
+	}
+
+	/* Perform RSA computation on big integer input data. */
+	if (big_modexp(&msg, &msg, &(rsakey.e), &(rsakey.n), NULL) !=
+	    BIG_OK) {
+		rv = CKR_HOST_MEMORY;
+		goto clean3;
+	}
+
+	/* Convert the big integer output data to octet string. */
+	bignum2bytestring(out, &msg, modulus_bytes);
+
+clean3:
+	big_finish(&msg);
+clean2:
+	RSA_key_finish(&rsakey);
 
 /* EXPORT DELETE END */
 
-	return (CKR_OK);
+	return (rv);
 }
 
-
+/*
+ * RSA decrypt operation
+ */
 CK_RV
-soft_verify_rsa_pkcs_decode(uint8_t *data, int *mbit_l)
+rsa_decrypt(RSAbytekey *bkey, uchar_t *in, uint32_t in_len, uchar_t *out)
 {
+	CK_RV rv = CKR_OK;
 
 /* EXPORT DELETE START */
 
-	int i;
+	BIGNUM msg;
+	RSAkey rsakey;
+	uint32_t modulus_bytes;
+
+	if (bkey == NULL)
+		return (CKR_ARGUMENTS_BAD);
 
-	/* Check to see if the padding of recovered data starts with 0x0001. */
-	if ((data[0] != 0x00) || (data[1] != 0x01)) {
-		return (CKR_SIGNATURE_INVALID);
+	/* Must have modulus, prime1, prime2, expo1, expo2, and coeff set */
+	if (bkey->modulus_bits == 0 || bkey->modulus == NULL ||
+	    bkey->prime1_bytes == 0 || bkey->prime1 == NULL ||
+	    bkey->prime2_bytes == 0 || bkey->prime2 == NULL ||
+	    bkey->expo1_bytes == 0 || bkey->expo1 == NULL ||
+	    bkey->expo2_bytes == 0 || bkey->expo2 == NULL ||
+	    bkey->coeff_bytes == 0 || bkey->coeff == NULL)
+		return (CKR_ARGUMENTS_BAD);
+
+	/* Note: modulus_bits may not be same as (8 * sizeof (modulus)) */
+	modulus_bytes = CRYPTO_BITS2BYTES(bkey->modulus_bits);
+
+	/* psize and qsize for RSA_key_init is in bits. */
+	if (RSA_key_init(&rsakey, CRYPTO_BYTES2BITS(bkey->prime2_bytes),
+	    CRYPTO_BYTES2BITS(bkey->prime1_bytes)) != BIG_OK) {
+		return (CKR_HOST_MEMORY);
+	}
+
+	/* Size for big_init is in BIG_CHUNK_TYPE words. */
+	if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
+		rv = CKR_HOST_MEMORY;
+		goto clean3;
 	}
-	/* Check to see if the recovered data is padded with 0xFFF...00. */
-	for (i = 2; i < *mbit_l; i++) {
-		if (data[i] == 0x00) {
-			i++;
-			if (i < MIN_PKCS1_PADLEN) {
-				return (CKR_SIGNATURE_INVALID);
-			}
-			*mbit_l -= i;
+	/* Convert octet string input data to big integer format. */
+	bytestring2bignum(&msg, in, in_len);
+
+	/* Convert octet string modulus to big integer format. */
+	bytestring2bignum(&(rsakey.n), bkey->modulus, modulus_bytes);
+
+	if (big_cmp_abs(&msg, &(rsakey.n)) > 0) {
+		rv = CKR_DATA_LEN_RANGE;
+		goto clean4;
+	}
+
+	/* Convert the rest of private key attributes to big integer format. */
+	bytestring2bignum(&(rsakey.q), bkey->prime1, bkey->prime1_bytes);
+	bytestring2bignum(&(rsakey.p), bkey->prime2, bkey->prime2_bytes);
+	bytestring2bignum(&(rsakey.dmodqminus1),
+	    bkey->expo1, bkey->expo1_bytes);
+	bytestring2bignum(&(rsakey.dmodpminus1),
+	    bkey->expo2, bkey->expo2_bytes);
+	bytestring2bignum(&(rsakey.pinvmodq),
+	    bkey->coeff, bkey->coeff_bytes);
 
-			return (CKR_OK);
-		} else if (data[i] != 0xFF) {
-			return (CKR_SIGNATURE_INVALID);
-		}
+	if ((big_cmp_abs(&(rsakey.dmodpminus1), &(rsakey.p)) > 0) ||
+	    (big_cmp_abs(&(rsakey.dmodqminus1), &(rsakey.q)) > 0) ||
+	    (big_cmp_abs(&(rsakey.pinvmodq), &(rsakey.q)) > 0)) {
+		rv = CKR_KEY_SIZE_RANGE;
+		goto clean4;
 	}
 
+	/* Perform RSA computation on big integer input data. */
+	if (big_modexp_crt(&msg, &msg, &(rsakey.dmodpminus1),
+	    &(rsakey.dmodqminus1), &(rsakey.p), &(rsakey.q),
+	    &(rsakey.pinvmodq), NULL, NULL) != BIG_OK) {
+		rv = CKR_HOST_MEMORY;
+		goto clean4;
+	}
+
+	/* Convert the big integer output data to octet string. */
+	bignum2bytestring(out, &msg, modulus_bytes);
+
+clean4:
+	big_finish(&msg);
+clean3:
+	RSA_key_finish(&rsakey);
+
 /* EXPORT DELETE END */
 
-	return (CKR_SIGNATURE_INVALID);
+	return (rv);
 }
--- a/usr/src/common/crypto/rsa/rsa_impl.h	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/common/crypto/rsa/rsa_impl.h	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef _RSA_IMPL_H
@@ -38,8 +38,6 @@
 #define	RSA_MIN_KEY_LEN	256	/* RSA min key length in bits */
 #define	RSA_MAX_KEY_LEN	4096	/* RSA max key length in bits */
 
-#define	MIN_PKCS1_PADLEN	11
-
 #ifdef _KERNEL
 
 #include <sys/sunddi.h>
@@ -48,12 +46,17 @@
 #define	CK_BYTE			uchar_t
 #define	CK_ULONG		ulong_t
 #define	CK_RV			int
+
 #define	CKR_OK			CRYPTO_SUCCESS
-#define	CKR_HOST_MEMORY		CRYPTO_HOST_MEMORY
+#define	CKR_ARGUMENTS_BAD	CRYPTO_ARGUMENTS_BAD
 #define	CKR_DATA_LEN_RANGE	CRYPTO_DATA_LEN_RANGE
-#define	CKR_ENCRYPTED_DATA_INVALID	CRYPTO_ENCRYPTED_DATA_INVALID
-#define	CKR_SIGNATURE_INVALID	CRYPTO_SIGNATURE_INVALID
-#define	CKR_FUNCTION_FAILED	CRYPTO_NOT_SUPPORTED
+#define	CKR_DEVICE_ERROR	CRYPTO_DEVICE_ERROR
+#define	CKR_GENERAL_ERROR	CRYPTO_GENERAL_ERROR
+#define	CKR_HOST_MEMORY		CRYPTO_HOST_MEMORY
+#define	CKR_KEY_SIZE_RANGE	CRYPTO_KEY_SIZE_RANGE
+
+int random_get_bytes(uint8_t *ran_out, size_t ran_len);
+int random_get_pseudo_bytes(uint8_t *ran_out, size_t ran_len);
 
 #else
 
@@ -76,6 +79,8 @@
 extern const CK_BYTE SHA512_DER_PREFIX[SHA2_DER_PREFIX_Len];
 extern const CK_BYTE DEFAULT_PUB_EXPO[DEFAULT_PUB_EXPO_Len];
 
+
+/* RSA key using BIGNUM representations */
 typedef struct {
 	int 	size;		/* key size in bits */
 	BIGNUM	p;		/* p */
@@ -83,29 +88,46 @@
 	BIGNUM	n;		/* n = p * q (the modulus) */
 	BIGNUM	d;		/* private exponent */
 	BIGNUM	e;		/* public exponent */
-	BIGNUM	dmodpminus1;	/* d mod (p - 1) */
-	BIGNUM	dmodqminus1;	/* d mod (q - 1) */
-	BIGNUM	pinvmodq;	/* p^(-1) mod q */
+	BIGNUM	dmodpminus1;	/* d mod (p - 1) (exponent 1) */
+	BIGNUM	dmodqminus1;	/* d mod (q - 1) (exponent 2) */
+	BIGNUM	pinvmodq;	/* p^(-1) mod q (the coefficient) */
 	BIGNUM	p_rr;		/* 2^(2*(32*p->len)) mod p */
 	BIGNUM	q_rr;		/* 2^(2*(32*q->len)) mod q */
 	BIGNUM	n_rr;		/* 2^(2*(32*n->len)) mod n */
 } RSAkey;
 
-BIG_ERR_CODE RSA_key_init(RSAkey *key, int psize, int qsize);
-void RSA_key_finish(RSAkey *key);
-
-CK_RV soft_encrypt_rsa_pkcs_encode(uint8_t *databuf,
-    size_t datalen, uint8_t *padbuf, size_t padbuflen);
-CK_RV soft_decrypt_rsa_pkcs_decode(uint8_t *padbuf, int *plen);
+/* RSA key using byte string representations, useful for parameter lists */
+typedef struct {
+	uint32_t modulus_bits;	/* size */
+	uchar_t	*modulus;	/* n */
+	uint32_t privexpo_bytes;
+	uchar_t	*privexpo;	/* d */
+	uint32_t pubexpo_bytes;
+	uchar_t	*pubexpo;	/* e */
+	uint32_t prime1_bytes;
+	uchar_t	*prime1;	/* p */
+	uint32_t prime2_bytes;
+	uchar_t	*prime2;	/* q */
+	uint32_t expo1_bytes;
+	uchar_t	*expo1;		/* = d mod (p - 1) */
+	uint32_t expo2_bytes;
+	uchar_t	*expo2;		/* = d mod (q - 1) */
+	uint32_t coeff_bytes;	/* = q bytes, .... or = p bytes */
+	uchar_t *coeff;		/* = p^(-1) mod q, or = q^(-1) mod p */
+	int (*rfunc)(void *, size_t);	/* random function */
+} RSAbytekey;
 
-CK_RV soft_sign_rsa_pkcs_encode(uint8_t *pData, size_t dataLen,
-    uint8_t *data, size_t mbit_l);
-CK_RV soft_verify_rsa_pkcs_decode(uint8_t *data, int *mbit_l);
+
+CK_RV rsa_genkey_pair(RSAbytekey *bkey);
+
+CK_RV rsa_encrypt(RSAbytekey *bkey,
+    uchar_t *msg, uint32_t msglen, uchar_t *encrmsg);
 
-#ifdef _KERNEL
-int knzero_random_generator(uint8_t *ran_out, size_t ran_len);
-void kmemset(uint8_t *buf, char pattern, size_t len);
-#endif
+CK_RV rsa_decrypt(RSAbytekey *bkey,
+    uchar_t *encrmsg, uint32_t encrmsglen, uchar_t *msg);
+
+#define	rsa_sign(key, msg, len, sig)	rsa_decrypt((key), (msg), (len), (sig))
+#define	rsa_verify(key, msg, len, sig)	rsa_encrypt((key), (msg), (len), (sig))
 
 /*
  * The following definitions and declarations are only used by RSA FIPS POST
@@ -131,34 +153,13 @@
 typedef struct RSAPrivateKey_s {
 	uint8_t		*version;
 	int		version_len;
-	uint8_t		*modulus;
-	int		modulus_len;
-	uint8_t		*public_expo;
-	int		public_expo_len;
-	uint8_t		*private_expo;
-	int		private_expo_len;
-	uint8_t		*prime1;
-	int		prime1_len;
-	uint8_t		*prime2;
-	int		prime2_len;
-	uint8_t		*exponent1;
-	int		exponent1_len;
-	uint8_t		*exponent2;
-	int		exponent2_len;
-	uint8_t		*coef;
-	int		coef_len;
+	RSAbytekey	bkey;
 } RSAPrivateKey_t;
 
 /* RSA FIPS functions */
 extern int fips_rsa_post(void);
-extern int fips_rsa_encrypt(uint8_t *, int, uint8_t *,
-	int, uint8_t *, int, uint8_t *);
-extern int fips_rsa_decrypt(RSAPrivateKey_t *, uint8_t *,
-	int, uint8_t *);
-extern int fips_rsa_sign(RSAPrivateKey_t *, uint8_t *,
-	uint32_t, uint8_t *);
-extern int fips_rsa_verify(RSAPrivateKey_t *, uint8_t *, uint32_t,
-	uint8_t *);
+extern int fips_rsa_encrypt(RSAPrivateKey_t *, uint8_t *, int, uint8_t *);
+extern int fips_rsa_decrypt(RSAPrivateKey_t *, uint8_t *, int, uint8_t *);
 
 #endif /* _RSA_FIPS_POST */
 
--- a/usr/src/lib/pkcs11/libsoftcrypto/Makefile.com	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/Makefile.com	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,11 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
 #
 # lib/pkcs11/libsoftcrypto/Makefile.com
 #
@@ -49,7 +51,7 @@
 DES_COMMON_SRC= $(DES_COMMON_OBJS:%.o=$(DES_DIR)/%.c)
 DES_FLAGS= -I$(DES_DIR)
 
-# BIGNUM
+# BIGNUM -- needed by DH, DSA, RSA
 BIGNUM_DIR= $(SRC)/common/bignum
 BIGNUM_COMMON_OBJS= bignumimpl.o
 BIGNUM_COMMON_SRC= $(BIGNUM_COMMON_OBJS:%.o=$(BIGNUM_DIR)/%.c)
@@ -59,7 +61,31 @@
 MODES_DIR= $(SRC)/common/crypto/modes
 MODES_COMMON_OBJS= modes.o ecb.o cbc.o ctr.o
 MODES_COMMON_SRC= $(MODES_COMMON_OBJS:%.o=$(MODES_DIR)/%.c)
+MODES_FLAGS= -I$(MODES_DIR)
 
+# DH
+DH_DIR= $(SRC)/common/crypto/dh
+DH_COMMON_OBJS= dh_impl.o
+DH_COMMON_SRC= $(DH_COMMON_OBJS:%.o=$(DH_DIR)/%.c)
+DH_FLAGS= $(BIGNUM_FLAGS) -I$(DH_DIR)
+
+# DSA
+DSA_DIR= $(SRC)/common/crypto/dsa
+DSA_COMMON_OBJS= dsa_impl.o
+DSA_COMMON_SRC= $(DSA_COMMON_OBJS:%.o=$(DSA_DIR)/%.c)
+DSA_FLAGS= $(BIGNUM_FLAGS) -I$(DSA_DIR)
+
+# RSA
+RSA_DIR= $(SRC)/common/crypto/rsa
+RSA_COMMON_OBJS= rsa_impl.o
+RSA_COMMON_SRC= $(RSA_COMMON_OBJS:%.o=$(RSA_DIR)/%.c)
+RSA_FLAGS= $(BIGNUM_FLAGS) -I$(RSA_DIR)
+
+# PADDING -- needed by RSA
+PAD_DIR= $(SRC)/common/crypto/padding
+PAD_COMMON_OBJS= pkcs1.o pkcs7.o
+PAD_COMMON_SRC= $(PAD_COMMON_OBJS:%.o=$(PAD_DIR)/%.c)
+PAD_FLAGS= -I$(PAD_DIR)
 
 # Object setup
 AES_OBJS= $(AES_COMMON_OBJS) $(AES_PSM_OBJS)
@@ -67,10 +93,15 @@
 BLOWFISH_OBJS= $(BLOWFISH_COMMON_OBJS) $(BLOWFISH_PSM_OBJS)
 DES_OBJS= $(DES_COMMON_OBJS) $(DES_PSM_OBJS)
 BIGNUM_OBJS= $(BIGNUM_COMMON_OBJS) $(BIGNUM_PSM_OBJS)
-MODES_OBJS= $(MODES_COMMON_OBJS)
+MODES_OBJS= $(MODES_COMMON_OBJS) $(MODES_PSM_OBJS)
+DH_OBJS= $(DH_COMMON_OBJS) $(DH_PSM_OBJS)
+DSA_OBJS= $(DSA_COMMON_OBJS) $(DSA_PSM_OBJS)
+RSA_OBJS= $(RSA_COMMON_OBJS) $(RSA_PSM_OBJS)
+PAD_OBJS= $(PAD_COMMON_OBJS) $(PAD_PSM_OBJS)
 
 OBJECTS= $(AES_OBJS) $(ARCFOUR_OBJS) $(BIGNUM_OBJS) $(BLOWFISH_OBJS) \
-	$(DES_OBJS) $(MODES_OBJS)
+	$(DES_OBJS) $(MODES_OBJS) $(DH_OBJS) $(DSA_OBJS) \
+	$(RSA_OBJS) $(PAD_OBJS)
 
 include $(SRC)/lib/Makefile.lib
 
@@ -80,10 +111,20 @@
 BLOWFISH_SRC= $(BLOWFISH_COMMON_SRC) $(BLOWFISH_PSM_SRC)
 DES_SRC= $(DES_COMMON_SRC) $(DES_PSM_SRC)
 BIGNUM_SRC= $(BIGNUM_COMMON_SRC) $(BIGNUM_PSM_SRC)
-MODES_SRC= $(MODES_COMMON_SRC)
+MODES_SRC= $(MODES_COMMON_SRC) $(MODES_PSM_SRC)
+DH_SRC= $(DH_COMMON_SRC) $(DH_PSM_SRC)
+DSA_SRC= $(DSA_COMMON_SRC) $(DSA_PSM_SRC)
+RSA_SRC= $(RSA_COMMON_SRC) $(RSA_PSM_SRC)
+PAD_SRC= $(PAD_COMMON_SRC) $(PAD_PSM_SRC)
 
 SRCS=	$(AES_SRC) $(ARCFOUR_SRC) $(BIGNUM_SRC) $(BLOWFISH_SRC) $(DES_SRC) \
-	$(MODES_SRC)
+	$(MODES_SRC) $(DH_SRC) $(DSA_SRC) $(RSA_SRC) \
+	$(PAD_SRC)
+
+# Do not lint ECC and MPI
+LINTABLE= \
+	$(AES_SRC) $(ARCFOUR_SRC) $(BIGNUM_SRC) $(BLOWFISH_SRC) $(DES_SRC) \
+	$(MODES_SRC) $(DH_SRC) $(DSA_SRC) $(RSA_SRC) $(PAD_SRC)
 
 #
 # Compiler settings
@@ -91,22 +132,36 @@
 
 SRCDIR=	$(SRC)/lib/pkcs11/libsoftcrypto/common/
 CRYPTODIR= $(SRC)/common/crypto/
-MODESDIR= $(SRC)/uts/common/
+UTSDIR= $(SRC)/uts/common/
 ROOTLIBDIR= $(ROOT)/usr/lib
 ROOTLIBDIR64= $(ROOT)/usr/lib/$(MACH64)
 ROOTHWCAPDIR= $(ROOTLIBDIR)/libsoftcrypto
 
+# $(LINTLIB) is not included here;  i386_hwcap1/Makefile does not make
+# a lint library, so each of the other platform-specific Makefiles adds
+# the lint library target individually
 LIBS = $(DYNLIB)
+LDLIBS += -lc
 
 CFLAGS += $(CCVERBOSE) $(C_BIGPICFLAGS)
-CPPFLAGS += -I$(SRCDIR) -I$(CRYPTODIR) -I$(MODESDIR) -D_POSIX_PTHREAD_SEMANTICS
+CPPFLAGS += -I$(SRCDIR) -I$(CRYPTODIR) -I$(UTSDIR) \
+	$(BIGNUM_FLAGS) \
+	-D_POSIX_PTHREAD_SEMANTICS
 ASFLAGS = $(AS_PICFLAGS) -P -D__STDC__ -D_ASM
-LINTFLAGS64 += -errchk=longptr64
+EXTRA_LINT_FLAGS = \
+	$(AES_FLAGS) $(BLOWFISH_FLAGS) $(ARCFOUR_FLAGS) $(DES_FLAGS) \
+	$(BIGNUM_FLAGS) $(MODES_FLAGS) $(DH_FLAGS) $(DSA_FLAGS) \
+	$(RSA_FLAGS) $(PAD_FLAGS)
+LINTFLAGS += $(EXTRA_LINT_FLAGS)
+LINTFLAGS64 += $(EXTRA_LINT_FLAGS) -errchk=longptr64
+
+LINTLIB=	llib-l$(LIBNAME).ln
+$(LINTLIB)	:= 	SRCS = $(LINTABLE)
+lintcheck	:=	SRCS = $(LINTABLE)
 
 all:	$(LIBS)
 
-lint:	$(SRCS)
-	$(LINT.c) $(LINTCHECKFLAGS) $(SRCS) $(LDLIBS)
+lint:	lintcheck
 
 pics/%.o:	$(AES_DIR)/%.c
 	$(COMPILE.c) $(AES_FLAGS) -o $@ $<
@@ -129,9 +184,24 @@
 	$(POST_PROCESS_O)
 
 pics/%.o:	$(MODES_DIR)/%.c
-	$(COMPILE.c) -o $@ $<
+	$(COMPILE.c) $(MODES_FLAGS) -o $@ $<
+	$(POST_PROCESS_O)
+
+pics/%.o:	$(DH_DIR)/%.c
+	$(COMPILE.c) $(DH_FLAGS) -o $@ $<
 	$(POST_PROCESS_O)
 
+pics/%.o:	$(DSA_DIR)/%.c
+	$(COMPILE.c) $(DSA_FLAGS) -o $@ $<
+	$(POST_PROCESS_O)
+
+pics/%.o:	$(RSA_DIR)/%.c
+	$(COMPILE.c) $(RSA_FLAGS) -o $@ $<
+	$(POST_PROCESS_O)
+
+pics/%.o:	$(PAD_DIR)/%.c
+	$(COMPILE.c) $(PAD_FLAGS) -o $@ $<
+	$(POST_PROCESS_O)
 
 #
 # Platform-specific targets
--- a/usr/src/lib/pkcs11/libsoftcrypto/amd64/Makefile	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/amd64/Makefile	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,11 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
 #
 # lib/pkcs11/libsoftcrypto/amd64/Makefile
 #
@@ -47,7 +49,7 @@
 LINTFLAGS64	+= $(BIGNUM_FLAGS) $(AES_FLAGS) $(ARCFOUR_FLAGS)
 CLEANFILES	+= arcfour-x86_64.s
 
-LDLIBS  += -lc
+LDLIBS += -lcryptoutil
 LIBS += $(LINTLIB)
 
 install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
--- a/usr/src/lib/pkcs11/libsoftcrypto/common/llib-lsoftcrypto	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/common/llib-lsoftcrypto	Mon Jun 07 08:54:25 2010 -0700
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 
@@ -36,4 +35,8 @@
 #include <blowfish_impl.h>
 #include <des_cbc_crypt.h>
 #include <des_impl.h>
+#include <dh_impl.h>
+#include <dsa_impl.h>
 #include <modes.h>
+#include <padding.h>
+#include <rsa_impl.h>
--- a/usr/src/lib/pkcs11/libsoftcrypto/common/mapfile-vers	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/common/mapfile-vers	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 #
@@ -65,6 +65,7 @@
 	big_modexp_crt;
 	big_mul;
 	big_nextprime_pos;
+	big_random;
 	big_sub;
 	big_sub_pos;
 	bignum2bytestring;
@@ -82,6 +83,25 @@
 	des_encrypt_contiguous_blocks;
 	des_init_keysched;
 	des_keycheck;
+	dh_genkey_pair;
+	dh_key_derive;
+	dsa_genkey_pair;
+	dsa_sign;
+	dsa_verify;
+	pkcs1_decode;
+	pkcs1_encode;
+	pkcs7_decode;
+	pkcs7_encode;
+	rsa_decrypt;
+	rsa_encrypt;
+	rsa_genkey_pair;
+	DEFAULT_PUB_EXPO;
+	MD5_DER_PREFIX;
+	SHA1_DER_PREFIX;
+	SHA1_DER_PREFIX_OID;
+	SHA256_DER_PREFIX;
+	SHA384_DER_PREFIX;
+	SHA512_DER_PREFIX;
     local:
 	*;
 };
--- a/usr/src/lib/pkcs11/libsoftcrypto/i386/Makefile	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/i386/Makefile	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,11 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
 #
 # lib/pkcs11/libsoftcrypto/i386/Makefile
 #
@@ -30,8 +32,9 @@
 
 include ../Makefile.com
 
-LDLIBS  += -lc
+LDLIBS += -lcryptoutil
 LIBS += $(LINTLIB)
+
 DYNFLAGS += -Wl,-f/usr/lib/libsoftcrypto/\$$HWCAP
 
 install:  all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
--- a/usr/src/lib/pkcs11/libsoftcrypto/i386_hwcap1/Makefile	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/i386_hwcap1/Makefile	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,11 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
 #
 # lib/pkcs11/libsoftcrypto/i386_hwcap1/Makefile
 #
@@ -37,7 +39,8 @@
 
 BIGNUM_FLAGS += -DMMX_MANAGE -DHWCAP -DPSR_MUL
 LINTFLAGS += $(BIGNUM_FLAGS)
-LDLIBS  += -lc
+
+LDLIBS += -lcryptoutil
 
 $(ROOTHWCAPDIR)/% := FILEMODE= 755
 
--- a/usr/src/lib/pkcs11/libsoftcrypto/sparc/Makefile	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sparc/Makefile	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,11 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
 #
 # lib/pkcs11/libsoftcrypto/sparc/Makefile
 #
@@ -30,7 +32,7 @@
 
 include ../Makefile.com
 
-LDLIBS  += -lc
+LDLIBS	+= -lcryptoutil
 LIBS += $(LINTLIB)
 
 DYNFLAGS +=     -Wl,-f/usr/platform/\$$PLATFORM/lib/$(DYNLIBPSR)
--- a/usr/src/lib/pkcs11/libsoftcrypto/sparcv9/Makefile	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sparcv9/Makefile	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,11 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
 #
 # lib/pkcs11/libsoftcrypto/sparcv9/Makefile
 #
@@ -31,7 +33,7 @@
 include ../Makefile.com
 include $(SRC)/lib/Makefile.lib.64
 
-LDLIBS  += -lc
+LDLIBS	+= -lcryptoutil
 LIBS += $(LINTLIB)
 
 DYNFLAGS +=     -Wl,-f/usr/platform/\$$PLATFORM/lib/$(MACH64)/$(DYNLIBPSR)
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4u/Makefile.com	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4u/Makefile.com	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,11 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
 #
 # lib/pkcs11/libsoftcrypto/sun4u/Makefile.com
 #
@@ -35,6 +37,75 @@
 include ../../Makefile.com
 
 # Platform-specific settings
+#
+# Specifying *_OBJS here brings in both *_COMMON_OBJS and *_PSM_OBJS to this
+# platform-specific implementation, and *supercedes* (replaces) the common
+# version.  Specifying only *_PSM_OBJS is used when the PSM version is
+# intended to *augment* (add onto) the common version.
+#
+# COMMON and PSM source/object setup is done in libsoftcrypto/Makefile.com,
+# and does not need to be repeated here.  Only list *_SRCS/*_PSM_SRCS and
+# *_OBJS/*_PSM_OBJS that are platform-specific here.  Keep SRCS= and
+# OBJECTS= in sync with each other.  Update mapfile-vers to list only
+# the functions that are actually compiled into this platform-specific
+# library; do not duplicate what is already in common/mapfile-vers unless
+# this library is providing a superceded version of that function here.
+#
+# Note:  This Makefile.com is set up to compile the PSM objects for AES,
+# ARCFOUR, and DES to augment the corresponding COMMON objects already
+# included in the base libsoftcrypto library.  It does not compile anything
+# for sun4u sparc/sparcv9 to supercede a COMMON object from libsoftcrypto.
+# See the sun4v platform-specific implementation for an alternate example.
+#
+# NOTE: BIGNUM is different.  There is actually no COMMON object in
+# libsoftcrypto for currently-supported platforms (sun4u, sun4v, i386/amd64).
+# The COMMON objects for BIGNUM are a starting point if a new platform is
+# ever added.  Thus, BIGNUM_OBJS is listed in every currently-supported
+# platform-specific Makefile.com, in effect always overriding what it is
+# in the COMMON implementation.  BIGNUM_PSM_OBJS is then used to further
+# augment BIGNUM_COMMON_OBJS on a platform-by-platform basis.
+#
+# Example:
+# 1.	common/Makefile.com:
+#		FOO_COMMON_OBJS = foo.o
+#		FOO_PSM_OBJS = <blank>
+#		FOO_OBJS = $(FOO_COMMON_OBJS) $(FOO_PSM_OBJS)
+#
+#		BAR_COMMON_OBJS = bar.o
+#		BAR_PSM_OBJS = <blank>
+#		BAR_OBJS = $(BAR_COMMON_OBJS) $(BAR_PSM_OBJS)
+#
+#		OBJECTS = $(FOO_OBJS) $(BAR_OBJS)
+#		LIB = libsoftcrypto
+#
+#	Compiling here will make a library libsoftcrypto.so containing:
+#		foo.o bar.o
+#
+#	Run time sees, unless it is a sun4u or sun4v platform (see below):
+#		foo.o bar.o
+#
+# 2.	sun4u/Makefile.com:
+#		FOO_PSM_OBJS = foo-plus.o
+#		OBJECTS = $(FOO_OBJS)		/* defined in common */
+#		LIB = libsoftcrypto_psr
+#
+#	Compiling here will make a library libsoftcrypto_psr.so containing:
+#		foo-plus.o
+#
+#	Run time sees, on a sun4u platform only:
+#		foo.o bar.o foo-plus.o		/* note the difference */
+#
+# 3.	sun4v/Makefile.com:
+#		BAR_PSM_OBJS = bar'.o
+#		OBJECTS = $(BAR_PSM_OBJS)	/* not $(BAR_OBJS) */
+#		LIB - libsoftcrypto_psr
+#
+#	Compiling here will make a library libsoftcrypto_psr.so containing:
+#		bar'.o
+#
+#	Run time sees, on a sun4v platform only:
+#		foo.o bar'.o			/* note the difference */
+#
 AES_PSM_OBJS= aes_crypt_asm.o
 ARCFOUR_PSM_OBJS= arcfour_crypt_asm.o
 DES_PSM_OBJS= des_crypt_asm.o
@@ -46,7 +117,6 @@
 	$(MODES_OBJS)
 
 # Compiler settings
-LDLIBS  += -lc
 CFLAGS += -D$(PLATFORM)
 CFLAGS64 += -D$(PLATFORM)
 ASFLAGS += -DPIC
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4u/mapfile-vers	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4u/mapfile-vers	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 #
@@ -63,6 +63,7 @@
 	big_modexp_crt;
 	big_mul;
 	big_nextprime_pos;
+	big_random;
 	big_sub;
 	big_sub_pos;
 	bignum2bytestring;
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparc/Makefile	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparc/Makefile	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,11 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
 #
 # lib/pkcs11/libsoftcrypto/sun4u/sparc/Makefile
 #
@@ -30,7 +32,7 @@
 include ../Makefile.com
 
 ASFLAGS +=   -xarch=v8plus
-LINTFLAGS += -D$(PLATFORM)
+LINTFLAGS += -D$(PLATFORM) -erroff=E_STATIC_UNUSED
 
 install:  all $(SOFT_PSR_LINKS) $(USR_PSM_LIBS)
 
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparcv9/Makefile	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparcv9/Makefile	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,11 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
 #
 # lib/pkcs11/libsoftcrypto/sun4u/sparcv9/Makefile
 #
@@ -30,7 +32,8 @@
 include ../Makefile.com
 include $(SRC)/lib/Makefile.lib.64
 
-LINTFLAGS64 += -D$(PLATFORM)
+# E_STATIC_UNUSED is for bignumimpl.c, big_modexp_ncp_int/big_modexp_ncp_float
+LINTFLAGS64 += -D$(PLATFORM) -erroff=E_STATIC_UNUSED
 
 install:  all $(SOFT_PSR64_LINKS) $(USR_PSM_LIBS64)
 
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4v/Makefile.com	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4v/Makefile.com	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,11 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
 #
 # lib/pkcs11/libsoftcrypto/sun4v/Makefile.com
 #
@@ -35,10 +37,17 @@
 include ../../Makefile.com
 
 # Platform-specific settings
+#
+# See the sun4u platform-specific Makefile.com for important information
+# that also relates to this file.
+#
+# Note:  This file is set up to compile the PSM objects for ARCFOUR to
+# *augment* (add onto) its common objects from libsoftcrypto, and to compile
+# BIGNUM to *supercede* (replaced) its common objects from libsoftcrypto.
+#
 ARCFOUR_PSM_OBJS=  arcfour_crypt.o
 ARCFOUR_PSM_SRC=   $(ARCFOUR_DIR)/sun4v/arcfour_crypt.c 
 BIGNUM_FLAGS += -DUMUL64
-SRCS= $(ARCFOUR_PSM_SRC) $(BIGNUM_SRC)
 
 MAPFILES= ../mapfile-vers
 OBJECTS= $(ARCFOUR_PSM_OBJS) $(BIGNUM_OBJS)
@@ -52,9 +61,6 @@
 CFLAGS64 += -D$(PLATFORM)
 ASFLAGS +=  -DPIC
 
-# For bignum
-LDLIBS +=   -lc
-
 $(USR_PSM_LIB_DIR)/% := FILEMODE = 755
 
 pics/arcfour_crypt.o: $(ARCFOUR_DIR)/sun4v/arcfour_crypt.c
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4v/mapfile-vers	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4v/mapfile-vers	Mon Jun 07 08:54:25 2010 -0700
@@ -20,8 +20,8 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
 
 #
 # MAPFILE HEADER START
@@ -58,6 +58,7 @@
 	big_modexp_crt;
 	big_mul;
 	big_nextprime_pos;
+	big_random;
 	big_sub;
 	big_sub_pos;
 	bignum2bytestring;
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparc/Makefile	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparc/Makefile	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,11 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
 #
 # lib/pkcs11/libsoftcrypto/sun4v/sparc/Makefile
 #
@@ -29,7 +31,7 @@
 
 include ../Makefile.com
 
-LINTFLAGS += -D$(PLATFORM)
+LINTFLAGS += -D$(PLATFORM) -erroff=E_NAME_MULTIPLY_DEF2
 
 install:  all $(SOFT_PSR_LINKS) $(USR_PSM_LIBS)
 
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparcv9/Makefile	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparcv9/Makefile	Mon Jun 07 08:54:25 2010 -0700
@@ -17,10 +17,12 @@
 # information: Portions Copyright [yyyy] [name of copyright owner]
 #
 # CDDL HEADER END
+#
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
 #
 # lib/pkcs11/libsoftcrypto/sun4v/sparcv9/Makefile
 #
@@ -30,7 +32,9 @@
 include ../Makefile.com
 include $(SRC)/lib/Makefile.lib.64
 
-LINTFLAGS64 += -D$(PLATFORM)
+# E_NAME_MULTIPLY_DEF2 is for arcfour_key_init and arcfour_crypt in
+# different implementations of arcfour_crypt.c
+LINTFLAGS64 += -D$(PLATFORM) -erroff=E_NAME_MULTIPLY_DEF2
 
 install:  all $(SOFT_PSR64_LINKS) $(USR_PSM_LIBS64)
 
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/Makefile.com	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/Makefile.com	Mon Jun 07 08:54:25 2010 -0700
@@ -51,13 +51,11 @@
 	softVerifyUtil.o	\
 	softMAC.o		\
 	softRSA.o		\
-	softRandUtil.o		\
 	softKeysUtil.o		\
 	softARCFourCrypt.o	\
 	softDSA.o		\
 	softDH.o		\
 	softAESCrypt.o		\
-	softCrypt.o		\
 	softKeystore.o		\
 	softKeystoreUtil.o	\
 	softSSL.o		\
@@ -65,8 +63,7 @@
 	softBlowfishCrypt.o	\
 	softEC.o		\
 	softFipsPost.o		\
-	softFipsPostUtil.o	\
-	softFipsDSAUtil.o
+	softFipsPostUtil.o
 
 ASFLAGS = $(AS_PICFLAGS) -P -D__STDC__ -D_ASM $(CPPFLAGS)
 
@@ -78,15 +75,14 @@
 	ec2_test.o ecp_test.o
 
 MPI_COBJECTS = mp_gf2m.o mpi.o mplogic.o mpmontg.o mpprime.o
-RSA_COBJECTS = rsa_impl.o
 RNG_COBJECTS = fips_random.o
-FIPS_COBJECTS = fips_des_util.o \
-		fips_aes_util.o fips_sha1_util.o fips_sha2_util.o \
-		fips_rsa_util.o fips_ecc_util.o fips_random_util.o
+FIPS_COBJECTS = fips_aes_util.o fips_des_util.o \
+		fips_sha1_util.o fips_sha2_util.o \
+		fips_dsa_util.o fips_rsa_util.o \
+		fips_ecc_util.o fips_random_util.o
 
 ECC_OBJECTS = $(ECC_COBJECTS) $(ECC_PSR_OBJECTS)
 MPI_OBJECTS = $(MPI_COBJECTS) $(MPI_PSR_OBJECTS)
-RSA_OBJECTS = $(RSA_COBJECTS) $(RSA_PSR_OBJECTS)
 RNG_OBJECTS = $(RNG_COBJECTS)
 FIPS_OBJECTS = $(FIPS_COBJECTS)
 BER_OBJECTS = bprint.o decode.o encode.o io.o
@@ -94,7 +90,6 @@
 OBJECTS = \
 	$(LCL_OBJECTS)		\
 	$(MPI_OBJECTS)		\
-	$(RSA_OBJECTS)		\
 	$(RNG_OBJECTS)		\
 	$(FIPS_OBJECTS)		\
 	$(BIGNUM_OBJECTS)       \
@@ -105,6 +100,8 @@
 BLOWFISHDIR=    $(SRC)/common/crypto/blowfish
 ARCFOURDIR=     $(SRC)/common/crypto/arcfour
 DESDIR=         $(SRC)/common/crypto/des
+DHDIR=		$(SRC)/common/crypto/dh
+DSADIR=		$(SRC)/common/crypto/dsa
 ECCDIR=		$(SRC)/common/crypto/ecc
 MPIDIR=		$(SRC)/common/mpi
 RSADIR=		$(SRC)/common/crypto/rsa
@@ -113,6 +110,7 @@
 SHA1DIR=	$(SRC)/common/crypto/sha1
 SHA2DIR=	$(SRC)/common/crypto/sha2
 BIGNUMDIR=	$(SRC)/common/bignum
+PADDIR=		$(SRC)/common/crypto/padding
 BERDIR=		../../../libldap5/sources/ldap/ber
 
 include $(SRC)/lib/Makefile.lib
@@ -125,7 +123,6 @@
 SRCS =	\
 	$(LCL_OBJECTS:%.o=$(SRCDIR)/%.c) \
 	$(MPI_COBJECTS:%.o=$(MPIDIR)/%.c) \
-	$(RSA_COBJECTS:%.o=$(RSADIR)/%.c) \
 	$(ECC_COBJECTS:%.o=$(ECCDIR)/%.c) \
 	$(RNG_COBJECTS:%.o=$(RNGDIR)/%.c) \
 	$(FIPS_COBJECTS:%.o=$(FIPSDIR)/%.c)
@@ -137,9 +134,10 @@
 CFLAGS 	+=      $(CCVERBOSE)
 
 CPPFLAGS += -I$(AESDIR) -I$(BLOWFISHDIR) -I$(ARCFOURDIR) -I$(DESDIR) \
-	    -I$(ECCDIR) -I$(SRC)/common/crypto -I$(MPIDIR) -I$(RSADIR) -I$(RNGDIR) \
+	    -I$(DHDIR) -I$(DSADIR) -I$(ECCDIR) -I$(SRC)/common/crypto \
+	    -I$(MPIDIR) -I$(RSADIR) -I$(RNGDIR) \
 	    -I$(FIPSDIR) -I$(SHA1DIR) -I$(SHA2DIR) -I$(SRCDIR) \
-	    -I$(BIGNUMDIR) -D_POSIX_PTHREAD_SEMANTICS \
+	    -I$(BIGNUMDIR) -I$(PADDIR) -D_POSIX_PTHREAD_SEMANTICS \
 	    -DMP_API_COMPATIBLE -DNSS_ECC_MORE_THAN_SUITE_B
 
 LINTFLAGS64 += -errchk=longptr64
@@ -149,7 +147,6 @@
 
 LINTSRC = \
 	$(LCL_OBJECTS:%.o=$(SRCDIR)/%.c) \
-	$(RSA_COBJECTS:%.o=$(RSADIR)/%.c) \
 	$(RNG_COBJECTS:%.o=$(RNGDIR)/%.c) \
 	$(FIPS_COBJECTS:%.o=$(FIPSDIR)/%.c)
 
@@ -173,10 +170,6 @@
 	$(COMPILE.c) -o $@ $<
 	$(POST_PROCESS_O)
 
-pics/%.o:	$(RSADIR)/%.c
-	$(COMPILE.c) -o $@ $<
-	$(POST_PROCESS_O)
-
 pics/%.o:	$(RNGDIR)/%.c
 	$(COMPILE.c) -o $@ $<
 	$(POST_PROCESS_O)
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <pthread.h>
@@ -726,7 +726,7 @@
 			 * plaintext.
 			 */
 			rv = soft_remove_pkcs7_padding(last_block,
-			    AES_BLOCK_LEN, &rem_len, AES_BLOCK_LEN);
+			    AES_BLOCK_LEN, &rem_len);
 			if (rv == CKR_OK) {
 				if (rem_len != 0)
 					(void) memcpy(out_buf + out_len,
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,39 +18,37 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
 #include <lber.h>
 #include <security/cryptoki.h>
-#include <rsa_impl.h>
 #include "softDSA.h"
 #include "softDH.h"
+#include "softRSA.h"
 #include "softObject.h"
 #include "softASN1.h"
 
 #define	OID_TAG			0x06
 
-#define	MAX_DH_KEY	(MAX_DH_KEYLENGTH >> 3)	/* bytes in a DH key */
+#define	MAX_DH_KEY	MAX_DH_KEYLENGTH_IN_BYTES	/* bytes in DH key */
 static uchar_t	DH_OID[] = {
 	/* DH key agreement OID:  1 . 2 . 840 . 113549 . 1 . 3 . 1 */
 	0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x03, 0x01
 };
 
-#define	MAX_DH942_KEY	(MAX_DH_KEYLENGTH >> 3)	/* bytes in a DH X9.42 key */
+#define	MAX_DH942_KEY	MAX_DH_KEYLENGTH_IN_BYTES /* bytes in DH X9.42 key */
 static uchar_t	DH942_OID[] = {
 	/* DH X9.42 OID:  1 . 2 . 840 . 10046 . 1  */
 	0x2A, 0x86, 0x48, 0xCE, 0x3E, 0x01
 };
 
-#define	MAX_DSA_KEY	MAX_DSA_KEY_LEN 	/* bytes in a DSA key */
+#define	MAX_DSA_KEY	MAX_DSA_KEY_LEN 	/* bytes in DSA key */
 static uchar_t	DSA_OID[] = {
 	/* DSA algorithm OID:  1 . 2 . 840 . 10040 . 4 . 1  */
 	0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01
@@ -100,7 +98,7 @@
 	/* Set zero-pad at first byte, then append actual big_value. */
 	dst->big_value[0] = 0x0;
 	(void) memcpy(&(dst->big_value[padding]), src->big_value,
-		src->big_value_len);
+	    src->big_value_len);
 	return (CKR_OK);
 }
 
@@ -268,7 +266,7 @@
 		goto cleanup_rsapri2asn;
 	}
 
-	/* ... coeffient } end-sequence */
+	/* ... coefficient } end-sequence */
 	if ((rv = pad_bigint_attr(OBJ_PRI_RSA_COEF(objp), &tmp_pad)) != CKR_OK)
 		goto cleanup_rsapri2asn;
 	else if (ber_printf(key_asn, "to}", LBER_INTEGER,
@@ -534,16 +532,16 @@
 	}
 
 	if (key_asn != NULLBER)
-	    ber_free(key_asn, 1);
+		ber_free(key_asn, 1);
 
 	if (key_octs != NULL)
-	    ber_bvfree(key_octs);
+		ber_bvfree(key_octs);
 
 	if (p8obj_asn != NULLBER)
-	    ber_free(p8obj_asn, 1);
+		ber_free(p8obj_asn, 1);
 
 	if (p8obj_octs != NULL)
-	    ber_bvfree(p8obj_octs);
+		ber_bvfree(p8obj_octs);
 
 	return (rv);
 }
@@ -708,16 +706,16 @@
 	}
 
 	if (key_asn != NULLBER)
-	    ber_free(key_asn, 1);
+		ber_free(key_asn, 1);
 
 	if (key_octs != NULL)
-	    ber_bvfree(key_octs);
+		ber_bvfree(key_octs);
 
 	if (p8obj_asn != NULLBER)
-	    ber_free(p8obj_asn, 1);
+		ber_free(p8obj_asn, 1);
 
 	if (p8obj_octs != NULL)
-	    ber_bvfree(p8obj_octs);
+		ber_bvfree(p8obj_octs);
 
 	return (rv);
 }
@@ -900,16 +898,16 @@
 	}
 
 	if (key_asn != NULLBER)
-	    ber_free(key_asn, 1);
+		ber_free(key_asn, 1);
 
 	if (key_octs != NULL)
-	    ber_bvfree(key_octs);
+		ber_bvfree(key_octs);
 
 	if (p8obj_asn != NULLBER)
-	    ber_free(p8obj_asn, 1);
+		ber_free(p8obj_asn, 1);
 
 	if (p8obj_octs != NULL)
-	    ber_bvfree(p8obj_octs);
+		ber_bvfree(p8obj_octs);
 
 	return (rv);
 }
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.c	Mon Jun 07 11:37:25 2010 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-
-#include <sys/types.h>
-#include <security/cryptoki.h>
-#include <bignum.h>
-
-
-CK_RV
-convert_rv(BIG_ERR_CODE err)
-{
-	switch (err) {
-
-	case BIG_OK:
-		return (CKR_OK);
-
-	case BIG_NO_MEM:
-		return (CKR_HOST_MEMORY);
-
-	case BIG_NO_RANDOM:
-		return (CKR_DEVICE_ERROR);
-
-	case BIG_INVALID_ARGS:
-		return (CKR_ARGUMENTS_BAD);
-
-	case BIG_DIV_BY_0:
-	default:
-		return (CKR_GENERAL_ERROR);
-	}
-}
-
-BIG_ERR_CODE
-convert_brv(CK_RV err)
-{
-	switch (err) {
-
-	case CKR_OK:
-		return (BIG_OK);
-
-	case CKR_HOST_MEMORY:
-		return (BIG_NO_MEM);
-
-	case CKR_DEVICE_ERROR:
-		return (BIG_NO_RANDOM);
-
-	case CKR_ARGUMENTS_BAD:
-		return (BIG_INVALID_ARGS);
-
-	default:
-		return (BIG_GENERAL_ERR);
-	}
-}
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.h	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.h	Mon Jun 07 08:54:25 2010 -0700
@@ -18,16 +18,14 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef _SOFTCRYPT_H
 #define	_SOFTCRYPT_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -38,7 +36,6 @@
 #include <aes_impl.h>
 #include <blowfish_impl.h>
 #include <des_impl.h>
-#include <bignum.h>
 #include "softObject.h"
 #include "softSession.h"
 
@@ -99,7 +96,7 @@
 
 void soft_add_pkcs7_padding(CK_BYTE *, int, CK_ULONG);
 
-CK_RV soft_remove_pkcs7_padding(CK_BYTE *, CK_ULONG, CK_ULONG *, int);
+CK_RV soft_remove_pkcs7_padding(CK_BYTE *, CK_ULONG, CK_ULONG *);
 
 CK_RV soft_arcfour_crypt_init(soft_session_t *, CK_MECHANISM_PTR,
 	soft_object_t *, boolean_t);
@@ -130,10 +127,6 @@
 CK_RV soft_blowfish_decrypt_common(soft_session_t *, CK_BYTE_PTR, CK_ULONG,
 	CK_BYTE_PTR, CK_ULONG_PTR, boolean_t);
 
-CK_RV convert_rv(BIG_ERR_CODE);
-
-BIG_ERR_CODE convert_brv(CK_RV);
-
 #ifdef	__cplusplus
 }
 #endif
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDESCrypt.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDESCrypt.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <pthread.h>
@@ -732,7 +732,7 @@
 			 * plaintext.
 			 */
 			rv = soft_remove_pkcs7_padding(last_block,
-			    DES_BLOCK_LEN, &rem_len, DES_BLOCK_LEN);
+			    DES_BLOCK_LEN, &rem_len);
 			if (rv == CKR_OK) {
 				if (rem_len != 0)
 					(void) memcpy(out_buf + out_len,
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,59 +18,39 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
 #include <sys/types.h>
 #include <security/cryptoki.h>
 #include <sys/crypto/common.h>
-#include <bignum.h>
 #include <des_impl.h>
+#include <cryptoutil.h>
 #include "softGlobal.h"
 #include "softSession.h"
 #include "softObject.h"
 #include "softDH.h"
-#include "softRandom.h"
 #include "softCrypt.h"
 
 
 /*
- * This function converts the big integer of the specified attribute
- * to an octet string and store it in the corresponding key object.
+ * This function takes a converted big integer of the specified attribute
+ * as an octet string and stores it in the corresponding key object.
  */
-CK_RV
-soft_genDHkey_set_attribute(soft_object_t *key, BIGNUM *bn,
-    CK_ATTRIBUTE_TYPE type, uint32_t prime_len, boolean_t public)
+static CK_RV
+soft_genDHkey_set_attribute(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
+    uchar_t *buf, uint32_t buflen, boolean_t public)
 {
 
-	uchar_t	*buf;
-	uint32_t buflen;
 	CK_RV rv = CKR_OK;
 	biginteger_t *dst = NULL;
 	biginteger_t src;
 
-	/*
-	 * Allocate the buffer used to store the value of key fields
-	 * for bignum2bytestring. Since bignum only deals with a buffer
-	 * whose size is multiple of 4, prime_len is rounded up to be
-	 * multiple of 4.
-	 */
-	if ((buf = malloc((prime_len + sizeof (BIG_CHUNK_TYPE) - 1) &
-	    ~(sizeof (BIG_CHUNK_TYPE) - 1))) == NULL) {
-		rv = CKR_HOST_MEMORY;
-		goto cleanexit;
-	}
-
-	buflen = bn->len * (int)sizeof (BIG_CHUNK_TYPE);
-	bignum2bytestring(buf, bn, buflen);
-
 	switch (type) {
 
 	case CKA_VALUE:
@@ -89,19 +69,14 @@
 		break;
 	}
 
-	src.big_value_len = buflen;
-
-	if ((src.big_value = malloc(buflen)) == NULL) {
-		rv = CKR_HOST_MEMORY;
+	if ((rv = dup_bigint_attr(&src, buf, buflen)) != CKR_OK)
 		goto cleanexit;
-	}
-	(void) memcpy(src.big_value, buf, buflen);
 
 	/* Copy the attribute in the key object. */
 	copy_bigint_attr(&src, dst);
 
 cleanexit:
-	free(buf);
+	/* No need to free big_value because dst holds it now after copy. */
 	return (rv);
 
 }
@@ -113,18 +88,15 @@
 soft_dh_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
 {
 	CK_RV		rv;
-	BIG_ERR_CODE	brv;
+	CK_ATTRIBUTE 	template;
 	uchar_t		prime[MAX_KEY_ATTR_BUFLEN];
 	uint32_t	prime_len = sizeof (prime);
-	uint32_t	primebit_len;
-	uint32_t	value_bits;
 	uchar_t		base[MAX_KEY_ATTR_BUFLEN];
 	uint32_t	base_len = sizeof (base);
-	BIGNUM		bnprime;
-	BIGNUM		bnbase;
-	BIGNUM		bnprival;
-	BIGNUM		bnpubval;
-	CK_ATTRIBUTE 	template;
+	uint32_t	value_bits;
+	uchar_t		private_x[MAX_KEY_ATTR_BUFLEN];
+	uchar_t		public_y[MAX_KEY_ATTR_BUFLEN];
+	DHbytekey	k;
 
 	if ((pubkey->class != CKO_PUBLIC_KEY) ||
 	    (pubkey->key_type != CKK_DH)) {
@@ -136,74 +108,19 @@
 		return (CKR_KEY_TYPE_INCONSISTENT);
 	}
 
-	/*
-	 * The input to the first phase shall be the Diffie-Hellman
-	 * parameters, which include prime, base, and private-value length.
-	 */
-	rv = soft_get_public_value(pubkey, CKA_PRIME, prime, &prime_len);
-
+	/* Get private-value length in bits */
+	template.pValue = malloc(sizeof (CK_ULONG));
+	if (template.pValue == NULL) {
+		return (CKR_HOST_MEMORY);
+	}
+	template.ulValueLen = sizeof (CK_ULONG);
+	rv = get_ulong_attr_from_object(OBJ_PRI_DH_VAL_BITS(prikey),
+	    &template);
 	if (rv != CKR_OK) {
+		free(template.pValue);
 		return (rv);
 	}
 
-	if ((prime_len < (MIN_DH_KEYLENGTH / 8)) ||
-	    (prime_len > (MAX_DH_KEYLENGTH / 8))) {
-		rv = CKR_ATTRIBUTE_VALUE_INVALID;
-		goto ret0;
-	}
-
-	if ((brv = big_init(&bnprime, CHARLEN2BIGNUMLEN(prime_len))) !=
-	    BIG_OK) {
-		rv = convert_rv(brv);
-		goto ret0;
-	}
-
-	/* Convert the prime octet string to big integer format. */
-	bytestring2bignum(&bnprime, prime, prime_len);
-
-	rv = soft_get_public_value(pubkey, CKA_BASE, base, &base_len);
-
-	if (rv != CKR_OK) {
-		goto ret1;
-	}
-
-	if ((brv = big_init(&bnbase, CHARLEN2BIGNUMLEN(base_len))) != BIG_OK) {
-		rv = convert_rv(brv);
-		goto ret1;
-	}
-
-	/* Convert the base octet string to big integer format. */
-	bytestring2bignum(&bnbase, base, base_len);
-
-	if (big_cmp_abs(&bnbase, &bnprime) >= 0) {
-		rv = CKR_ATTRIBUTE_VALUE_INVALID;
-		goto ret2;
-	}
-
-	primebit_len = big_bitlength(&bnprime);
-
-	template.pValue = malloc(sizeof (CK_ULONG));
-
-	if (template.pValue == NULL) {
-		rv = CKR_HOST_MEMORY;
-		goto ret2;
-	}
-
-	template.ulValueLen = sizeof (CK_ULONG);
-
-	rv = get_ulong_attr_from_object(OBJ_PRI_DH_VAL_BITS(prikey),
-	    &template);
-
-	if (rv != CKR_OK) {
-		goto ret2;
-	}
-
-	/*
-	 * The intention of selecting a private-value length is to reduce
-	 * the computation time for key agreement, while maintaining a
-	 * given level of security.
-	 */
-
 #ifdef	__sparcv9
 	/* LINTED */
 	value_bits = (uint32_t)(*((CK_ULONG *)(template.pValue)));
@@ -211,109 +128,87 @@
 	value_bits = *((CK_ULONG *)(template.pValue));
 #endif	/* __sparcv9 */
 
-	if (value_bits > primebit_len) {
-		rv = CKR_ATTRIBUTE_VALUE_INVALID;
-		goto ret3;
-	}
-
-	/* Generate DH key pair private and public values. */
-	if ((brv = big_init(&bnprival, CHARLEN2BIGNUMLEN(prime_len)))
-	    != BIG_OK) {
-		rv = convert_rv(brv);
-		goto ret3;
-	}
-
-	if ((brv = big_init(&bnpubval, CHARLEN2BIGNUMLEN(prime_len)))
-	    != BIG_OK) {
-		rv = convert_rv(brv);
-		goto ret4;
-	}
+	free(template.pValue);
 
 	/*
-	 * The big integer of the private value shall be generated privately
-	 * and randomly.
+	 * The input to the first phase shall be the Diffie-Hellman
+	 * parameters, which include prime, base, and private-value length.
 	 */
-	if ((brv = random_bignum(&bnprival, (value_bits == 0) ?
-	    primebit_len : value_bits, (IS_TOKEN_OBJECT(pubkey) ||
-	    IS_TOKEN_OBJECT(prikey)))) != BIG_OK) {
-		rv = convert_rv(brv);
-		goto ret5;
+	rv = soft_get_public_value(pubkey, CKA_PRIME, prime, &prime_len);
+	if (rv != CKR_OK) {
+		return (rv);
+	}
+
+	rv = soft_get_public_value(pubkey, CKA_BASE, base, &base_len);
+	if (rv != CKR_OK) {
+		goto ret;
 	}
 
-	/*
-	 * The base g shall be raised to the private value x modulo p to
-	 * give an integer y, the integer public value.
-	 */
-	if ((brv = big_modexp(&bnpubval,
-	    &bnbase, &bnprival, &bnprime, NULL)) != BIG_OK) {
-		rv = convert_rv(brv);
-		goto ret5;
+	/* Inputs to DH key pair generation. */
+	k.prime = prime;
+	k.prime_bits = CRYPTO_BYTES2BITS(prime_len);
+	k.base = base;
+	k.base_bytes = base_len;
+	k.value_bits = value_bits;
+	k.rfunc = (IS_TOKEN_OBJECT(pubkey) || IS_TOKEN_OBJECT(prikey)) ?
+	    pkcs11_get_random : pkcs11_get_urandom;
+
+	/* Outputs from DH key pair generation. */
+	k.private_x = private_x;
+	k.public_y = public_y;
+
+	/* If value_bits is 0, it will return as same size as prime */
+	if ((rv = dh_genkey_pair(&k)) != CKR_OK) {
+		goto ret;
 	}
 
 	/*
 	 * The integer public value y shall be converted to an octet
 	 * string PV of length k, the public value.
 	 */
-	if ((rv = soft_genDHkey_set_attribute(pubkey, &bnpubval,
-	    CKA_VALUE, prime_len, B_TRUE)) != CKR_OK) {
-		goto ret5;
+	if ((rv = soft_genDHkey_set_attribute(pubkey, CKA_VALUE, public_y,
+	    CRYPTO_BITS2BYTES(k.value_bits), B_TRUE)) != CKR_OK) {
+		goto ret;
 	}
 
 	/* Convert the big integer private value to an octet string. */
-	if ((rv = soft_genDHkey_set_attribute(prikey, &bnprival,
-	    CKA_VALUE, prime_len, B_FALSE)) != CKR_OK) {
-		goto ret5;
+	if ((rv = soft_genDHkey_set_attribute(prikey, CKA_VALUE, private_x,
+	    CRYPTO_BITS2BYTES(k.value_bits), B_FALSE)) != CKR_OK) {
+		goto ret;
 	}
 
 	/* Convert the big integer prime to an octet string. */
-	if ((rv = soft_genDHkey_set_attribute(prikey, &bnprime,
-	    CKA_PRIME, prime_len, B_FALSE)) != CKR_OK) {
-		goto ret5;
+	if ((rv = soft_genDHkey_set_attribute(prikey, CKA_PRIME, prime,
+	    CRYPTO_BITS2BYTES(k.prime_bits), B_FALSE)) != CKR_OK) {
+		goto ret;
 	}
 
 	/* Convert the big integer base to an octet string. */
-	if ((rv = soft_genDHkey_set_attribute(prikey, &bnbase,
-	    CKA_BASE, prime_len, B_FALSE)) != CKR_OK) {
-		goto ret5;
-	}
-
-	if (value_bits == 0) {
-		OBJ_PRI_DH_VAL_BITS(prikey) = primebit_len;
+	if ((rv = soft_genDHkey_set_attribute(prikey, CKA_BASE, base,
+	    k.base_bytes, B_FALSE)) != CKR_OK) {
+		goto ret;
 	}
 
+	/* Update private-value length in bits; could have been 0 before */
+	OBJ_PRI_DH_VAL_BITS(prikey) = k.value_bits;
 
-ret5:
-	big_finish(&bnpubval);
-ret4:
-	big_finish(&bnprival);
-ret3:
-	free(template.pValue);
-ret2:
-	big_finish(&bnbase);
-ret1:
-	big_finish(&bnprime);
-ret0:
+ret:
 	return (rv);
 }
 
+/* ARGSUSED3 */
 CK_RV
 soft_dh_key_derive(soft_object_t *basekey, soft_object_t *secretkey,
     void *publicvalue, size_t publicvaluelen)
 {
+	CK_RV		rv;
 	uchar_t		privatevalue[MAX_KEY_ATTR_BUFLEN];
 	uint32_t	privatevaluelen = sizeof (privatevalue);
 	uchar_t		privateprime[MAX_KEY_ATTR_BUFLEN];
 	uint32_t	privateprimelen = sizeof (privateprime);
-	uchar_t		*value;
-	uint32_t	valuelen;
+	uchar_t		key[MAX_KEY_ATTR_BUFLEN];
 	uint32_t	keylen;
-	uchar_t		*buf = NULL;
-	CK_RV		rv;
-	BIG_ERR_CODE	brv;
-	BIGNUM		bnprime;
-	BIGNUM		bnpublic;
-	BIGNUM		bnprivate;
-	BIGNUM		bnsecret;
+	DHbytekey	k;
 
 	rv = soft_get_private_value(basekey, CKA_VALUE, privatevalue,
 	    &privatevaluelen);
@@ -324,123 +219,38 @@
 	rv = soft_get_private_value(basekey, CKA_PRIME, privateprime,
 	    &privateprimelen);
 	if (rv != CKR_OK) {
-		goto ret0;
-	}
-
-	if ((brv = big_init(&bnprime, CHARLEN2BIGNUMLEN(privateprimelen))) !=
-	    BIG_OK) {
-		rv = convert_rv(brv);
-		goto ret0;
-	}
-
-	bytestring2bignum(&bnprime, privateprime, privateprimelen);
-
-	if ((brv = big_init(&bnprivate, CHARLEN2BIGNUMLEN(privatevaluelen))) !=
-	    BIG_OK) {
-		rv = convert_rv(brv);
-		goto ret1;
+		goto ret;
 	}
 
-	bytestring2bignum(&bnprivate, privatevalue, privatevaluelen);
-
-#ifdef	__sparcv9
-	if ((brv = big_init(&bnpublic,
-	    (int)CHARLEN2BIGNUMLEN(publicvaluelen))) != BIG_OK) {
-#else	/* !__sparcv9 */
-	if ((brv = big_init(&bnpublic,
-	    CHARLEN2BIGNUMLEN(publicvaluelen))) != BIG_OK) {
-#endif	/* __sparcv9 */
-		rv = convert_rv(brv);
-		goto ret2;
-	}
-
-	bytestring2bignum(&bnpublic, (uchar_t *)publicvalue, publicvaluelen);
-
-	if ((brv = big_init(&bnsecret,
-	    CHARLEN2BIGNUMLEN(privateprimelen))) != BIG_OK) {
-		rv = convert_rv(brv);
-		goto ret3;
-	}
-
-	if ((brv = big_modexp(&bnsecret, &bnpublic, &bnprivate, &bnprime,
-	    NULL)) != BIG_OK) {
-		rv = convert_rv(brv);
-		goto ret4;
+	/* keylen may be 0 if CKA_VALUE_LEN did not specify */
+	keylen = OBJ_SEC_VALUE_LEN(secretkey);
+	if (keylen > sizeof (key)) {		/* check for overflow */
+		rv = CKR_ATTRIBUTE_VALUE_INVALID;
+		goto ret;
 	}
 
-	if ((buf = malloc((privateprimelen + sizeof (BIG_CHUNK_TYPE) - 1) &
-	    ~(sizeof (BIG_CHUNK_TYPE) - 1))) == NULL) {
-		rv = CKR_HOST_MEMORY;
-		goto ret4;
-	}
-
-	value = buf;
-	valuelen = bnsecret.len * (int)sizeof (BIG_CHUNK_TYPE);
-	bignum2bytestring(value, &bnsecret, valuelen);
-
-	switch (secretkey->key_type) {
+	k.prime = privateprime;
+	k.prime_bits = CRYPTO_BYTES2BITS(privateprimelen);
+	k.value_bits = CRYPTO_BYTES2BITS(privatevaluelen);
+	k.private_x = privatevalue;
+	k.public_y = publicvalue;
+	k.rfunc = NULL;
 
-	case CKK_DES:
-		keylen = DES_KEYSIZE;
-		break;
-	case CKK_DES2:
-		keylen = DES2_KEYSIZE;
-		break;
-	case CKK_DES3:
-		keylen = DES3_KEYSIZE;
-		break;
-	case CKK_RC4:
-	case CKK_AES:
-	case CKK_GENERIC_SECRET:
-#ifdef	__sparcv9
-		/* LINTED */
-		keylen = (uint32_t)OBJ_SEC_VALUE_LEN(secretkey);
-#else	/* !__sparcv9 */
-		keylen = OBJ_SEC_VALUE_LEN(secretkey);
-#endif	/* __sparcv9 */
-		break;
-	}
+	/* keylen may be modified if it was 0 or conflicts with key type */
+	rv = dh_key_derive(&k, secretkey->key_type, key, &keylen);
 
-	if (keylen == 0) {
-		/*
-		 * keylen == 0 only if CKA_VALUE_LEN did not specify.
-		 */
-		keylen = valuelen;
-	}
-	/*
-	 * Note: No need to have "default:" case here since invalid key type
-	 * if any has been detected at function soft_build_secret_key_object()
-	 * before it gets here.
-	 */
-
-	if (keylen > valuelen) {
-		rv = CKR_ATTRIBUTE_VALUE_INVALID;
-		goto ret5;
+	if (rv != CKR_OK) {
+		goto ret;
 	}
 
 	if ((OBJ_SEC_VALUE(secretkey) = malloc(keylen)) == NULL) {
 		rv = CKR_HOST_MEMORY;
-		goto ret5;
+		goto ret;
 	}
-	OBJ_SEC_VALUE_LEN(secretkey) = keylen;
-
-	/*
-	 * The truncation removes bytes from the leading end of the
-	 * secret value.
-	 */
-	(void) memcpy(OBJ_SEC_VALUE(secretkey), (value + valuelen - keylen),
-	    keylen);
 
-ret5:
-	free(buf);
-ret4:
-	big_finish(&bnsecret);
-ret3:
-	big_finish(&bnpublic);
-ret2:
-	big_finish(&bnprivate);
-ret1:
-	big_finish(&bnprime);
-ret0:
+	OBJ_SEC_VALUE_LEN(secretkey) = keylen;
+	(void) memcpy(OBJ_SEC_VALUE(secretkey), key, keylen);
+
+ret:
 	return (rv);
 }
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.h	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.h	Mon Jun 07 08:54:25 2010 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,29 +18,25 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef _SOFTDH_H
 #define	_SOFTDH_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #include <sys/types.h>
 #include <security/pkcs11t.h>
+#include <dh_impl.h>
 #include "softObject.h"
 #include "softSession.h"
 
 
-#define	MIN_DH_KEYLENGTH 64
-#define	MAX_DH_KEYLENGTH 4096
-
 /*
  * Function Prototypes.
  */
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <pthread.h>
@@ -29,12 +29,11 @@
 #include <strings.h>
 #include <sys/types.h>
 #include <security/cryptoki.h>
-#include <bignum.h>
+#include <cryptoutil.h>
 #include "softGlobal.h"
 #include "softSession.h"
 #include "softObject.h"
 #include "softDSA.h"
-#include "softRandom.h"
 #include "softOps.h"
 #include "softMAC.h"
 #include "softCrypt.h"
@@ -114,76 +113,11 @@
 }
 
 
-/* size is in bits */
-BIG_ERR_CODE
-DSA_key_init(DSAkey *key, int size)
+static CK_RV
+local_dsa_sign(soft_object_t *key, CK_BYTE_PTR in, CK_ULONG inlen,
+    CK_BYTE_PTR out)
 {
-	BIG_ERR_CODE err;
-	int len, len160;
-
-	len = BITLEN2BIGNUMLEN(size);
-	len160 = BIG_CHUNKS_FOR_160BITS;
-	key->size = size;
-	if ((err = big_init1(&(key->q), len160, NULL, 0)) != BIG_OK)
-		return (err);
-	if ((err = big_init1(&(key->p), len, NULL, 0)) != BIG_OK)
-		goto ret1;
-	if ((err = big_init1(&(key->g), len, NULL, 0)) != BIG_OK)
-		goto ret2;
-	if ((err = big_init1(&(key->x), len160, NULL, 0)) != BIG_OK)
-		goto ret3;
-	if ((err = big_init1(&(key->y), len, NULL, 0)) != BIG_OK)
-		goto ret4;
-	if ((err = big_init1(&(key->k), len160, NULL, 0)) != BIG_OK)
-		goto ret5;
-	if ((err = big_init1(&(key->r), len160, NULL, 0)) != BIG_OK)
-		goto ret6;
-	if ((err = big_init1(&(key->s), len160, NULL, 0)) != BIG_OK)
-		goto ret7;
-	if ((err = big_init1(&(key->v), len160, NULL, 0)) != BIG_OK)
-		goto ret8;
-
-	return (BIG_OK);
-
-ret8:
-	big_finish(&(key->s));
-ret7:
-	big_finish(&(key->r));
-ret6:
-	big_finish(&(key->k));
-ret5:
-	big_finish(&(key->y));
-ret4:
-	big_finish(&(key->x));
-ret3:
-	big_finish(&(key->g));
-ret2:
-	big_finish(&(key->p));
-ret1:
-	big_finish(&(key->q));
-	return (err);
-}
-
-
-void
-DSA_key_finish(DSAkey *key)
-{
-	big_finish(&(key->v));
-	big_finish(&(key->s));
-	big_finish(&(key->r));
-	big_finish(&(key->k));
-	big_finish(&(key->y));
-	big_finish(&(key->x));
-	big_finish(&(key->g));
-	big_finish(&(key->p));
-	big_finish(&(key->q));
-}
-
-
-CK_RV
-dsa_sign(soft_object_t *key, CK_BYTE_PTR in, CK_ULONG inlen, CK_BYTE_PTR out)
-{
-
+	CK_RV rv;
 	uchar_t q[MAX_KEY_ATTR_BUFLEN];
 	uchar_t p[MAX_KEY_ATTR_BUFLEN];
 	uchar_t g[MAX_KEY_ATTR_BUFLEN];
@@ -192,22 +126,14 @@
 	uint_t plen = sizeof (p);
 	uint_t glen = sizeof (g);
 	uint_t xlen = sizeof (x);
-	DSAkey dsakey;
-	BIGNUM msg, tmp, tmp1, tmp2;
-	BIG_ERR_CODE err;
-	CK_RV rv;
+	DSAbytekey k;
 
-	rv = soft_get_private_value(key, CKA_SUBPRIME, q, &qlen);
+	rv = soft_get_private_value(key, CKA_PRIME, p, &plen);
 	if (rv != CKR_OK) {
 		goto clean1;
 	}
 
-	if (DSA_SUBPRIME_BYTES != qlen) {
-		rv = CKR_KEY_SIZE_RANGE;
-		goto clean1;
-	}
-
-	rv = soft_get_private_value(key, CKA_PRIME, p, &plen);
+	rv = soft_get_private_value(key, CKA_SUBPRIME, q, &qlen);
 	if (rv != CKR_OK) {
 		goto clean1;
 	}
@@ -222,103 +148,26 @@
 		goto clean1;
 	}
 
-	if (DSA_SUBPRIME_BYTES < xlen) {
-		rv = CKR_KEY_SIZE_RANGE;
-		goto clean1;
-	}
-
-	if ((err = DSA_key_init(&dsakey, plen * 8)) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean1;
-	}
-
-	if ((err = big_init(&msg, BIG_CHUNKS_FOR_160BITS)) != BIG_OK) {
-		goto clean6;
-	}
-	if ((err = big_init(&tmp, CHARLEN2BIGNUMLEN(plen) +
-	    2 * BIG_CHUNKS_FOR_160BITS + 1)) != BIG_OK) {
-		goto clean7;
-	}
-	if ((err = big_init(&tmp1, 2 * BIG_CHUNKS_FOR_160BITS + 1)) != BIG_OK) {
-		goto clean8;
-	}
-	if ((err = big_init(&tmp2, BIG_CHUNKS_FOR_160BITS)) != BIG_OK) {
-		goto clean9;
-	}
-
-	bytestring2bignum(&(dsakey.g), g, plen);
-	bytestring2bignum(&(dsakey.x), x, DSA_SUBPRIME_BYTES);
-	bytestring2bignum(&(dsakey.p), p, plen);
-	bytestring2bignum(&(dsakey.q), q, DSA_SUBPRIME_BYTES);
-	bytestring2bignum(&msg, (uchar_t *)in, inlen);
-
-	if ((err = random_bignum(&(dsakey.k), DSA_SUBPRIME_BITS,
-	    B_FALSE)) != BIG_OK)
-		goto clean10;
-
-	if ((err = big_div_pos(NULL, &(dsakey.k), &(dsakey.k),
-	    &(dsakey.q))) != BIG_OK)
-		goto clean10;
-
-	if ((err = big_modexp(&tmp, &(dsakey.g), &(dsakey.k), &(dsakey.p),
-	    NULL)) != BIG_OK)
-		goto clean10;
+	k.prime = p;
+	k.prime_bits = CRYPTO_BYTES2BITS(plen);
+	k.subprime = q;
+	k.subprime_bits = CRYPTO_BYTES2BITS(qlen);
+	k.base = g;
+	k.base_bytes = glen;
+	k.private_x_bits = CRYPTO_BYTES2BITS(xlen);
+	k.private_x = x;
+	k.rfunc = NULL;
 
-	if ((err = big_div_pos(NULL, &(dsakey.r), &tmp, &(dsakey.q))) !=
-	    BIG_OK)
-		goto clean10;
-
-	if ((err = big_ext_gcd_pos(NULL, NULL, &tmp, &(dsakey.q),
-	    &(dsakey.k))) != BIG_OK)
-		goto clean10;
-
-	if (tmp.sign == -1)
-		if ((err = big_add(&tmp, &tmp, &(dsakey.q))) != BIG_OK)
-			goto clean10;			/* tmp <- k^-1 */
-
-	if ((err = big_mul(&tmp1, &(dsakey.x), &(dsakey.r))) != BIG_OK)
-		goto clean10;
-
-	if ((err = big_add(&tmp1, &tmp1, &msg)) != BIG_OK)
-		goto clean10;
-
-	if ((err = big_mul(&tmp, &tmp1, &tmp)) != BIG_OK)
-		goto clean10;
+	rv = dsa_sign(&k, in, inlen, out);
 
-	if ((err = big_div_pos(NULL, &(dsakey.s), &tmp, &(dsakey.q))) !=
-	    BIG_OK)
-		goto clean10;
-
-	bignum2bytestring((uchar_t *)out, &(dsakey.r), DSA_SUBPRIME_BYTES);
-	bignum2bytestring((uchar_t *)out + DSA_SUBPRIME_BYTES, &(dsakey.s),
-	    DSA_SUBPRIME_BYTES);
-
-	err = BIG_OK;
-
-clean10:
-	big_finish(&tmp2);
-clean9:
-	big_finish(&tmp1);
-clean8:
-	big_finish(&tmp);
-clean7:
-	big_finish(&msg);
-clean6:
-	DSA_key_finish(&dsakey);
-	if (err == BIG_OK)
-		rv = CKR_OK;
-	else if (err == BIG_NO_MEM)
-		rv = CKR_HOST_MEMORY;
-	else
-		rv = CKR_FUNCTION_FAILED;
 clean1:
 	return (rv);
 }
 
-CK_RV
-dsa_verify(soft_object_t *key, CK_BYTE_PTR data, CK_BYTE_PTR sig)
+static CK_RV
+local_dsa_verify(soft_object_t *key, CK_BYTE_PTR data, CK_BYTE_PTR sig)
 {
-
+	CK_RV rv;
 	uchar_t g[MAX_KEY_ATTR_BUFLEN];
 	uchar_t y[MAX_KEY_ATTR_BUFLEN];
 	uchar_t p[MAX_KEY_ATTR_BUFLEN];
@@ -327,21 +176,14 @@
 	uint_t ylen = sizeof (y);
 	uint_t plen = sizeof (p);
 	uint_t qlen = sizeof (q);
-	DSAkey dsakey;
-	BIGNUM msg, tmp1, tmp2, tmp3;
-	CK_RV rv;
+	DSAbytekey k;
 
-	rv = soft_get_public_value(key, CKA_SUBPRIME, q, &qlen);
+	rv = soft_get_public_value(key, CKA_PRIME, p, &plen);
 	if (rv != CKR_OK) {
 		goto clean1;
 	}
 
-	if (DSA_SUBPRIME_BYTES != qlen) {
-		rv = CKR_KEY_SIZE_RANGE;
-		goto clean1;
-	}
-
-	rv = soft_get_public_value(key, CKA_PRIME, p, &plen);
+	rv = soft_get_public_value(key, CKA_SUBPRIME, q, &qlen);
 	if (rv != CKR_OK) {
 		goto clean1;
 	}
@@ -351,99 +193,23 @@
 		goto clean1;
 	}
 
-	if (plen < glen) {
-		rv = CKR_KEY_SIZE_RANGE;
-		goto clean1;
-	}
-
 	rv = soft_get_public_value(key, CKA_VALUE, y, &ylen);
 	if (rv != CKR_OK) {
 		goto clean1;
 	}
 
-	if (plen < ylen) {
-		rv = CKR_KEY_SIZE_RANGE;
-		goto clean1;
-	}
-
-	if (DSA_key_init(&dsakey, plen * 8) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean1;
-	}
-
-	rv = CKR_HOST_MEMORY;
-	if (big_init(&msg, BIG_CHUNKS_FOR_160BITS) != BIG_OK) {
-		goto clean6;
-	}
-	if (big_init(&tmp1, 2 * CHARLEN2BIGNUMLEN(plen)) != BIG_OK) {
-		goto clean7;
-	}
-	if (big_init(&tmp2, CHARLEN2BIGNUMLEN(plen)) != BIG_OK) {
-		goto clean8;
-	}
-	if (big_init(&tmp3, 2 * BIG_CHUNKS_FOR_160BITS) != BIG_OK) {
-		goto clean9;
-	}
-
-	bytestring2bignum(&(dsakey.g), g, glen);
-	bytestring2bignum(&(dsakey.y), y, ylen);
-	bytestring2bignum(&(dsakey.p), p, plen);
-	bytestring2bignum(&(dsakey.q), q, DSA_SUBPRIME_BYTES);
-	bytestring2bignum(&(dsakey.r), (uchar_t *)sig, DSA_SUBPRIME_BYTES);
-	bytestring2bignum(&(dsakey.s), ((uchar_t *)sig) + DSA_SUBPRIME_BYTES,
-	    DSA_SUBPRIME_BYTES);
-	bytestring2bignum(&msg, (uchar_t *)data, DSA_SUBPRIME_BYTES);
-
-	if (big_ext_gcd_pos(NULL, &tmp2, NULL, &(dsakey.s), &(dsakey.q)) !=
-	    BIG_OK)
-		goto clean10;
-
-	if (tmp2.sign == -1)
-		if (big_add(&tmp2, &tmp2, &(dsakey.q)) != BIG_OK)
-			goto clean10;			/* tmp2 <- w */
+	k.prime = p;
+	k.prime_bits = CRYPTO_BYTES2BITS(plen);
+	k.subprime = q;
+	k.subprime_bits = CRYPTO_BYTES2BITS(qlen);
+	k.base = g;
+	k.base_bytes = glen;
+	k.public_y_bits = CRYPTO_BYTES2BITS(ylen);
+	k.public_y = y;
+	k.rfunc = NULL;
 
-	if (big_mul(&tmp1, &msg, &tmp2) != BIG_OK)
-		goto clean10;
-
-	if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.q)) != BIG_OK)
-		goto clean10;				/* tmp1 <- u_1 */
-
-	if (big_mul(&tmp2, &tmp2, &(dsakey.r)) != BIG_OK)
-		goto clean10;
-
-	if (big_div_pos(NULL, &tmp2, &tmp2, &(dsakey.q)) != BIG_OK)
-		goto clean10;				/* tmp2 <- u_2 */
-
-	if (big_modexp(&tmp1, &(dsakey.g), &tmp1, &(dsakey.p), NULL) != BIG_OK)
-		goto clean10;
-
-	if (big_modexp(&tmp2, &(dsakey.y), &tmp2, &(dsakey.p), NULL) != BIG_OK)
-		goto clean10;
-
-	if (big_mul(&tmp1, &tmp1, &tmp2) != BIG_OK)
-		goto clean10;
+	rv = dsa_verify(&k, data, sig);
 
-	if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.p)) != BIG_OK)
-		goto clean10;
-
-	if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.q)) != BIG_OK)
-		goto clean10;
-
-	if (big_cmp_abs(&tmp1, &(dsakey.r)) == 0)
-		rv = CKR_OK;
-	else
-		rv = CKR_SIGNATURE_INVALID;
-
-clean10:
-	big_finish(&tmp3);
-clean9:
-	big_finish(&tmp2);
-clean8:
-	big_finish(&tmp1);
-clean7:
-	big_finish(&msg);
-clean6:
-	DSA_key_finish(&dsakey);
 clean1:
 	return (rv);
 }
@@ -538,7 +304,7 @@
 		return (CKR_BUFFER_TOO_SMALL);
 	}
 
-	rv = dsa_sign(key, pData, ulDataLen, pSigned);
+	rv = local_dsa_sign(key, pData, ulDataLen, pSigned);
 	if (rv == CKR_OK) {
 		*pulSignedLen = DSA_SIGNATURE_LENGTH;
 	}
@@ -569,19 +335,19 @@
 		goto clean_exit;
 	}
 
+	/* Input data length needs to be 20 bytes. */
+	if (ulDataLen != DSA_SUBPRIME_BYTES) {
+		rv = CKR_DATA_LEN_RANGE;
+		goto clean_exit;
+	}
+
 	/* The signature length is always 40 bytes. */
 	if (ulSignatureLen != DSA_SIGNATURE_LENGTH) {
 		rv = CKR_SIGNATURE_LEN_RANGE;
 		goto clean_exit;
 	}
 
-	/* Input data length needs to be 20 bytes. */
-	if (ulDataLen != DSA_SUBPRIME_BYTES) {
-		rv = CKR_DATA_LEN_RANGE;
-		goto clean_exit;
-	}
-
-	rv = dsa_verify(key, pData, pSignature);
+	rv = local_dsa_verify(key, pData, pSignature);
 
 clean_exit:
 	(void) pthread_mutex_lock(&session_p->session_mutex);
@@ -635,7 +401,7 @@
 }
 
 
-CK_RV
+static CK_RV
 soft_genDSAkey_set_attribute(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
     uchar_t *value, uint32_t value_len, boolean_t public)
 {
@@ -644,7 +410,6 @@
 	biginteger_t *dst = NULL;
 	biginteger_t src;
 
-
 	switch (type) {
 
 	case CKA_VALUE:
@@ -676,13 +441,14 @@
 		break;
 	}
 
-	src.big_value_len = value_len;
+	/* Note: removal of preceding 0x00 imitates similar code in RSA */
+	while (value[0] == 0) {		/* remove preceding 0x00 */
+		value++;
+		value_len--;
+	}
 
-	if ((src.big_value = malloc(value_len)) == NULL) {
-		rv = CKR_HOST_MEMORY;
+	if ((rv = dup_bigint_attr(&src, value, value_len)) != CKR_OK)
 		goto cleanexit;
-	}
-	(void) memcpy(src.big_value, value, value_len);
 
 	/* Copy the attribute in the key object. */
 	copy_bigint_attr(&src, dst);
@@ -695,44 +461,20 @@
 
 
 CK_RV
-generate_dsa_key(DSAkey *key, boolean_t token_obj)
-{
-	BIG_ERR_CODE err;
-
-	do {
-		if ((err = random_bignum(&(key->x), DSA_SUBPRIME_BITS,
-		    token_obj)) != BIG_OK) {
-			return (convert_rv(err));
-		}
-	} while (big_cmp_abs(&(key->x), &(key->q)) > 0);
-
-	if ((err = big_modexp(&(key->y), &(key->g), (&key->x),
-	    (&key->p), NULL)) != BIG_OK)
-		return (convert_rv(err));
-
-	return (CKR_OK);
-}
-
-
-CK_RV
 soft_dsa_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
 {
-	BIG_ERR_CODE brv;
 	CK_RV rv;
-	uchar_t	prime[MAX_KEY_ATTR_BUFLEN];
+	uchar_t prime[MAX_KEY_ATTR_BUFLEN];
 	uint32_t prime_len = sizeof (prime);
 	uchar_t	subprime[MAX_KEY_ATTR_BUFLEN];
 	uint32_t subprime_len = sizeof (subprime);
 	uchar_t	base[MAX_KEY_ATTR_BUFLEN];
 	uint32_t base_len = sizeof (base);
-	uchar_t	*pubvalue;
-	uint32_t pubvalue_len;
-	uchar_t	*privalue;
-	uint32_t privalue_len;
-	DSAkey	dsakey = {0};
-
-	pubvalue = NULL;
-	privalue = NULL;
+	uchar_t	pubvalue[MAX_KEY_ATTR_BUFLEN];
+	uint32_t pubvalue_len = sizeof (pubvalue);
+	uchar_t	privalue[DSA_SUBPRIME_BYTES];
+	uint32_t privalue_len = sizeof (privalue);
+	DSAbytekey k;
 
 	if ((pubkey == NULL) || (prikey == NULL)) {
 		return (CKR_ARGUMENTS_BAD);
@@ -745,12 +487,6 @@
 		goto cleanexit;
 	}
 
-	if ((prime_len < MIN_DSA_KEY_LEN) ||
-	    (prime_len > MAX_DSA_KEY_LEN)) {
-		rv = CKR_ATTRIBUTE_VALUE_INVALID;
-		goto cleanexit;
-	}
-
 	rv = soft_get_public_value(pubkey, CKA_SUBPRIME, subprime,
 	    &subprime_len);
 	if (rv != CKR_OK) {
@@ -758,109 +494,60 @@
 		goto cleanexit;
 	}
 
-	if (subprime_len != DSA_SUBPRIME_BYTES) {
-		rv = CKR_ATTRIBUTE_VALUE_INVALID;
-		goto cleanexit;
-	}
-
 	rv = soft_get_public_value(pubkey, CKA_BASE, base, &base_len);
 	if (rv != CKR_OK) {
 		rv = CKR_TEMPLATE_INCOMPLETE;
 		goto cleanexit;
 	}
 
-	/*
-	 * initialize the dsa key
-	 * Note: big_extend takes length in words
-	 */
-	if ((brv = DSA_key_init(&dsakey, prime_len * 8)) != BIG_OK) {
-		rv = convert_rv(brv);
-		goto cleanexit;
-	}
+	/* Inputs to DSA key pair generation. */
+	k.prime = prime;
+	k.prime_bits = CRYPTO_BYTES2BITS(prime_len);
+	k.subprime = subprime;
+	k.subprime_bits = CRYPTO_BYTES2BITS(subprime_len);
+	k.base = base;
+	k.base_bytes = base_len;
+	k.rfunc = (IS_TOKEN_OBJECT(pubkey) || IS_TOKEN_OBJECT(prikey)) ?
+	    pkcs11_get_random : pkcs11_get_urandom;
 
-	if ((brv = big_extend(&dsakey.p,
-	    CHARLEN2BIGNUMLEN(prime_len))) != BIG_OK) {
-		rv = convert_rv(brv);
-		goto cleanexit;
-	}
+	/* Outputs from DSA key pair generation. */
+	k.public_y = pubvalue;
+	k.public_y_bits = CRYPTO_BYTES2BITS(pubvalue_len);
+	k.private_x = privalue;
+	k.private_x_bits = CRYPTO_BYTES2BITS(privalue_len);
 
-	bytestring2bignum(&dsakey.p, prime, prime_len);
+	rv = dsa_genkey_pair(&k);
 
-	if ((brv = big_extend(&dsakey.q, CHARLEN2BIGNUMLEN(subprime_len))) !=
-	    BIG_OK) {
-		rv = convert_rv(brv);
+	if (rv != CKR_OK) {
 		goto cleanexit;
 	}
 
-	bytestring2bignum(&dsakey.q, subprime, subprime_len);
-
-	if ((brv = big_extend(&dsakey.g, CHARLEN2BIGNUMLEN(base_len))) !=
-	    BIG_OK) {
-		rv = convert_rv(brv);
-		goto cleanexit;
-	}
-
-	bytestring2bignum(&dsakey.g, base, base_len);
-
-	/*
-	 * generate DSA key pair
-	 * Note: bignum.len is length of value in words
-	 */
-	if ((rv = generate_dsa_key(&dsakey, (IS_TOKEN_OBJECT(pubkey) ||
-	    IS_TOKEN_OBJECT(prikey)))) != CKR_OK) {
-		goto cleanexit;
-	}
-
-	pubvalue_len = prime_len;
-	if ((pubvalue = malloc(pubvalue_len)) == NULL) {
-		rv = CKR_HOST_MEMORY;
-		goto cleanexit;
-	}
-	bignum2bytestring(pubvalue, &dsakey.y, pubvalue_len);
-
-	privalue_len = DSA_SUBPRIME_BYTES;
-	if ((privalue = malloc(privalue_len)) == NULL) {
-		rv = CKR_HOST_MEMORY;
-		goto cleanexit;
-	}
-	bignum2bytestring(privalue, &dsakey.x, privalue_len);
-
 	/* Update attribute in public key. */
 	if ((rv = soft_genDSAkey_set_attribute(pubkey, CKA_VALUE,
-	    pubvalue, pubvalue_len, B_TRUE)) != CKR_OK) {
+	    pubvalue, CRYPTO_BITS2BYTES(k.public_y_bits), B_TRUE)) != CKR_OK) {
 		goto cleanexit;
 	}
 	/* Update attributes in private key. */
 	if ((rv = soft_genDSAkey_set_attribute(prikey, CKA_PRIME,
-	    prime, prime_len, B_FALSE)) != CKR_OK) {
+	    prime, CRYPTO_BITS2BYTES(k.prime_bits), B_FALSE)) != CKR_OK) {
 		goto cleanexit;
 	}
 
-	if ((rv = soft_genDSAkey_set_attribute(prikey, CKA_SUBPRIME,
-	    subprime, subprime_len, B_FALSE)) != CKR_OK) {
+	if ((rv = soft_genDSAkey_set_attribute(prikey, CKA_SUBPRIME, subprime,
+	    CRYPTO_BITS2BYTES(k.subprime_bits), B_FALSE)) != CKR_OK) {
 		goto cleanexit;
 	}
 
 	if ((rv = soft_genDSAkey_set_attribute(prikey, CKA_BASE,
-	    base, base_len, B_FALSE)) != CKR_OK) {
+	    base, k.base_bytes, B_FALSE)) != CKR_OK) {
 		goto cleanexit;
 	}
 
-	if ((rv = soft_genDSAkey_set_attribute(prikey, CKA_VALUE,
-	    privalue, privalue_len, B_FALSE)) != CKR_OK) {
+	if ((rv = soft_genDSAkey_set_attribute(prikey, CKA_VALUE, privalue,
+	    CRYPTO_BITS2BYTES(k.private_x_bits), B_FALSE)) != CKR_OK) {
 		goto cleanexit;
 	}
 
 cleanexit:
-	DSA_key_finish(&dsakey);
-
-	if (pubvalue != NULL) {
-		free(pubvalue);
-	}
-
-	if (privalue != NULL) {
-		free(privalue);
-	}
-
 	return (rv);
 }
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.h	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.h	Mon Jun 07 08:54:25 2010 -0700
@@ -18,53 +18,31 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef _SOFTDSA_H
 #define	_SOFTDSA_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #include <sys/types.h>
 #include <security/pkcs11t.h>
-#include <bignum.h>
+#include <padding.h>
+#define	_DSA_FIPS_POST
+#include <dsa_impl.h>
 #include "softObject.h"
 #include "softSession.h"
 
-/* DSA Signature is always 40 bytes */
-#define	DSA_SIGNATURE_LENGTH	40
-#define	MAX_DSA_KEY_LEN		(1024 >> 3)
-#define	MIN_DSA_KEY_LEN		(512 >> 3)
-
-#define	DSA_SUBPRIME_BITS	160
-#define	DSA_SUBPRIME_BYTES	(DSA_SUBPRIME_BITS >> 3)
 
 typedef struct soft_dsa_ctx {
 	soft_object_t *key;
 } soft_dsa_ctx_t;
 
-typedef struct {
-	int 	size;		/* key size in bits */
-	BIGNUM	q;		/* q (160-bit prime) */
-	BIGNUM	p;		/* p (<size-bit> prime) */
-	BIGNUM	g;		/* g (the base) */
-	BIGNUM	x;		/* private key (< q) */
-	BIGNUM	y;		/* = g^x mod p */
-	BIGNUM	k;		/* k (random number < q) */
-	BIGNUM	r;		/* r (signiture 1st part) */
-	BIGNUM	s;		/* s (signiture 2nd part) */
-	BIGNUM	v;		/* v (verification value - should be = r ) */
-	BIGNUM	p_rr;		/* 2^(2*(32*p->len)) mod p */
-	BIGNUM	q_rr;		/* 2^(2*(32*q->len)) mod q */
-} DSAkey;
-
 
 /*
  * Function Prototypes.
@@ -81,10 +59,6 @@
 CK_RV soft_dsa_sign(soft_session_t *, CK_BYTE_PTR, CK_ULONG,
 	CK_BYTE_PTR, CK_ULONG_PTR);
 
-BIG_ERR_CODE DSA_key_init(DSAkey *, int);
-
-void DSA_key_finish(DSAkey *);
-
 CK_RV soft_dsa_genkey_pair(soft_object_t *, soft_object_t *);
 
 CK_RV soft_dsa_digest_sign_common(soft_session_t *, CK_BYTE_PTR,
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDecryptUtil.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDecryptUtil.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,13 +18,11 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
@@ -44,24 +42,18 @@
  */
 CK_RV
 soft_remove_pkcs7_padding(CK_BYTE *pData, CK_ULONG padded_len,
-    CK_ULONG *pulDataLen, int block_size)
+    CK_ULONG *pulDataLen)
 {
-
-	CK_BYTE  pad_value;
-	ulong_t i;
-
-	pad_value = pData[padded_len - 1];
-
+	CK_RV	rv;
 
-	/* Make sure there is a valid padding value. */
-	if ((pad_value == 0) || (pad_value > block_size))
-		return (CKR_ENCRYPTED_DATA_INVALID);
+#ifdef	__sparcv9
+	if ((rv = pkcs7_decode(pData, (&padded_len))) != CKR_OK)
+#else	/* !__sparcv9 */
+	if ((rv = pkcs7_decode(pData, (size_t *)(&padded_len))) != CKR_OK)
+#endif	/* __sparcv9 */
+		return (rv);
 
-	for (i = padded_len - pad_value; i < padded_len; i++)
-		if (pad_value != pData[i])
-			return (CKR_ENCRYPTED_DATA_INVALID);
-
-	*pulDataLen = padded_len - pad_value;
+	*pulDataLen = padded_len;
 	return (CKR_OK);
 }
 
@@ -604,7 +596,7 @@
 				 * plaintext.
 				 */
 				rv = soft_remove_pkcs7_padding(pLastPart,
-				    DES_BLOCK_LEN, &out_len, DES_BLOCK_LEN);
+				    DES_BLOCK_LEN, &out_len);
 				if (rv != CKR_OK)
 					*pulLastPartLen = 0;
 				else
@@ -713,7 +705,7 @@
 				 * plaintext.
 				 */
 				rv = soft_remove_pkcs7_padding(pLastPart,
-				    AES_BLOCK_LEN, &out_len, AES_BLOCK_LEN);
+				    AES_BLOCK_LEN, &out_len);
 				if (rv != CKR_OK)
 					*pulLastPartLen = 0;
 				else
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <pthread.h>
@@ -43,15 +43,7 @@
 void
 soft_add_pkcs7_padding(CK_BYTE *buf, int block_size, CK_ULONG data_len)
 {
-
-	ulong_t i, pad_len;
-	CK_BYTE pad_value;
-
-	pad_len = block_size - (data_len % block_size);
-	pad_value = (CK_BYTE)pad_len;
-
-	for (i = 0; i < pad_len; i++)
-		buf[i] = pad_value;
+	(void) pkcs7_encode(NULL, data_len, buf, block_size, block_size);
 }
 
 /*
@@ -844,7 +836,7 @@
  * or by the 2nd tier of session close routine. Since the 1st tier
  * caller will always call this function without locking the session
  * mutex and the 2nd tier caller will call with the lock, we add the
- * third parameter "lock_held" to distiguish this case.
+ * third parameter "lock_held" to distinguish this case.
  */
 void
 soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt,
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSA.h	Mon Jun 07 11:37:25 2010 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef	_FIPS_DSA_H
-#define	_FIPS_DSA_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define	FIPS_DSA_DIGEST_LENGTH		20 /*  160-bits */
-#define	FIPS_DSA_SEED_LENGTH		20 /*  160-bits */
-#define	FIPS_DSA_SUBPRIME_LENGTH	20 /*  160-bits */
-#define	FIPS_DSA_SIGNATURE_LENGTH	40 /*  320-bits */
-#define	FIPS_DSA_PRIME_LENGTH		128 /* 1024-bits */
-#define	FIPS_DSA_BASE_LENGTH		128 /* 1024-bits */
-
-typedef struct DSAParams_s {
-	uint8_t		*prime;
-	int		prime_len;
-	uint8_t		*subprime;
-	int		subprime_len;
-	uint8_t		*base;
-	int		base_len;
-} DSAParams_t;
-
-typedef struct fips_key_s {
-	uint8_t		*key;
-	int		key_len;
-} fips_key_t;
-
-
-/* DSA functions */
-extern CK_RV fips_generate_dsa_key(DSAkey *, uint8_t *, int);
-extern CK_RV fips_dsa_genkey_pair(DSAParams_t *,
-	fips_key_t *, fips_key_t *, uint8_t *, int);
-extern CK_RV fips_dsa_digest_sign(DSAParams_t *,
-	fips_key_t *, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, uint8_t *, int);
-extern CK_RV fips_dsa_verify(DSAParams_t *, fips_key_t *,
-	CK_BYTE_PTR, CK_BYTE_PTR);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif /* _FIPS_DSA_H */
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSAUtil.c	Mon Jun 07 11:37:25 2010 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,509 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/errno.h>
-#include <sys/fcntl.h>
-#include <sys/time.h>
-#include <sys/unistd.h>
-#include <sys/kmem.h>
-#include <sys/systm.h>
-#include <sys/sysmacros.h>
-#include <sys/sha1.h>
-#define	_SHA2_IMPL
-#include <sys/sha2.h>
-#include <sys/crypto/common.h>
-#include <modes/modes.h>
-#include <bignum.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <stdio.h>
-#include <security/cryptoki.h>
-#include <cryptoutil.h>
-#include "softCrypt.h"
-#include "softGlobal.h"
-#include "softRSA.h"
-#include "softDSA.h"
-#include "softRandom.h"
-#include "softOps.h"
-#include "softMAC.h"
-#include "softFipsDSA.h"
-#include <sha1_impl.h>
-
-CK_RV
-fips_generate_dsa_key(DSAkey *key, uint8_t *seed, int seed_len)
-{
-	BIG_ERR_CODE err;
-
-
-	bytestring2bignum(&key->x, seed, seed_len);
-
-	/* Compute public key y = g**x mod p */
-	if ((err = big_modexp(&(key->y), &(key->g), (&key->x),
-	    (&key->p), NULL)) != BIG_OK)
-		return (convert_rv(err));
-
-	return (CKR_OK);
-}
-
-CK_RV
-fips_dsa_genkey_pair(DSAParams_t *dsa_params, fips_key_t *pubkey,
-	fips_key_t *prikey, uint8_t *seed, int seed_len)
-{
-	BIG_ERR_CODE brv;
-	CK_RV rv;
-	DSAkey	dsakey = {0};
-
-	/*
-	 * initialize the dsa key
-	 * Note: big_extend takes length in words
-	 */
-	if ((brv = DSA_key_init(&dsakey, dsa_params->prime_len * 8))
-	    != BIG_OK) {
-		rv = convert_rv(brv);
-		goto cleanexit;
-	}
-
-	if ((brv = big_extend(&dsakey.p,
-	    CHARLEN2BIGNUMLEN(dsa_params->prime_len))) != BIG_OK) {
-		rv = convert_rv(brv);
-		goto cleanexit;
-	}
-
-	bytestring2bignum(&dsakey.p, dsa_params->prime, dsa_params->prime_len);
-
-	if ((brv = big_extend(&dsakey.q,
-	    CHARLEN2BIGNUMLEN(dsa_params->subprime_len))) != BIG_OK) {
-		rv = convert_rv(brv);
-		goto cleanexit;
-	}
-
-	bytestring2bignum(&dsakey.q, dsa_params->subprime,
-	    dsa_params->subprime_len);
-
-	if ((brv = big_extend(&dsakey.g,
-	    CHARLEN2BIGNUMLEN(dsa_params->base_len))) != BIG_OK) {
-		rv = convert_rv(brv);
-		goto cleanexit;
-	}
-
-	bytestring2bignum(&dsakey.g, dsa_params->base, dsa_params->base_len);
-
-	/*
-	 * generate DSA key pair
-	 * Note: bignum.len is length of value in words
-	 */
-	if ((rv = fips_generate_dsa_key(&dsakey, seed, seed_len)) != CKR_OK) {
-		goto cleanexit;
-	}
-
-	/* pubkey->key_len = dsakey.y.len * (int)sizeof (uint32_t); */
-	pubkey->key_len = dsa_params->prime_len;
-	if ((pubkey->key = malloc(pubkey->key_len)) == NULL) {
-		rv = CKR_HOST_MEMORY;
-		goto cleanexit;
-	}
-	bignum2bytestring(pubkey->key, &dsakey.y, pubkey->key_len);
-
-	/* prikey->key_len = dsakey.x.len * (int)sizeof (uint32_t); */
-	prikey->key_len = DSA_SUBPRIME_BYTES;
-	if ((prikey->key = malloc(prikey->key_len)) == NULL) {
-		rv = CKR_HOST_MEMORY;
-		goto cleanexit;
-	}
-	bignum2bytestring(prikey->key, &dsakey.x, prikey->key_len);
-	DSA_key_finish(&dsakey);
-	return (CKR_OK);
-
-cleanexit:
-	DSA_key_finish(&dsakey);
-
-	if (pubkey->key != NULL) {
-		free(pubkey->key);
-	}
-
-	if (prikey->key != NULL) {
-		free(prikey->key);
-	}
-
-	return (rv);
-}
-
-CK_RV
-fips_dsa_digest_sign(DSAParams_t *dsa_params, fips_key_t *key,
-	CK_BYTE_PTR in, CK_ULONG inlen, CK_BYTE_PTR out,
-	uint8_t *seed, int seed_len)
-{
-
-
-	DSAkey dsakey;
-	BIGNUM msg, tmp, tmp1, tmp2;
-	BIG_ERR_CODE err;
-	CK_RV rv = CKR_OK;
-	SHA1_CTX *sha1_context = NULL;
-	uint8_t sha1_computed_digest[FIPS_DSA_DIGEST_LENGTH];
-
-	sha1_context = fips_sha1_build_context();
-	if (sha1_context == NULL)
-		return (CKR_HOST_MEMORY);
-
-	rv = fips_sha1_hash(sha1_context, in, inlen, sha1_computed_digest);
-
-	if ((err = DSA_key_init(&dsakey, dsa_params->prime_len * 8)) !=
-	    BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean1;
-	}
-
-	if ((err = big_init(&msg, BIG_CHUNKS_FOR_160BITS)) != BIG_OK) {
-		goto clean2;
-	}
-	if ((err = big_init(&tmp, CHARLEN2BIGNUMLEN(dsa_params->prime_len) +
-	    2 * BIG_CHUNKS_FOR_160BITS + 1)) != BIG_OK) {
-		goto clean3;
-	}
-	if ((err = big_init(&tmp1, 2 * BIG_CHUNKS_FOR_160BITS + 1)) != BIG_OK) {
-		goto clean4;
-	}
-	if ((err = big_init(&tmp2, BIG_CHUNKS_FOR_160BITS)) != BIG_OK) {
-		goto clean5;
-	}
-
-	bytestring2bignum(&(dsakey.g), dsa_params->base,
-	    dsa_params->prime_len);
-	bytestring2bignum(&(dsakey.x), key->key, seed_len);
-	bytestring2bignum(&(dsakey.p), dsa_params->prime,
-	    dsa_params->prime_len);
-	bytestring2bignum(&(dsakey.q), dsa_params->subprime,
-	    DSA_SUBPRIME_BYTES);
-	bytestring2bignum(&msg, (uchar_t *)sha1_computed_digest,
-	    FIPS_DSA_DIGEST_LENGTH);
-
-	bytestring2bignum(&(dsakey.k), seed, seed_len);
-
-	if ((err = big_div_pos(NULL, &(dsakey.k), &(dsakey.k),
-	    &(dsakey.q))) != BIG_OK)
-		goto clean6;
-
-	if ((err = big_modexp(&tmp, &(dsakey.g), &(dsakey.k), &(dsakey.p),
-	    NULL)) != BIG_OK)
-		goto clean6;
-
-	if ((err = big_div_pos(NULL, &(dsakey.r), &tmp, &(dsakey.q))) !=
-	    BIG_OK)
-		goto clean6;
-
-	if ((err = big_ext_gcd_pos(NULL, NULL, &tmp, &(dsakey.q),
-	    &(dsakey.k))) != BIG_OK)
-		goto clean6;
-
-	if (tmp.sign == -1)
-		if ((err = big_add(&tmp, &tmp, &(dsakey.q))) != BIG_OK)
-			goto clean6;			/* tmp <- k^-1 */
-
-	if ((err = big_mul(&tmp1, &(dsakey.x), &(dsakey.r))) != BIG_OK)
-		goto clean6;
-
-	if ((err = big_add(&tmp1, &tmp1, &msg)) != BIG_OK)
-		goto clean6;
-
-	if ((err = big_mul(&tmp, &tmp1, &tmp)) != BIG_OK)
-		goto clean6;
-
-	if ((err = big_div_pos(NULL, &(dsakey.s), &tmp, &(dsakey.q))) !=
-	    BIG_OK)
-		goto clean6;
-
-	bignum2bytestring((uchar_t *)out, &(dsakey.r), 20);
-	bignum2bytestring((uchar_t *)out + 20, &(dsakey.s), 20);
-
-	err = BIG_OK;
-
-clean6:
-	big_finish(&tmp2);
-clean5:
-	big_finish(&tmp1);
-clean4:
-	big_finish(&tmp);
-clean3:
-	big_finish(&msg);
-clean2:
-	DSA_key_finish(&dsakey);
-	if (err == BIG_OK)
-		rv = CKR_OK;
-	else if (err == BIG_NO_MEM)
-		rv = CKR_HOST_MEMORY;
-	else
-		rv = CKR_FUNCTION_FAILED;
-clean1:
-	free(sha1_context);
-	return (rv);
-}
-
-CK_RV
-fips_dsa_verify(DSAParams_t *dsa_params, fips_key_t *key,
-	CK_BYTE_PTR data, CK_BYTE_PTR sig)
-{
-
-	DSAkey dsakey;
-	BIGNUM msg, tmp1, tmp2, tmp3;
-	CK_RV rv = CKR_OK;
-	SHA1_CTX *sha1_context = NULL;
-	uint8_t sha1_computed_digest[FIPS_DSA_DIGEST_LENGTH];
-
-	sha1_context = fips_sha1_build_context();
-	if (sha1_context == NULL)
-		return (CKR_HOST_MEMORY);
-
-	rv = fips_sha1_hash(sha1_context, data,
-	    FIPS_DSA_DIGEST_LENGTH, sha1_computed_digest);
-
-	if (DSA_key_init(&dsakey, dsa_params->prime_len * 8) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean1;
-	}
-
-	rv = CKR_HOST_MEMORY;
-	if (big_init(&msg, BIG_CHUNKS_FOR_160BITS) != BIG_OK) {
-		goto clean6;
-	}
-	if (big_init(&tmp1, 2 * CHARLEN2BIGNUMLEN(dsa_params->prime_len)) !=
-	    BIG_OK) {
-		goto clean7;
-	}
-	if (big_init(&tmp2, CHARLEN2BIGNUMLEN(dsa_params->prime_len)) !=
-	    BIG_OK) {
-		goto clean8;
-	}
-	if (big_init(&tmp3, 2 * BIG_CHUNKS_FOR_160BITS) != BIG_OK) {
-		goto clean9;
-	}
-
-	bytestring2bignum(&(dsakey.g), dsa_params->base,
-	    dsa_params->base_len);
-	bytestring2bignum(&(dsakey.y), key->key, key->key_len);
-	bytestring2bignum(&(dsakey.p), dsa_params->prime,
-	    dsa_params->prime_len);
-	bytestring2bignum(&(dsakey.q), dsa_params->subprime,
-	    DSA_SUBPRIME_BYTES);
-	bytestring2bignum(&(dsakey.r), (uchar_t *)sig, 20);
-	bytestring2bignum(&(dsakey.s), ((uchar_t *)sig) + 20, 20);
-	bytestring2bignum(&msg, (uchar_t *)sha1_computed_digest,
-	    FIPS_DSA_DIGEST_LENGTH);
-
-	if (big_ext_gcd_pos(NULL, &tmp2, NULL, &(dsakey.s), &(dsakey.q)) !=
-	    BIG_OK)
-		goto clean10;
-
-	if (tmp2.sign == -1)
-		if (big_add(&tmp2, &tmp2, &(dsakey.q)) != BIG_OK)
-			goto clean10;			/* tmp2 <- w */
-
-	if (big_mul(&tmp1, &msg, &tmp2) != BIG_OK)
-		goto clean10;
-
-	if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.q)) != BIG_OK)
-		goto clean10;				/* tmp1 <- u_1 */
-
-	if (big_mul(&tmp2, &tmp2, &(dsakey.r)) != BIG_OK)
-		goto clean10;
-
-	if (big_div_pos(NULL, &tmp2, &tmp2, &(dsakey.q)) != BIG_OK)
-		goto clean10;				/* tmp2 <- u_2 */
-
-	if (big_modexp(&tmp1, &(dsakey.g), &tmp1, &(dsakey.p), NULL) !=
-	    BIG_OK)
-		goto clean10;
-
-	if (big_modexp(&tmp2, &(dsakey.y), &tmp2, &(dsakey.p), NULL) !=
-	    BIG_OK)
-		goto clean10;
-
-	if (big_mul(&tmp1, &tmp1, &tmp2) != BIG_OK)
-		goto clean10;
-
-	if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.p)) != BIG_OK)
-		goto clean10;
-
-	if (big_div_pos(NULL, &tmp1, &tmp1, &(dsakey.q)) != BIG_OK)
-		goto clean10;
-
-	if (big_cmp_abs(&tmp1, &(dsakey.r)) == 0)
-		rv = CKR_OK;
-	else
-		rv = CKR_SIGNATURE_INVALID;
-
-clean10:
-	big_finish(&tmp3);
-clean9:
-	big_finish(&tmp2);
-clean8:
-	big_finish(&tmp1);
-clean7:
-	big_finish(&msg);
-clean6:
-	DSA_key_finish(&dsakey);
-clean1:
-	free(sha1_context);
-	return (rv);
-}
-
-/*
- * DSA Power-On SelfTest(s).
- */
-CK_RV
-soft_fips_dsa_post(void)
-{
-	/* DSA Known P (1024-bits), Q (160-bits), and G (1024-bits) Values. */
-	static uint8_t dsa_P[] = {
-		0x80, 0xb0, 0xd1, 0x9d, 0x6e, 0xa4, 0xf3, 0x28,
-		0x9f, 0x24, 0xa9, 0x8a, 0x49, 0xd0, 0x0c, 0x63,
-		0xe8, 0x59, 0x04, 0xf9, 0x89, 0x4a, 0x5e, 0xc0,
-		0x6d, 0xd2, 0x67, 0x6b, 0x37, 0x81, 0x83, 0x0c,
-		0xfe, 0x3a, 0x8a, 0xfd, 0xa0, 0x3b, 0x08, 0x91,
-		0x1c, 0xcb, 0xb5, 0x63, 0xb0, 0x1c, 0x70, 0xd0,
-		0xae, 0xe1, 0x60, 0x2e, 0x12, 0xeb, 0x54, 0xc7,
-		0xcf, 0xc6, 0xcc, 0xae, 0x97, 0x52, 0x32, 0x63,
-		0xd3, 0xeb, 0x55, 0xea, 0x2f, 0x4c, 0xd5, 0xd7,
-		0x3f, 0xda, 0xec, 0x49, 0x27, 0x0b, 0x14, 0x56,
-		0xc5, 0x09, 0xbe, 0x4d, 0x09, 0x15, 0x75, 0x2b,
-		0xa3, 0x42, 0x0d, 0x03, 0x71, 0xdf, 0x0f, 0xf4,
-		0x0e, 0xe9, 0x0c, 0x46, 0x93, 0x3d, 0x3f, 0xa6,
-		0x6c, 0xdb, 0xca, 0xe5, 0xac, 0x96, 0xc8, 0x64,
-		0x5c, 0xec, 0x4b, 0x35, 0x65, 0xfc, 0xfb, 0x5a,
-		0x1b, 0x04, 0x1b, 0xa1, 0x0e, 0xfd, 0x88, 0x15
-	};
-
-	static uint8_t dsa_Q[] = {
-		0xad, 0x22, 0x59, 0xdf, 0xe5, 0xec, 0x4c, 0x6e,
-		0xf9, 0x43, 0xf0, 0x4b, 0x2d, 0x50, 0x51, 0xc6,
-		0x91, 0x99, 0x8b, 0xcf
-	};
-
-	static uint8_t dsa_G[] = {
-		0x78, 0x6e, 0xa9, 0xd8, 0xcd, 0x4a, 0x85, 0xa4,
-		0x45, 0xb6, 0x6e, 0x5d, 0x21, 0x50, 0x61, 0xf6,
-		0x5f, 0xdf, 0x5c, 0x7a, 0xde, 0x0d, 0x19, 0xd3,
-		0xc1, 0x3b, 0x14, 0xcc, 0x8e, 0xed, 0xdb, 0x17,
-		0xb6, 0xca, 0xba, 0x86, 0xa9, 0xea, 0x51, 0x2d,
-		0xc1, 0xa9, 0x16, 0xda, 0xf8, 0x7b, 0x59, 0x8a,
-		0xdf, 0xcb, 0xa4, 0x67, 0x00, 0x44, 0xea, 0x24,
-		0x73, 0xe5, 0xcb, 0x4b, 0xaf, 0x2a, 0x31, 0x25,
-		0x22, 0x28, 0x3f, 0x16, 0x10, 0x82, 0xf7, 0xeb,
-		0x94, 0x0d, 0xdd, 0x09, 0x22, 0x14, 0x08, 0x79,
-		0xba, 0x11, 0x0b, 0xf1, 0xff, 0x2d, 0x67, 0xac,
-		0xeb, 0xb6, 0x55, 0x51, 0x69, 0x97, 0xa7, 0x25,
-		0x6b, 0x9c, 0xa0, 0x9b, 0xd5, 0x08, 0x9b, 0x27,
-		0x42, 0x1c, 0x7a, 0x69, 0x57, 0xe6, 0x2e, 0xed,
-		0xa9, 0x5b, 0x25, 0xe8, 0x1f, 0xd2, 0xed, 0x1f,
-		0xdf, 0xe7, 0x80, 0x17, 0xba, 0x0d, 0x4d, 0x38
-	};
-
-	/*
-	 * DSA Known Random Values (known random key block is 160-bits)
-	 * and (known random signature block is 160-bits).
-	 */
-	static uint8_t dsa_known_random_key_block[] = {
-		"This is DSA RNG key!"
-	};
-
-	static uint8_t dsa_known_random_signature_block[] = {
-		"Random DSA Signature"
-	};
-
-	/* DSA Known Digest (160-bits) */
-	static uint8_t dsa_known_digest[] = {
-		"DSA Signature Digest"
-	};
-
-	/* DSA Known Signature (320-bits). */
-	static uint8_t dsa_known_signature[] = {
-		0x25, 0x7c, 0x3a, 0x79, 0x32, 0x45, 0xb7, 0x32,
-		0x70, 0xca, 0x62, 0x63, 0x2b, 0xf6, 0x29, 0x2c,
-		0x22, 0x2a, 0x03, 0xce, 0x65, 0x02, 0x72, 0x5a,
-		0x66, 0x29, 0xcf, 0x56, 0xe6, 0xdf, 0xb0, 0xcc,
-		0x53, 0x72, 0x56, 0x70, 0x92, 0xb5, 0x45, 0x75
-
-	};
-
-	/* DSA variables. */
-	DSAParams_t	dsa_params;
-	CK_RV rv = CKR_OK;
-
-	fips_key_t dsa_private_key;
-	fips_key_t dsa_public_key;
-	uint8_t dsa_computed_signature[FIPS_DSA_SIGNATURE_LENGTH];
-
-	dsa_params.prime = dsa_P;
-	dsa_params.prime_len = FIPS_DSA_PRIME_LENGTH;
-	dsa_params.subprime = dsa_Q;
-	dsa_params.subprime_len = FIPS_DSA_SUBPRIME_LENGTH;
-	dsa_params.base = dsa_G;
-	dsa_params.base_len = FIPS_DSA_BASE_LENGTH;
-
-
-	/* Generate a DSA public/private key pair. */
-	rv = fips_dsa_genkey_pair(&dsa_params, &dsa_public_key,
-	    &dsa_private_key, dsa_known_random_key_block,
-	    FIPS_DSA_SEED_LENGTH);
-
-	if (rv != CKR_OK)
-		return (CKR_DEVICE_ERROR);
-
-	/*
-	 * DSA Known Answer Signature Test
-	 */
-
-	/* Perform DSA signature process. */
-	rv = fips_dsa_digest_sign(&dsa_params, &dsa_private_key,
-	    dsa_known_digest, FIPS_DSA_DIGEST_LENGTH,
-	    dsa_computed_signature, dsa_known_random_signature_block,
-	    FIPS_DSA_SEED_LENGTH);
-
-	if ((rv != CKR_OK) ||
-	    (memcmp(dsa_computed_signature, dsa_known_signature,
-	    FIPS_DSA_SIGNATURE_LENGTH) != 0)) {
-		goto clean;
-	}
-
-	/*
-	 * DSA Known Answer Verification Test
-	 */
-
-	/* Perform DSA verification process. */
-	rv = fips_dsa_verify(&dsa_params, &dsa_public_key,
-	    dsa_known_digest, dsa_computed_signature);
-
-clean:
-	free(dsa_private_key.key);
-	free(dsa_public_key.key);
-
-	if (rv != CKR_OK)
-		return (CKR_DEVICE_ERROR);
-	else
-		return (CKR_OK);
-
-}
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPost.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPost.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <stdlib.h>
@@ -35,6 +35,8 @@
 #define	_AES_FIPS_POST
 #define	_DES_FIPS_POST
 #include "softCrypt.h"
+#define	_DSA_FIPS_POST
+#include <dsa_impl.h>
 #define	_RSA_FIPS_POST
 #include <rsa_impl.h>
 #include <sha1_impl.h>
@@ -43,7 +45,6 @@
 
 
 extern int fips_ecdsa_post(void);
-extern CK_RV soft_fips_dsa_post(void);
 
 
 /*
@@ -143,7 +144,7 @@
 	 * 1. DSA Sign on SHA-1 digest
 	 * 2. DSA Verification
 	 */
-	rv = soft_fips_dsa_post();
+	rv = fips_dsa_post();
 
 	if (rv != CKR_OK)
 		return (rv);
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPostUtil.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPostUtil.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <sys/types.h>
@@ -36,7 +36,6 @@
 #include <sys/sha2.h>
 #include <sys/crypto/common.h>
 #include <modes/modes.h>
-#include <bignum.h>
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
@@ -47,12 +46,10 @@
 #include "softGlobal.h"
 #include "softRSA.h"
 #include "softDSA.h"
-#include "softRandom.h"
 #include "softOps.h"
 #include "softMAC.h"
 #include <fips_post.h>
 
-#define	FIPS_DSA_SIGNATURE_LENGTH	40 /*  320-bits */
 #define	MAX_ECKEY_LEN		72
 
 
@@ -62,7 +59,7 @@
  * This function returns
  *   CKR_OK               if pairwise consistency check passed
  *   CKR_GENERAL_ERROR    if pairwise consistency check failed
- *   other error codes    if paiswise consistency check could not be
+ *   other error codes    if pairwise consistency check could not be
  *                        performed, for example, CKR_HOST_MEMORY.
  *
  *                      Key type    Mechanism type
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.h	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.h	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef	_SOFTOBJECT_H
@@ -922,6 +922,8 @@
 CK_RV get_bigint_attr_from_template(biginteger_t *big,
 	CK_ATTRIBUTE_PTR template);
 
+CK_RV dup_bigint_attr(biginteger_t *bi, CK_BYTE *buf, CK_ULONG buflen);
+
 #ifdef	__cplusplus
 }
 #endif
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObjectUtil.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObjectUtil.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <pthread.h>
@@ -1493,3 +1493,14 @@
 	delete_all_objs_in_list(added_objs_list);
 	return (rv);
 }
+
+CK_RV
+dup_bigint_attr(biginteger_t *bi, CK_BYTE *buf, CK_ULONG buflen)
+{
+	bi->big_value_len = buflen;
+	if ((bi->big_value = malloc(buflen)) == NULL) {
+		return (CKR_HOST_MEMORY);
+	}
+	(void) memcpy(bi->big_value, buf, buflen);
+	return (CKR_OK);
+}
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,27 +18,24 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
 #include <sys/types.h>
 #include <security/cryptoki.h>
-#include <bignum.h>
+#include <cryptoutil.h>
 #include "softGlobal.h"
 #include "softSession.h"
 #include "softObject.h"
 #include "softOps.h"
 #include "softRSA.h"
 #include "softMAC.h"
-#include "softRandom.h"
 #include "softCrypt.h"
 
 CK_RV
@@ -54,8 +51,7 @@
 	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
 	uint32_t expo_len = sizeof (expo);
 	uint32_t modulus_len = sizeof (modulus);
-	BIGNUM msg;
-	RSAkey *rsakey;
+	RSAbytekey k;
 
 	if (realpublic) {
 		rv = soft_get_public_value(key, CKA_PUBLIC_EXPONENT, expo,
@@ -76,58 +72,14 @@
 		goto clean1;
 	}
 
-	if (expo_len > modulus_len) {
-		rv = CKR_KEY_SIZE_RANGE;
-		goto clean1;
-	}
-
-	rsakey = calloc(1, sizeof (RSAkey));
-	if (rsakey == NULL) {
-		rv = CKR_HOST_MEMORY;
-		goto clean1;
-	}
-
-	if (RSA_key_init(rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean4;
-	}
-
-	/* Size for big_init is in BIG_CHUNK_TYPE words. */
-	if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean5;
-	}
-
-	/* Convert octet string exponent to big integer format. */
-	bytestring2bignum(&(rsakey->e), expo, expo_len);
+	k.modulus = modulus;
+	k.modulus_bits = CRYPTO_BYTES2BITS(modulus_len);
+	k.pubexpo = expo;
+	k.pubexpo_bytes = expo_len;
+	k.rfunc = NULL;
 
-	/* Convert octet string modulus to big integer format. */
-	bytestring2bignum(&(rsakey->n), modulus, modulus_len);
-
-	/* Convert octet string input data to big integer format. */
-	bytestring2bignum(&msg, (uchar_t *)in, in_len);
-
-	if (big_cmp_abs(&msg, &(rsakey->n)) > 0) {
-		rv = CKR_DATA_LEN_RANGE;
-		goto clean6;
-	}
+	rv = rsa_encrypt(&k, in, in_len, out);
 
-	/* Perform RSA computation on big integer input data. */
-	if (big_modexp(&msg, &msg, &(rsakey->e), &(rsakey->n), NULL) !=
-	    BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean6;
-	}
-
-	/* Convert the big integer output data to octet string. */
-	bignum2bytestring((uchar_t *)out, &msg, modulus_len);
-
-clean6:
-	big_finish(&msg);
-clean5:
-	RSA_key_finish(rsakey);
-clean4:
-	free(rsakey);
 clean1:
 
 /* EXPORT DELETE END */
@@ -157,8 +109,7 @@
 	uint32_t expo1_len = sizeof (expo1);
 	uint32_t expo2_len = sizeof (expo2);
 	uint32_t coef_len = sizeof (coef);
-	BIGNUM msg;
-	RSAkey *rsakey;
+	RSAbytekey k;
 
 	rv = soft_get_private_value(key, CKA_MODULUS, modulus, &modulus_len);
 	if (rv != CKR_OK) {
@@ -215,66 +166,22 @@
 			goto clean1;
 	}
 
-	rsakey = calloc(1, sizeof (RSAkey));
-	if (rsakey == NULL) {
-		rv = CKR_HOST_MEMORY;
-		goto clean1;
-	}
-
-	/* psize and qsize for RSA_key_init is in bits. */
-	if (RSA_key_init(rsakey, prime2_len * 8, prime1_len * 8) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean8;
-	}
-
-	/* Size for big_init is in BIG_CHUNK_TYPE words. */
-	if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean9;
-	}
-
-	/* Convert octet string input data to big integer format. */
-	bytestring2bignum(&msg, (uchar_t *)in, in_len);
-
-	/* Convert octet string modulus to big integer format. */
-	bytestring2bignum(&(rsakey->n), modulus, modulus_len);
-
-	if (big_cmp_abs(&msg, &(rsakey->n)) > 0) {
-		rv = CKR_DATA_LEN_RANGE;
-		goto clean10;
-	}
+	k.modulus = modulus;
+	k.modulus_bits = CRYPTO_BYTES2BITS(modulus_len);
+	k.prime1 = prime1;
+	k.prime1_bytes = prime1_len;
+	k.prime2 = prime2;
+	k.prime2_bytes = prime2_len;
+	k.expo1 = expo1;
+	k.expo1_bytes = expo1_len;
+	k.expo2 = expo2;
+	k.expo2_bytes = expo2_len;
+	k.coeff = coef;
+	k.coeff_bytes = coef_len;
+	k.rfunc = NULL;
 
-	/* Convert the rest of private key attributes to big integer format. */
-	bytestring2bignum(&(rsakey->dmodpminus1), expo2, expo2_len);
-	bytestring2bignum(&(rsakey->dmodqminus1), expo1, expo1_len);
-	bytestring2bignum(&(rsakey->p), prime2, prime2_len);
-	bytestring2bignum(&(rsakey->q), prime1, prime1_len);
-	bytestring2bignum(&(rsakey->pinvmodq), coef, coef_len);
-
-	if ((big_cmp_abs(&(rsakey->dmodpminus1), &(rsakey->p)) > 0) ||
-	    (big_cmp_abs(&(rsakey->dmodqminus1), &(rsakey->q)) > 0) ||
-	    (big_cmp_abs(&(rsakey->pinvmodq), &(rsakey->q)) > 0)) {
-		rv = CKR_KEY_SIZE_RANGE;
-		goto clean10;
-	}
+	rv = rsa_decrypt(&k, in, in_len, out);
 
-	/* Perform RSA computation on big integer input data. */
-	if (big_modexp_crt(&msg, &msg, &(rsakey->dmodpminus1),
-	    &(rsakey->dmodqminus1), &(rsakey->p), &(rsakey->q),
-	    &(rsakey->pinvmodq), NULL, NULL) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean10;
-	}
-
-	/* Convert the big integer output data to octet string. */
-	bignum2bytestring((uchar_t *)out, &msg, modulus_len);
-
-clean10:
-	big_finish(&msg);
-clean9:
-	RSA_key_finish(rsakey);
-clean8:
-	free(rsakey);
 clean1:
 
 /* EXPORT DELETE END */
@@ -397,7 +304,7 @@
 		 * Add PKCS padding to the input data to format a block
 		 * type "02" encryption block.
 		 */
-		rv = soft_encrypt_rsa_pkcs_encode(pData, ulDataLen, plain_data,
+		rv = pkcs1_encode(PKCS1_ENCRYPT, pData, ulDataLen, plain_data,
 		    modulus_len);
 
 		if (rv != CKR_OK)
@@ -474,11 +381,11 @@
 	}
 
 	if (mechanism == CKM_RSA_PKCS) {
-		int plain_len = modulus_len;
-		uint32_t num_padding;
+		size_t plain_len = modulus_len;
+		size_t num_padding;
 
 		/* Strip off the PKCS block formatting data. */
-		rv = soft_decrypt_rsa_pkcs_decode(plain_data, &plain_len);
+		rv = pkcs1_decode(PKCS1_DECRYPT, plain_data, &plain_len);
 		if (rv != CKR_OK)
 			goto clean_exit;
 
@@ -691,7 +598,7 @@
 		 * Add PKCS padding to the input data to format a block
 		 * type "01" encryption block.
 		 */
-		rv = soft_sign_rsa_pkcs_encode(pData, ulDataLen, plain_data,
+		rv = pkcs1_encode(PKCS1_SIGN, pData, ulDataLen, plain_data,
 		    modulus_len);
 
 		if (rv != CKR_OK) {
@@ -755,6 +662,11 @@
 		goto clean_exit;
 	}
 
+	if (ulDataLen == 0) {
+		rv = CKR_DATA_LEN_RANGE;
+		goto clean_exit;
+	}
+
 	if (ulSignatureLen != (CK_ULONG)modulus_len) {
 		rv = CKR_SIGNATURE_LEN_RANGE;
 		goto clean_exit;
@@ -780,15 +692,15 @@
 			 * recovered data, then compare the recovered data with
 			 * the original data.
 			 */
-			int data_len = modulus_len;
+			size_t data_len = modulus_len;
 
-			rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len);
+			rv = pkcs1_decode(PKCS1_VERIFY, plain_data, &data_len);
 			if (rv != CKR_OK) {
 				goto clean_exit;
 			}
 
 			if ((CK_ULONG)data_len != ulDataLen) {
-				rv = CKR_SIGNATURE_LEN_RANGE;
+				rv = CKR_DATA_LEN_RANGE;
 				goto clean_exit;
 			} else if (memcmp(pData,
 			    &plain_data[modulus_len - data_len],
@@ -840,36 +752,17 @@
 }
 
 CK_RV
-soft_genRSAkey_set_attribute(soft_object_t *key, RSAkey *rsakey,
-    CK_ATTRIBUTE_TYPE type, uint32_t modulus_len, boolean_t public)
+soft_genRSAkey_set_attribute(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
+    uchar_t *buf, uint32_t buflen, boolean_t public)
 {
-
-	uchar_t	*buf, *buf1;
-	uint32_t buflen;
 	CK_RV rv = CKR_OK;
 	biginteger_t *dst = NULL;
 	biginteger_t src;
 
-	/*
-	 * Allocate the buffer used to store the value of key fields
-	 * for bignum2bytestring. Since bignum only deals with a buffer
-	 * whose size is multiple of sizeof (BIG_CHUNK_TYPE),
-	 * modulus_len is rounded up to be multiple of that.
-	 */
-	if ((buf1 = malloc((modulus_len + sizeof (BIG_CHUNK_TYPE) - 1) &
-	    ~(sizeof (BIG_CHUNK_TYPE) - 1))) == NULL) {
-		rv = CKR_HOST_MEMORY;
-		goto cleanexit;
-	}
-
-	buf = buf1;
-
 	switch (type) {
 
 	case CKA_MODULUS:
 
-		buflen = rsakey->n.len * (int)sizeof (BIG_CHUNK_TYPE);
-		bignum2bytestring(buf, &rsakey->n, buflen);
 		if (public)
 			dst = OBJ_PUB_RSA_MOD(key);
 		else
@@ -878,8 +771,6 @@
 
 	case CKA_PUBLIC_EXPONENT:
 
-		buflen = rsakey->e.len * (int)sizeof (BIG_CHUNK_TYPE);
-		bignum2bytestring(buf, &rsakey->e, buflen);
 		if (public)
 			dst = OBJ_PUB_RSA_PUBEXPO(key);
 		else
@@ -888,269 +779,90 @@
 
 	case CKA_PRIVATE_EXPONENT:
 
-		buflen = rsakey->d.len * (int)sizeof (BIG_CHUNK_TYPE);
-		bignum2bytestring(buf, &rsakey->d, buflen);
 		dst = OBJ_PRI_RSA_PRIEXPO(key);
 		break;
 
 	case CKA_PRIME_1:
 
-		buflen = rsakey->q.len * (int)sizeof (BIG_CHUNK_TYPE);
-		bignum2bytestring(buf, &rsakey->q, buflen);
 		dst = OBJ_PRI_RSA_PRIME1(key);
 		break;
 
 	case CKA_PRIME_2:
 
-		buflen = rsakey->p.len * (int)sizeof (BIG_CHUNK_TYPE);
-		bignum2bytestring(buf, &rsakey->p, buflen);
 		dst = OBJ_PRI_RSA_PRIME2(key);
 		break;
 
 	case CKA_EXPONENT_1:
 
-		buflen = rsakey->dmodqminus1.len *
-		    (int)sizeof (BIG_CHUNK_TYPE);
-		bignum2bytestring(buf, &rsakey->dmodqminus1, buflen);
 		dst = OBJ_PRI_RSA_EXPO1(key);
 		break;
 
 	case CKA_EXPONENT_2:
 
-		buflen = rsakey->dmodpminus1.len *
-		    (int)sizeof (BIG_CHUNK_TYPE);
-		bignum2bytestring(buf, &rsakey->dmodpminus1, buflen);
 		dst = OBJ_PRI_RSA_EXPO2(key);
 		break;
 
 	case CKA_COEFFICIENT:
 
-		buflen = rsakey->pinvmodq.len * (int)sizeof (BIG_CHUNK_TYPE);
-		bignum2bytestring(buf, &rsakey->pinvmodq, buflen);
 		dst = OBJ_PRI_RSA_COEF(key);
 		break;
 	}
 
+	/* Note: no explanation found for why this is needed */
 	while (buf[0] == 0) {	/* remove proceeding 0x00 */
 		buf++;
 		buflen--;
 	}
 
-	src.big_value_len = buflen;
-
-	if ((src.big_value = malloc(buflen)) == NULL) {
-		rv = CKR_HOST_MEMORY;
+	if ((rv = dup_bigint_attr(&src, buf, buflen)) != CKR_OK)
 		goto cleanexit;
-	}
-	(void) memcpy(src.big_value, buf, buflen);
 
 	/* Copy the attribute in the key object. */
 	copy_bigint_attr(&src, dst);
 
 cleanexit:
-	free(buf1);
 	return (rv);
 
 }
 
 
 CK_RV
-generate_rsa_key(RSAkey *key, int psize, int qsize, BIGNUM * pubexp,
-    boolean_t token_obj)
-{
-	CK_RV		rv = CKR_OK;
-
-/* EXPORT DELETE START */
-
-	BIGNUM		a, b, c, d, e, f, g, h;
-	int		len, keylen, size;
-	BIG_ERR_CODE	brv = BIG_OK;
-
-	size = psize + qsize;
-	keylen = BITLEN2BIGNUMLEN(size);
-	len = keylen * 2 + 1;
-	key->size = size;
-
-	a.malloced = 0;
-	b.malloced = 0;
-	c.malloced = 0;
-	d.malloced = 0;
-	e.malloced = 0;
-	f.malloced = 0;
-	g.malloced = 0;
-	h.malloced = 0;
-
-	if ((big_init(&a, len) != BIG_OK) ||
-	    (big_init(&b, len) != BIG_OK) ||
-	    (big_init(&c, len) != BIG_OK) ||
-	    (big_init(&d, len) != BIG_OK) ||
-	    (big_init(&e, len) != BIG_OK) ||
-	    (big_init(&f, len) != BIG_OK) ||
-	    (big_init(&g, len) != BIG_OK) ||
-	    (big_init(&h, len) != BIG_OK)) {
-		big_finish(&h);
-		big_finish(&g);
-		big_finish(&f);
-		big_finish(&e);
-		big_finish(&d);
-		big_finish(&c);
-		big_finish(&b);
-		big_finish(&a);
-
-		return (CKR_HOST_MEMORY);
-	}
-nextp:
-	if ((brv = random_bignum(&a, psize, token_obj)) != BIG_OK) {
-		goto ret;
-	}
-
-	if ((brv = big_nextprime_pos(&b, &a)) != BIG_OK) {
-		goto ret;
-	}
-	(void) big_sub_pos(&a, &b, &big_One);
-	if ((brv = big_ext_gcd_pos(&f, &d, &g, pubexp, &a)) != BIG_OK) {
-		goto ret;
-	}
-	if (big_cmp_abs(&f, &big_One) != 0) {
-		goto nextp;
-	}
-
-	if ((brv = random_bignum(&c, qsize, token_obj)) != BIG_OK) {
-		goto ret;
-	}
-
-nextq:
-	(void) big_add(&a, &c, &big_Two);
-
-	if (big_bitlength(&a) != qsize) {
-		goto nextp;
-	}
-	if (big_cmp_abs(&a, &b) == 0) {
-		goto nextp;
-	}
-	if ((brv = big_nextprime_pos(&c, &a)) != BIG_OK) {
-		goto ret;
-	}
-	if ((brv = big_mul(&g, &b, &c)) != BIG_OK) {
-		goto ret;
-	}
-	if (big_bitlength(&g) != size) {
-		goto nextp;
-	}
-
-	(void) big_sub_pos(&a, &b, &big_One);
-	(void) big_sub_pos(&d, &c, &big_One);
-
-	if ((brv = big_mul(&a, &a, &d)) != BIG_OK) {
-		goto ret;
-	}
-	if ((brv = big_ext_gcd_pos(&f, &d, &h, pubexp, &a)) != BIG_OK) {
-		goto ret;
-	}
-	if (big_cmp_abs(&f, &big_One) != 0) {
-		goto nextq;
-	} else {
-		(void) big_copy(&e, pubexp);
-	}
-	if (d.sign == -1) {
-		if ((brv = big_add(&d, &d, &a)) != BIG_OK) {
-			goto ret;
-		}
-	}
-	(void) big_copy(&(key->p), &b);
-	(void) big_copy(&(key->q), &c);
-	(void) big_copy(&(key->n), &g);
-	(void) big_copy(&(key->d), &d);
-	(void) big_copy(&(key->e), &e);
-
-	if ((brv = big_ext_gcd_pos(&a, &f, &h, &b, &c)) != BIG_OK) {
-		goto ret;
-	}
-	if (f.sign == -1) {
-		if ((brv = big_add(&f, &f, &c)) != BIG_OK) {
-			goto ret;
-		}
-	}
-	(void) big_copy(&(key->pinvmodq), &f);
-
-	(void) big_sub(&a, &b, &big_One);
-	if ((brv = big_div_pos(&a, &f, &d, &a)) != BIG_OK) {
-		goto ret;
-	}
-	(void) big_copy(&(key->dmodpminus1), &f);
-	(void) big_sub(&a, &c, &big_One);
-	if ((brv = big_div_pos(&a, &f, &d, &a)) != BIG_OK) {
-		goto ret;
-	}
-	(void) big_copy(&(key->dmodqminus1), &f);
-
-	if ((brv = random_bignum(&h, size, token_obj)) != BIG_OK) {
-		goto ret;
-	}
-	if ((brv = big_div_pos(&a, &h, &h, &g)) != BIG_OK) {
-		goto ret;
-	}
-	if ((brv = big_modexp(&a, &h, &d, &g, NULL)) != BIG_OK) {
-		goto ret;
-	}
-
-	if ((brv = big_modexp(&b, &a, &e, &g, NULL)) != BIG_OK) {
-		goto ret;
-	}
-
-	if (big_cmp_abs(&b, &h) != 0) {
-		rv = generate_rsa_key(key, psize, qsize, pubexp, token_obj);
-		goto ret1;
-	} else {
-		brv = BIG_OK;
-	}
-
-ret:
-	rv = convert_rv(brv);
-ret1:
-	big_finish(&h);
-	big_finish(&g);
-	big_finish(&f);
-	big_finish(&e);
-	big_finish(&d);
-	big_finish(&c);
-	big_finish(&b);
-	big_finish(&a);
-
-/* EXPORT DELETE END */
-
-	return (rv);
-}
-
-
-CK_RV
 soft_rsa_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
 {
-
 	CK_RV rv = CKR_OK;
+	CK_ATTRIBUTE template;
+	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
 	uint32_t modulus_len;
-	uchar_t	pub_expo[MAX_KEY_ATTR_BUFLEN];
+	uchar_t pub_expo[MAX_KEY_ATTR_BUFLEN];
 	uint32_t pub_expo_len = sizeof (pub_expo);
-	BIGNUM	public_exponent = {0};
-	RSAkey	rsakey = {0};
-	CK_ATTRIBUTE template;
+	uchar_t private_exponent[MAX_KEY_ATTR_BUFLEN];
+	uint32_t private_exponent_len = sizeof (private_exponent);
+	uchar_t prime1[MAX_KEY_ATTR_BUFLEN];
+	uint32_t prime1_len = sizeof (prime1);
+	uchar_t prime2[MAX_KEY_ATTR_BUFLEN];
+	uint32_t prime2_len = sizeof (prime2);
+	uchar_t exponent1[MAX_KEY_ATTR_BUFLEN];
+	uint32_t exponent1_len = sizeof (exponent1);
+	uchar_t exponent2[MAX_KEY_ATTR_BUFLEN];
+	uint32_t exponent2_len = sizeof (exponent2);
+	uchar_t coefficient[MAX_KEY_ATTR_BUFLEN];
+	uint32_t coefficient_len = sizeof (coefficient);
+	RSAbytekey k;
 
 	if ((pubkey == NULL) || (prikey == NULL)) {
 		return (CKR_ARGUMENTS_BAD);
 	}
 
 	template.pValue = malloc(sizeof (CK_ULONG));
-
 	if (template.pValue == NULL) {
 		return (CKR_HOST_MEMORY);
 	}
-
 	template.ulValueLen = sizeof (CK_ULONG);
 
 	rv = get_ulong_attr_from_object(OBJ_PUB_RSA_MOD_BITS(pubkey),
 	    &template);
-
 	if (rv != CKR_OK) {
+		free(template.pValue);
 		goto clean0;
 	}
 
@@ -1161,15 +873,7 @@
 	modulus_len = *((CK_ULONG *)(template.pValue));
 #endif	/* __sparcv9 */
 
-	/* Convert modulus length from bit length to byte length. */
-	modulus_len = (modulus_len + 7) / 8;
-
-	/* Modulus length needs to be between min key size and max key size. */
-	if ((modulus_len < MIN_RSA_KEYLENGTH_IN_BYTES) ||
-	    (modulus_len > MAX_RSA_KEYLENGTH_IN_BYTES)) {
-		rv = CKR_ATTRIBUTE_VALUE_INVALID;
-		goto clean0;
-	}
+	free(template.pValue);
 
 	rv = soft_get_public_value(pubkey, CKA_PUBLIC_EXPONENT, pub_expo,
 	    &pub_expo_len);
@@ -1177,82 +881,85 @@
 		goto clean0;
 	}
 
-	/* Create a public exponent in bignum format. */
-	if (big_init(&public_exponent, CHARLEN2BIGNUMLEN(modulus_len)) !=
-	    BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean0;
-	}
-	bytestring2bignum(&public_exponent, pub_expo, pub_expo_len);
+	/* Inputs to RSA key pair generation */
+	k.modulus_bits = modulus_len;		/* save modulus len in bits  */
+	modulus_len = CRYPTO_BITS2BYTES(modulus_len);	/* convert to bytes */
+	k.modulus = modulus;
+	k.pubexpo = pub_expo;
+	k.pubexpo_bytes = pub_expo_len;
+	k.rfunc = (IS_TOKEN_OBJECT(pubkey) || IS_TOKEN_OBJECT(prikey)) ?
+	    pkcs11_get_random : pkcs11_get_urandom;
 
-	if (RSA_key_init(&rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) {
-		rv = CKR_HOST_MEMORY;
-		goto clean2;
-	}
+	/* Outputs from RSA key pair generation */
+	k.privexpo = private_exponent;
+	k.privexpo_bytes = private_exponent_len;
+	k.prime1 = prime1;
+	k.prime1_bytes = prime1_len;
+	k.prime2 = prime2;
+	k.prime2_bytes = prime2_len;
+	k.expo1 = exponent1;
+	k.expo1_bytes = exponent1_len;
+	k.expo2 = exponent2;
+	k.expo2_bytes = exponent2_len;
+	k.coeff = coefficient;
+	k.coeff_bytes = coefficient_len;
 
-	/* Generate RSA key pair. */
-	if ((rv = generate_rsa_key(&rsakey, modulus_len * 4, modulus_len * 4,
-	    &public_exponent, (IS_TOKEN_OBJECT(pubkey) ||
-	    IS_TOKEN_OBJECT(prikey)))) != CKR_OK) {
-		goto clean3;
+	rv = rsa_genkey_pair(&k);
+
+	if (rv != CKR_OK) {
+		goto clean0;
 	}
 
 	/*
 	 * Add modulus in public template, and add all eight key fields
 	 * in private template.
 	 */
-	if ((rv = soft_genRSAkey_set_attribute(pubkey, &rsakey,
-	    CKA_MODULUS, modulus_len, B_TRUE)) != CKR_OK) {
-		goto clean3;
-	}
-
-	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
-	    CKA_MODULUS, modulus_len, B_FALSE)) != CKR_OK) {
-		goto clean3;
+	if ((rv = soft_genRSAkey_set_attribute(pubkey, CKA_MODULUS,
+	    modulus, CRYPTO_BITS2BYTES(k.modulus_bits), B_TRUE)) != CKR_OK) {
+		goto clean0;
 	}
 
-	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
-	    CKA_PRIVATE_EXPONENT, modulus_len, B_FALSE)) != CKR_OK) {
-		goto clean3;
+	if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_MODULUS,
+	    modulus, CRYPTO_BITS2BYTES(k.modulus_bits), B_FALSE)) != CKR_OK) {
+		goto clean0;
 	}
 
-	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
-	    CKA_PUBLIC_EXPONENT, modulus_len, B_FALSE)) != CKR_OK) {
-		goto clean3;
+	if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PRIVATE_EXPONENT,
+	    private_exponent, k.privexpo_bytes, B_FALSE)) != CKR_OK) {
+		goto clean0;
 	}
 
-	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
-	    CKA_PRIME_1, modulus_len, B_FALSE)) != CKR_OK) {
-		goto clean3;
+	if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PUBLIC_EXPONENT,
+	    pub_expo, k.pubexpo_bytes, B_FALSE)) != CKR_OK) {
+		goto clean0;
 	}
 
-	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
-	    CKA_PRIME_2, modulus_len, B_FALSE)) != CKR_OK) {
-		goto clean3;
+	if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PRIME_1,
+	    prime1, k.prime1_bytes, B_FALSE)) != CKR_OK) {
+		goto clean0;
 	}
 
-	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
-	    CKA_EXPONENT_1, modulus_len, B_FALSE)) != CKR_OK) {
-		goto clean3;
+	if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PRIME_2,
+	    prime2, k.prime2_bytes, B_FALSE)) != CKR_OK) {
+		goto clean0;
 	}
 
-	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
-	    CKA_EXPONENT_2, modulus_len, B_FALSE)) != CKR_OK) {
-		goto clean3;
+	if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_EXPONENT_1,
+	    exponent1, k.expo1_bytes, B_FALSE)) != CKR_OK) {
+		goto clean0;
 	}
 
-	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
-	    CKA_COEFFICIENT, modulus_len, B_FALSE)) != CKR_OK) {
-		goto clean3;
+	if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_EXPONENT_2,
+	    exponent2, k.expo2_bytes, B_FALSE)) != CKR_OK) {
+		goto clean0;
 	}
 
-clean3:
-	RSA_key_finish(&rsakey);
-clean2:
-	big_finish(&public_exponent);
+	if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_COEFFICIENT,
+	    coefficient, k.coeff_bytes, B_FALSE)) != CKR_OK) {
+		goto clean0;
+	}
+
 clean0:
-	free(template.pValue);
-
 	return (rv);
 }
 
@@ -1509,9 +1216,9 @@
 			 * Strip off the encoded padding bytes in front of the
 			 * recovered data.
 			 */
-			int data_len = modulus_len;
+			size_t data_len = modulus_len;
 
-			rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len);
+			rv = pkcs1_decode(PKCS1_VERIFY, plain_data, &data_len);
 			if (rv != CKR_OK) {
 				goto clean_exit;
 			}
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.h	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.h	Mon Jun 07 08:54:25 2010 -0700
@@ -18,26 +18,24 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef _SOFTRSA_H
 #define	_SOFTRSA_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #include <sys/types.h>
 #include <security/pkcs11t.h>
-#include <bignum.h>
 #include "softObject.h"
 #include "softSession.h"
-#include "rsa_impl.h"
+#include <padding.h>
+#include <rsa_impl.h>
 
 
 typedef struct soft_rsa_ctx {
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandUtil.c	Mon Jun 07 11:37:25 2010 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <fcntl.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <security/cryptoki.h>
-#include <bignum.h>
-#include <cryptoutil.h>
-#include "softGlobal.h"
-#include "softRandom.h"
-#include "softCrypt.h"
-
-CK_RV
-soft_random_generator(CK_BYTE *ran_out, CK_ULONG ran_len, boolean_t token)
-{
-	/*
-	 * When random-number generator is called by asymmetric token
-	 * (persistent) key generation, use /dev/random. Otherwise,
-	 * use /dev/urandom.
-	 */
-	if (token) {
-		if (pkcs11_get_random(ran_out, ran_len) < 0)
-			return (CKR_DEVICE_ERROR);
-	} else {
-		if (pkcs11_get_urandom(ran_out, ran_len) < 0)
-			return (CKR_DEVICE_ERROR);
-	}
-	return (CKR_OK);
-}
-
-
-/*
- * Generate random number in BIGNUM format. length is in bits
- */
-BIG_ERR_CODE
-random_bignum(BIGNUM *r, int length, boolean_t token_obj)
-{
-	size_t len1;
-	CK_RV rv = CKR_OK;
-
-	/* Convert length of bits to length of word to hold valid data. */
-	r->len = (length-1) / BIG_CHUNK_SIZE + 1;
-
-	/* len1 is the byte count. */
-	len1 = r->len * sizeof (BIG_CHUNK_TYPE);
-
-	/* Generate len1 bytes of data and store in memory pointed by value. */
-	rv = soft_random_generator((CK_BYTE *)(r->value), len1, token_obj);
-
-	if (rv != CKR_OK) {
-		return (convert_brv(rv));
-	}
-
-	r->value[r->len - 1] |= BIG_CHUNK_HIGHBIT;
-
-	/*
-	 * If the bit length is not on word boundary, shift the existing
-	 * bits in last word to right adjusted.
-	 */
-	if ((length % BIG_CHUNK_SIZE) != 0)
-		r->value[r->len - 1] =
-		    r->value[r->len - 1] >>
-		    (BIG_CHUNK_SIZE - (length % BIG_CHUNK_SIZE));
-	r->sign = 1;
-
-	return (BIG_OK);
-}
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h	Mon Jun 07 11:37:25 2010 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SOFTRANDOM_H
-#define	_SOFTRANDOM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/types.h>
-#include <security/pkcs11t.h>
-#include <bignum.h>
-#include "softSession.h"
-
-BIG_ERR_CODE random_bignum(BIGNUM *, int, boolean_t);
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif /* _SOFTRANDOM_H */
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.h	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.h	Mon Jun 07 08:54:25 2010 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -19,23 +18,20 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef _SOFTSSL_H
 #define	_SOFTSSL_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #include <sys/types.h>
 #include <security/pkcs11t.h>
-#include <bignum.h>
 #include "softObject.h"
 #include "softSession.h"
 
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,6 +18,7 @@
  *
  * CDDL HEADER END
  */
+
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
@@ -207,10 +208,10 @@
 	{256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA256_RSA_PKCS in bits */
 	{256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA384_RSA_PKCS in bits */
 	{256, 4096, CKF_SIGN|CKF_VERIFY}, /* CKM_SHA512_RSA_PKCS in bits */
-	{MIN_DH_KEYLENGTH, MAX_DH_KEYLENGTH, CKF_GENERATE_KEY_PAIR},
+	{DH_MIN_KEY_LEN, DH_MAX_KEY_LEN, CKF_GENERATE_KEY_PAIR},
 						/* CKM_DH_PKCS_KEY_PAIR_GEN */
 						/* in bits */
-	{MIN_DH_KEYLENGTH, MAX_DH_KEYLENGTH, CKF_DERIVE},
+	{DH_MIN_KEY_LEN, DH_MAX_KEY_LEN, CKF_DERIVE},
 						/* CKM_DH_PKCS_DERIVE; */
 						/* in bits */
 	{1, 16, CKF_DERIVE},			/* CKM_MD5_KEY_DERIVATION */
--- a/usr/src/uts/common/Makefile.files	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/uts/common/Makefile.files	Mon Jun 07 08:54:25 2010 -0700
@@ -19,7 +19,9 @@
 # CDDL HEADER END
 #
 
+#
 # Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
+#
 
 #
 # This Makefile defines all file modules for the directory uts/common
@@ -1542,7 +1544,7 @@
 		mpi.o mplogic.o mpmontg.o mpprime.o oid.o \
 		secitem.o ec2_test.o ecp_test.o fips_ecc_util.o
 
-RSAPROV_OBJS += rsa.o rsa_impl.o fips_rsa_util.o
+RSAPROV_OBJS += rsa.o rsa_impl.o pkcs1.o fips_rsa_util.o
 
 SWRANDPROV_OBJS += swrand.o fips_random_util.o
 
--- a/usr/src/uts/common/Makefile.rules	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/uts/common/Makefile.rules	Mon Jun 07 08:54:25 2010 -0700
@@ -19,7 +19,9 @@
 # CDDL HEADER END
 #
 
+#
 # Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
+#
 
 #
 # uts/common/Makefile.rules
@@ -63,6 +65,10 @@
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
 
+$(OBJS_DIR)/%.o:		$(COMMONBASE)/crypto/padding/%.c
+	$(COMPILE.c) -o $@ $<
+	$(CTFCONVERT_O)
+
 $(OBJS_DIR)/%.o:		$(COMMONBASE)/crypto/rng/%.c
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
@@ -1549,6 +1555,9 @@
 $(LINTS_DIR)/%.ln:		$(COMMONBASE)/crypto/modes/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
+$(LINTS_DIR)/%.ln:		$(COMMONBASE)/crypto/padding/%.c
+	@($(LHEAD) $(LINT.c) $< $(LTAIL))
+
 $(LINTS_DIR)/%.ln:		$(COMMONBASE)/crypto/rng/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
--- a/usr/src/uts/common/crypto/io/rsa.c	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/uts/common/crypto/io/rsa.c	Mon Jun 07 08:54:25 2010 -0700
@@ -18,9 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -43,6 +43,7 @@
 #include <sys/crypto/impl.h>
 #include <sha1/sha1_impl.h>
 #include <sha2/sha2_impl.h>
+#include <padding/padding.h>
 #define	_RSA_FIPS_POST
 #include <rsa/rsa_impl.h>
 
@@ -180,12 +181,12 @@
 
 static int rsa_common_init(crypto_ctx_t *, crypto_mechanism_t *,
     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
-static int rsa_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
+static int rsaprov_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
     crypto_req_handle_t);
 static int rsa_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
-static int rsa_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
+static int rsaprov_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
     crypto_req_handle_t);
 static int rsa_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
@@ -197,12 +198,12 @@
  */
 static crypto_cipher_ops_t rsa_cipher_ops = {
 	rsa_common_init,
-	rsa_encrypt,
+	rsaprov_encrypt,
 	NULL,
 	NULL,
 	rsa_encrypt_atomic,
 	rsa_common_init,
-	rsa_decrypt,
+	rsaprov_decrypt,
 	NULL,
 	NULL,
 	rsa_decrypt_atomic
@@ -210,7 +211,7 @@
 
 static int rsa_sign_verify_common_init(crypto_ctx_t *, crypto_mechanism_t *,
     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
-static int rsa_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
+static int rsaprov_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
     crypto_req_handle_t);
 static int rsa_sign_update(crypto_ctx_t *, crypto_data_t *,
     crypto_req_handle_t);
@@ -227,16 +228,16 @@
  */
 static crypto_sign_ops_t rsa_sign_ops = {
 	rsa_sign_verify_common_init,
-	rsa_sign,
+	rsaprov_sign,
 	rsa_sign_update,
 	rsa_sign_final,
 	rsa_sign_atomic,
 	rsa_sign_verify_common_init,
-	rsa_sign,
+	rsaprov_sign,
 	rsa_sign_atomic
 };
 
-static int rsa_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
+static int rsaprov_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
     crypto_req_handle_t);
 static int rsa_verify_update(crypto_ctx_t *, crypto_data_t *,
     crypto_req_handle_t);
@@ -258,7 +259,7 @@
  */
 static crypto_verify_ops_t rsa_verify_ops = {
 	rsa_sign_verify_common_init,
-	rsa_verify,
+	rsaprov_verify,
 	rsa_verify_update,
 	rsa_verify_final,
 	rsa_verify_atomic,
@@ -312,21 +313,19 @@
 };
 
 static int rsa_encrypt_common(rsa_mech_type_t, crypto_key_t *,
-    crypto_data_t *, crypto_data_t *, int);
+    crypto_data_t *, crypto_data_t *);
 static int rsa_decrypt_common(rsa_mech_type_t, crypto_key_t *,
-    crypto_data_t *, crypto_data_t *, int);
+    crypto_data_t *, crypto_data_t *);
 static int rsa_sign_common(rsa_mech_type_t, crypto_key_t *,
-    crypto_data_t *, crypto_data_t *, int);
+    crypto_data_t *, crypto_data_t *);
 static int rsa_verify_common(rsa_mech_type_t, crypto_key_t *,
-    crypto_data_t *, crypto_data_t *, int);
+    crypto_data_t *, crypto_data_t *);
 static int compare_data(crypto_data_t *, uchar_t *);
 
 /* EXPORT DELETE START */
 
-static int core_rsa_encrypt(crypto_key_t *, uchar_t *,
-    int, uchar_t *, int, int);
-static int core_rsa_decrypt(crypto_key_t *, uchar_t *, int,
-    uchar_t *, int);
+static int core_rsa_encrypt(crypto_key_t *, uchar_t *, int, uchar_t *, int);
+static int core_rsa_decrypt(crypto_key_t *, uchar_t *, int, uchar_t *);
 
 /* EXPORT DELETE END */
 
@@ -536,7 +535,7 @@
 
 /* ARGSUSED */
 static int
-rsa_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
+rsaprov_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
     crypto_data_t *ciphertext, crypto_req_handle_t req)
 {
 	int rv;
@@ -549,12 +548,12 @@
 
 	/*
 	 * Note on the KM_SLEEP flag passed to the routine below -
-	 * rsa_encrypt() is a single-part encryption routine which is
+	 * rsaprov_encrypt() is a single-part encryption routine which is
 	 * currently usable only by /dev/crypto. Since /dev/crypto calls are
 	 * always synchronous, we can safely pass KM_SLEEP here.
 	 */
 	rv = rsa_encrypt_common(ctxp->mech_type, ctxp->key, plaintext,
-	    ciphertext, KM_SLEEP);
+	    ciphertext);
 
 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
 		(void) rsa_free_context(ctx);
@@ -576,7 +575,7 @@
 	RSA_ARG_INPLACE(plaintext, ciphertext);
 
 	return (rsa_encrypt_common(mechanism->cm_type, key, plaintext,
-	    ciphertext, crypto_kmflag(req)));
+	    ciphertext));
 }
 
 static int
@@ -602,7 +601,7 @@
 
 static int
 rsa_encrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key,
-    crypto_data_t *plaintext, crypto_data_t *ciphertext, int kmflag)
+    crypto_data_t *plaintext, crypto_data_t *ciphertext)
 {
 	int rv = CRYPTO_FAILED;
 
@@ -644,7 +643,7 @@
 		return (rv);
 
 	if (mech_type == RSA_PKCS_MECH_INFO_TYPE) {
-		rv = soft_encrypt_rsa_pkcs_encode(ptptr, plen,
+		rv = pkcs1_encode(PKCS1_ENCRYPT, ptptr, plen,
 		    plain_data, modulus_len);
 
 		if (rv != CRYPTO_SUCCESS)
@@ -654,8 +653,7 @@
 		bcopy(ptptr, &plain_data[modulus_len - plen], plen);
 	}
 
-	rv = core_rsa_encrypt(key, plain_data, modulus_len,
-	    cipher_data, kmflag, 1);
+	rv = core_rsa_encrypt(key, plain_data, modulus_len, cipher_data, 1);
 	if (rv == CRYPTO_SUCCESS) {
 		/* copy out to ciphertext */
 		if ((rv = crypto_put_output_data(cipher_data,
@@ -674,14 +672,13 @@
 
 static int
 core_rsa_encrypt(crypto_key_t *key, uchar_t *in,
-    int in_len, uchar_t *out, int kmflag, int is_public)
+    int in_len, uchar_t *out, int is_public)
 {
 	int rv;
 	uchar_t *expo, *modulus;
 	ssize_t	expo_len;
 	ssize_t modulus_len;
-	BIGNUM msg;
-	RSAkey *rsakey;
+	RSAbytekey k;
 
 	if (is_public) {
 		if ((rv = crypto_get_key_attr(key, SUN_CKA_PUBLIC_EXPONENT,
@@ -703,56 +700,13 @@
 		return (rv);
 	}
 
-	rsakey = kmem_alloc(sizeof (RSAkey), kmflag);
-	if (rsakey == NULL)
-		return (CRYPTO_HOST_MEMORY);
-
-	/* psize and qsize for RSA_key_init is in bits. */
-	if (RSA_key_init(rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) {
-		rv = CRYPTO_HOST_MEMORY;
-		goto clean1;
-	}
-
-	/* Size for big_init is in BIG_CHUNK_TYPE words. */
-	if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
-		rv = CRYPTO_HOST_MEMORY;
-		goto clean2;
-	}
-
-	/* Convert octet string exponent to big integer format. */
-	bytestring2bignum(&(rsakey->e), expo, expo_len);
-
-	/* Convert octet string modulus to big integer format. */
-	bytestring2bignum(&(rsakey->n), modulus, modulus_len);
-
-	/* Convert octet string input data to big integer format. */
-	bytestring2bignum(&msg, in, in_len);
+	k.modulus = modulus;
+	k.modulus_bits = CRYPTO_BYTES2BITS(modulus_len);
+	k.pubexpo = expo;
+	k.pubexpo_bytes = expo_len;
+	k.rfunc = NULL;
 
-	if (big_cmp_abs(&msg, &(rsakey->n)) > 0) {
-		rv = CRYPTO_DATA_LEN_RANGE;
-		goto clean3;
-	}
-
-	/* Perform RSA computation on big integer input data. */
-	if (big_modexp(&msg, &msg, &(rsakey->e), &(rsakey->n), NULL)
-	    != BIG_OK) {
-		rv = CRYPTO_HOST_MEMORY;
-		goto clean3;
-	}
-
-	/* Convert the big integer output data to octet string. */
-	bignum2bytestring(out, &msg, modulus_len);
-
-	/*
-	 * Should not free modulus and expo as both are just pointers
-	 * to an attribute value buffer from the caller.
-	 */
-clean3:
-	big_finish(&msg);
-clean2:
-	RSA_key_finish(rsakey);
-clean1:
-	kmem_free(rsakey, sizeof (RSAkey));
+	rv = rsa_encrypt(&k, in, in_len, out);
 
 	return (rv);
 }
@@ -761,7 +715,7 @@
 
 /* ARGSUSED */
 static int
-rsa_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
+rsaprov_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
     crypto_data_t *plaintext, crypto_req_handle_t req)
 {
 	int rv;
@@ -772,9 +726,9 @@
 
 	RSA_ARG_INPLACE(ciphertext, plaintext);
 
-	/* See the comments on KM_SLEEP flag in rsa_encrypt() */
+	/* See the comments on KM_SLEEP flag in rsaprov_encrypt() */
 	rv = rsa_decrypt_common(ctxp->mech_type, ctxp->key,
-	    ciphertext, plaintext, KM_SLEEP);
+	    ciphertext, plaintext);
 
 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
 		(void) rsa_free_context(ctx);
@@ -796,18 +750,18 @@
 	RSA_ARG_INPLACE(ciphertext, plaintext);
 
 	return (rsa_decrypt_common(mechanism->cm_type, key, ciphertext,
-	    plaintext, crypto_kmflag(req)));
+	    plaintext));
 }
 
 static int
 rsa_decrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key,
-    crypto_data_t *ciphertext, crypto_data_t *plaintext, int kmflag)
+    crypto_data_t *ciphertext, crypto_data_t *plaintext)
 {
 	int rv = CRYPTO_FAILED;
 
 /* EXPORT DELETE START */
 
-	int plain_len;
+	size_t plain_len;
 	uchar_t *ctptr;
 	uchar_t *modulus;
 	ssize_t modulus_len;
@@ -830,13 +784,13 @@
 	    != CRYPTO_SUCCESS)
 		return (rv);
 
-	rv = core_rsa_decrypt(key, ctptr, modulus_len, plain_data, kmflag);
+	rv = core_rsa_decrypt(key, ctptr, modulus_len, plain_data);
 	if (rv == CRYPTO_SUCCESS) {
 		plain_len = modulus_len;
 
 		if (mech_type == RSA_PKCS_MECH_INFO_TYPE) {
 			/* Strip off the PKCS block formatting data. */
-			rv = soft_decrypt_rsa_pkcs_decode(plain_data,
+			rv = pkcs1_decode(PKCS1_DECRYPT, plain_data,
 			    &plain_len);
 			if (rv != CRYPTO_SUCCESS)
 				return (rv);
@@ -863,16 +817,14 @@
 /* EXPORT DELETE START */
 
 static int
-core_rsa_decrypt(crypto_key_t *key, uchar_t *in, int in_len,
-    uchar_t *out, int kmflag)
+core_rsa_decrypt(crypto_key_t *key, uchar_t *in, int in_len, uchar_t *out)
 {
 	int rv;
 	uchar_t *modulus, *prime1, *prime2, *expo1, *expo2, *coef;
 	ssize_t modulus_len;
 	ssize_t	prime1_len, prime2_len;
 	ssize_t	expo1_len, expo2_len, coef_len;
-	BIGNUM msg;
-	RSAkey *rsakey;
+	RSAbytekey k;
 
 	if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus,
 	    &modulus_len)) != CRYPTO_SUCCESS) {
@@ -896,72 +848,24 @@
 	    != CRYPTO_SUCCESS) ||
 	    (crypto_get_key_attr(key, SUN_CKA_COEFFICIENT, &coef, &coef_len)
 	    != CRYPTO_SUCCESS)) {
-		return (core_rsa_encrypt(key, in, in_len, out, kmflag, 0));
-	}
-
-	rsakey = kmem_alloc(sizeof (RSAkey), kmflag);
-	if (rsakey == NULL)
-		return (CRYPTO_HOST_MEMORY);
-
-	/* psize and qsize for RSA_key_init is in bits. */
-	if (RSA_key_init(rsakey, CRYPTO_BYTES2BITS(prime2_len),
-	    CRYPTO_BYTES2BITS(prime1_len)) != BIG_OK) {
-		rv = CRYPTO_HOST_MEMORY;
-		goto clean1;
-	}
-
-	/* Size for big_init is in BIG_CHUNK_TYPE words. */
-	if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
-		rv = CRYPTO_HOST_MEMORY;
-		goto clean2;
-	}
-
-	/* Convert octet string input data to big integer format. */
-	bytestring2bignum(&msg, in, in_len);
-
-	/* Convert octet string modulus to big integer format. */
-	bytestring2bignum(&(rsakey->n), modulus, modulus_len);
-
-	if (big_cmp_abs(&msg, &(rsakey->n)) > 0) {
-		rv = CRYPTO_DATA_LEN_RANGE;
-		goto clean3;
+		return (core_rsa_encrypt(key, in, in_len, out, 0));
 	}
 
-	/* Convert the rest of private key attributes to big integer format. */
-	bytestring2bignum(&(rsakey->dmodpminus1), expo2, expo2_len);
-	bytestring2bignum(&(rsakey->dmodqminus1), expo1, expo1_len);
-	bytestring2bignum(&(rsakey->p), prime2, prime2_len);
-	bytestring2bignum(&(rsakey->q), prime1, prime1_len);
-	bytestring2bignum(&(rsakey->pinvmodq), coef, coef_len);
-
-	if ((big_cmp_abs(&(rsakey->dmodpminus1), &(rsakey->p)) > 0) ||
-	    (big_cmp_abs(&(rsakey->dmodqminus1), &(rsakey->q)) > 0) ||
-	    (big_cmp_abs(&(rsakey->pinvmodq), &(rsakey->q)) > 0)) {
-		rv = CRYPTO_KEY_SIZE_RANGE;
-		goto clean3;
-	}
+	k.modulus = modulus;
+	k.modulus_bits = CRYPTO_BYTES2BITS(modulus_len);
+	k.prime1 = prime1;
+	k.prime1_bytes = prime1_len;
+	k.prime2 = prime2;
+	k.prime2_bytes = prime2_len;
+	k.expo1 = expo1;
+	k.expo1_bytes = expo1_len;
+	k.expo2 = expo2;
+	k.expo2_bytes = expo2_len;
+	k.coeff = coef;
+	k.coeff_bytes = coef_len;
+	k.rfunc = NULL;
 
-	/* Perform RSA computation on big integer input data. */
-	if (big_modexp_crt(&msg, &msg, &(rsakey->dmodpminus1),
-	    &(rsakey->dmodqminus1), &(rsakey->p), &(rsakey->q),
-	    &(rsakey->pinvmodq), NULL, NULL) != BIG_OK) {
-		rv = CRYPTO_HOST_MEMORY;
-		goto clean3;
-	}
-
-	/* Convert the big integer output data to octet string. */
-	bignum2bytestring(out, &msg, modulus_len);
-
-	/*
-	 * Should not free modulus and friends as they are just pointers
-	 * to an attribute value buffer from the caller.
-	 */
-clean3:
-	big_finish(&msg);
-clean2:
-	RSA_key_finish(rsakey);
-clean1:
-	kmem_free(rsakey, sizeof (RSAkey));
+	rv = rsa_decrypt(&k, in, in_len, out);
 
 	return (rv);
 }
@@ -1060,7 +964,7 @@
 
 static int
 rsa_digest_svrfy_common(digest_rsa_ctx_t *ctxp, crypto_data_t *data,
-    crypto_data_t *signature, int kmflag, uchar_t flag)
+    crypto_data_t *signature, uchar_t flag)
 {
 	int rv = CRYPTO_FAILED;
 
@@ -1166,10 +1070,10 @@
 	 */
 	if (flag & CRYPTO_DO_SIGN)
 		rv = rsa_sign_common(mech_type, ctxp->key, &der_cd,
-		    signature, kmflag);
+		    signature);
 	else
 		rv = rsa_verify_common(mech_type, ctxp->key, &der_cd,
-		    signature, kmflag);
+		    signature);
 
 /* EXPORT DELETE END */
 
@@ -1178,7 +1082,7 @@
 
 static int
 rsa_sign_common(rsa_mech_type_t mech_type, crypto_key_t *key,
-    crypto_data_t *data, crypto_data_t *signature, int kmflag)
+    crypto_data_t *data, crypto_data_t *signature)
 {
 	int rv = CRYPTO_FAILED;
 
@@ -1229,7 +1133,7 @@
 		 * Add PKCS padding to the input data to format a block
 		 * type "01" encryption block.
 		 */
-		rv = soft_sign_rsa_pkcs_encode(dataptr, dlen, plain_data,
+		rv = pkcs1_encode(PKCS1_SIGN, dataptr, dlen, plain_data,
 		    modulus_len);
 		if (rv != CRYPTO_SUCCESS)
 			return (rv);
@@ -1242,8 +1146,7 @@
 		break;
 	}
 
-	rv = core_rsa_decrypt(key, plain_data, modulus_len, signed_data,
-	    kmflag);
+	rv = core_rsa_decrypt(key, plain_data, modulus_len, signed_data);
 	if (rv == CRYPTO_SUCCESS) {
 		/* copy out to signature */
 		if ((rv = crypto_put_output_data(signed_data,
@@ -1260,7 +1163,7 @@
 
 /* ARGSUSED */
 static int
-rsa_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
+rsaprov_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
     crypto_req_handle_t req)
 {
 	int rv;
@@ -1269,7 +1172,7 @@
 	ASSERT(ctx->cc_provider_private != NULL);
 	ctxp = ctx->cc_provider_private;
 
-	/* See the comments on KM_SLEEP flag in rsa_encrypt() */
+	/* See the comments on KM_SLEEP flag in rsaprov_encrypt() */
 	switch (ctxp->mech_type) {
 	case MD5_RSA_PKCS_MECH_INFO_TYPE:
 	case SHA1_RSA_PKCS_MECH_INFO_TYPE:
@@ -1277,12 +1180,12 @@
 	case SHA384_RSA_PKCS_MECH_INFO_TYPE:
 	case SHA512_RSA_PKCS_MECH_INFO_TYPE:
 		rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data,
-		    signature, KM_SLEEP, CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE |
+		    signature, CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE |
 		    CRYPTO_DO_FINAL);
 		break;
 	default:
 		rv = rsa_sign_common(ctxp->mech_type, ctxp->key, data,
-		    signature, KM_SLEEP);
+		    signature);
 		break;
 	}
 
@@ -1326,6 +1229,7 @@
 	return (rv);
 }
 
+/* ARGSUSED2 */
 static int
 rsa_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature,
     crypto_req_handle_t req)
@@ -1337,7 +1241,7 @@
 	ctxp = ctx->cc_provider_private;
 
 	rv = rsa_digest_svrfy_common(ctxp, NULL, signature,
-	    crypto_kmflag(req), CRYPTO_DO_SIGN | CRYPTO_DO_FINAL);
+	    CRYPTO_DO_SIGN | CRYPTO_DO_FINAL);
 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
 		(void) rsa_free_context(ctx);
 
@@ -1360,7 +1264,7 @@
 	if (mechanism->cm_type == RSA_PKCS_MECH_INFO_TYPE ||
 	    mechanism->cm_type == RSA_X_509_MECH_INFO_TYPE)
 		rv = rsa_sign_common(mechanism->cm_type, key, data,
-		    signature, crypto_kmflag(req));
+		    signature);
 
 	else {
 		dctx.mech_type = mechanism->cm_type;
@@ -1388,8 +1292,7 @@
 		}
 
 		rv = rsa_digest_svrfy_common(&dctx, data, signature,
-		    crypto_kmflag(req), CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE |
-		    CRYPTO_DO_FINAL);
+		    CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE | CRYPTO_DO_FINAL);
 	}
 
 	return (rv);
@@ -1397,7 +1300,7 @@
 
 static int
 rsa_verify_common(rsa_mech_type_t mech_type, crypto_key_t *key,
-    crypto_data_t *data, crypto_data_t *signature, int kmflag)
+    crypto_data_t *data, crypto_data_t *signature)
 {
 	int rv = CRYPTO_FAILED;
 
@@ -1421,7 +1324,7 @@
 	    != CRYPTO_SUCCESS)
 		return (rv);
 
-	rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1);
+	rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, 1);
 	if (rv != CRYPTO_SUCCESS)
 		return (rv);
 
@@ -1431,14 +1334,14 @@
 			rv = CRYPTO_SIGNATURE_INVALID;
 
 	} else {
-		int data_len = modulus_len;
+		size_t data_len = modulus_len;
 
 		/*
 		 * Strip off the encoded padding bytes in front of the
 		 * recovered data, then compare the recovered data with
 		 * the original data.
 		 */
-		rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len);
+		rv = pkcs1_decode(PKCS1_VERIFY, plain_data, &data_len);
 		if (rv != CRYPTO_SUCCESS)
 			return (rv);
 
@@ -1457,8 +1360,8 @@
 
 /* ARGSUSED */
 static int
-rsa_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
-    crypto_req_handle_t req)
+rsaprov_verify(crypto_ctx_t *ctx, crypto_data_t *data,
+    crypto_data_t *signature, crypto_req_handle_t req)
 {
 	int rv;
 	rsa_ctx_t *ctxp;
@@ -1466,7 +1369,7 @@
 	ASSERT(ctx->cc_provider_private != NULL);
 	ctxp = ctx->cc_provider_private;
 
-	/* See the comments on KM_SLEEP flag in rsa_encrypt() */
+	/* See the comments on KM_SLEEP flag in rsaprov_encrypt() */
 	switch (ctxp->mech_type) {
 	case MD5_RSA_PKCS_MECH_INFO_TYPE:
 	case SHA1_RSA_PKCS_MECH_INFO_TYPE:
@@ -1474,12 +1377,12 @@
 	case SHA384_RSA_PKCS_MECH_INFO_TYPE:
 	case SHA512_RSA_PKCS_MECH_INFO_TYPE:
 		rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data,
-		    signature, KM_SLEEP, CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE |
+		    signature, CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE |
 		    CRYPTO_DO_FINAL);
 		break;
 	default:
 		rv = rsa_verify_common(ctxp->mech_type, ctxp->key, data,
-		    signature, KM_SLEEP);
+		    signature);
 		break;
 	}
 
@@ -1529,6 +1432,7 @@
 	return (rv);
 }
 
+/* ARGSUSED2 */
 static int
 rsa_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature,
     crypto_req_handle_t req)
@@ -1540,7 +1444,7 @@
 	ctxp = ctx->cc_provider_private;
 
 	rv = rsa_digest_svrfy_common(ctxp, NULL, signature,
-	    crypto_kmflag(req), CRYPTO_DO_VERIFY | CRYPTO_DO_FINAL);
+	    CRYPTO_DO_VERIFY | CRYPTO_DO_FINAL);
 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
 		(void) rsa_free_context(ctx);
 
@@ -1565,7 +1469,7 @@
 	if (mechanism->cm_type == RSA_PKCS_MECH_INFO_TYPE ||
 	    mechanism->cm_type == RSA_X_509_MECH_INFO_TYPE)
 		rv = rsa_verify_common(mechanism->cm_type, key, data,
-		    signature, crypto_kmflag(req));
+		    signature);
 
 	else {
 		dctx.mech_type = mechanism->cm_type;
@@ -1593,8 +1497,7 @@
 			break;
 		}
 
-		rv = rsa_digest_svrfy_common(&dctx, data,
-		    signature, crypto_kmflag(req),
+		rv = rsa_digest_svrfy_common(&dctx, data, signature,
 		    CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE | CRYPTO_DO_FINAL);
 	}
 
@@ -1603,13 +1506,13 @@
 
 static int
 rsa_verify_recover_common(rsa_mech_type_t mech_type, crypto_key_t *key,
-    crypto_data_t *signature, crypto_data_t *data, int kmflag)
+    crypto_data_t *signature, crypto_data_t *data)
 {
 	int rv = CRYPTO_FAILED;
 
 /* EXPORT DELETE START */
 
-	int data_len;
+	size_t data_len;
 	uchar_t *sigptr, *modulus;
 	ssize_t modulus_len;
 	uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
@@ -1628,7 +1531,7 @@
 	    != CRYPTO_SUCCESS)
 		return (rv);
 
-	rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1);
+	rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, 1);
 	if (rv != CRYPTO_SUCCESS)
 		return (rv);
 
@@ -1640,7 +1543,7 @@
 		 * recovered data, then compare the recovered data with
 		 * the original data.
 		 */
-		rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len);
+		rv = pkcs1_decode(PKCS1_VERIFY, plain_data, &data_len);
 		if (rv != CRYPTO_SUCCESS)
 			return (rv);
 	}
@@ -1671,9 +1574,9 @@
 	ASSERT(ctx->cc_provider_private != NULL);
 	ctxp = ctx->cc_provider_private;
 
-	/* See the comments on KM_SLEEP flag in rsa_encrypt() */
+	/* See the comments on KM_SLEEP flag in rsaprov_encrypt() */
 	rv = rsa_verify_recover_common(ctxp->mech_type, ctxp->key,
-	    signature, data, KM_SLEEP);
+	    signature, data);
 
 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
 		(void) rsa_free_context(ctx);
@@ -1694,11 +1597,11 @@
 		return (rv);
 
 	return (rsa_verify_recover_common(mechanism->cm_type, key,
-	    signature, data, crypto_kmflag(req)));
+	    signature, data));
 }
 
 /*
- * RSA Power-Up Self-Test
+ * RSA Power-On Self-Test
  */
 void
 rsa_POST(int *rc)
--- a/usr/src/uts/sun4v/Makefile.rules	Mon Jun 07 11:37:25 2010 -0400
+++ b/usr/src/uts/sun4v/Makefile.rules	Mon Jun 07 08:54:25 2010 -0700
@@ -20,8 +20,9 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
 #
 #	This Makefile defines the build rules for the directory uts/sun4v
 #	and its children. These are the source files which sun4v
@@ -269,3 +270,6 @@
 
 $(LINTS_DIR)/%.ln:		$(SRC)/common/atomic/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln:		$(SRC)/common/crypto/arcfour/sun4v/%.c
+	@($(LHEAD) $(LINT.c) $< $(LTAIL))