diff options
author | Dina K Nimeh <Dina.Nimeh@Sun.COM> | 2010-06-07 08:54:25 -0700 |
---|---|---|
committer | Dina K Nimeh <Dina.Nimeh@Sun.COM> | 2010-06-07 08:54:25 -0700 |
commit | 726fad2a65f16c200a03969c29cb5c86c2d427db (patch) | |
tree | aca280cc44a7b599ab39116a9229a98428f7c9d7 | |
parent | ad559bec55fd74f310399483501e1fa231f65528 (diff) | |
download | illumos-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
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)) |