xref: /onnv-gate/usr/src/uts/common/crypto/io/rsa.c (revision 10732:498ac26a63d5)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
55072Smcpowers  * Common Development and Distribution License (the "License").
65072Smcpowers  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
2210500SHai-May.Chao@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate  * RSA provider for the Kernel Cryptographic Framework (KCF)
280Sstevel@tonic-gate  */
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #include <sys/types.h>
310Sstevel@tonic-gate #include <sys/systm.h>
320Sstevel@tonic-gate #include <sys/modctl.h>
330Sstevel@tonic-gate #include <sys/cmn_err.h>
340Sstevel@tonic-gate #include <sys/ddi.h>
350Sstevel@tonic-gate #include <sys/crypto/spi.h>
360Sstevel@tonic-gate #include <sys/sysmacros.h>
370Sstevel@tonic-gate #include <sys/strsun.h>
380Sstevel@tonic-gate #include <sys/md5.h>
390Sstevel@tonic-gate #include <sys/sha1.h>
4010500SHai-May.Chao@Sun.COM #define	_SHA2_IMPL
41676Sizick #include <sys/sha2.h>
420Sstevel@tonic-gate #include <sys/random.h>
437188Smcpowers #include <sys/crypto/impl.h>
4410500SHai-May.Chao@Sun.COM #include <sha1/sha1_impl.h>
4510500SHai-May.Chao@Sun.COM #include <sha2/sha2_impl.h>
4610500SHai-May.Chao@Sun.COM #define	_RSA_FIPS_POST
4710500SHai-May.Chao@Sun.COM #include <rsa/rsa_impl.h>
480Sstevel@tonic-gate 
490Sstevel@tonic-gate extern struct mod_ops mod_cryptoops;
500Sstevel@tonic-gate 
510Sstevel@tonic-gate /*
520Sstevel@tonic-gate  * Module linkage information for the kernel.
530Sstevel@tonic-gate  */
540Sstevel@tonic-gate static struct modlcrypto modlcrypto = {
550Sstevel@tonic-gate 	&mod_cryptoops,
565072Smcpowers 	"RSA Kernel SW Provider"
570Sstevel@tonic-gate };
580Sstevel@tonic-gate 
590Sstevel@tonic-gate static struct modlinkage modlinkage = {
600Sstevel@tonic-gate 	MODREV_1,
610Sstevel@tonic-gate 	(void *)&modlcrypto,
620Sstevel@tonic-gate 	NULL
630Sstevel@tonic-gate };
640Sstevel@tonic-gate 
650Sstevel@tonic-gate /*
660Sstevel@tonic-gate  * CSPI information (entry points, provider info, etc.)
670Sstevel@tonic-gate  */
680Sstevel@tonic-gate typedef enum rsa_mech_type {
690Sstevel@tonic-gate 	RSA_PKCS_MECH_INFO_TYPE,	/* SUN_CKM_RSA_PKCS */
700Sstevel@tonic-gate 	RSA_X_509_MECH_INFO_TYPE,	/* SUN_CKM_RSA_X_509 */
710Sstevel@tonic-gate 	MD5_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_MD5_RSA_PKCS */
72676Sizick 	SHA1_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_SHA1_RSA_PKCS */
73676Sizick 	SHA256_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_SHA256_RSA_PKCS */
74676Sizick 	SHA384_RSA_PKCS_MECH_INFO_TYPE,	/* SUN_SHA384_RSA_PKCS */
75676Sizick 	SHA512_RSA_PKCS_MECH_INFO_TYPE	/* SUN_SHA512_RSA_PKCS */
760Sstevel@tonic-gate } rsa_mech_type_t;
770Sstevel@tonic-gate 
780Sstevel@tonic-gate /*
790Sstevel@tonic-gate  * Context for RSA_PKCS and RSA_X_509 mechanisms.
800Sstevel@tonic-gate  */
810Sstevel@tonic-gate typedef struct rsa_ctx {
820Sstevel@tonic-gate 	rsa_mech_type_t	mech_type;
830Sstevel@tonic-gate 	crypto_key_t *key;
840Sstevel@tonic-gate 	size_t keychunk_size;
850Sstevel@tonic-gate } rsa_ctx_t;
860Sstevel@tonic-gate 
870Sstevel@tonic-gate /*
88676Sizick  * Context for MD5_RSA_PKCS and SHA*_RSA_PKCS mechanisms.
890Sstevel@tonic-gate  */
900Sstevel@tonic-gate typedef struct digest_rsa_ctx {
910Sstevel@tonic-gate 	rsa_mech_type_t	mech_type;
920Sstevel@tonic-gate 	crypto_key_t *key;
930Sstevel@tonic-gate 	size_t keychunk_size;
940Sstevel@tonic-gate 	union {
950Sstevel@tonic-gate 		MD5_CTX md5ctx;
960Sstevel@tonic-gate 		SHA1_CTX sha1ctx;
97676Sizick 		SHA2_CTX sha2ctx;
980Sstevel@tonic-gate 	} dctx_u;
990Sstevel@tonic-gate } digest_rsa_ctx_t;
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate #define	md5_ctx		dctx_u.md5ctx
1020Sstevel@tonic-gate #define	sha1_ctx	dctx_u.sha1ctx
103676Sizick #define	sha2_ctx	dctx_u.sha2ctx
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate /*
1060Sstevel@tonic-gate  * Mechanism info structure passed to KCF during registration.
1070Sstevel@tonic-gate  */
1080Sstevel@tonic-gate static crypto_mech_info_t rsa_mech_info_tab[] = {
1090Sstevel@tonic-gate 	/* RSA_PKCS */
1100Sstevel@tonic-gate 	{SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE,
1110Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
1120Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
1130Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
1140Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
1150Sstevel@tonic-gate 	    CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
1160Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
1170Sstevel@tonic-gate 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 	/* RSA_X_509 */
1200Sstevel@tonic-gate 	{SUN_CKM_RSA_X_509, RSA_X_509_MECH_INFO_TYPE,
1210Sstevel@tonic-gate 	    CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC |
1220Sstevel@tonic-gate 	    CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC |
1230Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
1240Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC |
1250Sstevel@tonic-gate 	    CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC |
1260Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC,
1270Sstevel@tonic-gate 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 	/* MD5_RSA_PKCS */
1300Sstevel@tonic-gate 	{SUN_CKM_MD5_RSA_PKCS, MD5_RSA_PKCS_MECH_INFO_TYPE,
1310Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
1320Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
1330Sstevel@tonic-gate 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate 	/* SHA1_RSA_PKCS */
1360Sstevel@tonic-gate 	{SUN_CKM_SHA1_RSA_PKCS, SHA1_RSA_PKCS_MECH_INFO_TYPE,
1370Sstevel@tonic-gate 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
1380Sstevel@tonic-gate 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
139676Sizick 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
140676Sizick 
141676Sizick 	/* SHA256_RSA_PKCS */
142676Sizick 	{SUN_CKM_SHA256_RSA_PKCS, SHA256_RSA_PKCS_MECH_INFO_TYPE,
143676Sizick 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
144676Sizick 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
145676Sizick 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
146676Sizick 
147676Sizick 	/* SHA384_RSA_PKCS */
148676Sizick 	{SUN_CKM_SHA384_RSA_PKCS, SHA384_RSA_PKCS_MECH_INFO_TYPE,
149676Sizick 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
150676Sizick 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
151676Sizick 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS},
152676Sizick 
153676Sizick 	/* SHA512_RSA_PKCS */
154676Sizick 	{SUN_CKM_SHA512_RSA_PKCS, SHA512_RSA_PKCS_MECH_INFO_TYPE,
155676Sizick 	    CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC |
156676Sizick 	    CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC,
1570Sstevel@tonic-gate 	    RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}
158676Sizick 
1590Sstevel@tonic-gate };
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate #define	RSA_VALID_MECH(mech)					\
1620Sstevel@tonic-gate 	(((mech)->cm_type == RSA_PKCS_MECH_INFO_TYPE ||		\
1630Sstevel@tonic-gate 	(mech)->cm_type == RSA_X_509_MECH_INFO_TYPE ||		\
1640Sstevel@tonic-gate 	(mech)->cm_type == MD5_RSA_PKCS_MECH_INFO_TYPE ||	\
165676Sizick 	(mech)->cm_type == SHA1_RSA_PKCS_MECH_INFO_TYPE ||	\
166676Sizick 	(mech)->cm_type == SHA256_RSA_PKCS_MECH_INFO_TYPE ||	\
167676Sizick 	(mech)->cm_type == SHA384_RSA_PKCS_MECH_INFO_TYPE ||	\
168676Sizick 	(mech)->cm_type == SHA512_RSA_PKCS_MECH_INFO_TYPE) ? 1 : 0)
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate /* operations are in-place if the output buffer is NULL */
1710Sstevel@tonic-gate #define	RSA_ARG_INPLACE(input, output)				\
1720Sstevel@tonic-gate 	if ((output) == NULL)					\
1730Sstevel@tonic-gate 		(output) = (input);
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate static void rsa_provider_status(crypto_provider_handle_t, uint_t *);
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate static crypto_control_ops_t rsa_control_ops = {
1780Sstevel@tonic-gate 	rsa_provider_status
1790Sstevel@tonic-gate };
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate static int rsa_common_init(crypto_ctx_t *, crypto_mechanism_t *,
1820Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
1830Sstevel@tonic-gate static int rsa_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
1840Sstevel@tonic-gate     crypto_req_handle_t);
1850Sstevel@tonic-gate static int rsa_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
1860Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
1870Sstevel@tonic-gate     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
1880Sstevel@tonic-gate static int rsa_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
1890Sstevel@tonic-gate     crypto_req_handle_t);
1900Sstevel@tonic-gate static int rsa_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t,
1910Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
1920Sstevel@tonic-gate     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate /*
1950Sstevel@tonic-gate  * The RSA mechanisms do not have multiple-part cipher operations.
1960Sstevel@tonic-gate  * So, the update and final routines are set to NULL.
1970Sstevel@tonic-gate  */
1980Sstevel@tonic-gate static crypto_cipher_ops_t rsa_cipher_ops = {
1990Sstevel@tonic-gate 	rsa_common_init,
2000Sstevel@tonic-gate 	rsa_encrypt,
2010Sstevel@tonic-gate 	NULL,
2020Sstevel@tonic-gate 	NULL,
2030Sstevel@tonic-gate 	rsa_encrypt_atomic,
2040Sstevel@tonic-gate 	rsa_common_init,
2050Sstevel@tonic-gate 	rsa_decrypt,
2060Sstevel@tonic-gate 	NULL,
2070Sstevel@tonic-gate 	NULL,
2080Sstevel@tonic-gate 	rsa_decrypt_atomic
2090Sstevel@tonic-gate };
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate static int rsa_sign_verify_common_init(crypto_ctx_t *, crypto_mechanism_t *,
2120Sstevel@tonic-gate     crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
2130Sstevel@tonic-gate static int rsa_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
2140Sstevel@tonic-gate     crypto_req_handle_t);
2150Sstevel@tonic-gate static int rsa_sign_update(crypto_ctx_t *, crypto_data_t *,
2160Sstevel@tonic-gate     crypto_req_handle_t);
2170Sstevel@tonic-gate static int rsa_sign_final(crypto_ctx_t *, crypto_data_t *,
2180Sstevel@tonic-gate     crypto_req_handle_t);
2190Sstevel@tonic-gate static int rsa_sign_atomic(crypto_provider_handle_t, crypto_session_id_t,
2200Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *,
2210Sstevel@tonic-gate     crypto_spi_ctx_template_t, crypto_req_handle_t);
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate /*
2240Sstevel@tonic-gate  * We use the same routine for sign_init and sign_recover_init fields
2250Sstevel@tonic-gate  * as they do the same thing. Same holds for sign and sign_recover fields,
2260Sstevel@tonic-gate  * and sign_atomic and sign_recover_atomic fields.
2270Sstevel@tonic-gate  */
2280Sstevel@tonic-gate static crypto_sign_ops_t rsa_sign_ops = {
2290Sstevel@tonic-gate 	rsa_sign_verify_common_init,
2300Sstevel@tonic-gate 	rsa_sign,
2310Sstevel@tonic-gate 	rsa_sign_update,
2320Sstevel@tonic-gate 	rsa_sign_final,
2330Sstevel@tonic-gate 	rsa_sign_atomic,
2340Sstevel@tonic-gate 	rsa_sign_verify_common_init,
2350Sstevel@tonic-gate 	rsa_sign,
2360Sstevel@tonic-gate 	rsa_sign_atomic
2370Sstevel@tonic-gate };
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate static int rsa_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *,
2400Sstevel@tonic-gate     crypto_req_handle_t);
2410Sstevel@tonic-gate static int rsa_verify_update(crypto_ctx_t *, crypto_data_t *,
2420Sstevel@tonic-gate     crypto_req_handle_t);
2430Sstevel@tonic-gate static int rsa_verify_final(crypto_ctx_t *, crypto_data_t *,
2440Sstevel@tonic-gate     crypto_req_handle_t);
2450Sstevel@tonic-gate static int rsa_verify_atomic(crypto_provider_handle_t, crypto_session_id_t,
2460Sstevel@tonic-gate     crypto_mechanism_t *, crypto_key_t *, crypto_data_t *,
2470Sstevel@tonic-gate     crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t);
2480Sstevel@tonic-gate static int rsa_verify_recover(crypto_ctx_t *, crypto_data_t *,
2490Sstevel@tonic-gate     crypto_data_t *, crypto_req_handle_t);
2500Sstevel@tonic-gate static int rsa_verify_recover_atomic(crypto_provider_handle_t,
2510Sstevel@tonic-gate     crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *,
2520Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t,
2530Sstevel@tonic-gate     crypto_req_handle_t);
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate /*
2560Sstevel@tonic-gate  * We use the same routine (rsa_sign_verify_common_init) for verify_init
2570Sstevel@tonic-gate  * and verify_recover_init fields as they do the same thing.
2580Sstevel@tonic-gate  */
2590Sstevel@tonic-gate static crypto_verify_ops_t rsa_verify_ops = {
2600Sstevel@tonic-gate 	rsa_sign_verify_common_init,
2610Sstevel@tonic-gate 	rsa_verify,
2620Sstevel@tonic-gate 	rsa_verify_update,
2630Sstevel@tonic-gate 	rsa_verify_final,
2640Sstevel@tonic-gate 	rsa_verify_atomic,
2650Sstevel@tonic-gate 	rsa_sign_verify_common_init,
2660Sstevel@tonic-gate 	rsa_verify_recover,
2670Sstevel@tonic-gate 	rsa_verify_recover_atomic
2680Sstevel@tonic-gate };
2690Sstevel@tonic-gate 
2700Sstevel@tonic-gate static int rsa_free_context(crypto_ctx_t *);
2710Sstevel@tonic-gate 
2720Sstevel@tonic-gate static crypto_ctx_ops_t rsa_ctx_ops = {
2730Sstevel@tonic-gate 	NULL,
2740Sstevel@tonic-gate 	rsa_free_context
2750Sstevel@tonic-gate };
2760Sstevel@tonic-gate 
277*10732SAnthony.Scarpino@Sun.COM static void rsa_POST(int *);
278*10732SAnthony.Scarpino@Sun.COM 
279*10732SAnthony.Scarpino@Sun.COM static crypto_fips140_ops_t rsa_fips140_ops = {
280*10732SAnthony.Scarpino@Sun.COM 	rsa_POST
281*10732SAnthony.Scarpino@Sun.COM };
282*10732SAnthony.Scarpino@Sun.COM 
2830Sstevel@tonic-gate static crypto_ops_t rsa_crypto_ops = {
2840Sstevel@tonic-gate 	&rsa_control_ops,
2850Sstevel@tonic-gate 	NULL,
2860Sstevel@tonic-gate 	&rsa_cipher_ops,
2870Sstevel@tonic-gate 	NULL,
2880Sstevel@tonic-gate 	&rsa_sign_ops,
2890Sstevel@tonic-gate 	&rsa_verify_ops,
2900Sstevel@tonic-gate 	NULL,
2910Sstevel@tonic-gate 	NULL,
2920Sstevel@tonic-gate 	NULL,
2930Sstevel@tonic-gate 	NULL,
2940Sstevel@tonic-gate 	NULL,
2950Sstevel@tonic-gate 	NULL,
2960Sstevel@tonic-gate 	NULL,
297*10732SAnthony.Scarpino@Sun.COM 	&rsa_ctx_ops,
298*10732SAnthony.Scarpino@Sun.COM 	NULL,
299*10732SAnthony.Scarpino@Sun.COM 	NULL,
300*10732SAnthony.Scarpino@Sun.COM 	&rsa_fips140_ops
3010Sstevel@tonic-gate };
3020Sstevel@tonic-gate 
3030Sstevel@tonic-gate static crypto_provider_info_t rsa_prov_info = {
304*10732SAnthony.Scarpino@Sun.COM 	CRYPTO_SPI_VERSION_4,
3050Sstevel@tonic-gate 	"RSA Software Provider",
3060Sstevel@tonic-gate 	CRYPTO_SW_PROVIDER,
3070Sstevel@tonic-gate 	{&modlinkage},
3080Sstevel@tonic-gate 	NULL,
3090Sstevel@tonic-gate 	&rsa_crypto_ops,
3100Sstevel@tonic-gate 	sizeof (rsa_mech_info_tab)/sizeof (crypto_mech_info_t),
3110Sstevel@tonic-gate 	rsa_mech_info_tab
3120Sstevel@tonic-gate };
3130Sstevel@tonic-gate 
3140Sstevel@tonic-gate static int rsa_encrypt_common(rsa_mech_type_t, crypto_key_t *,
3150Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, int);
3160Sstevel@tonic-gate static int rsa_decrypt_common(rsa_mech_type_t, crypto_key_t *,
3170Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, int);
3180Sstevel@tonic-gate static int rsa_sign_common(rsa_mech_type_t, crypto_key_t *,
3190Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, int);
3200Sstevel@tonic-gate static int rsa_verify_common(rsa_mech_type_t, crypto_key_t *,
3210Sstevel@tonic-gate     crypto_data_t *, crypto_data_t *, int);
3220Sstevel@tonic-gate static int compare_data(crypto_data_t *, uchar_t *);
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate /* EXPORT DELETE START */
3250Sstevel@tonic-gate 
3260Sstevel@tonic-gate static int core_rsa_encrypt(crypto_key_t *, uchar_t *,
3270Sstevel@tonic-gate     int, uchar_t *, int, int);
3280Sstevel@tonic-gate static int core_rsa_decrypt(crypto_key_t *, uchar_t *, int,
3290Sstevel@tonic-gate     uchar_t *, int);
3300Sstevel@tonic-gate 
3310Sstevel@tonic-gate /* EXPORT DELETE END */
3320Sstevel@tonic-gate 
3330Sstevel@tonic-gate static crypto_kcf_provider_handle_t rsa_prov_handle = NULL;
3340Sstevel@tonic-gate 
3350Sstevel@tonic-gate int
3360Sstevel@tonic-gate _init(void)
3370Sstevel@tonic-gate {
3380Sstevel@tonic-gate 	int ret;
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate 	/*
3410Sstevel@tonic-gate 	 * Register with KCF. If the registration fails, return error.
3420Sstevel@tonic-gate 	 */
3430Sstevel@tonic-gate 	if ((ret = crypto_register_provider(&rsa_prov_info,
3440Sstevel@tonic-gate 	    &rsa_prov_handle)) != CRYPTO_SUCCESS) {
3450Sstevel@tonic-gate 		cmn_err(CE_WARN, "rsa _init: crypto_register_provider()"
3460Sstevel@tonic-gate 		    "failed (0x%x)", ret);
3470Sstevel@tonic-gate 		return (EACCES);
3480Sstevel@tonic-gate 	}
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate 	if ((ret = mod_install(&modlinkage)) != 0) {
3510Sstevel@tonic-gate 		int rv;
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate 		ASSERT(rsa_prov_handle != NULL);
3540Sstevel@tonic-gate 		/* We should not return if the unregister returns busy. */
3550Sstevel@tonic-gate 		while ((rv = crypto_unregister_provider(rsa_prov_handle))
3560Sstevel@tonic-gate 		    == CRYPTO_BUSY) {
3570Sstevel@tonic-gate 			cmn_err(CE_WARN, "rsa _init: "
3580Sstevel@tonic-gate 			    "crypto_unregister_provider() "
3590Sstevel@tonic-gate 			    "failed (0x%x). Retrying.", rv);
3600Sstevel@tonic-gate 			/* wait 10 seconds and try again. */
3610Sstevel@tonic-gate 			delay(10 * drv_usectohz(1000000));
3620Sstevel@tonic-gate 		}
3630Sstevel@tonic-gate 	}
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate 	return (ret);
3660Sstevel@tonic-gate }
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate int
3690Sstevel@tonic-gate _fini(void)
3700Sstevel@tonic-gate {
3710Sstevel@tonic-gate 	int ret;
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate 	/*
3740Sstevel@tonic-gate 	 * Unregister from KCF if previous registration succeeded.
3750Sstevel@tonic-gate 	 */
3760Sstevel@tonic-gate 	if (rsa_prov_handle != NULL) {
3770Sstevel@tonic-gate 		if ((ret = crypto_unregister_provider(rsa_prov_handle)) !=
3780Sstevel@tonic-gate 		    CRYPTO_SUCCESS) {
3790Sstevel@tonic-gate 			cmn_err(CE_WARN, "rsa _fini: "
3800Sstevel@tonic-gate 			    "crypto_unregister_provider() "
3810Sstevel@tonic-gate 			    "failed (0x%x)", ret);
3820Sstevel@tonic-gate 			return (EBUSY);
3830Sstevel@tonic-gate 		}
3840Sstevel@tonic-gate 		rsa_prov_handle = NULL;
3850Sstevel@tonic-gate 	}
3860Sstevel@tonic-gate 
3870Sstevel@tonic-gate 	return (mod_remove(&modlinkage));
3880Sstevel@tonic-gate }
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate int
3910Sstevel@tonic-gate _info(struct modinfo *modinfop)
3920Sstevel@tonic-gate {
3930Sstevel@tonic-gate 	return (mod_info(&modlinkage, modinfop));
3940Sstevel@tonic-gate }
3950Sstevel@tonic-gate 
3960Sstevel@tonic-gate /* ARGSUSED */
3970Sstevel@tonic-gate static void
3980Sstevel@tonic-gate rsa_provider_status(crypto_provider_handle_t provider, uint_t *status)
3990Sstevel@tonic-gate {
4000Sstevel@tonic-gate 	*status = CRYPTO_PROVIDER_READY;
4010Sstevel@tonic-gate }
4020Sstevel@tonic-gate 
4030Sstevel@tonic-gate static int
4040Sstevel@tonic-gate check_mech_and_key(crypto_mechanism_t *mechanism, crypto_key_t *key)
4050Sstevel@tonic-gate {
4060Sstevel@tonic-gate 	int rv = CRYPTO_FAILED;
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate /* EXPORT DELETE START */
4090Sstevel@tonic-gate 
4100Sstevel@tonic-gate 	uchar_t *modulus;
4110Sstevel@tonic-gate 	ssize_t modulus_len; /* In bytes */
4120Sstevel@tonic-gate 
4130Sstevel@tonic-gate 	if (!RSA_VALID_MECH(mechanism))
4140Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
4150Sstevel@tonic-gate 
4160Sstevel@tonic-gate 	/*
4170Sstevel@tonic-gate 	 * We only support RSA keys that are passed as a list of
4180Sstevel@tonic-gate 	 * object attributes.
4190Sstevel@tonic-gate 	 */
4200Sstevel@tonic-gate 	if (key->ck_format != CRYPTO_KEY_ATTR_LIST) {
4210Sstevel@tonic-gate 		return (CRYPTO_KEY_TYPE_INCONSISTENT);
4220Sstevel@tonic-gate 	}
4230Sstevel@tonic-gate 
4247188Smcpowers 	if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus,
4250Sstevel@tonic-gate 	    &modulus_len)) != CRYPTO_SUCCESS) {
4260Sstevel@tonic-gate 		return (rv);
4270Sstevel@tonic-gate 	}
4280Sstevel@tonic-gate 	if (modulus_len < MIN_RSA_KEYLENGTH_IN_BYTES ||
4290Sstevel@tonic-gate 	    modulus_len > MAX_RSA_KEYLENGTH_IN_BYTES)
4300Sstevel@tonic-gate 		return (CRYPTO_KEY_SIZE_RANGE);
4310Sstevel@tonic-gate 
4320Sstevel@tonic-gate /* EXPORT DELETE END */
4330Sstevel@tonic-gate 
4340Sstevel@tonic-gate 	return (rv);
4350Sstevel@tonic-gate }
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate void
4380Sstevel@tonic-gate kmemset(uint8_t *buf, char pattern, size_t len)
4390Sstevel@tonic-gate {
4400Sstevel@tonic-gate 	int i = 0;
4410Sstevel@tonic-gate 
4420Sstevel@tonic-gate 	while (i < len)
4430Sstevel@tonic-gate 		buf[i++] = pattern;
4440Sstevel@tonic-gate }
4450Sstevel@tonic-gate 
4460Sstevel@tonic-gate /*
4470Sstevel@tonic-gate  * This function guarantees to return non-zero random numbers.
4480Sstevel@tonic-gate  * This is needed as the /dev/urandom kernel interface,
4490Sstevel@tonic-gate  * random_get_pseudo_bytes(), may return zeros.
4500Sstevel@tonic-gate  */
4510Sstevel@tonic-gate int
4520Sstevel@tonic-gate knzero_random_generator(uint8_t *ran_out, size_t ran_len)
4530Sstevel@tonic-gate {
4540Sstevel@tonic-gate 	int rv;
4550Sstevel@tonic-gate 	size_t ebc = 0; /* count of extra bytes in extrarand */
4560Sstevel@tonic-gate 	size_t i = 0;
4570Sstevel@tonic-gate 	uint8_t extrarand[32];
4580Sstevel@tonic-gate 	size_t extrarand_len;
4590Sstevel@tonic-gate 
460*10732SAnthony.Scarpino@Sun.COM 	if ((rv = random_get_pseudo_bytes_fips140(ran_out, ran_len)) != 0)
4610Sstevel@tonic-gate 		return (rv);
4620Sstevel@tonic-gate 
4630Sstevel@tonic-gate 	/*
4640Sstevel@tonic-gate 	 * Walk through the returned random numbers pointed by ran_out,
4650Sstevel@tonic-gate 	 * and look for any random number which is zero.
4660Sstevel@tonic-gate 	 * If we find zero, call random_get_pseudo_bytes() to generate
4670Sstevel@tonic-gate 	 * another 32 random numbers pool. Replace any zeros in ran_out[]
4680Sstevel@tonic-gate 	 * from the random number in pool.
4690Sstevel@tonic-gate 	 */
4700Sstevel@tonic-gate 	while (i < ran_len) {
4710Sstevel@tonic-gate 		if (ran_out[i] != 0) {
4720Sstevel@tonic-gate 			i++;
4730Sstevel@tonic-gate 			continue;
4740Sstevel@tonic-gate 		}
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate 		/*
4770Sstevel@tonic-gate 		 * Note that it is 'while' so we are guaranteed a
4780Sstevel@tonic-gate 		 * non-zero value on exit.
4790Sstevel@tonic-gate 		 */
4800Sstevel@tonic-gate 		if (ebc == 0) {
4810Sstevel@tonic-gate 			/* refresh extrarand */
4820Sstevel@tonic-gate 			extrarand_len = sizeof (extrarand);
483*10732SAnthony.Scarpino@Sun.COM 			if ((rv = random_get_pseudo_bytes_fips140(extrarand,
4840Sstevel@tonic-gate 			    extrarand_len)) != 0) {
4850Sstevel@tonic-gate 				return (rv);
4860Sstevel@tonic-gate 			}
4870Sstevel@tonic-gate 
4880Sstevel@tonic-gate 			ebc = extrarand_len;
4890Sstevel@tonic-gate 		}
4900Sstevel@tonic-gate 		/* Replace zero with byte from extrarand. */
4910Sstevel@tonic-gate 		-- ebc;
4920Sstevel@tonic-gate 
4930Sstevel@tonic-gate 		/*
4940Sstevel@tonic-gate 		 * The new random byte zero/non-zero will be checked in
4950Sstevel@tonic-gate 		 * the next pass through the loop.
4960Sstevel@tonic-gate 		 */
4970Sstevel@tonic-gate 		ran_out[i] = extrarand[ebc];
4980Sstevel@tonic-gate 	}
4990Sstevel@tonic-gate 
5000Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
5010Sstevel@tonic-gate }
5020Sstevel@tonic-gate 
5030Sstevel@tonic-gate static int
5040Sstevel@tonic-gate compare_data(crypto_data_t *data, uchar_t *buf)
5050Sstevel@tonic-gate {
5060Sstevel@tonic-gate 	int len;
5070Sstevel@tonic-gate 	uchar_t *dptr;
5080Sstevel@tonic-gate 
5090Sstevel@tonic-gate 	len = data->cd_length;
5100Sstevel@tonic-gate 	switch (data->cd_format) {
5110Sstevel@tonic-gate 	case CRYPTO_DATA_RAW:
5120Sstevel@tonic-gate 		dptr = (uchar_t *)(data->cd_raw.iov_base +
5130Sstevel@tonic-gate 		    data->cd_offset);
5140Sstevel@tonic-gate 
5150Sstevel@tonic-gate 		return (bcmp(dptr, buf, len));
5160Sstevel@tonic-gate 
5170Sstevel@tonic-gate 	case CRYPTO_DATA_UIO:
5187188Smcpowers 		return (crypto_uio_data(data, buf, len,
5197188Smcpowers 		    COMPARE_TO_DATA, NULL, NULL));
5200Sstevel@tonic-gate 
5210Sstevel@tonic-gate 	case CRYPTO_DATA_MBLK:
5227188Smcpowers 		return (crypto_mblk_data(data, buf, len,
5237188Smcpowers 		    COMPARE_TO_DATA, NULL, NULL));
5240Sstevel@tonic-gate 	}
5250Sstevel@tonic-gate 
5260Sstevel@tonic-gate 	return (CRYPTO_FAILED);
5270Sstevel@tonic-gate }
5280Sstevel@tonic-gate 
5290Sstevel@tonic-gate /* ARGSUSED */
5300Sstevel@tonic-gate static int
5310Sstevel@tonic-gate rsa_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
5320Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t template,
5330Sstevel@tonic-gate     crypto_req_handle_t req)
5340Sstevel@tonic-gate {
5350Sstevel@tonic-gate 	int rv;
5360Sstevel@tonic-gate 	int kmflag;
5370Sstevel@tonic-gate 	rsa_ctx_t *ctxp;
5380Sstevel@tonic-gate 
5390Sstevel@tonic-gate 	if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS)
5400Sstevel@tonic-gate 		return (rv);
5410Sstevel@tonic-gate 
5420Sstevel@tonic-gate 	/*
5430Sstevel@tonic-gate 	 * Allocate a RSA context.
5440Sstevel@tonic-gate 	 */
5450Sstevel@tonic-gate 	kmflag = crypto_kmflag(req);
5460Sstevel@tonic-gate 	if ((ctxp = kmem_zalloc(sizeof (rsa_ctx_t), kmflag)) == NULL)
5470Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
5480Sstevel@tonic-gate 
5497188Smcpowers 	if ((rv = crypto_copy_key_to_ctx(key, &ctxp->key, &ctxp->keychunk_size,
5507188Smcpowers 	    kmflag)) != CRYPTO_SUCCESS) {
5510Sstevel@tonic-gate 		kmem_free(ctxp, sizeof (rsa_ctx_t));
5520Sstevel@tonic-gate 		return (rv);
5530Sstevel@tonic-gate 	}
5540Sstevel@tonic-gate 	ctxp->mech_type = mechanism->cm_type;
5550Sstevel@tonic-gate 
5560Sstevel@tonic-gate 	ctx->cc_provider_private = ctxp;
5570Sstevel@tonic-gate 
5580Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
5590Sstevel@tonic-gate }
5600Sstevel@tonic-gate 
5610Sstevel@tonic-gate /* ARGSUSED */
5620Sstevel@tonic-gate static int
5630Sstevel@tonic-gate rsa_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext,
5640Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_req_handle_t req)
5650Sstevel@tonic-gate {
5660Sstevel@tonic-gate 	int rv;
5670Sstevel@tonic-gate 	rsa_ctx_t *ctxp;
5680Sstevel@tonic-gate 
5690Sstevel@tonic-gate 	ASSERT(ctx->cc_provider_private != NULL);
5700Sstevel@tonic-gate 	ctxp = ctx->cc_provider_private;
5710Sstevel@tonic-gate 
5720Sstevel@tonic-gate 	RSA_ARG_INPLACE(plaintext, ciphertext);
5730Sstevel@tonic-gate 
5740Sstevel@tonic-gate 	/*
5750Sstevel@tonic-gate 	 * Note on the KM_SLEEP flag passed to the routine below -
5760Sstevel@tonic-gate 	 * rsa_encrypt() is a single-part encryption routine which is
5770Sstevel@tonic-gate 	 * currently usable only by /dev/crypto. Since /dev/crypto calls are
5780Sstevel@tonic-gate 	 * always synchronous, we can safely pass KM_SLEEP here.
5790Sstevel@tonic-gate 	 */
5800Sstevel@tonic-gate 	rv = rsa_encrypt_common(ctxp->mech_type, ctxp->key, plaintext,
5810Sstevel@tonic-gate 	    ciphertext, KM_SLEEP);
5820Sstevel@tonic-gate 
5830Sstevel@tonic-gate 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
5840Sstevel@tonic-gate 		(void) rsa_free_context(ctx);
5850Sstevel@tonic-gate 
5860Sstevel@tonic-gate 	return (rv);
5870Sstevel@tonic-gate }
5880Sstevel@tonic-gate 
5890Sstevel@tonic-gate /* ARGSUSED */
5900Sstevel@tonic-gate static int
5910Sstevel@tonic-gate rsa_encrypt_atomic(crypto_provider_handle_t provider,
5920Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
5930Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext,
5940Sstevel@tonic-gate     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
5950Sstevel@tonic-gate {
5960Sstevel@tonic-gate 	int rv;
5970Sstevel@tonic-gate 
5980Sstevel@tonic-gate 	if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS)
5990Sstevel@tonic-gate 		return (rv);
6000Sstevel@tonic-gate 	RSA_ARG_INPLACE(plaintext, ciphertext);
6010Sstevel@tonic-gate 
6020Sstevel@tonic-gate 	return (rsa_encrypt_common(mechanism->cm_type, key, plaintext,
6030Sstevel@tonic-gate 	    ciphertext, crypto_kmflag(req)));
6040Sstevel@tonic-gate }
6050Sstevel@tonic-gate 
6060Sstevel@tonic-gate static int
6070Sstevel@tonic-gate rsa_free_context(crypto_ctx_t *ctx)
6080Sstevel@tonic-gate {
6090Sstevel@tonic-gate 	rsa_ctx_t *ctxp = ctx->cc_provider_private;
6100Sstevel@tonic-gate 
6110Sstevel@tonic-gate 	if (ctxp != NULL) {
6120Sstevel@tonic-gate 		bzero(ctxp->key, ctxp->keychunk_size);
6130Sstevel@tonic-gate 		kmem_free(ctxp->key, ctxp->keychunk_size);
6140Sstevel@tonic-gate 
6150Sstevel@tonic-gate 		if (ctxp->mech_type == RSA_PKCS_MECH_INFO_TYPE ||
6160Sstevel@tonic-gate 		    ctxp->mech_type == RSA_X_509_MECH_INFO_TYPE)
6170Sstevel@tonic-gate 			kmem_free(ctxp, sizeof (rsa_ctx_t));
6180Sstevel@tonic-gate 		else
6190Sstevel@tonic-gate 			kmem_free(ctxp, sizeof (digest_rsa_ctx_t));
6200Sstevel@tonic-gate 
6210Sstevel@tonic-gate 		ctx->cc_provider_private = NULL;
6220Sstevel@tonic-gate 	}
6230Sstevel@tonic-gate 
6240Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
6250Sstevel@tonic-gate }
6260Sstevel@tonic-gate 
6270Sstevel@tonic-gate static int
6280Sstevel@tonic-gate rsa_encrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key,
6290Sstevel@tonic-gate     crypto_data_t *plaintext, crypto_data_t *ciphertext, int kmflag)
6300Sstevel@tonic-gate {
6310Sstevel@tonic-gate 	int rv = CRYPTO_FAILED;
6320Sstevel@tonic-gate 
6330Sstevel@tonic-gate /* EXPORT DELETE START */
6340Sstevel@tonic-gate 
6350Sstevel@tonic-gate 	int plen;
6360Sstevel@tonic-gate 	uchar_t *ptptr;
6370Sstevel@tonic-gate 	uchar_t *modulus;
6380Sstevel@tonic-gate 	ssize_t modulus_len;
6390Sstevel@tonic-gate 	uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES];
6400Sstevel@tonic-gate 	uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
6410Sstevel@tonic-gate 	uchar_t cipher_data[MAX_RSA_KEYLENGTH_IN_BYTES];
6420Sstevel@tonic-gate 
6437188Smcpowers 	if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus,
6440Sstevel@tonic-gate 	    &modulus_len)) != CRYPTO_SUCCESS) {
6450Sstevel@tonic-gate 		return (rv);
6460Sstevel@tonic-gate 	}
6470Sstevel@tonic-gate 
6480Sstevel@tonic-gate 	plen = plaintext->cd_length;
6490Sstevel@tonic-gate 	if (mech_type == RSA_PKCS_MECH_INFO_TYPE) {
6500Sstevel@tonic-gate 		if (plen > (modulus_len - MIN_PKCS1_PADLEN))
6510Sstevel@tonic-gate 			return (CRYPTO_DATA_LEN_RANGE);
6520Sstevel@tonic-gate 	} else {
6530Sstevel@tonic-gate 		if (plen > modulus_len)
6540Sstevel@tonic-gate 			return (CRYPTO_DATA_LEN_RANGE);
6550Sstevel@tonic-gate 	}
6560Sstevel@tonic-gate 
6570Sstevel@tonic-gate 	/*
6580Sstevel@tonic-gate 	 * Output buf len must not be less than RSA modulus size.
6590Sstevel@tonic-gate 	 */
6600Sstevel@tonic-gate 	if (ciphertext->cd_length < modulus_len) {
6610Sstevel@tonic-gate 		ciphertext->cd_length = modulus_len;
6620Sstevel@tonic-gate 		return (CRYPTO_BUFFER_TOO_SMALL);
6630Sstevel@tonic-gate 	}
6640Sstevel@tonic-gate 
6650Sstevel@tonic-gate 	ASSERT(plaintext->cd_length <= sizeof (tmp_data));
6667188Smcpowers 	if ((rv = crypto_get_input_data(plaintext, &ptptr, tmp_data))
6670Sstevel@tonic-gate 	    != CRYPTO_SUCCESS)
6680Sstevel@tonic-gate 		return (rv);
6690Sstevel@tonic-gate 
6700Sstevel@tonic-gate 	if (mech_type == RSA_PKCS_MECH_INFO_TYPE) {
6710Sstevel@tonic-gate 		rv = soft_encrypt_rsa_pkcs_encode(ptptr, plen,
6720Sstevel@tonic-gate 		    plain_data, modulus_len);
6730Sstevel@tonic-gate 
6740Sstevel@tonic-gate 		if (rv != CRYPTO_SUCCESS)
6750Sstevel@tonic-gate 			return (rv);
6760Sstevel@tonic-gate 	} else {
6770Sstevel@tonic-gate 		bzero(plain_data, modulus_len - plen);
6780Sstevel@tonic-gate 		bcopy(ptptr, &plain_data[modulus_len - plen], plen);
6790Sstevel@tonic-gate 	}
6800Sstevel@tonic-gate 
6810Sstevel@tonic-gate 	rv = core_rsa_encrypt(key, plain_data, modulus_len,
6820Sstevel@tonic-gate 	    cipher_data, kmflag, 1);
6830Sstevel@tonic-gate 	if (rv == CRYPTO_SUCCESS) {
6840Sstevel@tonic-gate 		/* copy out to ciphertext */
6857188Smcpowers 		if ((rv = crypto_put_output_data(cipher_data,
6860Sstevel@tonic-gate 		    ciphertext, modulus_len)) != CRYPTO_SUCCESS)
6870Sstevel@tonic-gate 			return (rv);
6880Sstevel@tonic-gate 
6890Sstevel@tonic-gate 		ciphertext->cd_length = modulus_len;
6900Sstevel@tonic-gate 	}
6910Sstevel@tonic-gate 
6920Sstevel@tonic-gate /* EXPORT DELETE END */
6930Sstevel@tonic-gate 
6940Sstevel@tonic-gate 	return (rv);
6950Sstevel@tonic-gate }
6960Sstevel@tonic-gate 
6970Sstevel@tonic-gate /* EXPORT DELETE START */
6980Sstevel@tonic-gate 
6990Sstevel@tonic-gate static int
7000Sstevel@tonic-gate core_rsa_encrypt(crypto_key_t *key, uchar_t *in,
7010Sstevel@tonic-gate     int in_len, uchar_t *out, int kmflag, int is_public)
7020Sstevel@tonic-gate {
7030Sstevel@tonic-gate 	int rv;
7040Sstevel@tonic-gate 	uchar_t *expo, *modulus;
7050Sstevel@tonic-gate 	ssize_t	expo_len;
7060Sstevel@tonic-gate 	ssize_t modulus_len;
7070Sstevel@tonic-gate 	BIGNUM msg;
7080Sstevel@tonic-gate 	RSAkey *rsakey;
7090Sstevel@tonic-gate 
7100Sstevel@tonic-gate 	if (is_public) {
7117188Smcpowers 		if ((rv = crypto_get_key_attr(key, SUN_CKA_PUBLIC_EXPONENT,
7127188Smcpowers 		    &expo, &expo_len)) != CRYPTO_SUCCESS)
7130Sstevel@tonic-gate 			return (rv);
7140Sstevel@tonic-gate 	} else {
7150Sstevel@tonic-gate 		/*
7160Sstevel@tonic-gate 		 * SUN_CKA_PRIVATE_EXPONENT is a required attribute for a
7170Sstevel@tonic-gate 		 * RSA secret key. See the comments in core_rsa_decrypt
7180Sstevel@tonic-gate 		 * routine which calls this routine with a private key.
7190Sstevel@tonic-gate 		 */
7207188Smcpowers 		if ((rv = crypto_get_key_attr(key, SUN_CKA_PRIVATE_EXPONENT,
7217188Smcpowers 		    &expo, &expo_len)) != CRYPTO_SUCCESS)
7220Sstevel@tonic-gate 			return (rv);
7230Sstevel@tonic-gate 	}
7240Sstevel@tonic-gate 
7257188Smcpowers 	if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus,
7260Sstevel@tonic-gate 	    &modulus_len)) != CRYPTO_SUCCESS) {
7270Sstevel@tonic-gate 		return (rv);
7280Sstevel@tonic-gate 	}
7290Sstevel@tonic-gate 
7300Sstevel@tonic-gate 	rsakey = kmem_alloc(sizeof (RSAkey), kmflag);
7310Sstevel@tonic-gate 	if (rsakey == NULL)
7320Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
7330Sstevel@tonic-gate 
7340Sstevel@tonic-gate 	/* psize and qsize for RSA_key_init is in bits. */
7350Sstevel@tonic-gate 	if (RSA_key_init(rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) {
7360Sstevel@tonic-gate 		rv = CRYPTO_HOST_MEMORY;
7370Sstevel@tonic-gate 		goto clean1;
7380Sstevel@tonic-gate 	}
7390Sstevel@tonic-gate 
7406557Sfr41279 	/* Size for big_init is in BIG_CHUNK_TYPE words. */
7416557Sfr41279 	if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
7420Sstevel@tonic-gate 		rv = CRYPTO_HOST_MEMORY;
7430Sstevel@tonic-gate 		goto clean2;
7440Sstevel@tonic-gate 	}
7450Sstevel@tonic-gate 
7460Sstevel@tonic-gate 	/* Convert octet string exponent to big integer format. */
7470Sstevel@tonic-gate 	bytestring2bignum(&(rsakey->e), expo, expo_len);
7480Sstevel@tonic-gate 
7490Sstevel@tonic-gate 	/* Convert octet string modulus to big integer format. */
7500Sstevel@tonic-gate 	bytestring2bignum(&(rsakey->n), modulus, modulus_len);
7510Sstevel@tonic-gate 
7520Sstevel@tonic-gate 	/* Convert octet string input data to big integer format. */
7530Sstevel@tonic-gate 	bytestring2bignum(&msg, in, in_len);
7540Sstevel@tonic-gate 
7550Sstevel@tonic-gate 	if (big_cmp_abs(&msg, &(rsakey->n)) > 0) {
7560Sstevel@tonic-gate 		rv = CRYPTO_DATA_LEN_RANGE;
7570Sstevel@tonic-gate 		goto clean3;
7580Sstevel@tonic-gate 	}
7590Sstevel@tonic-gate 
7600Sstevel@tonic-gate 	/* Perform RSA computation on big integer input data. */
7610Sstevel@tonic-gate 	if (big_modexp(&msg, &msg, &(rsakey->e), &(rsakey->n), NULL)
7620Sstevel@tonic-gate 	    != BIG_OK) {
7630Sstevel@tonic-gate 		rv = CRYPTO_HOST_MEMORY;
7640Sstevel@tonic-gate 		goto clean3;
7650Sstevel@tonic-gate 	}
7660Sstevel@tonic-gate 
7670Sstevel@tonic-gate 	/* Convert the big integer output data to octet string. */
7680Sstevel@tonic-gate 	bignum2bytestring(out, &msg, modulus_len);
7690Sstevel@tonic-gate 
7700Sstevel@tonic-gate 	/*
7710Sstevel@tonic-gate 	 * Should not free modulus and expo as both are just pointers
7720Sstevel@tonic-gate 	 * to an attribute value buffer from the caller.
7730Sstevel@tonic-gate 	 */
7740Sstevel@tonic-gate clean3:
7750Sstevel@tonic-gate 	big_finish(&msg);
7760Sstevel@tonic-gate clean2:
7770Sstevel@tonic-gate 	RSA_key_finish(rsakey);
7780Sstevel@tonic-gate clean1:
7790Sstevel@tonic-gate 	kmem_free(rsakey, sizeof (RSAkey));
7800Sstevel@tonic-gate 
7810Sstevel@tonic-gate 	return (rv);
7820Sstevel@tonic-gate }
7830Sstevel@tonic-gate 
7840Sstevel@tonic-gate /* EXPORT DELETE END */
7850Sstevel@tonic-gate 
7860Sstevel@tonic-gate /* ARGSUSED */
7870Sstevel@tonic-gate static int
7880Sstevel@tonic-gate rsa_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext,
7890Sstevel@tonic-gate     crypto_data_t *plaintext, crypto_req_handle_t req)
7900Sstevel@tonic-gate {
7910Sstevel@tonic-gate 	int rv;
7920Sstevel@tonic-gate 	rsa_ctx_t *ctxp;
7930Sstevel@tonic-gate 
7940Sstevel@tonic-gate 	ASSERT(ctx->cc_provider_private != NULL);
7950Sstevel@tonic-gate 	ctxp = ctx->cc_provider_private;
7960Sstevel@tonic-gate 
7970Sstevel@tonic-gate 	RSA_ARG_INPLACE(ciphertext, plaintext);
7980Sstevel@tonic-gate 
7990Sstevel@tonic-gate 	/* See the comments on KM_SLEEP flag in rsa_encrypt() */
8000Sstevel@tonic-gate 	rv = rsa_decrypt_common(ctxp->mech_type, ctxp->key,
8010Sstevel@tonic-gate 	    ciphertext, plaintext, KM_SLEEP);
8020Sstevel@tonic-gate 
8030Sstevel@tonic-gate 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
8040Sstevel@tonic-gate 		(void) rsa_free_context(ctx);
8050Sstevel@tonic-gate 
8060Sstevel@tonic-gate 	return (rv);
8070Sstevel@tonic-gate }
8080Sstevel@tonic-gate 
8090Sstevel@tonic-gate /* ARGSUSED */
8100Sstevel@tonic-gate static int
8110Sstevel@tonic-gate rsa_decrypt_atomic(crypto_provider_handle_t provider,
8120Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
8130Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext,
8140Sstevel@tonic-gate     crypto_spi_ctx_template_t template, crypto_req_handle_t req)
8150Sstevel@tonic-gate {
8160Sstevel@tonic-gate 	int rv;
8170Sstevel@tonic-gate 
8180Sstevel@tonic-gate 	if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS)
8190Sstevel@tonic-gate 		return (rv);
8200Sstevel@tonic-gate 	RSA_ARG_INPLACE(ciphertext, plaintext);
8210Sstevel@tonic-gate 
8220Sstevel@tonic-gate 	return (rsa_decrypt_common(mechanism->cm_type, key, ciphertext,
8230Sstevel@tonic-gate 	    plaintext, crypto_kmflag(req)));
8240Sstevel@tonic-gate }
8250Sstevel@tonic-gate 
8260Sstevel@tonic-gate static int
8270Sstevel@tonic-gate rsa_decrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key,
8280Sstevel@tonic-gate     crypto_data_t *ciphertext, crypto_data_t *plaintext, int kmflag)
8290Sstevel@tonic-gate {
8300Sstevel@tonic-gate 	int rv = CRYPTO_FAILED;
8310Sstevel@tonic-gate 
8320Sstevel@tonic-gate /* EXPORT DELETE START */
8330Sstevel@tonic-gate 
8340Sstevel@tonic-gate 	int plain_len;
8350Sstevel@tonic-gate 	uchar_t *ctptr;
8360Sstevel@tonic-gate 	uchar_t *modulus;
8370Sstevel@tonic-gate 	ssize_t modulus_len;
8380Sstevel@tonic-gate 	uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
8390Sstevel@tonic-gate 	uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES];
8400Sstevel@tonic-gate 
8417188Smcpowers 	if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus,
8420Sstevel@tonic-gate 	    &modulus_len)) != CRYPTO_SUCCESS) {
8430Sstevel@tonic-gate 		return (rv);
8440Sstevel@tonic-gate 	}
8450Sstevel@tonic-gate 
8460Sstevel@tonic-gate 	/*
8470Sstevel@tonic-gate 	 * Ciphertext length must be equal to RSA modulus size.
8480Sstevel@tonic-gate 	 */
8490Sstevel@tonic-gate 	if (ciphertext->cd_length != modulus_len)
8500Sstevel@tonic-gate 		return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE);
8510Sstevel@tonic-gate 
8520Sstevel@tonic-gate 	ASSERT(ciphertext->cd_length <= sizeof (tmp_data));
8537188Smcpowers 	if ((rv = crypto_get_input_data(ciphertext, &ctptr, tmp_data))
8540Sstevel@tonic-gate 	    != CRYPTO_SUCCESS)
8550Sstevel@tonic-gate 		return (rv);
8560Sstevel@tonic-gate 
8570Sstevel@tonic-gate 	rv = core_rsa_decrypt(key, ctptr, modulus_len, plain_data, kmflag);
8580Sstevel@tonic-gate 	if (rv == CRYPTO_SUCCESS) {
8590Sstevel@tonic-gate 		plain_len = modulus_len;
8600Sstevel@tonic-gate 
8610Sstevel@tonic-gate 		if (mech_type == RSA_PKCS_MECH_INFO_TYPE) {
8620Sstevel@tonic-gate 			/* Strip off the PKCS block formatting data. */
8630Sstevel@tonic-gate 			rv = soft_decrypt_rsa_pkcs_decode(plain_data,
8640Sstevel@tonic-gate 			    &plain_len);
8650Sstevel@tonic-gate 			if (rv != CRYPTO_SUCCESS)
8660Sstevel@tonic-gate 				return (rv);
8670Sstevel@tonic-gate 		}
8680Sstevel@tonic-gate 
8690Sstevel@tonic-gate 		if (plain_len > plaintext->cd_length) {
8700Sstevel@tonic-gate 			plaintext->cd_length = plain_len;
8710Sstevel@tonic-gate 			return (CRYPTO_BUFFER_TOO_SMALL);
8720Sstevel@tonic-gate 		}
8730Sstevel@tonic-gate 
8747188Smcpowers 		if ((rv = crypto_put_output_data(
8757188Smcpowers 		    plain_data + modulus_len - plain_len,
8760Sstevel@tonic-gate 		    plaintext, plain_len)) != CRYPTO_SUCCESS)
8770Sstevel@tonic-gate 			return (rv);
8780Sstevel@tonic-gate 
8790Sstevel@tonic-gate 		plaintext->cd_length = plain_len;
8800Sstevel@tonic-gate 	}
8810Sstevel@tonic-gate 
8820Sstevel@tonic-gate /* EXPORT DELETE END */
8830Sstevel@tonic-gate 
8840Sstevel@tonic-gate 	return (rv);
8850Sstevel@tonic-gate }
8860Sstevel@tonic-gate 
8870Sstevel@tonic-gate /* EXPORT DELETE START */
8880Sstevel@tonic-gate 
8890Sstevel@tonic-gate static int
8900Sstevel@tonic-gate core_rsa_decrypt(crypto_key_t *key, uchar_t *in, int in_len,
8910Sstevel@tonic-gate     uchar_t *out, int kmflag)
8920Sstevel@tonic-gate {
8930Sstevel@tonic-gate 	int rv;
8940Sstevel@tonic-gate 	uchar_t *modulus, *prime1, *prime2, *expo1, *expo2, *coef;
8950Sstevel@tonic-gate 	ssize_t modulus_len;
8960Sstevel@tonic-gate 	ssize_t	prime1_len, prime2_len;
8970Sstevel@tonic-gate 	ssize_t	expo1_len, expo2_len, coef_len;
8980Sstevel@tonic-gate 	BIGNUM msg;
8990Sstevel@tonic-gate 	RSAkey *rsakey;
9000Sstevel@tonic-gate 
9017188Smcpowers 	if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus,
9020Sstevel@tonic-gate 	    &modulus_len)) != CRYPTO_SUCCESS) {
9030Sstevel@tonic-gate 		return (rv);
9040Sstevel@tonic-gate 	}
9050Sstevel@tonic-gate 
9060Sstevel@tonic-gate 	/*
9070Sstevel@tonic-gate 	 * The following attributes are not required to be
9080Sstevel@tonic-gate 	 * present in a RSA secret key. If any of them is not present
9090Sstevel@tonic-gate 	 * we call the encrypt routine with a flag indicating use of
9100Sstevel@tonic-gate 	 * private exponent (d). Note that SUN_CKA_PRIVATE_EXPONENT is
9110Sstevel@tonic-gate 	 * a required attribute for a RSA secret key.
9120Sstevel@tonic-gate 	 */
9137188Smcpowers 	if ((crypto_get_key_attr(key, SUN_CKA_PRIME_1, &prime1, &prime1_len)
9145072Smcpowers 	    != CRYPTO_SUCCESS) ||
9157188Smcpowers 	    (crypto_get_key_attr(key, SUN_CKA_PRIME_2, &prime2, &prime2_len)
9165072Smcpowers 	    != CRYPTO_SUCCESS) ||
9177188Smcpowers 	    (crypto_get_key_attr(key, SUN_CKA_EXPONENT_1, &expo1, &expo1_len)
9185072Smcpowers 	    != CRYPTO_SUCCESS) ||
9197188Smcpowers 	    (crypto_get_key_attr(key, SUN_CKA_EXPONENT_2, &expo2, &expo2_len)
9205072Smcpowers 	    != CRYPTO_SUCCESS) ||
9217188Smcpowers 	    (crypto_get_key_attr(key, SUN_CKA_COEFFICIENT, &coef, &coef_len)
9225072Smcpowers 	    != CRYPTO_SUCCESS)) {
9230Sstevel@tonic-gate 		return (core_rsa_encrypt(key, in, in_len, out, kmflag, 0));
9240Sstevel@tonic-gate 	}
9250Sstevel@tonic-gate 
9260Sstevel@tonic-gate 	rsakey = kmem_alloc(sizeof (RSAkey), kmflag);
9270Sstevel@tonic-gate 	if (rsakey == NULL)
9280Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
9290Sstevel@tonic-gate 
9300Sstevel@tonic-gate 	/* psize and qsize for RSA_key_init is in bits. */
9310Sstevel@tonic-gate 	if (RSA_key_init(rsakey, prime2_len * 8, prime1_len * 8) != BIG_OK) {
9320Sstevel@tonic-gate 		rv = CRYPTO_HOST_MEMORY;
9330Sstevel@tonic-gate 		goto clean1;
9340Sstevel@tonic-gate 	}
9350Sstevel@tonic-gate 
9366557Sfr41279 	/* Size for big_init is in BIG_CHUNK_TYPE words. */
9376557Sfr41279 	if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
9380Sstevel@tonic-gate 		rv = CRYPTO_HOST_MEMORY;
9390Sstevel@tonic-gate 		goto clean2;
9400Sstevel@tonic-gate 	}
9410Sstevel@tonic-gate 
9420Sstevel@tonic-gate 	/* Convert octet string input data to big integer format. */
9430Sstevel@tonic-gate 	bytestring2bignum(&msg, in, in_len);
9440Sstevel@tonic-gate 
9450Sstevel@tonic-gate 	/* Convert octet string modulus to big integer format. */
9460Sstevel@tonic-gate 	bytestring2bignum(&(rsakey->n), modulus, modulus_len);
9470Sstevel@tonic-gate 
9480Sstevel@tonic-gate 	if (big_cmp_abs(&msg, &(rsakey->n)) > 0) {
9490Sstevel@tonic-gate 		rv = CRYPTO_DATA_LEN_RANGE;
9500Sstevel@tonic-gate 		goto clean3;
9510Sstevel@tonic-gate 	}
9520Sstevel@tonic-gate 
9530Sstevel@tonic-gate 	/* Convert the rest of private key attributes to big integer format. */
9540Sstevel@tonic-gate 	bytestring2bignum(&(rsakey->dmodpminus1), expo2, expo2_len);
9550Sstevel@tonic-gate 	bytestring2bignum(&(rsakey->dmodqminus1), expo1, expo1_len);
9560Sstevel@tonic-gate 	bytestring2bignum(&(rsakey->p), prime2, prime2_len);
9570Sstevel@tonic-gate 	bytestring2bignum(&(rsakey->q), prime1, prime1_len);
9580Sstevel@tonic-gate 	bytestring2bignum(&(rsakey->pinvmodq), coef, coef_len);
9590Sstevel@tonic-gate 
9600Sstevel@tonic-gate 	if ((big_cmp_abs(&(rsakey->dmodpminus1), &(rsakey->p)) > 0) ||
9610Sstevel@tonic-gate 	    (big_cmp_abs(&(rsakey->dmodqminus1), &(rsakey->q)) > 0) ||
9620Sstevel@tonic-gate 	    (big_cmp_abs(&(rsakey->pinvmodq), &(rsakey->q)) > 0)) {
9630Sstevel@tonic-gate 		rv = CRYPTO_KEY_SIZE_RANGE;
9640Sstevel@tonic-gate 		goto clean3;
9650Sstevel@tonic-gate 	}
9660Sstevel@tonic-gate 
9670Sstevel@tonic-gate 	/* Perform RSA computation on big integer input data. */
9680Sstevel@tonic-gate 	if (big_modexp_crt(&msg, &msg, &(rsakey->dmodpminus1),
9690Sstevel@tonic-gate 	    &(rsakey->dmodqminus1), &(rsakey->p), &(rsakey->q),
9700Sstevel@tonic-gate 	    &(rsakey->pinvmodq), NULL, NULL) != BIG_OK) {
9710Sstevel@tonic-gate 		rv = CRYPTO_HOST_MEMORY;
9720Sstevel@tonic-gate 		goto clean3;
9730Sstevel@tonic-gate 	}
9740Sstevel@tonic-gate 
9750Sstevel@tonic-gate 	/* Convert the big integer output data to octet string. */
9760Sstevel@tonic-gate 	bignum2bytestring(out, &msg, modulus_len);
9770Sstevel@tonic-gate 
9780Sstevel@tonic-gate 	/*
9790Sstevel@tonic-gate 	 * Should not free modulus and friends as they are just pointers
9800Sstevel@tonic-gate 	 * to an attribute value buffer from the caller.
9810Sstevel@tonic-gate 	 */
9820Sstevel@tonic-gate clean3:
9830Sstevel@tonic-gate 	big_finish(&msg);
9840Sstevel@tonic-gate clean2:
9850Sstevel@tonic-gate 	RSA_key_finish(rsakey);
9860Sstevel@tonic-gate clean1:
9870Sstevel@tonic-gate 	kmem_free(rsakey, sizeof (RSAkey));
9880Sstevel@tonic-gate 
9890Sstevel@tonic-gate 	return (rv);
9900Sstevel@tonic-gate }
9910Sstevel@tonic-gate 
9920Sstevel@tonic-gate /* EXPORT DELETE END */
9930Sstevel@tonic-gate 
9940Sstevel@tonic-gate /* ARGSUSED */
9950Sstevel@tonic-gate static int
9960Sstevel@tonic-gate rsa_sign_verify_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism,
9970Sstevel@tonic-gate     crypto_key_t *key, crypto_spi_ctx_template_t ctx_template,
9980Sstevel@tonic-gate     crypto_req_handle_t req)
9990Sstevel@tonic-gate {
10000Sstevel@tonic-gate 	int rv;
10010Sstevel@tonic-gate 	int kmflag;
10020Sstevel@tonic-gate 	rsa_ctx_t *ctxp;
10030Sstevel@tonic-gate 	digest_rsa_ctx_t *dctxp;
10040Sstevel@tonic-gate 
10050Sstevel@tonic-gate 	if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS)
10060Sstevel@tonic-gate 		return (rv);
10070Sstevel@tonic-gate 
10080Sstevel@tonic-gate 	/*
10090Sstevel@tonic-gate 	 * Allocate a RSA context.
10100Sstevel@tonic-gate 	 */
10110Sstevel@tonic-gate 	kmflag = crypto_kmflag(req);
10120Sstevel@tonic-gate 	switch (mechanism->cm_type) {
10130Sstevel@tonic-gate 	case MD5_RSA_PKCS_MECH_INFO_TYPE:
10140Sstevel@tonic-gate 	case SHA1_RSA_PKCS_MECH_INFO_TYPE:
1015676Sizick 	case SHA256_RSA_PKCS_MECH_INFO_TYPE:
1016676Sizick 	case SHA384_RSA_PKCS_MECH_INFO_TYPE:
1017676Sizick 	case SHA512_RSA_PKCS_MECH_INFO_TYPE:
10180Sstevel@tonic-gate 		dctxp = kmem_zalloc(sizeof (digest_rsa_ctx_t), kmflag);
10190Sstevel@tonic-gate 		ctxp = (rsa_ctx_t *)dctxp;
10200Sstevel@tonic-gate 		break;
10210Sstevel@tonic-gate 	default:
10220Sstevel@tonic-gate 		ctxp = kmem_zalloc(sizeof (rsa_ctx_t), kmflag);
10230Sstevel@tonic-gate 		break;
10240Sstevel@tonic-gate 	}
10250Sstevel@tonic-gate 
10260Sstevel@tonic-gate 	if (ctxp == NULL)
10270Sstevel@tonic-gate 		return (CRYPTO_HOST_MEMORY);
10280Sstevel@tonic-gate 
10290Sstevel@tonic-gate 	ctxp->mech_type = mechanism->cm_type;
10307188Smcpowers 	if ((rv = crypto_copy_key_to_ctx(key, &ctxp->key, &ctxp->keychunk_size,
10317188Smcpowers 	    kmflag)) != CRYPTO_SUCCESS) {
10320Sstevel@tonic-gate 		switch (mechanism->cm_type) {
10330Sstevel@tonic-gate 		case MD5_RSA_PKCS_MECH_INFO_TYPE:
10340Sstevel@tonic-gate 		case SHA1_RSA_PKCS_MECH_INFO_TYPE:
1035676Sizick 		case SHA256_RSA_PKCS_MECH_INFO_TYPE:
1036676Sizick 		case SHA384_RSA_PKCS_MECH_INFO_TYPE:
1037676Sizick 		case SHA512_RSA_PKCS_MECH_INFO_TYPE:
10380Sstevel@tonic-gate 			kmem_free(dctxp, sizeof (digest_rsa_ctx_t));
10390Sstevel@tonic-gate 			break;
10400Sstevel@tonic-gate 		default:
10410Sstevel@tonic-gate 			kmem_free(ctxp, sizeof (rsa_ctx_t));
10420Sstevel@tonic-gate 			break;
10430Sstevel@tonic-gate 		}
10440Sstevel@tonic-gate 		return (rv);
10450Sstevel@tonic-gate 	}
10460Sstevel@tonic-gate 
10470Sstevel@tonic-gate 	switch (mechanism->cm_type) {
10480Sstevel@tonic-gate 	case MD5_RSA_PKCS_MECH_INFO_TYPE:
10490Sstevel@tonic-gate 		MD5Init(&(dctxp->md5_ctx));
10500Sstevel@tonic-gate 		break;
10510Sstevel@tonic-gate 
10520Sstevel@tonic-gate 	case SHA1_RSA_PKCS_MECH_INFO_TYPE:
10530Sstevel@tonic-gate 		SHA1Init(&(dctxp->sha1_ctx));
10540Sstevel@tonic-gate 		break;
1055676Sizick 
1056676Sizick 	case SHA256_RSA_PKCS_MECH_INFO_TYPE:
1057676Sizick 		SHA2Init(SHA256, &(dctxp->sha2_ctx));
1058676Sizick 		break;
1059676Sizick 
1060676Sizick 	case SHA384_RSA_PKCS_MECH_INFO_TYPE:
1061676Sizick 		SHA2Init(SHA384, &(dctxp->sha2_ctx));
1062676Sizick 		break;
1063676Sizick 
1064676Sizick 	case SHA512_RSA_PKCS_MECH_INFO_TYPE:
1065676Sizick 		SHA2Init(SHA512, &(dctxp->sha2_ctx));
1066676Sizick 		break;
10670Sstevel@tonic-gate 	}
10680Sstevel@tonic-gate 
10690Sstevel@tonic-gate 	ctx->cc_provider_private = ctxp;
10700Sstevel@tonic-gate 
10710Sstevel@tonic-gate 	return (CRYPTO_SUCCESS);
10720Sstevel@tonic-gate }
10730Sstevel@tonic-gate 
10740Sstevel@tonic-gate #define	SHA1_DIGEST_SIZE 20
10750Sstevel@tonic-gate #define	MD5_DIGEST_SIZE 16
10760Sstevel@tonic-gate 
10770Sstevel@tonic-gate #define	INIT_RAW_CRYPTO_DATA(data, base, len, cd_len)	\
10780Sstevel@tonic-gate 	(data).cd_format = CRYPTO_DATA_RAW;		\
10790Sstevel@tonic-gate 	(data).cd_offset = 0;				\
10800Sstevel@tonic-gate 	(data).cd_raw.iov_base = (char *)base;		\
10810Sstevel@tonic-gate 	(data).cd_raw.iov_len = len;			\
10820Sstevel@tonic-gate 	(data).cd_length = cd_len;
10830Sstevel@tonic-gate 
10840Sstevel@tonic-gate static int
10850Sstevel@tonic-gate rsa_digest_svrfy_common(digest_rsa_ctx_t *ctxp, crypto_data_t *data,
10860Sstevel@tonic-gate     crypto_data_t *signature, int kmflag, uchar_t flag)
10870Sstevel@tonic-gate {
10880Sstevel@tonic-gate 	int rv = CRYPTO_FAILED;
10890Sstevel@tonic-gate 
10900Sstevel@tonic-gate /* EXPORT DELETE START */
10910Sstevel@tonic-gate 
1092676Sizick 	uchar_t digest[SHA512_DIGEST_LENGTH];
10930Sstevel@tonic-gate 	/* The der_data size is enough for MD5 also */
1094676Sizick 	uchar_t der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len];
10950Sstevel@tonic-gate 	ulong_t der_data_len;
10960Sstevel@tonic-gate 	crypto_data_t der_cd;
10970Sstevel@tonic-gate 	rsa_mech_type_t mech_type;
10980Sstevel@tonic-gate 
10997188Smcpowers 	ASSERT(flag & CRYPTO_DO_SIGN || flag & CRYPTO_DO_VERIFY);
11007188Smcpowers 	ASSERT(data != NULL || (flag & CRYPTO_DO_FINAL));
11010Sstevel@tonic-gate 
11020Sstevel@tonic-gate 	mech_type = ctxp->mech_type;
1103676Sizick 	if (mech_type == RSA_PKCS_MECH_INFO_TYPE ||
1104676Sizick 	    mech_type == RSA_X_509_MECH_INFO_TYPE)
11050Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
11060Sstevel@tonic-gate 
11070Sstevel@tonic-gate 	/*
11080Sstevel@tonic-gate 	 * We need to do the BUFFER_TOO_SMALL check before digesting
11090Sstevel@tonic-gate 	 * the data. No check is needed for verify as signature is not
11100Sstevel@tonic-gate 	 * an output argument for verify.
11110Sstevel@tonic-gate 	 */
11127188Smcpowers 	if (flag & CRYPTO_DO_SIGN) {
11130Sstevel@tonic-gate 		uchar_t *modulus;
11140Sstevel@tonic-gate 		ssize_t modulus_len;
11150Sstevel@tonic-gate 
11167188Smcpowers 		if ((rv = crypto_get_key_attr(ctxp->key, SUN_CKA_MODULUS,
11177188Smcpowers 		    &modulus, &modulus_len)) != CRYPTO_SUCCESS) {
11180Sstevel@tonic-gate 			return (rv);
11190Sstevel@tonic-gate 		}
11200Sstevel@tonic-gate 
11210Sstevel@tonic-gate 		if (signature->cd_length < modulus_len) {
11220Sstevel@tonic-gate 			signature->cd_length = modulus_len;
11230Sstevel@tonic-gate 			return (CRYPTO_BUFFER_TOO_SMALL);
11240Sstevel@tonic-gate 		}
11250Sstevel@tonic-gate 	}
11260Sstevel@tonic-gate 
11270Sstevel@tonic-gate 	if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE)
11287188Smcpowers 		rv = crypto_digest_data(data, &(ctxp->md5_ctx),
11297188Smcpowers 		    digest, MD5Update, MD5Final, flag | CRYPTO_DO_MD5);
1130676Sizick 
1131676Sizick 	else if (mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE)
11327188Smcpowers 		rv = crypto_digest_data(data, &(ctxp->sha1_ctx),
11337188Smcpowers 		    digest, SHA1Update, SHA1Final,  flag | CRYPTO_DO_SHA1);
1134676Sizick 
1135676Sizick 	else
11367188Smcpowers 		rv = crypto_digest_data(data, &(ctxp->sha2_ctx),
11377188Smcpowers 		    digest, SHA2Update, SHA2Final, flag | CRYPTO_DO_SHA2);
1138676Sizick 
11390Sstevel@tonic-gate 	if (rv != CRYPTO_SUCCESS)
11400Sstevel@tonic-gate 		return (rv);
11410Sstevel@tonic-gate 
1142676Sizick 
11430Sstevel@tonic-gate 	/*
11440Sstevel@tonic-gate 	 * Prepare the DER encoding of the DigestInfo value as follows:
11450Sstevel@tonic-gate 	 * MD5:		MD5_DER_PREFIX || H
11460Sstevel@tonic-gate 	 * SHA-1:	SHA1_DER_PREFIX || H
11470Sstevel@tonic-gate 	 *
11480Sstevel@tonic-gate 	 * See rsa_impl.c for more details.
11490Sstevel@tonic-gate 	 */
1150676Sizick 	switch (mech_type) {
1151676Sizick 	case MD5_RSA_PKCS_MECH_INFO_TYPE:
11520Sstevel@tonic-gate 		bcopy(MD5_DER_PREFIX, der_data, MD5_DER_PREFIX_Len);
1153676Sizick 		bcopy(digest, der_data + MD5_DER_PREFIX_Len, MD5_DIGEST_SIZE);
1154676Sizick 		der_data_len = MD5_DER_PREFIX_Len + MD5_DIGEST_SIZE;
1155676Sizick 		break;
1156676Sizick 
1157676Sizick 	case SHA1_RSA_PKCS_MECH_INFO_TYPE:
11580Sstevel@tonic-gate 		bcopy(SHA1_DER_PREFIX, der_data, SHA1_DER_PREFIX_Len);
1159676Sizick 		bcopy(digest, der_data + SHA1_DER_PREFIX_Len,
1160676Sizick 		    SHA1_DIGEST_SIZE);
1161676Sizick 		der_data_len = SHA1_DER_PREFIX_Len + SHA1_DIGEST_SIZE;
1162676Sizick 		break;
1163676Sizick 
1164676Sizick 	case SHA256_RSA_PKCS_MECH_INFO_TYPE:
1165676Sizick 		bcopy(SHA256_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len);
1166676Sizick 		bcopy(digest, der_data + SHA2_DER_PREFIX_Len,
1167676Sizick 		    SHA256_DIGEST_LENGTH);
1168676Sizick 		der_data_len = SHA2_DER_PREFIX_Len + SHA256_DIGEST_LENGTH;
1169676Sizick 		break;
1170676Sizick 
1171676Sizick 	case SHA384_RSA_PKCS_MECH_INFO_TYPE:
1172676Sizick 		bcopy(SHA384_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len);
1173676Sizick 		bcopy(digest, der_data + SHA2_DER_PREFIX_Len,
1174676Sizick 		    SHA384_DIGEST_LENGTH);
1175676Sizick 		der_data_len = SHA2_DER_PREFIX_Len + SHA384_DIGEST_LENGTH;
1176676Sizick 		break;
1177676Sizick 
1178676Sizick 	case SHA512_RSA_PKCS_MECH_INFO_TYPE:
1179676Sizick 		bcopy(SHA512_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len);
1180676Sizick 		bcopy(digest, der_data + SHA2_DER_PREFIX_Len,
1181676Sizick 		    SHA512_DIGEST_LENGTH);
1182676Sizick 		der_data_len = SHA2_DER_PREFIX_Len + SHA512_DIGEST_LENGTH;
1183676Sizick 		break;
11840Sstevel@tonic-gate 	}
11850Sstevel@tonic-gate 
11860Sstevel@tonic-gate 	INIT_RAW_CRYPTO_DATA(der_cd, der_data, der_data_len, der_data_len);
11870Sstevel@tonic-gate 	/*
11880Sstevel@tonic-gate 	 * Now, we are ready to sign or verify the DER_ENCODED data.
11890Sstevel@tonic-gate 	 */
11907188Smcpowers 	if (flag & CRYPTO_DO_SIGN)
11910Sstevel@tonic-gate 		rv = rsa_sign_common(mech_type, ctxp->key, &der_cd,
11920Sstevel@tonic-gate 		    signature, kmflag);
11930Sstevel@tonic-gate 	else
11940Sstevel@tonic-gate 		rv = rsa_verify_common(mech_type, ctxp->key, &der_cd,
11950Sstevel@tonic-gate 		    signature, kmflag);
11960Sstevel@tonic-gate 
11970Sstevel@tonic-gate /* EXPORT DELETE END */
11980Sstevel@tonic-gate 
11990Sstevel@tonic-gate 	return (rv);
12000Sstevel@tonic-gate }
12010Sstevel@tonic-gate 
12020Sstevel@tonic-gate static int
12030Sstevel@tonic-gate rsa_sign_common(rsa_mech_type_t mech_type, crypto_key_t *key,
12040Sstevel@tonic-gate     crypto_data_t *data, crypto_data_t *signature, int kmflag)
12050Sstevel@tonic-gate {
12060Sstevel@tonic-gate 	int rv = CRYPTO_FAILED;
12070Sstevel@tonic-gate 
12080Sstevel@tonic-gate /* EXPORT DELETE START */
12090Sstevel@tonic-gate 
12100Sstevel@tonic-gate 	int dlen;
12110Sstevel@tonic-gate 	uchar_t *dataptr, *modulus;
12120Sstevel@tonic-gate 	ssize_t modulus_len;
12130Sstevel@tonic-gate 	uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES];
12140Sstevel@tonic-gate 	uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
12150Sstevel@tonic-gate 	uchar_t signed_data[MAX_RSA_KEYLENGTH_IN_BYTES];
12160Sstevel@tonic-gate 
12177188Smcpowers 	if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus,
12180Sstevel@tonic-gate 	    &modulus_len)) != CRYPTO_SUCCESS) {
12190Sstevel@tonic-gate 		return (rv);
12200Sstevel@tonic-gate 	}
12210Sstevel@tonic-gate 
12220Sstevel@tonic-gate 	dlen = data->cd_length;
12230Sstevel@tonic-gate 	switch (mech_type) {
12240Sstevel@tonic-gate 	case RSA_PKCS_MECH_INFO_TYPE:
12250Sstevel@tonic-gate 		if (dlen > (modulus_len - MIN_PKCS1_PADLEN))
12260Sstevel@tonic-gate 			return (CRYPTO_DATA_LEN_RANGE);
12270Sstevel@tonic-gate 		break;
12280Sstevel@tonic-gate 	case RSA_X_509_MECH_INFO_TYPE:
12290Sstevel@tonic-gate 		if (dlen > modulus_len)
12300Sstevel@tonic-gate 			return (CRYPTO_DATA_LEN_RANGE);
12310Sstevel@tonic-gate 		break;
12320Sstevel@tonic-gate 	}
12330Sstevel@tonic-gate 
12340Sstevel@tonic-gate 	if (signature->cd_length < modulus_len) {
12350Sstevel@tonic-gate 		signature->cd_length = modulus_len;
12360Sstevel@tonic-gate 		return (CRYPTO_BUFFER_TOO_SMALL);
12370Sstevel@tonic-gate 	}
12380Sstevel@tonic-gate 
12390Sstevel@tonic-gate 	ASSERT(data->cd_length <= sizeof (tmp_data));
12407188Smcpowers 	if ((rv = crypto_get_input_data(data, &dataptr, tmp_data))
12410Sstevel@tonic-gate 	    != CRYPTO_SUCCESS)
12420Sstevel@tonic-gate 		return (rv);
12430Sstevel@tonic-gate 
12440Sstevel@tonic-gate 	switch (mech_type) {
12450Sstevel@tonic-gate 	case RSA_PKCS_MECH_INFO_TYPE:
12460Sstevel@tonic-gate 	case MD5_RSA_PKCS_MECH_INFO_TYPE:
12470Sstevel@tonic-gate 	case SHA1_RSA_PKCS_MECH_INFO_TYPE:
1248676Sizick 	case SHA256_RSA_PKCS_MECH_INFO_TYPE:
1249676Sizick 	case SHA384_RSA_PKCS_MECH_INFO_TYPE:
1250676Sizick 	case SHA512_RSA_PKCS_MECH_INFO_TYPE:
12510Sstevel@tonic-gate 		/*
12520Sstevel@tonic-gate 		 * Add PKCS padding to the input data to format a block
12530Sstevel@tonic-gate 		 * type "01" encryption block.
12540Sstevel@tonic-gate 		 */
12550Sstevel@tonic-gate 		rv = soft_sign_rsa_pkcs_encode(dataptr, dlen, plain_data,
12560Sstevel@tonic-gate 		    modulus_len);
12570Sstevel@tonic-gate 		if (rv != CRYPTO_SUCCESS)
12580Sstevel@tonic-gate 			return (rv);
12590Sstevel@tonic-gate 
12600Sstevel@tonic-gate 		break;
12610Sstevel@tonic-gate 
12620Sstevel@tonic-gate 	case RSA_X_509_MECH_INFO_TYPE:
12630Sstevel@tonic-gate 		bzero(plain_data, modulus_len - dlen);
12640Sstevel@tonic-gate 		bcopy(dataptr, &plain_data[modulus_len - dlen], dlen);
12650Sstevel@tonic-gate 		break;
12660Sstevel@tonic-gate 	}
12670Sstevel@tonic-gate 
12680Sstevel@tonic-gate 	rv = core_rsa_decrypt(key, plain_data, modulus_len, signed_data,
12690Sstevel@tonic-gate 	    kmflag);
12700Sstevel@tonic-gate 	if (rv == CRYPTO_SUCCESS) {
12710Sstevel@tonic-gate 		/* copy out to signature */
12727188Smcpowers 		if ((rv = crypto_put_output_data(signed_data,
12730Sstevel@tonic-gate 		    signature, modulus_len)) != CRYPTO_SUCCESS)
12740Sstevel@tonic-gate 			return (rv);
12750Sstevel@tonic-gate 
12760Sstevel@tonic-gate 		signature->cd_length = modulus_len;
12770Sstevel@tonic-gate 	}
12780Sstevel@tonic-gate 
12790Sstevel@tonic-gate /* EXPORT DELETE END */
12800Sstevel@tonic-gate 
12810Sstevel@tonic-gate 	return (rv);
12820Sstevel@tonic-gate }
12830Sstevel@tonic-gate 
12840Sstevel@tonic-gate /* ARGSUSED */
12850Sstevel@tonic-gate static int
12860Sstevel@tonic-gate rsa_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
12870Sstevel@tonic-gate     crypto_req_handle_t req)
12880Sstevel@tonic-gate {
12890Sstevel@tonic-gate 	int rv;
12900Sstevel@tonic-gate 	rsa_ctx_t *ctxp;
12910Sstevel@tonic-gate 
12920Sstevel@tonic-gate 	ASSERT(ctx->cc_provider_private != NULL);
12930Sstevel@tonic-gate 	ctxp = ctx->cc_provider_private;
12940Sstevel@tonic-gate 
12950Sstevel@tonic-gate 	/* See the comments on KM_SLEEP flag in rsa_encrypt() */
12960Sstevel@tonic-gate 	switch (ctxp->mech_type) {
12970Sstevel@tonic-gate 	case MD5_RSA_PKCS_MECH_INFO_TYPE:
12980Sstevel@tonic-gate 	case SHA1_RSA_PKCS_MECH_INFO_TYPE:
1299676Sizick 	case SHA256_RSA_PKCS_MECH_INFO_TYPE:
1300676Sizick 	case SHA384_RSA_PKCS_MECH_INFO_TYPE:
1301676Sizick 	case SHA512_RSA_PKCS_MECH_INFO_TYPE:
13020Sstevel@tonic-gate 		rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data,
13037188Smcpowers 		    signature, KM_SLEEP, CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE |
13047188Smcpowers 		    CRYPTO_DO_FINAL);
13050Sstevel@tonic-gate 		break;
13060Sstevel@tonic-gate 	default:
13070Sstevel@tonic-gate 		rv = rsa_sign_common(ctxp->mech_type, ctxp->key, data,
13080Sstevel@tonic-gate 		    signature, KM_SLEEP);
13090Sstevel@tonic-gate 		break;
13100Sstevel@tonic-gate 	}
13110Sstevel@tonic-gate 
13120Sstevel@tonic-gate 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
13130Sstevel@tonic-gate 		(void) rsa_free_context(ctx);
13140Sstevel@tonic-gate 
13150Sstevel@tonic-gate 	return (rv);
13160Sstevel@tonic-gate }
13170Sstevel@tonic-gate 
13180Sstevel@tonic-gate /* ARGSUSED */
13190Sstevel@tonic-gate static int
13200Sstevel@tonic-gate rsa_sign_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req)
13210Sstevel@tonic-gate {
13220Sstevel@tonic-gate 	int rv;
13230Sstevel@tonic-gate 	digest_rsa_ctx_t *ctxp;
13240Sstevel@tonic-gate 	rsa_mech_type_t mech_type;
13250Sstevel@tonic-gate 
13260Sstevel@tonic-gate 	ASSERT(ctx->cc_provider_private != NULL);
13270Sstevel@tonic-gate 	ctxp = ctx->cc_provider_private;
13280Sstevel@tonic-gate 	mech_type = ctxp->mech_type;
13290Sstevel@tonic-gate 
1330676Sizick 	if (mech_type == RSA_PKCS_MECH_INFO_TYPE ||
1331676Sizick 	    mech_type == RSA_X_509_MECH_INFO_TYPE)
13320Sstevel@tonic-gate 		return (CRYPTO_MECHANISM_INVALID);
13330Sstevel@tonic-gate 
13340Sstevel@tonic-gate 	if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE)
13357188Smcpowers 		rv = crypto_digest_data(data, &(ctxp->md5_ctx),
13367188Smcpowers 		    NULL, MD5Update, MD5Final,
13377188Smcpowers 		    CRYPTO_DO_MD5 | CRYPTO_DO_UPDATE);
1338676Sizick 
1339676Sizick 	else if (mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE)
13407188Smcpowers 		rv = crypto_digest_data(data, &(ctxp->sha1_ctx),
13417188Smcpowers 		    NULL, SHA1Update, SHA1Final, CRYPTO_DO_SHA1 |
13427188Smcpowers 		    CRYPTO_DO_UPDATE);
1343676Sizick 
1344676Sizick 	else
13457188Smcpowers 		rv = crypto_digest_data(data, &(ctxp->sha2_ctx),
13467188Smcpowers 		    NULL, SHA2Update, SHA2Final, CRYPTO_DO_SHA2 |
13477188Smcpowers 		    CRYPTO_DO_UPDATE);
1348676Sizick 
13490Sstevel@tonic-gate 	return (rv);
13500Sstevel@tonic-gate }
13510Sstevel@tonic-gate 
13520Sstevel@tonic-gate static int
13530Sstevel@tonic-gate rsa_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature,
13540Sstevel@tonic-gate     crypto_req_handle_t req)
13550Sstevel@tonic-gate {
13560Sstevel@tonic-gate 	int rv;
13570Sstevel@tonic-gate 	digest_rsa_ctx_t *ctxp;
13580Sstevel@tonic-gate 
13590Sstevel@tonic-gate 	ASSERT(ctx->cc_provider_private != NULL);
13600Sstevel@tonic-gate 	ctxp = ctx->cc_provider_private;
13610Sstevel@tonic-gate 
13620Sstevel@tonic-gate 	rv = rsa_digest_svrfy_common(ctxp, NULL, signature,
13637188Smcpowers 	    crypto_kmflag(req), CRYPTO_DO_SIGN | CRYPTO_DO_FINAL);
13640Sstevel@tonic-gate 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
13650Sstevel@tonic-gate 		(void) rsa_free_context(ctx);
13660Sstevel@tonic-gate 
13670Sstevel@tonic-gate 	return (rv);
13680Sstevel@tonic-gate }
13690Sstevel@tonic-gate 
13700Sstevel@tonic-gate /* ARGSUSED */
13710Sstevel@tonic-gate static int
13720Sstevel@tonic-gate rsa_sign_atomic(crypto_provider_handle_t provider,
13730Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
13740Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature,
13750Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
13760Sstevel@tonic-gate {
13770Sstevel@tonic-gate 	int rv;
13780Sstevel@tonic-gate 	digest_rsa_ctx_t dctx;
13790Sstevel@tonic-gate 
13800Sstevel@tonic-gate 	if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS)
13810Sstevel@tonic-gate 		return (rv);
13820Sstevel@tonic-gate 
1383676Sizick 	if (mechanism->cm_type == RSA_PKCS_MECH_INFO_TYPE ||
1384676Sizick 	    mechanism->cm_type == RSA_X_509_MECH_INFO_TYPE)
1385676Sizick 		rv = rsa_sign_common(mechanism->cm_type, key, data,
1386676Sizick 		    signature, crypto_kmflag(req));
1387676Sizick 
1388676Sizick 	else {
13890Sstevel@tonic-gate 		dctx.mech_type = mechanism->cm_type;
13900Sstevel@tonic-gate 		dctx.key = key;
1391676Sizick 		switch (mechanism->cm_type) {
1392676Sizick 		case MD5_RSA_PKCS_MECH_INFO_TYPE:
13930Sstevel@tonic-gate 			MD5Init(&(dctx.md5_ctx));
1394676Sizick 			break;
1395676Sizick 
1396676Sizick 		case SHA1_RSA_PKCS_MECH_INFO_TYPE:
13970Sstevel@tonic-gate 			SHA1Init(&(dctx.sha1_ctx));
1398676Sizick 			break;
1399676Sizick 
1400676Sizick 		case SHA256_RSA_PKCS_MECH_INFO_TYPE:
1401676Sizick 			SHA2Init(SHA256, &(dctx.sha2_ctx));
1402676Sizick 			break;
1403676Sizick 
1404676Sizick 		case SHA384_RSA_PKCS_MECH_INFO_TYPE:
1405676Sizick 			SHA2Init(SHA384, &(dctx.sha2_ctx));
1406676Sizick 			break;
1407676Sizick 
1408676Sizick 		case SHA512_RSA_PKCS_MECH_INFO_TYPE:
1409676Sizick 			SHA2Init(SHA512, &(dctx.sha2_ctx));
1410676Sizick 			break;
1411676Sizick 		}
1412676Sizick 
1413676Sizick 		rv = rsa_digest_svrfy_common(&dctx, data, signature,
14147188Smcpowers 		    crypto_kmflag(req), CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE |
14157188Smcpowers 		    CRYPTO_DO_FINAL);
14160Sstevel@tonic-gate 	}
14170Sstevel@tonic-gate 
14180Sstevel@tonic-gate 	return (rv);
14190Sstevel@tonic-gate }
14200Sstevel@tonic-gate 
14210Sstevel@tonic-gate static int
14220Sstevel@tonic-gate rsa_verify_common(rsa_mech_type_t mech_type, crypto_key_t *key,
14230Sstevel@tonic-gate     crypto_data_t *data, crypto_data_t *signature, int kmflag)
14240Sstevel@tonic-gate {
14250Sstevel@tonic-gate 	int rv = CRYPTO_FAILED;
14260Sstevel@tonic-gate 
14270Sstevel@tonic-gate /* EXPORT DELETE START */
14280Sstevel@tonic-gate 
14290Sstevel@tonic-gate 	uchar_t *sigptr, *modulus;
14300Sstevel@tonic-gate 	ssize_t modulus_len;
14310Sstevel@tonic-gate 	uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
14320Sstevel@tonic-gate 	uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES];
14330Sstevel@tonic-gate 
14347188Smcpowers 	if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus,
14350Sstevel@tonic-gate 	    &modulus_len)) != CRYPTO_SUCCESS) {
14360Sstevel@tonic-gate 		return (rv);
14370Sstevel@tonic-gate 	}
14380Sstevel@tonic-gate 
14390Sstevel@tonic-gate 	if (signature->cd_length != modulus_len)
14400Sstevel@tonic-gate 		return (CRYPTO_SIGNATURE_LEN_RANGE);
14410Sstevel@tonic-gate 
14420Sstevel@tonic-gate 	ASSERT(signature->cd_length <= sizeof (tmp_data));
14437188Smcpowers 	if ((rv = crypto_get_input_data(signature, &sigptr, tmp_data))
14440Sstevel@tonic-gate 	    != CRYPTO_SUCCESS)
14450Sstevel@tonic-gate 		return (rv);
14460Sstevel@tonic-gate 
14470Sstevel@tonic-gate 	rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1);
14480Sstevel@tonic-gate 	if (rv != CRYPTO_SUCCESS)
14490Sstevel@tonic-gate 		return (rv);
14500Sstevel@tonic-gate 
1451676Sizick 	if (mech_type == RSA_X_509_MECH_INFO_TYPE) {
1452676Sizick 		if (compare_data(data, (plain_data + modulus_len
1453676Sizick 		    - data->cd_length)) != 0)
1454676Sizick 			rv = CRYPTO_SIGNATURE_INVALID;
1455676Sizick 
1456676Sizick 	} else {
14570Sstevel@tonic-gate 		int data_len = modulus_len;
14580Sstevel@tonic-gate 
14590Sstevel@tonic-gate 		/*
14600Sstevel@tonic-gate 		 * Strip off the encoded padding bytes in front of the
14610Sstevel@tonic-gate 		 * recovered data, then compare the recovered data with
14620Sstevel@tonic-gate 		 * the original data.
14630Sstevel@tonic-gate 		 */
14640Sstevel@tonic-gate 		rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len);
14650Sstevel@tonic-gate 		if (rv != CRYPTO_SUCCESS)
1466676Sizick 			return (rv);
14670Sstevel@tonic-gate 
1468676Sizick 		if (data_len != data->cd_length)
1469676Sizick 			return (CRYPTO_SIGNATURE_LEN_RANGE);
14700Sstevel@tonic-gate 
14710Sstevel@tonic-gate 		if (compare_data(data, (plain_data + modulus_len
14720Sstevel@tonic-gate 		    - data_len)) != 0)
14730Sstevel@tonic-gate 			rv = CRYPTO_SIGNATURE_INVALID;
14740Sstevel@tonic-gate 	}
14750Sstevel@tonic-gate 
14760Sstevel@tonic-gate /* EXPORT DELETE END */
14770Sstevel@tonic-gate 
14780Sstevel@tonic-gate 	return (rv);
14790Sstevel@tonic-gate }
14800Sstevel@tonic-gate 
14810Sstevel@tonic-gate /* ARGSUSED */
14820Sstevel@tonic-gate static int
14830Sstevel@tonic-gate rsa_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature,
14840Sstevel@tonic-gate     crypto_req_handle_t req)
14850Sstevel@tonic-gate {
14860Sstevel@tonic-gate 	int rv;
14870Sstevel@tonic-gate 	rsa_ctx_t *ctxp;
14880Sstevel@tonic-gate 
14890Sstevel@tonic-gate 	ASSERT(ctx->cc_provider_private != NULL);
14900Sstevel@tonic-gate 	ctxp = ctx->cc_provider_private;
14910Sstevel@tonic-gate 
14920Sstevel@tonic-gate 	/* See the comments on KM_SLEEP flag in rsa_encrypt() */
14930Sstevel@tonic-gate 	switch (ctxp->mech_type) {
14940Sstevel@tonic-gate 	case MD5_RSA_PKCS_MECH_INFO_TYPE:
14950Sstevel@tonic-gate 	case SHA1_RSA_PKCS_MECH_INFO_TYPE:
1496676Sizick 	case SHA256_RSA_PKCS_MECH_INFO_TYPE:
1497676Sizick 	case SHA384_RSA_PKCS_MECH_INFO_TYPE:
1498676Sizick 	case SHA512_RSA_PKCS_MECH_INFO_TYPE:
14990Sstevel@tonic-gate 		rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data,
15007188Smcpowers 		    signature, KM_SLEEP, CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE |
15017188Smcpowers 		    CRYPTO_DO_FINAL);
15020Sstevel@tonic-gate 		break;
15030Sstevel@tonic-gate 	default:
15040Sstevel@tonic-gate 		rv = rsa_verify_common(ctxp->mech_type, ctxp->key, data,
15050Sstevel@tonic-gate 		    signature, KM_SLEEP);
15060Sstevel@tonic-gate 		break;
15070Sstevel@tonic-gate 	}
15080Sstevel@tonic-gate 
15090Sstevel@tonic-gate 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
15100Sstevel@tonic-gate 		(void) rsa_free_context(ctx);
15110Sstevel@tonic-gate 
15120Sstevel@tonic-gate 	return (rv);
15130Sstevel@tonic-gate }
15140Sstevel@tonic-gate 
15150Sstevel@tonic-gate /* ARGSUSED */
15160Sstevel@tonic-gate static int
15170Sstevel@tonic-gate rsa_verify_update(crypto_ctx_t *ctx, crypto_data_t *data,
15180Sstevel@tonic-gate     crypto_req_handle_t req)
15190Sstevel@tonic-gate {
15200Sstevel@tonic-gate 	int rv;
15210Sstevel@tonic-gate 	digest_rsa_ctx_t *ctxp;
15220Sstevel@tonic-gate 
15230Sstevel@tonic-gate 	ASSERT(ctx->cc_provider_private != NULL);
15240Sstevel@tonic-gate 	ctxp = ctx->cc_provider_private;
15250Sstevel@tonic-gate 
1526676Sizick 	switch (ctxp->mech_type) {
15270Sstevel@tonic-gate 
1528676Sizick 	case MD5_RSA_PKCS_MECH_INFO_TYPE:
15297188Smcpowers 		rv = crypto_digest_data(data, &(ctxp->md5_ctx),
15307188Smcpowers 		    NULL, MD5Update, MD5Final, CRYPTO_DO_MD5 |
15317188Smcpowers 		    CRYPTO_DO_UPDATE);
1532676Sizick 		break;
1533676Sizick 
1534676Sizick 	case SHA1_RSA_PKCS_MECH_INFO_TYPE:
15357188Smcpowers 		rv = crypto_digest_data(data, &(ctxp->sha1_ctx),
15367188Smcpowers 		    NULL, SHA1Update, SHA1Final, CRYPTO_DO_SHA1 |
15377188Smcpowers 		    CRYPTO_DO_UPDATE);
1538676Sizick 		break;
1539676Sizick 
1540676Sizick 	case SHA256_RSA_PKCS_MECH_INFO_TYPE:
1541676Sizick 	case SHA384_RSA_PKCS_MECH_INFO_TYPE:
1542676Sizick 	case SHA512_RSA_PKCS_MECH_INFO_TYPE:
15437188Smcpowers 		rv = crypto_digest_data(data, &(ctxp->sha2_ctx),
15447188Smcpowers 		    NULL, SHA2Update, SHA2Final, CRYPTO_DO_SHA2 |
15457188Smcpowers 		    CRYPTO_DO_UPDATE);
1546676Sizick 		break;
1547676Sizick 
1548676Sizick 	default:
1549676Sizick 		return (CRYPTO_MECHANISM_INVALID);
1550676Sizick 	}
1551676Sizick 
15520Sstevel@tonic-gate 	return (rv);
15530Sstevel@tonic-gate }
15540Sstevel@tonic-gate 
15550Sstevel@tonic-gate static int
15560Sstevel@tonic-gate rsa_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature,
15570Sstevel@tonic-gate     crypto_req_handle_t req)
15580Sstevel@tonic-gate {
15590Sstevel@tonic-gate 	int rv;
15600Sstevel@tonic-gate 	digest_rsa_ctx_t *ctxp;
15610Sstevel@tonic-gate 
15620Sstevel@tonic-gate 	ASSERT(ctx->cc_provider_private != NULL);
15630Sstevel@tonic-gate 	ctxp = ctx->cc_provider_private;
15640Sstevel@tonic-gate 
15650Sstevel@tonic-gate 	rv = rsa_digest_svrfy_common(ctxp, NULL, signature,
15667188Smcpowers 	    crypto_kmflag(req), CRYPTO_DO_VERIFY | CRYPTO_DO_FINAL);
15670Sstevel@tonic-gate 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
15680Sstevel@tonic-gate 		(void) rsa_free_context(ctx);
15690Sstevel@tonic-gate 
15700Sstevel@tonic-gate 	return (rv);
15710Sstevel@tonic-gate }
15720Sstevel@tonic-gate 
15730Sstevel@tonic-gate 
15740Sstevel@tonic-gate /* ARGSUSED */
15750Sstevel@tonic-gate static int
15760Sstevel@tonic-gate rsa_verify_atomic(crypto_provider_handle_t provider,
15770Sstevel@tonic-gate     crypto_session_id_t session_id,
15780Sstevel@tonic-gate     crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data,
15790Sstevel@tonic-gate     crypto_data_t *signature, crypto_spi_ctx_template_t ctx_template,
15800Sstevel@tonic-gate     crypto_req_handle_t req)
15810Sstevel@tonic-gate {
15820Sstevel@tonic-gate 	int rv;
15830Sstevel@tonic-gate 	digest_rsa_ctx_t dctx;
15840Sstevel@tonic-gate 
15850Sstevel@tonic-gate 	if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS)
15860Sstevel@tonic-gate 		return (rv);
15870Sstevel@tonic-gate 
1588676Sizick 	if (mechanism->cm_type == RSA_PKCS_MECH_INFO_TYPE ||
1589676Sizick 	    mechanism->cm_type == RSA_X_509_MECH_INFO_TYPE)
1590676Sizick 		rv = rsa_verify_common(mechanism->cm_type, key, data,
1591676Sizick 		    signature, crypto_kmflag(req));
1592676Sizick 
1593676Sizick 	else {
15940Sstevel@tonic-gate 		dctx.mech_type = mechanism->cm_type;
15950Sstevel@tonic-gate 		dctx.key = key;
1596676Sizick 
1597676Sizick 		switch (mechanism->cm_type) {
1598676Sizick 		case MD5_RSA_PKCS_MECH_INFO_TYPE:
15990Sstevel@tonic-gate 			MD5Init(&(dctx.md5_ctx));
1600676Sizick 			break;
1601676Sizick 
1602676Sizick 		case SHA1_RSA_PKCS_MECH_INFO_TYPE:
16030Sstevel@tonic-gate 			SHA1Init(&(dctx.sha1_ctx));
1604676Sizick 			break;
1605676Sizick 
1606676Sizick 		case SHA256_RSA_PKCS_MECH_INFO_TYPE:
1607676Sizick 			SHA2Init(SHA256, &(dctx.sha2_ctx));
1608676Sizick 			break;
1609676Sizick 
1610676Sizick 		case SHA384_RSA_PKCS_MECH_INFO_TYPE:
1611676Sizick 			SHA2Init(SHA384, &(dctx.sha2_ctx));
1612676Sizick 			break;
1613676Sizick 
1614676Sizick 		case SHA512_RSA_PKCS_MECH_INFO_TYPE:
1615676Sizick 			SHA2Init(SHA512, &(dctx.sha2_ctx));
1616676Sizick 			break;
1617676Sizick 		}
1618676Sizick 
16190Sstevel@tonic-gate 		rv = rsa_digest_svrfy_common(&dctx, data,
16200Sstevel@tonic-gate 		    signature, crypto_kmflag(req),
16217188Smcpowers 		    CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE | CRYPTO_DO_FINAL);
16220Sstevel@tonic-gate 	}
16230Sstevel@tonic-gate 
16240Sstevel@tonic-gate 	return (rv);
16250Sstevel@tonic-gate }
16260Sstevel@tonic-gate 
16270Sstevel@tonic-gate static int
16280Sstevel@tonic-gate rsa_verify_recover_common(rsa_mech_type_t mech_type, crypto_key_t *key,
16290Sstevel@tonic-gate     crypto_data_t *signature, crypto_data_t *data, int kmflag)
16300Sstevel@tonic-gate {
16310Sstevel@tonic-gate 	int rv = CRYPTO_FAILED;
16320Sstevel@tonic-gate 
16330Sstevel@tonic-gate /* EXPORT DELETE START */
16340Sstevel@tonic-gate 
16350Sstevel@tonic-gate 	int data_len;
16360Sstevel@tonic-gate 	uchar_t *sigptr, *modulus;
16370Sstevel@tonic-gate 	ssize_t modulus_len;
16380Sstevel@tonic-gate 	uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
16390Sstevel@tonic-gate 	uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES];
16400Sstevel@tonic-gate 
16417188Smcpowers 	if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus,
16420Sstevel@tonic-gate 	    &modulus_len)) != CRYPTO_SUCCESS) {
16430Sstevel@tonic-gate 		return (rv);
16440Sstevel@tonic-gate 	}
16450Sstevel@tonic-gate 
16460Sstevel@tonic-gate 	if (signature->cd_length != modulus_len)
16470Sstevel@tonic-gate 		return (CRYPTO_SIGNATURE_LEN_RANGE);
16480Sstevel@tonic-gate 
16490Sstevel@tonic-gate 	ASSERT(signature->cd_length <= sizeof (tmp_data));
16507188Smcpowers 	if ((rv = crypto_get_input_data(signature, &sigptr, tmp_data))
16510Sstevel@tonic-gate 	    != CRYPTO_SUCCESS)
16520Sstevel@tonic-gate 		return (rv);
16530Sstevel@tonic-gate 
16540Sstevel@tonic-gate 	rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1);
16550Sstevel@tonic-gate 	if (rv != CRYPTO_SUCCESS)
16560Sstevel@tonic-gate 		return (rv);
16570Sstevel@tonic-gate 
16580Sstevel@tonic-gate 	data_len = modulus_len;
16590Sstevel@tonic-gate 
16600Sstevel@tonic-gate 	if (mech_type == RSA_PKCS_MECH_INFO_TYPE) {
16610Sstevel@tonic-gate 		/*
16620Sstevel@tonic-gate 		 * Strip off the encoded padding bytes in front of the
16630Sstevel@tonic-gate 		 * recovered data, then compare the recovered data with
16640Sstevel@tonic-gate 		 * the original data.
16650Sstevel@tonic-gate 		 */
16660Sstevel@tonic-gate 		rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len);
16670Sstevel@tonic-gate 		if (rv != CRYPTO_SUCCESS)
16680Sstevel@tonic-gate 			return (rv);
16690Sstevel@tonic-gate 	}
16700Sstevel@tonic-gate 
16710Sstevel@tonic-gate 	if (data->cd_length < data_len) {
16720Sstevel@tonic-gate 		data->cd_length = data_len;
16730Sstevel@tonic-gate 		return (CRYPTO_BUFFER_TOO_SMALL);
16740Sstevel@tonic-gate 	}
16750Sstevel@tonic-gate 
16767188Smcpowers 	if ((rv = crypto_put_output_data(plain_data + modulus_len - data_len,
16770Sstevel@tonic-gate 	    data, data_len)) != CRYPTO_SUCCESS)
16780Sstevel@tonic-gate 		return (rv);
16790Sstevel@tonic-gate 	data->cd_length = data_len;
16800Sstevel@tonic-gate 
16810Sstevel@tonic-gate /* EXPORT DELETE END */
16820Sstevel@tonic-gate 
16830Sstevel@tonic-gate 	return (rv);
16840Sstevel@tonic-gate }
16850Sstevel@tonic-gate 
16860Sstevel@tonic-gate /* ARGSUSED */
16870Sstevel@tonic-gate static int
16880Sstevel@tonic-gate rsa_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature,
16890Sstevel@tonic-gate     crypto_data_t *data, crypto_req_handle_t req)
16900Sstevel@tonic-gate {
16910Sstevel@tonic-gate 	int rv;
16920Sstevel@tonic-gate 	rsa_ctx_t *ctxp;
16930Sstevel@tonic-gate 
16940Sstevel@tonic-gate 	ASSERT(ctx->cc_provider_private != NULL);
16950Sstevel@tonic-gate 	ctxp = ctx->cc_provider_private;
16960Sstevel@tonic-gate 
16970Sstevel@tonic-gate 	/* See the comments on KM_SLEEP flag in rsa_encrypt() */
16980Sstevel@tonic-gate 	rv = rsa_verify_recover_common(ctxp->mech_type, ctxp->key,
16990Sstevel@tonic-gate 	    signature, data, KM_SLEEP);
17000Sstevel@tonic-gate 
17010Sstevel@tonic-gate 	if (rv != CRYPTO_BUFFER_TOO_SMALL)
17020Sstevel@tonic-gate 		(void) rsa_free_context(ctx);
17030Sstevel@tonic-gate 
17040Sstevel@tonic-gate 	return (rv);
17050Sstevel@tonic-gate }
17060Sstevel@tonic-gate 
17070Sstevel@tonic-gate /* ARGSUSED */
17080Sstevel@tonic-gate static int
17090Sstevel@tonic-gate rsa_verify_recover_atomic(crypto_provider_handle_t provider,
17100Sstevel@tonic-gate     crypto_session_id_t session_id, crypto_mechanism_t *mechanism,
17110Sstevel@tonic-gate     crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data,
17120Sstevel@tonic-gate     crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req)
17130Sstevel@tonic-gate {
17140Sstevel@tonic-gate 	int rv;
17150Sstevel@tonic-gate 
17160Sstevel@tonic-gate 	if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS)
17170Sstevel@tonic-gate 		return (rv);
17180Sstevel@tonic-gate 
17190Sstevel@tonic-gate 	return (rsa_verify_recover_common(mechanism->cm_type, key,
17200Sstevel@tonic-gate 	    signature, data, crypto_kmflag(req)));
17210Sstevel@tonic-gate }
172210500SHai-May.Chao@Sun.COM 
172310500SHai-May.Chao@Sun.COM /*
172410500SHai-May.Chao@Sun.COM  * RSA Power-Up Self-Test
172510500SHai-May.Chao@Sun.COM  */
172610500SHai-May.Chao@Sun.COM void
172710500SHai-May.Chao@Sun.COM rsa_POST(int *rc)
172810500SHai-May.Chao@Sun.COM {
172910500SHai-May.Chao@Sun.COM 
173010500SHai-May.Chao@Sun.COM 	*rc = fips_rsa_post();
173110500SHai-May.Chao@Sun.COM 
173210500SHai-May.Chao@Sun.COM }
1733