summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDina K Nimeh <Dina.Nimeh@Sun.COM>2010-06-07 08:54:25 -0700
committerDina K Nimeh <Dina.Nimeh@Sun.COM>2010-06-07 08:54:25 -0700
commit726fad2a65f16c200a03969c29cb5c86c2d427db (patch)
treeaca280cc44a7b599ab39116a9229a98428f7c9d7
parentad559bec55fd74f310399483501e1fa231f65528 (diff)
downloadillumos-gate-726fad2a65f16c200a03969c29cb5c86c2d427db.tar.gz
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
-rw-r--r--usr/src/common/bignum/bignum.h15
-rw-r--r--usr/src/common/bignum/bignumimpl.c49
-rw-r--r--usr/src/common/crypto/arcfour/sun4v/arcfour_crypt.c94
-rw-r--r--usr/src/common/crypto/dh/Makefile35
-rw-r--r--usr/src/common/crypto/dh/dh_impl.c380
-rw-r--r--usr/src/common/crypto/dh/dh_impl.h99
-rw-r--r--usr/src/common/crypto/dsa/Makefile35
-rw-r--r--usr/src/common/crypto/dsa/dsa_impl.c600
-rw-r--r--usr/src/common/crypto/dsa/dsa_impl.h136
-rw-r--r--usr/src/common/crypto/fips/fips_dsa_util.c260
-rw-r--r--usr/src/common/crypto/fips/fips_post.h6
-rw-r--r--usr/src/common/crypto/fips/fips_rsa_util.c374
-rw-r--r--usr/src/common/crypto/padding/Makefile35
-rw-r--r--usr/src/common/crypto/padding/padding.h80
-rw-r--r--usr/src/common/crypto/padding/pkcs1.c146
-rw-r--r--usr/src/common/crypto/padding/pkcs7.c121
-rw-r--r--usr/src/common/crypto/rsa/rsa_impl.c545
-rw-r--r--usr/src/common/crypto/rsa/rsa_impl.h101
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/Makefile.com98
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/amd64/Makefile8
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/common/llib-lsoftcrypto7
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/common/mapfile-vers24
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/i386/Makefile9
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/i386_hwcap1/Makefile9
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/sparc/Makefile8
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/sparcv9/Makefile8
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/sun4u/Makefile.com76
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/sun4u/mapfile-vers5
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparc/Makefile8
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparcv9/Makefile9
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/sun4v/Makefile.com18
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/sun4v/mapfile-vers5
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparc/Makefile8
-rw-r--r--usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparcv9/Makefile10
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/Makefile.com29
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c6
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c42
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.c78
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.h13
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softDESCrypt.c6
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.c358
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.h15
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.c473
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.h36
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softDecryptUtil.c34
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c16
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSA.h68
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSAUtil.c509
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPost.c9
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPostUtil.c9
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.h6
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softObjectUtil.c15
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.c523
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.h10
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandUtil.c96
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h44
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.h12
-rw-r--r--usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c5
-rw-r--r--usr/src/uts/common/Makefile.files4
-rw-r--r--usr/src/uts/common/Makefile.rules9
-rw-r--r--usr/src/uts/common/crypto/io/rsa.c285
-rw-r--r--usr/src/uts/sun4v/Makefile.rules8
62 files changed, 3321 insertions, 2818 deletions
diff --git a/usr/src/common/bignum/bignum.h b/usr/src/common/bignum/bignum.h
index dbc64de34b..bec0a40ff8 100644
--- a/usr/src/common/bignum/bignum.h
+++ b/usr/src/common/bignum/bignum.h
@@ -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 @@ extern "C" {
#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 @@ BIG_ERR_CODE big_modexp_crt_ext(BIGNUM *result, BIGNUM *a, BIGNUM *dmodpminus1,
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,
diff --git a/usr/src/common/bignum/bignumimpl.c b/usr/src/common/bignum/bignumimpl.c
index 079dad8dd0..fbd1511fd8 100644
--- a/usr/src/common/bignum/bignumimpl.c
+++ b/usr/src/common/bignum/bignumimpl.c
@@ -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 @@ ret1:
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);
+}
diff --git a/usr/src/common/crypto/arcfour/sun4v/arcfour_crypt.c b/usr/src/common/crypto/arcfour/sun4v/arcfour_crypt.c
index b752d62646..e08df1ad0c 100644
--- a/usr/src/common/crypto/arcfour/sun4v/arcfour_crypt.c
+++ b/usr/src/common/crypto/arcfour/sun4v/arcfour_crypt.c
@@ -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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
* 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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
* 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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
*/
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
/* 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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
*((unsigned long long *) (&out[ii])) = in0;
}
- i = i1;
+ i = (uchar_t)i1;
/*
* Handle any overrun
@@ -588,8 +588,8 @@ arcfour_crypt(ARCFour_key *key, uchar_t *in, uchar_t *out, size_t len)
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;
diff --git a/usr/src/common/crypto/dh/Makefile b/usr/src/common/crypto/dh/Makefile
new file mode 100644
index 0000000000..b10c44684f
--- /dev/null
+++ b/usr/src/common/crypto/dh/Makefile
@@ -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:
+
diff --git a/usr/src/common/crypto/dh/dh_impl.c b/usr/src/common/crypto/dh/dh_impl.c
new file mode 100644
index 0000000000..a1150dee8d
--- /dev/null
+++ b/usr/src/common/crypto/dh/dh_impl.c
@@ -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);
+}
diff --git a/usr/src/common/crypto/dh/dh_impl.h b/usr/src/common/crypto/dh/dh_impl.h
new file mode 100644
index 0000000000..addc1396bc
--- /dev/null
+++ b/usr/src/common/crypto/dh/dh_impl.h
@@ -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 */
diff --git a/usr/src/common/crypto/dsa/Makefile b/usr/src/common/crypto/dsa/Makefile
new file mode 100644
index 0000000000..3f0a6a0ac8
--- /dev/null
+++ b/usr/src/common/crypto/dsa/Makefile
@@ -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:
+
diff --git a/usr/src/common/crypto/dsa/dsa_impl.c b/usr/src/common/crypto/dsa/dsa_impl.c
new file mode 100644
index 0000000000..f2c4c5ccec
--- /dev/null
+++ b/usr/src/common/crypto/dsa/dsa_impl.c
@@ -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);
+}
diff --git a/usr/src/common/crypto/dsa/dsa_impl.h b/usr/src/common/crypto/dsa/dsa_impl.h
new file mode 100644
index 0000000000..c550aaf517
--- /dev/null
+++ b/usr/src/common/crypto/dsa/dsa_impl.h
@@ -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 */
diff --git a/usr/src/common/crypto/fips/fips_dsa_util.c b/usr/src/common/crypto/fips/fips_dsa_util.c
new file mode 100644
index 0000000000..b73f763cac
--- /dev/null
+++ b/usr/src/common/crypto/fips/fips_dsa_util.c
@@ -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);
+}
diff --git a/usr/src/common/crypto/fips/fips_post.h b/usr/src/common/crypto/fips/fips_post.h
index e622df7579..9ffce87838 100644
--- a/usr/src/common/crypto/fips/fips_post.h
+++ b/usr/src/common/crypto/fips/fips_post.h
@@ -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 @@ extern "C" {
#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 @@ extern "C" {
#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
diff --git a/usr/src/common/crypto/fips/fips_rsa_util.c b/usr/src/common/crypto/fips/fips_rsa_util.c
index d608f223a6..7cb121b92f 100644
--- a/usr/src/common/crypto/fips/fips_rsa_util.c
+++ b/usr/src/common/crypto/fips/fips_rsa_util.c
@@ -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>
-#include <sys/crypto/common.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)
-{
-
- 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);
-}
-
-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);
+#ifdef _KERNEL
- if (big_cmp_abs(&msg, &(rsakey->n)) > 0) {
- rv = CKR_DATA_LEN_RANGE;
- goto clean4;
- }
+#include <sys/param.h>
+#include <sys/kmem.h>
- /* 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;
- }
+#include <strings.h>
+#include <cryptoutil.h>
+#include "softMAC.h"
- /* Convert the big integer output data to octet string. */
- bignum2bytestring((uchar_t *)out, &msg, key->modulus_len);
+#include <security/cryptoki.h>
+#include <sys/crypto/common.h>
-clean4:
- big_finish(&msg);
-clean3:
- RSA_key_finish(rsakey);
-clean2:
-#ifndef _KERNEL
- free(rsakey);
-#else
- kmem_free(rsakey, sizeof (RSAkey));
#endif
-clean1:
-
- return (rv);
-}
+#include <padding/padding.h>
+#include <sha2/sha2_impl.h>
+#define _RSA_FIPS_POST
+#include <rsa/rsa_impl.h>
int
-fips_rsa_sign(RSAPrivateKey_t *rsa_params, uint8_t *in,
- uint32_t inlen, uint8_t *out)
+fips_rsa_encrypt(RSAPrivateKey_t *key, uint8_t *in, int in_len, 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);
-
+ return (rsa_encrypt(&(key->bkey), in, in_len, out));
}
int
-fips_rsa_verify(RSAPrivateKey_t *rsa_params, uint8_t *in, uint32_t in_len,
- uint8_t *out)
+fips_rsa_decrypt(RSAPrivateKey_t *key, uint8_t *in, int 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 @@ fips_rsa_sign_verify_test(CK_MECHANISM_TYPE mechanism,
}
}
- 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 @@ fips_rsa_sign_verify_test(CK_MECHANISM_TYPE mechanism,
* 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 @@ fips_rsa_sign_verify_test(CK_MECHANISM_TYPE mechanism,
* 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 @@ fips_rsa_post(void)
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 @@ fips_rsa_post(void)
*/
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,
diff --git a/usr/src/common/crypto/padding/Makefile b/usr/src/common/crypto/padding/Makefile
new file mode 100644
index 0000000000..8a3b35327a
--- /dev/null
+++ b/usr/src/common/crypto/padding/Makefile
@@ -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:
+
diff --git a/usr/src/common/crypto/padding/padding.h b/usr/src/common/crypto/padding/padding.h
new file mode 100644
index 0000000000..a27d17895e
--- /dev/null
+++ b/usr/src/common/crypto/padding/padding.h
@@ -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 */
diff --git a/usr/src/common/crypto/padding/pkcs1.c b/usr/src/common/crypto/padding/pkcs1.c
new file mode 100644
index 0000000000..c7e4970d72
--- /dev/null
+++ b/usr/src/common/crypto/padding/pkcs1.c
@@ -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);
+}
diff --git a/usr/src/common/crypto/padding/pkcs7.c b/usr/src/common/crypto/padding/pkcs7.c
new file mode 100644
index 0000000000..e1277c7bf8
--- /dev/null
+++ b/usr/src/common/crypto/padding/pkcs7.c
@@ -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);
+}
diff --git a/usr/src/common/crypto/rsa/rsa_impl.c b/usr/src/common/crypto/rsa/rsa_impl.c
index 220fe0be83..f6e637fe68 100644
--- a/usr/src/common/crypto/rsa/rsa_impl.c
+++ b/usr/src/common/crypto/rsa/rsa_impl.c
@@ -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 SHA512_DER_PREFIX[SHA2_DER_PREFIX_Len] = {0x30, 0x51, 0x30, 0x0d,
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 @@ ret1:
return (err);
}
-
-void
+static void
RSA_key_finish(RSAkey *key)
{
@@ -165,162 +190,472 @@ RSA_key_finish(RSAkey *key)
}
-
/*
- * 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;
-
- padlen = padbuflen - datalen;
- if (padlen < MIN_PKCS1_PADLEN) {
- return (CKR_DATA_LEN_RANGE);
+ 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;
+
+ 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);
}
- /* Pad with 0x0002+non-zero pseudorandom numbers+0x00. */
- padbuf[0] = 0x00;
- padbuf[1] = 0x02;
+ rf = rfunc;
+ if (rf == NULL) {
#ifdef _KERNEL
- rv = knzero_random_generator(padbuf + 2, padbuflen - 3);
+ rf = (int (*)(void *, size_t))random_get_pseudo_bytes;
#else
- rv = CKR_OK;
- if (pkcs11_get_nzero_urandom(padbuf + 2, padbuflen - 3) < 0)
- rv = CKR_DEVICE_ERROR;
+ rf = pkcs11_get_urandom;
#endif
- if (rv != CKR_OK) {
- return (rv);
}
- padbuf[padlen - 1] = 0x00;
- bcopy(databuf, padbuf + padlen, datalen);
+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;
+ }
+
+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;
+ }
+ 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);
+
+ /* 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);
- /* Check to see if the recovered data is padded is 0x0002. */
- if (padbuf[0] != 0x00 || padbuf[1] != 0x02) {
- return (CKR_ENCRYPTED_DATA_INVALID);
+ /* Must have public exponent set */
+ if (bkey->pubexpo_bytes == 0 || bkey->pubexpo == NULL)
+ return (CKR_ARGUMENTS_BAD);
+
+ /* 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);
}
- /* 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;
+ /*
+ * Initialize the RSA key.
+ */
+ if (RSA_key_init(&rsakey, modulus_bytes * 4, modulus_bytes * 4) !=
+ BIG_OK) {
+ return (CKR_HOST_MEMORY);
+ }
- return (CKR_OK);
- }
+ /* 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);
+
+ 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);
- padlen = mbit_l - dataLen;
- if (padlen < MIN_PKCS1_PADLEN) {
- return (CKR_DATA_LEN_RANGE);
+ /* 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);
+
+ /* 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);
}
- 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);
+ /* 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);
+ }
+
+ /* 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);
+
+ /* 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);
+ }
- /* Check to see if the padding of recovered data starts with 0x0001. */
- if ((data[0] != 0x00) || (data[1] != 0x01)) {
- return (CKR_SIGNATURE_INVALID);
+ /* 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);
- return (CKR_OK);
- } else if (data[i] != 0xFF) {
- return (CKR_SIGNATURE_INVALID);
- }
+ /* 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);
+
+ 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);
}
diff --git a/usr/src/common/crypto/rsa/rsa_impl.h b/usr/src/common/crypto/rsa/rsa_impl.h
index 89a7d49a50..60aba07d72 100644
--- a/usr/src/common/crypto/rsa/rsa_impl.h
+++ b/usr/src/common/crypto/rsa/rsa_impl.h
@@ -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 @@ extern "C" {
#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 @@ extern "C" {
#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 SHA384_DER_PREFIX[SHA2_DER_PREFIX_Len];
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 @@ typedef struct {
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);
-
-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);
-
-#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
+/* 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 rsa_genkey_pair(RSAbytekey *bkey);
+
+CK_RV rsa_encrypt(RSAbytekey *bkey,
+ uchar_t *msg, uint32_t msglen, uchar_t *encrmsg);
+
+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 @@ void kmemset(uint8_t *buf, char pattern, size_t len);
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 */
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/Makefile.com b/usr/src/lib/pkcs11/libsoftcrypto/Makefile.com
index e3669a3b80..afa93ad2a2 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/Makefile.com
+++ b/usr/src/lib/pkcs11/libsoftcrypto/Makefile.com
@@ -18,9 +18,11 @@
#
# CDDL HEADER END
#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+
#
# lib/pkcs11/libsoftcrypto/Makefile.com
#
@@ -49,7 +51,7 @@ DES_COMMON_OBJS= des_impl.o des_ks.o
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 @@ BIGNUM_FLAGS= -I$(BIGNUM_DIR)
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 @@ ARCFOUR_OBJS= $(ARCFOUR_COMMON_OBJS) $(ARCFOUR_PSM_OBJS)
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 @@ ARCFOUR_SRC= $(ARCFOUR_COMMON_SRC) $(ARCFOUR_PSM_SRC)
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 @@ SRCS= $(AES_SRC) $(ARCFOUR_SRC) $(BIGNUM_SRC) $(BLOWFISH_SRC) $(DES_SRC) \
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 @@ pics/%.o: $(DES_DIR)/%.c
$(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
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/amd64/Makefile b/usr/src/lib/pkcs11/libsoftcrypto/amd64/Makefile
index 2428cd56e0..fdfc885a93 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/amd64/Makefile
+++ b/usr/src/lib/pkcs11/libsoftcrypto/amd64/Makefile
@@ -18,9 +18,11 @@
#
# CDDL HEADER END
#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+
#
# lib/pkcs11/libsoftcrypto/amd64/Makefile
#
@@ -47,7 +49,7 @@ BIGNUM_FLAGS += -DPSR_MUL
LINTFLAGS64 += $(BIGNUM_FLAGS) $(AES_FLAGS) $(ARCFOUR_FLAGS)
CLEANFILES += arcfour-x86_64.s
-LDLIBS += -lc
+LDLIBS += -lcryptoutil
LIBS += $(LINTLIB)
install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/common/llib-lsoftcrypto b/usr/src/lib/pkcs11/libsoftcrypto/common/llib-lsoftcrypto
index e3d489b13c..a32a15a267 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/common/llib-lsoftcrypto
+++ b/usr/src/lib/pkcs11/libsoftcrypto/common/llib-lsoftcrypto
@@ -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>
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/common/mapfile-vers b/usr/src/lib/pkcs11/libsoftcrypto/common/mapfile-vers
index dd044efe8f..fd67ce6797 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/common/mapfile-vers
+++ b/usr/src/lib/pkcs11/libsoftcrypto/common/mapfile-vers
@@ -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 @@ SUNWprivate {
big_modexp_crt;
big_mul;
big_nextprime_pos;
+ big_random;
big_sub;
big_sub_pos;
bignum2bytestring;
@@ -82,6 +83,25 @@ SUNWprivate {
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:
*;
};
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/i386/Makefile b/usr/src/lib/pkcs11/libsoftcrypto/i386/Makefile
index a16c437698..dcd7241c09 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/i386/Makefile
+++ b/usr/src/lib/pkcs11/libsoftcrypto/i386/Makefile
@@ -18,9 +18,11 @@
#
# CDDL HEADER END
#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+
#
# lib/pkcs11/libsoftcrypto/i386/Makefile
#
@@ -30,8 +32,9 @@ VERS= .1
include ../Makefile.com
-LDLIBS += -lc
+LDLIBS += -lcryptoutil
LIBS += $(LINTLIB)
+
DYNFLAGS += -Wl,-f/usr/lib/libsoftcrypto/\$$HWCAP
install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/i386_hwcap1/Makefile b/usr/src/lib/pkcs11/libsoftcrypto/i386_hwcap1/Makefile
index 0bbc993a63..4f2eaa539b 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/i386_hwcap1/Makefile
+++ b/usr/src/lib/pkcs11/libsoftcrypto/i386_hwcap1/Makefile
@@ -18,9 +18,11 @@
#
# CDDL HEADER END
#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+
#
# lib/pkcs11/libsoftcrypto/i386_hwcap1/Makefile
#
@@ -37,7 +39,8 @@ include ../Makefile.com
BIGNUM_FLAGS += -DMMX_MANAGE -DHWCAP -DPSR_MUL
LINTFLAGS += $(BIGNUM_FLAGS)
-LDLIBS += -lc
+
+LDLIBS += -lcryptoutil
$(ROOTHWCAPDIR)/% := FILEMODE= 755
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/sparc/Makefile b/usr/src/lib/pkcs11/libsoftcrypto/sparc/Makefile
index 8d57c71b5a..56ad2c2205 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/sparc/Makefile
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sparc/Makefile
@@ -18,9 +18,11 @@
#
# CDDL HEADER END
#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+
#
# lib/pkcs11/libsoftcrypto/sparc/Makefile
#
@@ -30,7 +32,7 @@ VERS= .1
include ../Makefile.com
-LDLIBS += -lc
+LDLIBS += -lcryptoutil
LIBS += $(LINTLIB)
DYNFLAGS += -Wl,-f/usr/platform/\$$PLATFORM/lib/$(DYNLIBPSR)
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/sparcv9/Makefile b/usr/src/lib/pkcs11/libsoftcrypto/sparcv9/Makefile
index 952e064d45..037a1e36ef 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/sparcv9/Makefile
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sparcv9/Makefile
@@ -18,9 +18,11 @@
#
# CDDL HEADER END
#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+
#
# lib/pkcs11/libsoftcrypto/sparcv9/Makefile
#
@@ -31,7 +33,7 @@ VERS= .1
include ../Makefile.com
include $(SRC)/lib/Makefile.lib.64
-LDLIBS += -lc
+LDLIBS += -lcryptoutil
LIBS += $(LINTLIB)
DYNFLAGS += -Wl,-f/usr/platform/\$$PLATFORM/lib/$(MACH64)/$(DYNLIBPSR)
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/sun4u/Makefile.com b/usr/src/lib/pkcs11/libsoftcrypto/sun4u/Makefile.com
index b11f77cc2e..331bc8d77f 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4u/Makefile.com
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4u/Makefile.com
@@ -18,9 +18,11 @@
#
# CDDL HEADER END
#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+
#
# lib/pkcs11/libsoftcrypto/sun4u/Makefile.com
#
@@ -35,6 +37,75 @@ include ../Makefile.links
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 @@ OBJECTS = $(AES_OBJS) $(ARCFOUR_OBJS) $(DES_OBJS) $(BIGNUM_OBJS) \
$(MODES_OBJS)
# Compiler settings
-LDLIBS += -lc
CFLAGS += -D$(PLATFORM)
CFLAGS64 += -D$(PLATFORM)
ASFLAGS += -DPIC
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/sun4u/mapfile-vers b/usr/src/lib/pkcs11/libsoftcrypto/sun4u/mapfile-vers
index 7435a895ad..cb7d38c488 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4u/mapfile-vers
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4u/mapfile-vers
@@ -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 @@ SUNWprivate {
big_modexp_crt;
big_mul;
big_nextprime_pos;
+ big_random;
big_sub;
big_sub_pos;
bignum2bytestring;
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparc/Makefile b/usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparc/Makefile
index 9c83a288f3..a3d0363d6d 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparc/Makefile
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparc/Makefile
@@ -18,9 +18,11 @@
#
# CDDL HEADER END
#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+
#
# lib/pkcs11/libsoftcrypto/sun4u/sparc/Makefile
#
@@ -30,7 +32,7 @@ CLASS = 32
include ../Makefile.com
ASFLAGS += -xarch=v8plus
-LINTFLAGS += -D$(PLATFORM)
+LINTFLAGS += -D$(PLATFORM) -erroff=E_STATIC_UNUSED
install: all $(SOFT_PSR_LINKS) $(USR_PSM_LIBS)
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparcv9/Makefile b/usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparcv9/Makefile
index 6cf0f4f3d5..49c32e620d 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparcv9/Makefile
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4u/sparcv9/Makefile
@@ -18,9 +18,11 @@
#
# CDDL HEADER END
#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+
#
# lib/pkcs11/libsoftcrypto/sun4u/sparcv9/Makefile
#
@@ -30,7 +32,8 @@ CLASS = 64
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)
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/sun4v/Makefile.com b/usr/src/lib/pkcs11/libsoftcrypto/sun4v/Makefile.com
index 5ff3501370..3bc7dc8048 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4v/Makefile.com
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4v/Makefile.com
@@ -18,9 +18,11 @@
#
# CDDL HEADER END
#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+
#
# lib/pkcs11/libsoftcrypto/sun4v/Makefile.com
#
@@ -35,10 +37,17 @@ include ../Makefile.links
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 @@ CFLAGS += -xO5 -xbuiltin=%all -dalign -D$(PLATFORM)
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
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/sun4v/mapfile-vers b/usr/src/lib/pkcs11/libsoftcrypto/sun4v/mapfile-vers
index 3a4436e3d4..5b6e46606c 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4v/mapfile-vers
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4v/mapfile-vers
@@ -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 @@ SUNWprivate {
big_modexp_crt;
big_mul;
big_nextprime_pos;
+ big_random;
big_sub;
big_sub_pos;
bignum2bytestring;
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparc/Makefile b/usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparc/Makefile
index d972c319b2..35a083de83 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparc/Makefile
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparc/Makefile
@@ -18,9 +18,11 @@
#
# CDDL HEADER END
#
+
+#
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
-# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+
#
# lib/pkcs11/libsoftcrypto/sun4v/sparc/Makefile
#
@@ -29,7 +31,7 @@ CLASS = 32
include ../Makefile.com
-LINTFLAGS += -D$(PLATFORM)
+LINTFLAGS += -D$(PLATFORM) -erroff=E_NAME_MULTIPLY_DEF2
install: all $(SOFT_PSR_LINKS) $(USR_PSM_LIBS)
diff --git a/usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparcv9/Makefile b/usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparcv9/Makefile
index 4c82742a86..ba8463e5ae 100644
--- a/usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparcv9/Makefile
+++ b/usr/src/lib/pkcs11/libsoftcrypto/sun4v/sparcv9/Makefile
@@ -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 @@ CLASS = 64
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)
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/Makefile.com b/usr/src/lib/pkcs11/pkcs11_softtoken/Makefile.com
index 5c20226bb8..76218533ae 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/Makefile.com
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/Makefile.com
@@ -51,13 +51,11 @@ LCL_OBJECTS = \
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 @@ LCL_OBJECTS = \
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 @@ ECC_COBJECTS = \
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 @@ BER_OBJECTS = bprint.o decode.o encode.o io.o
OBJECTS = \
$(LCL_OBJECTS) \
$(MPI_OBJECTS) \
- $(RSA_OBJECTS) \
$(RNG_OBJECTS) \
$(FIPS_OBJECTS) \
$(BIGNUM_OBJECTS) \
@@ -105,6 +100,8 @@ AESDIR= $(SRC)/common/crypto/aes
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 @@ FIPSDIR= $(SRC)/common/crypto/fips
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 @@ SRCDIR= ../common
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 @@ LDLIBS += -lc -lmd -lcryptoutil -lsoftcrypto -lgen
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 @@ ROOTLIBDIR64= $(ROOT)/usr/lib/security/$(MACH64)
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 @@ pics/%.o: $(MPIDIR)/%.c
$(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)
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c
index 213492e322..7f2810033b 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softAESCrypt.c
@@ -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 @@ do_decryption:
* 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,
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c
index 0064e19db2..77f10e56d3 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c
@@ -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 @@ pad_bigint_attr(biginteger_t *src, biginteger_t *dst)
/* 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 @@ rsa_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
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 @@ cleanup_dsapri2asn:
}
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 @@ cleanup_dhpri2asn:
}
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 @@ cleanup_x942dhpri2asn:
}
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);
}
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.c
deleted file mode 100644
index 6042004d56..0000000000
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.c
+++ /dev/null
@@ -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);
- }
-}
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.h
index 8be7a430ed..d4c58bc9d3 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.h
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softCrypt.h
@@ -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 @@ extern "C" {
#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 @@ CK_RV soft_des_mac_sign_verify_update(soft_session_t *session_p,
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_encrypt_common(soft_session_t *, CK_BYTE_PTR, CK_ULONG,
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
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDESCrypt.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDESCrypt.c
index 84f4fd00be..8159e93624 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDESCrypt.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDESCrypt.c
@@ -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 @@ soft_des_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted,
* 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,
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.c
index 7991f7c267..06d9c22757 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.c
@@ -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 @@ soft_genDHkey_set_attribute(soft_object_t *key, BIGNUM *bn,
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 @@ CK_RV
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 @@ soft_dh_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
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);
-
- if (rv != CKR_OK) {
- 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);
-
+ /* Get private-value length in bits */
template.pValue = malloc(sizeof (CK_ULONG));
-
if (template.pValue == NULL) {
- rv = CKR_HOST_MEMORY;
- goto ret2;
+ 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) {
- goto ret2;
+ free(template.pValue);
+ return (rv);
}
- /*
- * 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 @@ soft_dh_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
value_bits = *((CK_ULONG *)(template.pValue));
#endif /* __sparcv9 */
- if (value_bits > primebit_len) {
- rv = CKR_ATTRIBUTE_VALUE_INVALID;
- goto ret3;
- }
+ free(template.pValue);
- /* Generate DH key pair private and public values. */
- if ((brv = big_init(&bnprival, CHARLEN2BIGNUMLEN(prime_len)))
- != BIG_OK) {
- rv = convert_rv(brv);
- goto ret3;
+ /*
+ * 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);
+ if (rv != CKR_OK) {
+ return (rv);
}
- if ((brv = big_init(&bnpubval, CHARLEN2BIGNUMLEN(prime_len)))
- != BIG_OK) {
- rv = convert_rv(brv);
- goto ret4;
+ rv = soft_get_public_value(pubkey, CKA_BASE, base, &base_len);
+ if (rv != CKR_OK) {
+ goto ret;
}
- /*
- * The big integer of the private value shall be generated privately
- * and randomly.
- */
- 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;
- }
+ /* 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;
- /*
- * 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;
+ /* 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 @@ soft_dh_key_derive(soft_object_t *basekey, soft_object_t *secretkey,
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;
- }
-
- 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;
+ goto ret;
}
- if ((buf = malloc((privateprimelen + sizeof (BIG_CHUNK_TYPE) - 1) &
- ~(sizeof (BIG_CHUNK_TYPE) - 1))) == NULL) {
- rv = CKR_HOST_MEMORY;
- 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;
}
- value = buf;
- valuelen = bnsecret.len * (int)sizeof (BIG_CHUNK_TYPE);
- bignum2bytestring(value, &bnsecret, valuelen);
-
- switch (secretkey->key_type) {
-
- 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;
- }
+ 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;
- 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.
- */
+ /* 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 > 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;
+ (void) memcpy(OBJ_SEC_VALUE(secretkey), key, 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:
+ret:
return (rv);
}
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.h
index 1e1db2bc22..ea0f83a962 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.h
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDH.h
@@ -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.
*/
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.c
index 24e3d1b7f5..b366cc2171 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.c
@@ -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 @@ soft_dsa_sign_verify_init_common(soft_session_t *session_p,
}
-/* size is in bits */
-BIG_ERR_CODE
-DSA_key_init(DSAkey *key, int size)
-{
- 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)
+static CK_RV
+local_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 @@ dsa_sign(soft_object_t *key, CK_BYTE_PTR in, CK_ULONG inlen, CK_BYTE_PTR out)
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 @@ dsa_sign(soft_object_t *key, CK_BYTE_PTR in, CK_ULONG inlen, CK_BYTE_PTR out)
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;
-
- if ((err = big_div_pos(NULL, &(dsakey.r), &tmp, &(dsakey.q))) !=
- 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_ext_gcd_pos(NULL, NULL, &tmp, &(dsakey.q),
- &(dsakey.k))) != BIG_OK)
- goto clean10;
+ rv = dsa_sign(&k, in, inlen, out);
- 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;
-
- 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 @@ dsa_verify(soft_object_t *key, CK_BYTE_PTR data, CK_BYTE_PTR sig)
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 @@ dsa_verify(soft_object_t *key, CK_BYTE_PTR data, CK_BYTE_PTR sig)
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;
+ rv = dsa_verify(&k, data, sig);
- 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:
return (rv);
}
@@ -538,7 +304,7 @@ soft_dsa_sign(soft_session_t *session_p, CK_BYTE_PTR pData,
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 @@ soft_dsa_verify(soft_session_t *session_p, CK_BYTE_PTR pData,
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);
+ /* The signature length is always 40 bytes. */
+ if (ulSignatureLen != DSA_SIGNATURE_LENGTH) {
+ rv = CKR_SIGNATURE_LEN_RANGE;
+ goto clean_exit;
+ }
+
+ rv = local_dsa_verify(key, pData, pSignature);
clean_exit:
(void) pthread_mutex_lock(&session_p->session_mutex);
@@ -635,7 +401,7 @@ clean_exit:
}
-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 @@ soft_genDSAkey_set_attribute(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
biginteger_t *dst = NULL;
biginteger_t src;
-
switch (type) {
case CKA_VALUE:
@@ -676,13 +441,14 @@ soft_genDSAkey_set_attribute(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
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 @@ cleanexit:
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 @@ soft_dsa_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
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 @@ soft_dsa_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
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;
- }
-
- if ((brv = big_extend(&dsakey.p,
- CHARLEN2BIGNUMLEN(prime_len))) != BIG_OK) {
- rv = convert_rv(brv);
- goto cleanexit;
- }
-
- bytestring2bignum(&dsakey.p, prime, prime_len);
-
- if ((brv = big_extend(&dsakey.q, CHARLEN2BIGNUMLEN(subprime_len))) !=
- BIG_OK) {
- rv = convert_rv(brv);
- goto cleanexit;
- }
-
- bytestring2bignum(&dsakey.q, subprime, subprime_len);
+ /* 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.g, CHARLEN2BIGNUMLEN(base_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.g, base, base_len);
+ rv = dsa_genkey_pair(&k);
- /*
- * 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;
+ if (rv != CKR_OK) {
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);
}
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.h
index 1cee89bc95..cceb6727f4 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.h
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDSA.h
@@ -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_verify(soft_session_t *, CK_BYTE_PTR, CK_ULONG,
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,
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDecryptUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDecryptUtil.c
index 7b912c68ce..355c3b5bdd 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDecryptUtil.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softDecryptUtil.c
@@ -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_RV rv;
- CK_BYTE pad_value;
- ulong_t i;
-
- pad_value = pData[padded_len - 1];
-
-
- /* Make sure there is a valid padding value. */
- if ((pad_value == 0) || (pad_value > block_size))
- return (CKR_ENCRYPTED_DATA_INVALID);
-
- for (i = padded_len - pad_value; i < padded_len; i++)
- if (pad_value != pData[i])
- 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);
- *pulDataLen = padded_len - pad_value;
+ *pulDataLen = padded_len;
return (CKR_OK);
}
@@ -604,7 +596,7 @@ soft_decrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastPart,
* 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 @@ soft_decrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastPart,
* 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
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c
index 8fa02ea1d0..39e863065e 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softEncryptUtil.c
@@ -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 @@ clean1:
* 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,
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSA.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSA.h
deleted file mode 100644
index 52cea0dcee..0000000000
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSA.h
+++ /dev/null
@@ -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 */
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSAUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSAUtil.c
deleted file mode 100644
index e8c7f2ee6f..0000000000
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsDSAUtil.c
+++ /dev/null
@@ -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);
-
-}
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPost.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPost.c
index e9bc272eee..7fdec8d5cf 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPost.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPost.c
@@ -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 @@ soft_fips_post(void)
* 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);
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPostUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPostUtil.c
index 5c9ab5c6d8..7cdb65edc8 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPostUtil.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softFipsPostUtil.c
@@ -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
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.h
index 64e154c314..ea73e1a58d 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.h
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObject.h
@@ -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 soft_add_extra_attr(CK_ATTRIBUTE_PTR template, soft_object_t *object_p);
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
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObjectUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObjectUtil.c
index aacc01a5a7..9794565299 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObjectUtil.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softObjectUtil.c
@@ -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 @@ cleanup:
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);
+}
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.c
index 669c1bfda4..a919b32d0e 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.c
@@ -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 @@ soft_rsa_encrypt(soft_object_t *key, CK_BYTE_PTR in, uint32_t in_len,
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 @@ soft_rsa_encrypt(soft_object_t *key, CK_BYTE_PTR in, uint32_t in_len,
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;
- }
+ k.modulus = modulus;
+ k.modulus_bits = CRYPTO_BYTES2BITS(modulus_len);
+ k.pubexpo = expo;
+ k.pubexpo_bytes = expo_len;
+ k.rfunc = NULL;
- 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);
-
- /* 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 @@ soft_rsa_decrypt(soft_object_t *key, CK_BYTE_PTR in, uint32_t in_len,
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 @@ soft_rsa_decrypt(soft_object_t *key, CK_BYTE_PTR in, uint32_t in_len,
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);
+ rv = rsa_decrypt(&k, in, in_len, out);
- 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;
- }
-
- /* 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 @@ soft_rsa_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData,
* 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 @@ soft_rsa_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted,
}
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 @@ soft_rsa_sign_common(soft_session_t *session_p, CK_BYTE_PTR pData,
* 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 @@ soft_rsa_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
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 @@ soft_rsa_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
* 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 @@ clean_exit:
}
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 @@ soft_genRSAkey_set_attribute(soft_object_t *key, RSAkey *rsakey,
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 @@ soft_genRSAkey_set_attribute(soft_object_t *key, RSAkey *rsakey,
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 @@ soft_rsa_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
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 @@ soft_rsa_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
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);
-
- if (RSA_key_init(&rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) {
- rv = CKR_HOST_MEMORY;
- goto clean2;
- }
+ /* 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;
+
+ /* 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;
+
+ rv = rsa_genkey_pair(&k);
- /* 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;
+ 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(pubkey, CKA_MODULUS,
+ modulus, CRYPTO_BITS2BYTES(k.modulus_bits), B_TRUE)) != CKR_OK) {
+ goto clean0;
}
- if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
- CKA_MODULUS, 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_PRIVATE_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_PUBLIC_EXPONENT, 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_1, 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_PRIME_2, 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_1, 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_EXPONENT_2, 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;
}
- 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_COEFFICIENT,
+ coefficient, k.coeff_bytes, B_FALSE)) != CKR_OK) {
+ goto clean0;
}
-clean3:
- RSA_key_finish(&rsakey);
-clean2:
- big_finish(&public_exponent);
clean0:
- free(template.pValue);
-
return (rv);
}
@@ -1509,9 +1216,9 @@ soft_rsa_verify_recover(soft_session_t *session_p, CK_BYTE_PTR pSignature,
* 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;
}
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.h
index ffc86f4370..e25390f2fa 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.h
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.h
@@ -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 {
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandUtil.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandUtil.c
deleted file mode 100644
index 0a63501cf2..0000000000
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandUtil.c
+++ /dev/null
@@ -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);
-}
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h
deleted file mode 100644
index 2307ac7264..0000000000
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRandom.h
+++ /dev/null
@@ -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 */
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.h b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.h
index 9dba84c946..39bff659e2 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.h
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSSL.h
@@ -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"
diff --git a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c
index 85249f6d45..a18633094d 100644
--- a/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c
+++ b/usr/src/lib/pkcs11/pkcs11_softtoken/common/softSlotToken.c
@@ -18,6 +18,7 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -207,10 +208,10 @@ static CK_MECHANISM_INFO soft_mechanism_info[] = {
{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 */
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index f7352b7ed6..fd94035afe 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -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 @@ ECCPROV_OBJS += ecc.o ec.o ec2_163.o ec2_mont.o ecdecode.o ecl_mult.o \
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
diff --git a/usr/src/uts/common/Makefile.rules b/usr/src/uts/common/Makefile.rules
index 62a7a1a470..246212a52d 100644
--- a/usr/src/uts/common/Makefile.rules
+++ b/usr/src/uts/common/Makefile.rules
@@ -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 @@ $(OBJS_DIR)/%.o: $(COMMONBASE)/crypto/modes/%.c
$(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/fips/%.c
$(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))
diff --git a/usr/src/uts/common/crypto/io/rsa.c b/usr/src/uts/common/crypto/io/rsa.c
index d38d7f18e8..eff25fa42a 100644
--- a/usr/src/uts/common/crypto/io/rsa.c
+++ b/usr/src/uts/common/crypto/io/rsa.c
@@ -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 crypto_control_ops_t rsa_control_ops = {
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 int rsa_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
*/
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 crypto_cipher_ops_t rsa_cipher_ops = {
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 int rsa_sign_atomic(crypto_provider_handle_t, crypto_session_id_t,
*/
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 int rsa_verify_recover_atomic(crypto_provider_handle_t,
*/
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 crypto_provider_info_t rsa_prov_info = {
};
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 @@ rsa_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
/* 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 @@ rsa_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
/*
* 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_encrypt_atomic(crypto_provider_handle_t provider,
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 @@ rsa_free_context(crypto_ctx_t *ctx)
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 @@ rsa_encrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key,
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 @@ rsa_encrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key,
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 @@ rsa_encrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key,
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 @@ core_rsa_encrypt(crypto_key_t *key, uchar_t *in,
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);
-
- 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;
- }
+ k.modulus = modulus;
+ k.modulus_bits = CRYPTO_BYTES2BITS(modulus_len);
+ k.pubexpo = expo;
+ k.pubexpo_bytes = expo_len;
+ k.rfunc = NULL;
- /* 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 @@ clean1:
/* 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_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
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_decrypt_atomic(crypto_provider_handle_t provider,
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 @@ rsa_decrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key,
!= 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 @@ rsa_decrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key,
/* 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 @@ core_rsa_decrypt(crypto_key_t *key, uchar_t *in, int in_len,
!= 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;
- }
-
- /* 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;
- }
-
- /* 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;
+ return (core_rsa_encrypt(key, in, in_len, out, 0));
}
- /* 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));
+ 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;
+
+ rv = rsa_decrypt(&k, in, in_len, out);
return (rv);
}
@@ -1060,7 +964,7 @@ rsa_sign_verify_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
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 @@ rsa_digest_svrfy_common(digest_rsa_ctx_t *ctxp, crypto_data_t *data,
*/
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 @@ rsa_digest_svrfy_common(digest_rsa_ctx_t *ctxp, crypto_data_t *data,
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 @@ rsa_sign_common(rsa_mech_type_t mech_type, crypto_key_t *key,
* 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 @@ rsa_sign_common(rsa_mech_type_t mech_type, crypto_key_t *key,
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 @@ rsa_sign_common(rsa_mech_type_t mech_type, crypto_key_t *key,
/* 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 @@ rsa_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
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 @@ rsa_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
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 @@ rsa_sign_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req)
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 @@ rsa_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature,
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 @@ rsa_sign_atomic(crypto_provider_handle_t provider,
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 @@ rsa_sign_atomic(crypto_provider_handle_t provider,
}
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 @@ rsa_sign_atomic(crypto_provider_handle_t provider,
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 @@ rsa_verify_common(rsa_mech_type_t mech_type, crypto_key_t *key,
!= 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 @@ rsa_verify_common(rsa_mech_type_t mech_type, crypto_key_t *key,
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 @@ rsa_verify_common(rsa_mech_type_t mech_type, crypto_key_t *key,
/* 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 @@ rsa_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
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 @@ rsa_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
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 @@ rsa_verify_update(crypto_ctx_t *ctx, crypto_data_t *data,
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 @@ rsa_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature,
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 @@ rsa_verify_atomic(crypto_provider_handle_t provider,
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 @@ rsa_verify_atomic(crypto_provider_handle_t provider,
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 @@ rsa_verify_atomic(crypto_provider_handle_t provider,
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 @@ rsa_verify_recover_common(rsa_mech_type_t mech_type, crypto_key_t *key,
!= 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 @@ rsa_verify_recover_common(rsa_mech_type_t mech_type, crypto_key_t *key,
* 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 @@ rsa_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature,
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 @@ rsa_verify_recover_atomic(crypto_provider_handle_t provider,
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)
diff --git a/usr/src/uts/sun4v/Makefile.rules b/usr/src/uts/sun4v/Makefile.rules
index b62f8d03e1..2f4730140a 100644
--- a/usr/src/uts/sun4v/Makefile.rules
+++ b/usr/src/uts/sun4v/Makefile.rules
@@ -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/mdesc/%.c
$(LINTS_DIR)/%.ln: $(SRC)/common/atomic/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
+
+$(LINTS_DIR)/%.ln: $(SRC)/common/crypto/arcfour/sun4v/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))