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 /* 22*10500SHai-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> 40*10500SHai-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> 44*10500SHai-May.Chao@Sun.COM #include <sha1/sha1_impl.h> 45*10500SHai-May.Chao@Sun.COM #include <sha2/sha2_impl.h> 46*10500SHai-May.Chao@Sun.COM #define _RSA_FIPS_POST 47*10500SHai-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 2770Sstevel@tonic-gate static crypto_ops_t rsa_crypto_ops = { 2780Sstevel@tonic-gate &rsa_control_ops, 2790Sstevel@tonic-gate NULL, 2800Sstevel@tonic-gate &rsa_cipher_ops, 2810Sstevel@tonic-gate NULL, 2820Sstevel@tonic-gate &rsa_sign_ops, 2830Sstevel@tonic-gate &rsa_verify_ops, 2840Sstevel@tonic-gate NULL, 2850Sstevel@tonic-gate NULL, 2860Sstevel@tonic-gate NULL, 2870Sstevel@tonic-gate NULL, 2880Sstevel@tonic-gate NULL, 2890Sstevel@tonic-gate NULL, 2900Sstevel@tonic-gate NULL, 2910Sstevel@tonic-gate &rsa_ctx_ops 2920Sstevel@tonic-gate }; 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate static crypto_provider_info_t rsa_prov_info = { 2950Sstevel@tonic-gate CRYPTO_SPI_VERSION_1, 2960Sstevel@tonic-gate "RSA Software Provider", 2970Sstevel@tonic-gate CRYPTO_SW_PROVIDER, 2980Sstevel@tonic-gate {&modlinkage}, 2990Sstevel@tonic-gate NULL, 3000Sstevel@tonic-gate &rsa_crypto_ops, 3010Sstevel@tonic-gate sizeof (rsa_mech_info_tab)/sizeof (crypto_mech_info_t), 3020Sstevel@tonic-gate rsa_mech_info_tab 3030Sstevel@tonic-gate }; 3040Sstevel@tonic-gate 3050Sstevel@tonic-gate static int rsa_encrypt_common(rsa_mech_type_t, crypto_key_t *, 3060Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3070Sstevel@tonic-gate static int rsa_decrypt_common(rsa_mech_type_t, crypto_key_t *, 3080Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3090Sstevel@tonic-gate static int rsa_sign_common(rsa_mech_type_t, crypto_key_t *, 3100Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3110Sstevel@tonic-gate static int rsa_verify_common(rsa_mech_type_t, crypto_key_t *, 3120Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3130Sstevel@tonic-gate static int compare_data(crypto_data_t *, uchar_t *); 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate /* EXPORT DELETE START */ 3160Sstevel@tonic-gate 3170Sstevel@tonic-gate static int core_rsa_encrypt(crypto_key_t *, uchar_t *, 3180Sstevel@tonic-gate int, uchar_t *, int, int); 3190Sstevel@tonic-gate static int core_rsa_decrypt(crypto_key_t *, uchar_t *, int, 3200Sstevel@tonic-gate uchar_t *, int); 3210Sstevel@tonic-gate 3220Sstevel@tonic-gate /* EXPORT DELETE END */ 3230Sstevel@tonic-gate 3240Sstevel@tonic-gate static crypto_kcf_provider_handle_t rsa_prov_handle = NULL; 3250Sstevel@tonic-gate 3260Sstevel@tonic-gate int 3270Sstevel@tonic-gate _init(void) 3280Sstevel@tonic-gate { 3290Sstevel@tonic-gate int ret; 3300Sstevel@tonic-gate 3310Sstevel@tonic-gate /* 3320Sstevel@tonic-gate * Register with KCF. If the registration fails, return error. 3330Sstevel@tonic-gate */ 3340Sstevel@tonic-gate if ((ret = crypto_register_provider(&rsa_prov_info, 3350Sstevel@tonic-gate &rsa_prov_handle)) != CRYPTO_SUCCESS) { 3360Sstevel@tonic-gate cmn_err(CE_WARN, "rsa _init: crypto_register_provider()" 3370Sstevel@tonic-gate "failed (0x%x)", ret); 3380Sstevel@tonic-gate return (EACCES); 3390Sstevel@tonic-gate } 3400Sstevel@tonic-gate 3410Sstevel@tonic-gate if ((ret = mod_install(&modlinkage)) != 0) { 3420Sstevel@tonic-gate int rv; 3430Sstevel@tonic-gate 3440Sstevel@tonic-gate ASSERT(rsa_prov_handle != NULL); 3450Sstevel@tonic-gate /* We should not return if the unregister returns busy. */ 3460Sstevel@tonic-gate while ((rv = crypto_unregister_provider(rsa_prov_handle)) 3470Sstevel@tonic-gate == CRYPTO_BUSY) { 3480Sstevel@tonic-gate cmn_err(CE_WARN, "rsa _init: " 3490Sstevel@tonic-gate "crypto_unregister_provider() " 3500Sstevel@tonic-gate "failed (0x%x). Retrying.", rv); 3510Sstevel@tonic-gate /* wait 10 seconds and try again. */ 3520Sstevel@tonic-gate delay(10 * drv_usectohz(1000000)); 3530Sstevel@tonic-gate } 3540Sstevel@tonic-gate } 3550Sstevel@tonic-gate 3560Sstevel@tonic-gate return (ret); 3570Sstevel@tonic-gate } 3580Sstevel@tonic-gate 3590Sstevel@tonic-gate int 3600Sstevel@tonic-gate _fini(void) 3610Sstevel@tonic-gate { 3620Sstevel@tonic-gate int ret; 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate /* 3650Sstevel@tonic-gate * Unregister from KCF if previous registration succeeded. 3660Sstevel@tonic-gate */ 3670Sstevel@tonic-gate if (rsa_prov_handle != NULL) { 3680Sstevel@tonic-gate if ((ret = crypto_unregister_provider(rsa_prov_handle)) != 3690Sstevel@tonic-gate CRYPTO_SUCCESS) { 3700Sstevel@tonic-gate cmn_err(CE_WARN, "rsa _fini: " 3710Sstevel@tonic-gate "crypto_unregister_provider() " 3720Sstevel@tonic-gate "failed (0x%x)", ret); 3730Sstevel@tonic-gate return (EBUSY); 3740Sstevel@tonic-gate } 3750Sstevel@tonic-gate rsa_prov_handle = NULL; 3760Sstevel@tonic-gate } 3770Sstevel@tonic-gate 3780Sstevel@tonic-gate return (mod_remove(&modlinkage)); 3790Sstevel@tonic-gate } 3800Sstevel@tonic-gate 3810Sstevel@tonic-gate int 3820Sstevel@tonic-gate _info(struct modinfo *modinfop) 3830Sstevel@tonic-gate { 3840Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 3850Sstevel@tonic-gate } 3860Sstevel@tonic-gate 3870Sstevel@tonic-gate /* ARGSUSED */ 3880Sstevel@tonic-gate static void 3890Sstevel@tonic-gate rsa_provider_status(crypto_provider_handle_t provider, uint_t *status) 3900Sstevel@tonic-gate { 3910Sstevel@tonic-gate *status = CRYPTO_PROVIDER_READY; 3920Sstevel@tonic-gate } 3930Sstevel@tonic-gate 3940Sstevel@tonic-gate static int 3950Sstevel@tonic-gate check_mech_and_key(crypto_mechanism_t *mechanism, crypto_key_t *key) 3960Sstevel@tonic-gate { 3970Sstevel@tonic-gate int rv = CRYPTO_FAILED; 3980Sstevel@tonic-gate 3990Sstevel@tonic-gate /* EXPORT DELETE START */ 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate uchar_t *modulus; 4020Sstevel@tonic-gate ssize_t modulus_len; /* In bytes */ 4030Sstevel@tonic-gate 4040Sstevel@tonic-gate if (!RSA_VALID_MECH(mechanism)) 4050Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 4060Sstevel@tonic-gate 4070Sstevel@tonic-gate /* 4080Sstevel@tonic-gate * We only support RSA keys that are passed as a list of 4090Sstevel@tonic-gate * object attributes. 4100Sstevel@tonic-gate */ 4110Sstevel@tonic-gate if (key->ck_format != CRYPTO_KEY_ATTR_LIST) { 4120Sstevel@tonic-gate return (CRYPTO_KEY_TYPE_INCONSISTENT); 4130Sstevel@tonic-gate } 4140Sstevel@tonic-gate 4157188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 4160Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 4170Sstevel@tonic-gate return (rv); 4180Sstevel@tonic-gate } 4190Sstevel@tonic-gate if (modulus_len < MIN_RSA_KEYLENGTH_IN_BYTES || 4200Sstevel@tonic-gate modulus_len > MAX_RSA_KEYLENGTH_IN_BYTES) 4210Sstevel@tonic-gate return (CRYPTO_KEY_SIZE_RANGE); 4220Sstevel@tonic-gate 4230Sstevel@tonic-gate /* EXPORT DELETE END */ 4240Sstevel@tonic-gate 4250Sstevel@tonic-gate return (rv); 4260Sstevel@tonic-gate } 4270Sstevel@tonic-gate 4280Sstevel@tonic-gate void 4290Sstevel@tonic-gate kmemset(uint8_t *buf, char pattern, size_t len) 4300Sstevel@tonic-gate { 4310Sstevel@tonic-gate int i = 0; 4320Sstevel@tonic-gate 4330Sstevel@tonic-gate while (i < len) 4340Sstevel@tonic-gate buf[i++] = pattern; 4350Sstevel@tonic-gate } 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate /* 4380Sstevel@tonic-gate * This function guarantees to return non-zero random numbers. 4390Sstevel@tonic-gate * This is needed as the /dev/urandom kernel interface, 4400Sstevel@tonic-gate * random_get_pseudo_bytes(), may return zeros. 4410Sstevel@tonic-gate */ 4420Sstevel@tonic-gate int 4430Sstevel@tonic-gate knzero_random_generator(uint8_t *ran_out, size_t ran_len) 4440Sstevel@tonic-gate { 4450Sstevel@tonic-gate int rv; 4460Sstevel@tonic-gate size_t ebc = 0; /* count of extra bytes in extrarand */ 4470Sstevel@tonic-gate size_t i = 0; 4480Sstevel@tonic-gate uint8_t extrarand[32]; 4490Sstevel@tonic-gate size_t extrarand_len; 4500Sstevel@tonic-gate 4510Sstevel@tonic-gate if ((rv = random_get_pseudo_bytes(ran_out, ran_len)) != 0) 4520Sstevel@tonic-gate return (rv); 4530Sstevel@tonic-gate 4540Sstevel@tonic-gate /* 4550Sstevel@tonic-gate * Walk through the returned random numbers pointed by ran_out, 4560Sstevel@tonic-gate * and look for any random number which is zero. 4570Sstevel@tonic-gate * If we find zero, call random_get_pseudo_bytes() to generate 4580Sstevel@tonic-gate * another 32 random numbers pool. Replace any zeros in ran_out[] 4590Sstevel@tonic-gate * from the random number in pool. 4600Sstevel@tonic-gate */ 4610Sstevel@tonic-gate while (i < ran_len) { 4620Sstevel@tonic-gate if (ran_out[i] != 0) { 4630Sstevel@tonic-gate i++; 4640Sstevel@tonic-gate continue; 4650Sstevel@tonic-gate } 4660Sstevel@tonic-gate 4670Sstevel@tonic-gate /* 4680Sstevel@tonic-gate * Note that it is 'while' so we are guaranteed a 4690Sstevel@tonic-gate * non-zero value on exit. 4700Sstevel@tonic-gate */ 4710Sstevel@tonic-gate if (ebc == 0) { 4720Sstevel@tonic-gate /* refresh extrarand */ 4730Sstevel@tonic-gate extrarand_len = sizeof (extrarand); 4740Sstevel@tonic-gate if ((rv = random_get_pseudo_bytes(extrarand, 4750Sstevel@tonic-gate extrarand_len)) != 0) { 4760Sstevel@tonic-gate return (rv); 4770Sstevel@tonic-gate } 4780Sstevel@tonic-gate 4790Sstevel@tonic-gate ebc = extrarand_len; 4800Sstevel@tonic-gate } 4810Sstevel@tonic-gate /* Replace zero with byte from extrarand. */ 4820Sstevel@tonic-gate -- ebc; 4830Sstevel@tonic-gate 4840Sstevel@tonic-gate /* 4850Sstevel@tonic-gate * The new random byte zero/non-zero will be checked in 4860Sstevel@tonic-gate * the next pass through the loop. 4870Sstevel@tonic-gate */ 4880Sstevel@tonic-gate ran_out[i] = extrarand[ebc]; 4890Sstevel@tonic-gate } 4900Sstevel@tonic-gate 4910Sstevel@tonic-gate return (CRYPTO_SUCCESS); 4920Sstevel@tonic-gate } 4930Sstevel@tonic-gate 4940Sstevel@tonic-gate static int 4950Sstevel@tonic-gate compare_data(crypto_data_t *data, uchar_t *buf) 4960Sstevel@tonic-gate { 4970Sstevel@tonic-gate int len; 4980Sstevel@tonic-gate uchar_t *dptr; 4990Sstevel@tonic-gate 5000Sstevel@tonic-gate len = data->cd_length; 5010Sstevel@tonic-gate switch (data->cd_format) { 5020Sstevel@tonic-gate case CRYPTO_DATA_RAW: 5030Sstevel@tonic-gate dptr = (uchar_t *)(data->cd_raw.iov_base + 5040Sstevel@tonic-gate data->cd_offset); 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate return (bcmp(dptr, buf, len)); 5070Sstevel@tonic-gate 5080Sstevel@tonic-gate case CRYPTO_DATA_UIO: 5097188Smcpowers return (crypto_uio_data(data, buf, len, 5107188Smcpowers COMPARE_TO_DATA, NULL, NULL)); 5110Sstevel@tonic-gate 5120Sstevel@tonic-gate case CRYPTO_DATA_MBLK: 5137188Smcpowers return (crypto_mblk_data(data, buf, len, 5147188Smcpowers COMPARE_TO_DATA, NULL, NULL)); 5150Sstevel@tonic-gate } 5160Sstevel@tonic-gate 5170Sstevel@tonic-gate return (CRYPTO_FAILED); 5180Sstevel@tonic-gate } 5190Sstevel@tonic-gate 5200Sstevel@tonic-gate /* ARGSUSED */ 5210Sstevel@tonic-gate static int 5220Sstevel@tonic-gate rsa_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 5230Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t template, 5240Sstevel@tonic-gate crypto_req_handle_t req) 5250Sstevel@tonic-gate { 5260Sstevel@tonic-gate int rv; 5270Sstevel@tonic-gate int kmflag; 5280Sstevel@tonic-gate rsa_ctx_t *ctxp; 5290Sstevel@tonic-gate 5300Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 5310Sstevel@tonic-gate return (rv); 5320Sstevel@tonic-gate 5330Sstevel@tonic-gate /* 5340Sstevel@tonic-gate * Allocate a RSA context. 5350Sstevel@tonic-gate */ 5360Sstevel@tonic-gate kmflag = crypto_kmflag(req); 5370Sstevel@tonic-gate if ((ctxp = kmem_zalloc(sizeof (rsa_ctx_t), kmflag)) == NULL) 5380Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 5390Sstevel@tonic-gate 5407188Smcpowers if ((rv = crypto_copy_key_to_ctx(key, &ctxp->key, &ctxp->keychunk_size, 5417188Smcpowers kmflag)) != CRYPTO_SUCCESS) { 5420Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 5430Sstevel@tonic-gate return (rv); 5440Sstevel@tonic-gate } 5450Sstevel@tonic-gate ctxp->mech_type = mechanism->cm_type; 5460Sstevel@tonic-gate 5470Sstevel@tonic-gate ctx->cc_provider_private = ctxp; 5480Sstevel@tonic-gate 5490Sstevel@tonic-gate return (CRYPTO_SUCCESS); 5500Sstevel@tonic-gate } 5510Sstevel@tonic-gate 5520Sstevel@tonic-gate /* ARGSUSED */ 5530Sstevel@tonic-gate static int 5540Sstevel@tonic-gate rsa_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext, 5550Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_req_handle_t req) 5560Sstevel@tonic-gate { 5570Sstevel@tonic-gate int rv; 5580Sstevel@tonic-gate rsa_ctx_t *ctxp; 5590Sstevel@tonic-gate 5600Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 5610Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 5620Sstevel@tonic-gate 5630Sstevel@tonic-gate RSA_ARG_INPLACE(plaintext, ciphertext); 5640Sstevel@tonic-gate 5650Sstevel@tonic-gate /* 5660Sstevel@tonic-gate * Note on the KM_SLEEP flag passed to the routine below - 5670Sstevel@tonic-gate * rsa_encrypt() is a single-part encryption routine which is 5680Sstevel@tonic-gate * currently usable only by /dev/crypto. Since /dev/crypto calls are 5690Sstevel@tonic-gate * always synchronous, we can safely pass KM_SLEEP here. 5700Sstevel@tonic-gate */ 5710Sstevel@tonic-gate rv = rsa_encrypt_common(ctxp->mech_type, ctxp->key, plaintext, 5720Sstevel@tonic-gate ciphertext, KM_SLEEP); 5730Sstevel@tonic-gate 5740Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 5750Sstevel@tonic-gate (void) rsa_free_context(ctx); 5760Sstevel@tonic-gate 5770Sstevel@tonic-gate return (rv); 5780Sstevel@tonic-gate } 5790Sstevel@tonic-gate 5800Sstevel@tonic-gate /* ARGSUSED */ 5810Sstevel@tonic-gate static int 5820Sstevel@tonic-gate rsa_encrypt_atomic(crypto_provider_handle_t provider, 5830Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 5840Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext, 5850Sstevel@tonic-gate crypto_spi_ctx_template_t template, crypto_req_handle_t req) 5860Sstevel@tonic-gate { 5870Sstevel@tonic-gate int rv; 5880Sstevel@tonic-gate 5890Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 5900Sstevel@tonic-gate return (rv); 5910Sstevel@tonic-gate RSA_ARG_INPLACE(plaintext, ciphertext); 5920Sstevel@tonic-gate 5930Sstevel@tonic-gate return (rsa_encrypt_common(mechanism->cm_type, key, plaintext, 5940Sstevel@tonic-gate ciphertext, crypto_kmflag(req))); 5950Sstevel@tonic-gate } 5960Sstevel@tonic-gate 5970Sstevel@tonic-gate static int 5980Sstevel@tonic-gate rsa_free_context(crypto_ctx_t *ctx) 5990Sstevel@tonic-gate { 6000Sstevel@tonic-gate rsa_ctx_t *ctxp = ctx->cc_provider_private; 6010Sstevel@tonic-gate 6020Sstevel@tonic-gate if (ctxp != NULL) { 6030Sstevel@tonic-gate bzero(ctxp->key, ctxp->keychunk_size); 6040Sstevel@tonic-gate kmem_free(ctxp->key, ctxp->keychunk_size); 6050Sstevel@tonic-gate 6060Sstevel@tonic-gate if (ctxp->mech_type == RSA_PKCS_MECH_INFO_TYPE || 6070Sstevel@tonic-gate ctxp->mech_type == RSA_X_509_MECH_INFO_TYPE) 6080Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 6090Sstevel@tonic-gate else 6100Sstevel@tonic-gate kmem_free(ctxp, sizeof (digest_rsa_ctx_t)); 6110Sstevel@tonic-gate 6120Sstevel@tonic-gate ctx->cc_provider_private = NULL; 6130Sstevel@tonic-gate } 6140Sstevel@tonic-gate 6150Sstevel@tonic-gate return (CRYPTO_SUCCESS); 6160Sstevel@tonic-gate } 6170Sstevel@tonic-gate 6180Sstevel@tonic-gate static int 6190Sstevel@tonic-gate rsa_encrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key, 6200Sstevel@tonic-gate crypto_data_t *plaintext, crypto_data_t *ciphertext, int kmflag) 6210Sstevel@tonic-gate { 6220Sstevel@tonic-gate int rv = CRYPTO_FAILED; 6230Sstevel@tonic-gate 6240Sstevel@tonic-gate /* EXPORT DELETE START */ 6250Sstevel@tonic-gate 6260Sstevel@tonic-gate int plen; 6270Sstevel@tonic-gate uchar_t *ptptr; 6280Sstevel@tonic-gate uchar_t *modulus; 6290Sstevel@tonic-gate ssize_t modulus_len; 6300Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 6310Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 6320Sstevel@tonic-gate uchar_t cipher_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 6330Sstevel@tonic-gate 6347188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 6350Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 6360Sstevel@tonic-gate return (rv); 6370Sstevel@tonic-gate } 6380Sstevel@tonic-gate 6390Sstevel@tonic-gate plen = plaintext->cd_length; 6400Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 6410Sstevel@tonic-gate if (plen > (modulus_len - MIN_PKCS1_PADLEN)) 6420Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 6430Sstevel@tonic-gate } else { 6440Sstevel@tonic-gate if (plen > modulus_len) 6450Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 6460Sstevel@tonic-gate } 6470Sstevel@tonic-gate 6480Sstevel@tonic-gate /* 6490Sstevel@tonic-gate * Output buf len must not be less than RSA modulus size. 6500Sstevel@tonic-gate */ 6510Sstevel@tonic-gate if (ciphertext->cd_length < modulus_len) { 6520Sstevel@tonic-gate ciphertext->cd_length = modulus_len; 6530Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 6540Sstevel@tonic-gate } 6550Sstevel@tonic-gate 6560Sstevel@tonic-gate ASSERT(plaintext->cd_length <= sizeof (tmp_data)); 6577188Smcpowers if ((rv = crypto_get_input_data(plaintext, &ptptr, tmp_data)) 6580Sstevel@tonic-gate != CRYPTO_SUCCESS) 6590Sstevel@tonic-gate return (rv); 6600Sstevel@tonic-gate 6610Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 6620Sstevel@tonic-gate rv = soft_encrypt_rsa_pkcs_encode(ptptr, plen, 6630Sstevel@tonic-gate plain_data, modulus_len); 6640Sstevel@tonic-gate 6650Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 6660Sstevel@tonic-gate return (rv); 6670Sstevel@tonic-gate } else { 6680Sstevel@tonic-gate bzero(plain_data, modulus_len - plen); 6690Sstevel@tonic-gate bcopy(ptptr, &plain_data[modulus_len - plen], plen); 6700Sstevel@tonic-gate } 6710Sstevel@tonic-gate 6720Sstevel@tonic-gate rv = core_rsa_encrypt(key, plain_data, modulus_len, 6730Sstevel@tonic-gate cipher_data, kmflag, 1); 6740Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 6750Sstevel@tonic-gate /* copy out to ciphertext */ 6767188Smcpowers if ((rv = crypto_put_output_data(cipher_data, 6770Sstevel@tonic-gate ciphertext, modulus_len)) != CRYPTO_SUCCESS) 6780Sstevel@tonic-gate return (rv); 6790Sstevel@tonic-gate 6800Sstevel@tonic-gate ciphertext->cd_length = modulus_len; 6810Sstevel@tonic-gate } 6820Sstevel@tonic-gate 6830Sstevel@tonic-gate /* EXPORT DELETE END */ 6840Sstevel@tonic-gate 6850Sstevel@tonic-gate return (rv); 6860Sstevel@tonic-gate } 6870Sstevel@tonic-gate 6880Sstevel@tonic-gate /* EXPORT DELETE START */ 6890Sstevel@tonic-gate 6900Sstevel@tonic-gate static int 6910Sstevel@tonic-gate core_rsa_encrypt(crypto_key_t *key, uchar_t *in, 6920Sstevel@tonic-gate int in_len, uchar_t *out, int kmflag, int is_public) 6930Sstevel@tonic-gate { 6940Sstevel@tonic-gate int rv; 6950Sstevel@tonic-gate uchar_t *expo, *modulus; 6960Sstevel@tonic-gate ssize_t expo_len; 6970Sstevel@tonic-gate ssize_t modulus_len; 6980Sstevel@tonic-gate BIGNUM msg; 6990Sstevel@tonic-gate RSAkey *rsakey; 7000Sstevel@tonic-gate 7010Sstevel@tonic-gate if (is_public) { 7027188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_PUBLIC_EXPONENT, 7037188Smcpowers &expo, &expo_len)) != CRYPTO_SUCCESS) 7040Sstevel@tonic-gate return (rv); 7050Sstevel@tonic-gate } else { 7060Sstevel@tonic-gate /* 7070Sstevel@tonic-gate * SUN_CKA_PRIVATE_EXPONENT is a required attribute for a 7080Sstevel@tonic-gate * RSA secret key. See the comments in core_rsa_decrypt 7090Sstevel@tonic-gate * routine which calls this routine with a private key. 7100Sstevel@tonic-gate */ 7117188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_PRIVATE_EXPONENT, 7127188Smcpowers &expo, &expo_len)) != CRYPTO_SUCCESS) 7130Sstevel@tonic-gate return (rv); 7140Sstevel@tonic-gate } 7150Sstevel@tonic-gate 7167188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 7170Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 7180Sstevel@tonic-gate return (rv); 7190Sstevel@tonic-gate } 7200Sstevel@tonic-gate 7210Sstevel@tonic-gate rsakey = kmem_alloc(sizeof (RSAkey), kmflag); 7220Sstevel@tonic-gate if (rsakey == NULL) 7230Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 7240Sstevel@tonic-gate 7250Sstevel@tonic-gate /* psize and qsize for RSA_key_init is in bits. */ 7260Sstevel@tonic-gate if (RSA_key_init(rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) { 7270Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 7280Sstevel@tonic-gate goto clean1; 7290Sstevel@tonic-gate } 7300Sstevel@tonic-gate 7316557Sfr41279 /* Size for big_init is in BIG_CHUNK_TYPE words. */ 7326557Sfr41279 if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) { 7330Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 7340Sstevel@tonic-gate goto clean2; 7350Sstevel@tonic-gate } 7360Sstevel@tonic-gate 7370Sstevel@tonic-gate /* Convert octet string exponent to big integer format. */ 7380Sstevel@tonic-gate bytestring2bignum(&(rsakey->e), expo, expo_len); 7390Sstevel@tonic-gate 7400Sstevel@tonic-gate /* Convert octet string modulus to big integer format. */ 7410Sstevel@tonic-gate bytestring2bignum(&(rsakey->n), modulus, modulus_len); 7420Sstevel@tonic-gate 7430Sstevel@tonic-gate /* Convert octet string input data to big integer format. */ 7440Sstevel@tonic-gate bytestring2bignum(&msg, in, in_len); 7450Sstevel@tonic-gate 7460Sstevel@tonic-gate if (big_cmp_abs(&msg, &(rsakey->n)) > 0) { 7470Sstevel@tonic-gate rv = CRYPTO_DATA_LEN_RANGE; 7480Sstevel@tonic-gate goto clean3; 7490Sstevel@tonic-gate } 7500Sstevel@tonic-gate 7510Sstevel@tonic-gate /* Perform RSA computation on big integer input data. */ 7520Sstevel@tonic-gate if (big_modexp(&msg, &msg, &(rsakey->e), &(rsakey->n), NULL) 7530Sstevel@tonic-gate != BIG_OK) { 7540Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 7550Sstevel@tonic-gate goto clean3; 7560Sstevel@tonic-gate } 7570Sstevel@tonic-gate 7580Sstevel@tonic-gate /* Convert the big integer output data to octet string. */ 7590Sstevel@tonic-gate bignum2bytestring(out, &msg, modulus_len); 7600Sstevel@tonic-gate 7610Sstevel@tonic-gate /* 7620Sstevel@tonic-gate * Should not free modulus and expo as both are just pointers 7630Sstevel@tonic-gate * to an attribute value buffer from the caller. 7640Sstevel@tonic-gate */ 7650Sstevel@tonic-gate clean3: 7660Sstevel@tonic-gate big_finish(&msg); 7670Sstevel@tonic-gate clean2: 7680Sstevel@tonic-gate RSA_key_finish(rsakey); 7690Sstevel@tonic-gate clean1: 7700Sstevel@tonic-gate kmem_free(rsakey, sizeof (RSAkey)); 7710Sstevel@tonic-gate 7720Sstevel@tonic-gate return (rv); 7730Sstevel@tonic-gate } 7740Sstevel@tonic-gate 7750Sstevel@tonic-gate /* EXPORT DELETE END */ 7760Sstevel@tonic-gate 7770Sstevel@tonic-gate /* ARGSUSED */ 7780Sstevel@tonic-gate static int 7790Sstevel@tonic-gate rsa_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext, 7800Sstevel@tonic-gate crypto_data_t *plaintext, crypto_req_handle_t req) 7810Sstevel@tonic-gate { 7820Sstevel@tonic-gate int rv; 7830Sstevel@tonic-gate rsa_ctx_t *ctxp; 7840Sstevel@tonic-gate 7850Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 7860Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 7870Sstevel@tonic-gate 7880Sstevel@tonic-gate RSA_ARG_INPLACE(ciphertext, plaintext); 7890Sstevel@tonic-gate 7900Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 7910Sstevel@tonic-gate rv = rsa_decrypt_common(ctxp->mech_type, ctxp->key, 7920Sstevel@tonic-gate ciphertext, plaintext, KM_SLEEP); 7930Sstevel@tonic-gate 7940Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 7950Sstevel@tonic-gate (void) rsa_free_context(ctx); 7960Sstevel@tonic-gate 7970Sstevel@tonic-gate return (rv); 7980Sstevel@tonic-gate } 7990Sstevel@tonic-gate 8000Sstevel@tonic-gate /* ARGSUSED */ 8010Sstevel@tonic-gate static int 8020Sstevel@tonic-gate rsa_decrypt_atomic(crypto_provider_handle_t provider, 8030Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 8040Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext, 8050Sstevel@tonic-gate crypto_spi_ctx_template_t template, crypto_req_handle_t req) 8060Sstevel@tonic-gate { 8070Sstevel@tonic-gate int rv; 8080Sstevel@tonic-gate 8090Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 8100Sstevel@tonic-gate return (rv); 8110Sstevel@tonic-gate RSA_ARG_INPLACE(ciphertext, plaintext); 8120Sstevel@tonic-gate 8130Sstevel@tonic-gate return (rsa_decrypt_common(mechanism->cm_type, key, ciphertext, 8140Sstevel@tonic-gate plaintext, crypto_kmflag(req))); 8150Sstevel@tonic-gate } 8160Sstevel@tonic-gate 8170Sstevel@tonic-gate static int 8180Sstevel@tonic-gate rsa_decrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key, 8190Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_data_t *plaintext, int kmflag) 8200Sstevel@tonic-gate { 8210Sstevel@tonic-gate int rv = CRYPTO_FAILED; 8220Sstevel@tonic-gate 8230Sstevel@tonic-gate /* EXPORT DELETE START */ 8240Sstevel@tonic-gate 8250Sstevel@tonic-gate int plain_len; 8260Sstevel@tonic-gate uchar_t *ctptr; 8270Sstevel@tonic-gate uchar_t *modulus; 8280Sstevel@tonic-gate ssize_t modulus_len; 8290Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 8300Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 8310Sstevel@tonic-gate 8327188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 8330Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 8340Sstevel@tonic-gate return (rv); 8350Sstevel@tonic-gate } 8360Sstevel@tonic-gate 8370Sstevel@tonic-gate /* 8380Sstevel@tonic-gate * Ciphertext length must be equal to RSA modulus size. 8390Sstevel@tonic-gate */ 8400Sstevel@tonic-gate if (ciphertext->cd_length != modulus_len) 8410Sstevel@tonic-gate return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 8420Sstevel@tonic-gate 8430Sstevel@tonic-gate ASSERT(ciphertext->cd_length <= sizeof (tmp_data)); 8447188Smcpowers if ((rv = crypto_get_input_data(ciphertext, &ctptr, tmp_data)) 8450Sstevel@tonic-gate != CRYPTO_SUCCESS) 8460Sstevel@tonic-gate return (rv); 8470Sstevel@tonic-gate 8480Sstevel@tonic-gate rv = core_rsa_decrypt(key, ctptr, modulus_len, plain_data, kmflag); 8490Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 8500Sstevel@tonic-gate plain_len = modulus_len; 8510Sstevel@tonic-gate 8520Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 8530Sstevel@tonic-gate /* Strip off the PKCS block formatting data. */ 8540Sstevel@tonic-gate rv = soft_decrypt_rsa_pkcs_decode(plain_data, 8550Sstevel@tonic-gate &plain_len); 8560Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 8570Sstevel@tonic-gate return (rv); 8580Sstevel@tonic-gate } 8590Sstevel@tonic-gate 8600Sstevel@tonic-gate if (plain_len > plaintext->cd_length) { 8610Sstevel@tonic-gate plaintext->cd_length = plain_len; 8620Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 8630Sstevel@tonic-gate } 8640Sstevel@tonic-gate 8657188Smcpowers if ((rv = crypto_put_output_data( 8667188Smcpowers plain_data + modulus_len - plain_len, 8670Sstevel@tonic-gate plaintext, plain_len)) != CRYPTO_SUCCESS) 8680Sstevel@tonic-gate return (rv); 8690Sstevel@tonic-gate 8700Sstevel@tonic-gate plaintext->cd_length = plain_len; 8710Sstevel@tonic-gate } 8720Sstevel@tonic-gate 8730Sstevel@tonic-gate /* EXPORT DELETE END */ 8740Sstevel@tonic-gate 8750Sstevel@tonic-gate return (rv); 8760Sstevel@tonic-gate } 8770Sstevel@tonic-gate 8780Sstevel@tonic-gate /* EXPORT DELETE START */ 8790Sstevel@tonic-gate 8800Sstevel@tonic-gate static int 8810Sstevel@tonic-gate core_rsa_decrypt(crypto_key_t *key, uchar_t *in, int in_len, 8820Sstevel@tonic-gate uchar_t *out, int kmflag) 8830Sstevel@tonic-gate { 8840Sstevel@tonic-gate int rv; 8850Sstevel@tonic-gate uchar_t *modulus, *prime1, *prime2, *expo1, *expo2, *coef; 8860Sstevel@tonic-gate ssize_t modulus_len; 8870Sstevel@tonic-gate ssize_t prime1_len, prime2_len; 8880Sstevel@tonic-gate ssize_t expo1_len, expo2_len, coef_len; 8890Sstevel@tonic-gate BIGNUM msg; 8900Sstevel@tonic-gate RSAkey *rsakey; 8910Sstevel@tonic-gate 8927188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 8930Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 8940Sstevel@tonic-gate return (rv); 8950Sstevel@tonic-gate } 8960Sstevel@tonic-gate 8970Sstevel@tonic-gate /* 8980Sstevel@tonic-gate * The following attributes are not required to be 8990Sstevel@tonic-gate * present in a RSA secret key. If any of them is not present 9000Sstevel@tonic-gate * we call the encrypt routine with a flag indicating use of 9010Sstevel@tonic-gate * private exponent (d). Note that SUN_CKA_PRIVATE_EXPONENT is 9020Sstevel@tonic-gate * a required attribute for a RSA secret key. 9030Sstevel@tonic-gate */ 9047188Smcpowers if ((crypto_get_key_attr(key, SUN_CKA_PRIME_1, &prime1, &prime1_len) 9055072Smcpowers != CRYPTO_SUCCESS) || 9067188Smcpowers (crypto_get_key_attr(key, SUN_CKA_PRIME_2, &prime2, &prime2_len) 9075072Smcpowers != CRYPTO_SUCCESS) || 9087188Smcpowers (crypto_get_key_attr(key, SUN_CKA_EXPONENT_1, &expo1, &expo1_len) 9095072Smcpowers != CRYPTO_SUCCESS) || 9107188Smcpowers (crypto_get_key_attr(key, SUN_CKA_EXPONENT_2, &expo2, &expo2_len) 9115072Smcpowers != CRYPTO_SUCCESS) || 9127188Smcpowers (crypto_get_key_attr(key, SUN_CKA_COEFFICIENT, &coef, &coef_len) 9135072Smcpowers != CRYPTO_SUCCESS)) { 9140Sstevel@tonic-gate return (core_rsa_encrypt(key, in, in_len, out, kmflag, 0)); 9150Sstevel@tonic-gate } 9160Sstevel@tonic-gate 9170Sstevel@tonic-gate rsakey = kmem_alloc(sizeof (RSAkey), kmflag); 9180Sstevel@tonic-gate if (rsakey == NULL) 9190Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 9200Sstevel@tonic-gate 9210Sstevel@tonic-gate /* psize and qsize for RSA_key_init is in bits. */ 9220Sstevel@tonic-gate if (RSA_key_init(rsakey, prime2_len * 8, prime1_len * 8) != BIG_OK) { 9230Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 9240Sstevel@tonic-gate goto clean1; 9250Sstevel@tonic-gate } 9260Sstevel@tonic-gate 9276557Sfr41279 /* Size for big_init is in BIG_CHUNK_TYPE words. */ 9286557Sfr41279 if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) { 9290Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 9300Sstevel@tonic-gate goto clean2; 9310Sstevel@tonic-gate } 9320Sstevel@tonic-gate 9330Sstevel@tonic-gate /* Convert octet string input data to big integer format. */ 9340Sstevel@tonic-gate bytestring2bignum(&msg, in, in_len); 9350Sstevel@tonic-gate 9360Sstevel@tonic-gate /* Convert octet string modulus to big integer format. */ 9370Sstevel@tonic-gate bytestring2bignum(&(rsakey->n), modulus, modulus_len); 9380Sstevel@tonic-gate 9390Sstevel@tonic-gate if (big_cmp_abs(&msg, &(rsakey->n)) > 0) { 9400Sstevel@tonic-gate rv = CRYPTO_DATA_LEN_RANGE; 9410Sstevel@tonic-gate goto clean3; 9420Sstevel@tonic-gate } 9430Sstevel@tonic-gate 9440Sstevel@tonic-gate /* Convert the rest of private key attributes to big integer format. */ 9450Sstevel@tonic-gate bytestring2bignum(&(rsakey->dmodpminus1), expo2, expo2_len); 9460Sstevel@tonic-gate bytestring2bignum(&(rsakey->dmodqminus1), expo1, expo1_len); 9470Sstevel@tonic-gate bytestring2bignum(&(rsakey->p), prime2, prime2_len); 9480Sstevel@tonic-gate bytestring2bignum(&(rsakey->q), prime1, prime1_len); 9490Sstevel@tonic-gate bytestring2bignum(&(rsakey->pinvmodq), coef, coef_len); 9500Sstevel@tonic-gate 9510Sstevel@tonic-gate if ((big_cmp_abs(&(rsakey->dmodpminus1), &(rsakey->p)) > 0) || 9520Sstevel@tonic-gate (big_cmp_abs(&(rsakey->dmodqminus1), &(rsakey->q)) > 0) || 9530Sstevel@tonic-gate (big_cmp_abs(&(rsakey->pinvmodq), &(rsakey->q)) > 0)) { 9540Sstevel@tonic-gate rv = CRYPTO_KEY_SIZE_RANGE; 9550Sstevel@tonic-gate goto clean3; 9560Sstevel@tonic-gate } 9570Sstevel@tonic-gate 9580Sstevel@tonic-gate /* Perform RSA computation on big integer input data. */ 9590Sstevel@tonic-gate if (big_modexp_crt(&msg, &msg, &(rsakey->dmodpminus1), 9600Sstevel@tonic-gate &(rsakey->dmodqminus1), &(rsakey->p), &(rsakey->q), 9610Sstevel@tonic-gate &(rsakey->pinvmodq), NULL, NULL) != BIG_OK) { 9620Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 9630Sstevel@tonic-gate goto clean3; 9640Sstevel@tonic-gate } 9650Sstevel@tonic-gate 9660Sstevel@tonic-gate /* Convert the big integer output data to octet string. */ 9670Sstevel@tonic-gate bignum2bytestring(out, &msg, modulus_len); 9680Sstevel@tonic-gate 9690Sstevel@tonic-gate /* 9700Sstevel@tonic-gate * Should not free modulus and friends as they are just pointers 9710Sstevel@tonic-gate * to an attribute value buffer from the caller. 9720Sstevel@tonic-gate */ 9730Sstevel@tonic-gate clean3: 9740Sstevel@tonic-gate big_finish(&msg); 9750Sstevel@tonic-gate clean2: 9760Sstevel@tonic-gate RSA_key_finish(rsakey); 9770Sstevel@tonic-gate clean1: 9780Sstevel@tonic-gate kmem_free(rsakey, sizeof (RSAkey)); 9790Sstevel@tonic-gate 9800Sstevel@tonic-gate return (rv); 9810Sstevel@tonic-gate } 9820Sstevel@tonic-gate 9830Sstevel@tonic-gate /* EXPORT DELETE END */ 9840Sstevel@tonic-gate 9850Sstevel@tonic-gate /* ARGSUSED */ 9860Sstevel@tonic-gate static int 9870Sstevel@tonic-gate rsa_sign_verify_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 9880Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 9890Sstevel@tonic-gate crypto_req_handle_t req) 9900Sstevel@tonic-gate { 9910Sstevel@tonic-gate int rv; 9920Sstevel@tonic-gate int kmflag; 9930Sstevel@tonic-gate rsa_ctx_t *ctxp; 9940Sstevel@tonic-gate digest_rsa_ctx_t *dctxp; 9950Sstevel@tonic-gate 9960Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 9970Sstevel@tonic-gate return (rv); 9980Sstevel@tonic-gate 9990Sstevel@tonic-gate /* 10000Sstevel@tonic-gate * Allocate a RSA context. 10010Sstevel@tonic-gate */ 10020Sstevel@tonic-gate kmflag = crypto_kmflag(req); 10030Sstevel@tonic-gate switch (mechanism->cm_type) { 10040Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 10050Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1006676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1007676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1008676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 10090Sstevel@tonic-gate dctxp = kmem_zalloc(sizeof (digest_rsa_ctx_t), kmflag); 10100Sstevel@tonic-gate ctxp = (rsa_ctx_t *)dctxp; 10110Sstevel@tonic-gate break; 10120Sstevel@tonic-gate default: 10130Sstevel@tonic-gate ctxp = kmem_zalloc(sizeof (rsa_ctx_t), kmflag); 10140Sstevel@tonic-gate break; 10150Sstevel@tonic-gate } 10160Sstevel@tonic-gate 10170Sstevel@tonic-gate if (ctxp == NULL) 10180Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 10190Sstevel@tonic-gate 10200Sstevel@tonic-gate ctxp->mech_type = mechanism->cm_type; 10217188Smcpowers if ((rv = crypto_copy_key_to_ctx(key, &ctxp->key, &ctxp->keychunk_size, 10227188Smcpowers kmflag)) != CRYPTO_SUCCESS) { 10230Sstevel@tonic-gate switch (mechanism->cm_type) { 10240Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 10250Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1026676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1027676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1028676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 10290Sstevel@tonic-gate kmem_free(dctxp, sizeof (digest_rsa_ctx_t)); 10300Sstevel@tonic-gate break; 10310Sstevel@tonic-gate default: 10320Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 10330Sstevel@tonic-gate break; 10340Sstevel@tonic-gate } 10350Sstevel@tonic-gate return (rv); 10360Sstevel@tonic-gate } 10370Sstevel@tonic-gate 10380Sstevel@tonic-gate switch (mechanism->cm_type) { 10390Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 10400Sstevel@tonic-gate MD5Init(&(dctxp->md5_ctx)); 10410Sstevel@tonic-gate break; 10420Sstevel@tonic-gate 10430Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 10440Sstevel@tonic-gate SHA1Init(&(dctxp->sha1_ctx)); 10450Sstevel@tonic-gate break; 1046676Sizick 1047676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1048676Sizick SHA2Init(SHA256, &(dctxp->sha2_ctx)); 1049676Sizick break; 1050676Sizick 1051676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1052676Sizick SHA2Init(SHA384, &(dctxp->sha2_ctx)); 1053676Sizick break; 1054676Sizick 1055676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1056676Sizick SHA2Init(SHA512, &(dctxp->sha2_ctx)); 1057676Sizick break; 10580Sstevel@tonic-gate } 10590Sstevel@tonic-gate 10600Sstevel@tonic-gate ctx->cc_provider_private = ctxp; 10610Sstevel@tonic-gate 10620Sstevel@tonic-gate return (CRYPTO_SUCCESS); 10630Sstevel@tonic-gate } 10640Sstevel@tonic-gate 10650Sstevel@tonic-gate #define SHA1_DIGEST_SIZE 20 10660Sstevel@tonic-gate #define MD5_DIGEST_SIZE 16 10670Sstevel@tonic-gate 10680Sstevel@tonic-gate #define INIT_RAW_CRYPTO_DATA(data, base, len, cd_len) \ 10690Sstevel@tonic-gate (data).cd_format = CRYPTO_DATA_RAW; \ 10700Sstevel@tonic-gate (data).cd_offset = 0; \ 10710Sstevel@tonic-gate (data).cd_raw.iov_base = (char *)base; \ 10720Sstevel@tonic-gate (data).cd_raw.iov_len = len; \ 10730Sstevel@tonic-gate (data).cd_length = cd_len; 10740Sstevel@tonic-gate 10750Sstevel@tonic-gate static int 10760Sstevel@tonic-gate rsa_digest_svrfy_common(digest_rsa_ctx_t *ctxp, crypto_data_t *data, 10770Sstevel@tonic-gate crypto_data_t *signature, int kmflag, uchar_t flag) 10780Sstevel@tonic-gate { 10790Sstevel@tonic-gate int rv = CRYPTO_FAILED; 10800Sstevel@tonic-gate 10810Sstevel@tonic-gate /* EXPORT DELETE START */ 10820Sstevel@tonic-gate 1083676Sizick uchar_t digest[SHA512_DIGEST_LENGTH]; 10840Sstevel@tonic-gate /* The der_data size is enough for MD5 also */ 1085676Sizick uchar_t der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len]; 10860Sstevel@tonic-gate ulong_t der_data_len; 10870Sstevel@tonic-gate crypto_data_t der_cd; 10880Sstevel@tonic-gate rsa_mech_type_t mech_type; 10890Sstevel@tonic-gate 10907188Smcpowers ASSERT(flag & CRYPTO_DO_SIGN || flag & CRYPTO_DO_VERIFY); 10917188Smcpowers ASSERT(data != NULL || (flag & CRYPTO_DO_FINAL)); 10920Sstevel@tonic-gate 10930Sstevel@tonic-gate mech_type = ctxp->mech_type; 1094676Sizick if (mech_type == RSA_PKCS_MECH_INFO_TYPE || 1095676Sizick mech_type == RSA_X_509_MECH_INFO_TYPE) 10960Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 10970Sstevel@tonic-gate 10980Sstevel@tonic-gate /* 10990Sstevel@tonic-gate * We need to do the BUFFER_TOO_SMALL check before digesting 11000Sstevel@tonic-gate * the data. No check is needed for verify as signature is not 11010Sstevel@tonic-gate * an output argument for verify. 11020Sstevel@tonic-gate */ 11037188Smcpowers if (flag & CRYPTO_DO_SIGN) { 11040Sstevel@tonic-gate uchar_t *modulus; 11050Sstevel@tonic-gate ssize_t modulus_len; 11060Sstevel@tonic-gate 11077188Smcpowers if ((rv = crypto_get_key_attr(ctxp->key, SUN_CKA_MODULUS, 11087188Smcpowers &modulus, &modulus_len)) != CRYPTO_SUCCESS) { 11090Sstevel@tonic-gate return (rv); 11100Sstevel@tonic-gate } 11110Sstevel@tonic-gate 11120Sstevel@tonic-gate if (signature->cd_length < modulus_len) { 11130Sstevel@tonic-gate signature->cd_length = modulus_len; 11140Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 11150Sstevel@tonic-gate } 11160Sstevel@tonic-gate } 11170Sstevel@tonic-gate 11180Sstevel@tonic-gate if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE) 11197188Smcpowers rv = crypto_digest_data(data, &(ctxp->md5_ctx), 11207188Smcpowers digest, MD5Update, MD5Final, flag | CRYPTO_DO_MD5); 1121676Sizick 1122676Sizick else if (mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE) 11237188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha1_ctx), 11247188Smcpowers digest, SHA1Update, SHA1Final, flag | CRYPTO_DO_SHA1); 1125676Sizick 1126676Sizick else 11277188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha2_ctx), 11287188Smcpowers digest, SHA2Update, SHA2Final, flag | CRYPTO_DO_SHA2); 1129676Sizick 11300Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 11310Sstevel@tonic-gate return (rv); 11320Sstevel@tonic-gate 1133676Sizick 11340Sstevel@tonic-gate /* 11350Sstevel@tonic-gate * Prepare the DER encoding of the DigestInfo value as follows: 11360Sstevel@tonic-gate * MD5: MD5_DER_PREFIX || H 11370Sstevel@tonic-gate * SHA-1: SHA1_DER_PREFIX || H 11380Sstevel@tonic-gate * 11390Sstevel@tonic-gate * See rsa_impl.c for more details. 11400Sstevel@tonic-gate */ 1141676Sizick switch (mech_type) { 1142676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 11430Sstevel@tonic-gate bcopy(MD5_DER_PREFIX, der_data, MD5_DER_PREFIX_Len); 1144676Sizick bcopy(digest, der_data + MD5_DER_PREFIX_Len, MD5_DIGEST_SIZE); 1145676Sizick der_data_len = MD5_DER_PREFIX_Len + MD5_DIGEST_SIZE; 1146676Sizick break; 1147676Sizick 1148676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 11490Sstevel@tonic-gate bcopy(SHA1_DER_PREFIX, der_data, SHA1_DER_PREFIX_Len); 1150676Sizick bcopy(digest, der_data + SHA1_DER_PREFIX_Len, 1151676Sizick SHA1_DIGEST_SIZE); 1152676Sizick der_data_len = SHA1_DER_PREFIX_Len + SHA1_DIGEST_SIZE; 1153676Sizick break; 1154676Sizick 1155676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1156676Sizick bcopy(SHA256_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len); 1157676Sizick bcopy(digest, der_data + SHA2_DER_PREFIX_Len, 1158676Sizick SHA256_DIGEST_LENGTH); 1159676Sizick der_data_len = SHA2_DER_PREFIX_Len + SHA256_DIGEST_LENGTH; 1160676Sizick break; 1161676Sizick 1162676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1163676Sizick bcopy(SHA384_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len); 1164676Sizick bcopy(digest, der_data + SHA2_DER_PREFIX_Len, 1165676Sizick SHA384_DIGEST_LENGTH); 1166676Sizick der_data_len = SHA2_DER_PREFIX_Len + SHA384_DIGEST_LENGTH; 1167676Sizick break; 1168676Sizick 1169676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1170676Sizick bcopy(SHA512_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len); 1171676Sizick bcopy(digest, der_data + SHA2_DER_PREFIX_Len, 1172676Sizick SHA512_DIGEST_LENGTH); 1173676Sizick der_data_len = SHA2_DER_PREFIX_Len + SHA512_DIGEST_LENGTH; 1174676Sizick break; 11750Sstevel@tonic-gate } 11760Sstevel@tonic-gate 11770Sstevel@tonic-gate INIT_RAW_CRYPTO_DATA(der_cd, der_data, der_data_len, der_data_len); 11780Sstevel@tonic-gate /* 11790Sstevel@tonic-gate * Now, we are ready to sign or verify the DER_ENCODED data. 11800Sstevel@tonic-gate */ 11817188Smcpowers if (flag & CRYPTO_DO_SIGN) 11820Sstevel@tonic-gate rv = rsa_sign_common(mech_type, ctxp->key, &der_cd, 11830Sstevel@tonic-gate signature, kmflag); 11840Sstevel@tonic-gate else 11850Sstevel@tonic-gate rv = rsa_verify_common(mech_type, ctxp->key, &der_cd, 11860Sstevel@tonic-gate signature, kmflag); 11870Sstevel@tonic-gate 11880Sstevel@tonic-gate /* EXPORT DELETE END */ 11890Sstevel@tonic-gate 11900Sstevel@tonic-gate return (rv); 11910Sstevel@tonic-gate } 11920Sstevel@tonic-gate 11930Sstevel@tonic-gate static int 11940Sstevel@tonic-gate rsa_sign_common(rsa_mech_type_t mech_type, crypto_key_t *key, 11950Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *signature, int kmflag) 11960Sstevel@tonic-gate { 11970Sstevel@tonic-gate int rv = CRYPTO_FAILED; 11980Sstevel@tonic-gate 11990Sstevel@tonic-gate /* EXPORT DELETE START */ 12000Sstevel@tonic-gate 12010Sstevel@tonic-gate int dlen; 12020Sstevel@tonic-gate uchar_t *dataptr, *modulus; 12030Sstevel@tonic-gate ssize_t modulus_len; 12040Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 12050Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 12060Sstevel@tonic-gate uchar_t signed_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 12070Sstevel@tonic-gate 12087188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 12090Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 12100Sstevel@tonic-gate return (rv); 12110Sstevel@tonic-gate } 12120Sstevel@tonic-gate 12130Sstevel@tonic-gate dlen = data->cd_length; 12140Sstevel@tonic-gate switch (mech_type) { 12150Sstevel@tonic-gate case RSA_PKCS_MECH_INFO_TYPE: 12160Sstevel@tonic-gate if (dlen > (modulus_len - MIN_PKCS1_PADLEN)) 12170Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 12180Sstevel@tonic-gate break; 12190Sstevel@tonic-gate case RSA_X_509_MECH_INFO_TYPE: 12200Sstevel@tonic-gate if (dlen > modulus_len) 12210Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 12220Sstevel@tonic-gate break; 12230Sstevel@tonic-gate } 12240Sstevel@tonic-gate 12250Sstevel@tonic-gate if (signature->cd_length < modulus_len) { 12260Sstevel@tonic-gate signature->cd_length = modulus_len; 12270Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 12280Sstevel@tonic-gate } 12290Sstevel@tonic-gate 12300Sstevel@tonic-gate ASSERT(data->cd_length <= sizeof (tmp_data)); 12317188Smcpowers if ((rv = crypto_get_input_data(data, &dataptr, tmp_data)) 12320Sstevel@tonic-gate != CRYPTO_SUCCESS) 12330Sstevel@tonic-gate return (rv); 12340Sstevel@tonic-gate 12350Sstevel@tonic-gate switch (mech_type) { 12360Sstevel@tonic-gate case RSA_PKCS_MECH_INFO_TYPE: 12370Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 12380Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1239676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1240676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1241676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 12420Sstevel@tonic-gate /* 12430Sstevel@tonic-gate * Add PKCS padding to the input data to format a block 12440Sstevel@tonic-gate * type "01" encryption block. 12450Sstevel@tonic-gate */ 12460Sstevel@tonic-gate rv = soft_sign_rsa_pkcs_encode(dataptr, dlen, plain_data, 12470Sstevel@tonic-gate modulus_len); 12480Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 12490Sstevel@tonic-gate return (rv); 12500Sstevel@tonic-gate 12510Sstevel@tonic-gate break; 12520Sstevel@tonic-gate 12530Sstevel@tonic-gate case RSA_X_509_MECH_INFO_TYPE: 12540Sstevel@tonic-gate bzero(plain_data, modulus_len - dlen); 12550Sstevel@tonic-gate bcopy(dataptr, &plain_data[modulus_len - dlen], dlen); 12560Sstevel@tonic-gate break; 12570Sstevel@tonic-gate } 12580Sstevel@tonic-gate 12590Sstevel@tonic-gate rv = core_rsa_decrypt(key, plain_data, modulus_len, signed_data, 12600Sstevel@tonic-gate kmflag); 12610Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 12620Sstevel@tonic-gate /* copy out to signature */ 12637188Smcpowers if ((rv = crypto_put_output_data(signed_data, 12640Sstevel@tonic-gate signature, modulus_len)) != CRYPTO_SUCCESS) 12650Sstevel@tonic-gate return (rv); 12660Sstevel@tonic-gate 12670Sstevel@tonic-gate signature->cd_length = modulus_len; 12680Sstevel@tonic-gate } 12690Sstevel@tonic-gate 12700Sstevel@tonic-gate /* EXPORT DELETE END */ 12710Sstevel@tonic-gate 12720Sstevel@tonic-gate return (rv); 12730Sstevel@tonic-gate } 12740Sstevel@tonic-gate 12750Sstevel@tonic-gate /* ARGSUSED */ 12760Sstevel@tonic-gate static int 12770Sstevel@tonic-gate rsa_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 12780Sstevel@tonic-gate crypto_req_handle_t req) 12790Sstevel@tonic-gate { 12800Sstevel@tonic-gate int rv; 12810Sstevel@tonic-gate rsa_ctx_t *ctxp; 12820Sstevel@tonic-gate 12830Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 12840Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 12850Sstevel@tonic-gate 12860Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 12870Sstevel@tonic-gate switch (ctxp->mech_type) { 12880Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 12890Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1290676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1291676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1292676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 12930Sstevel@tonic-gate rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data, 12947188Smcpowers signature, KM_SLEEP, CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE | 12957188Smcpowers CRYPTO_DO_FINAL); 12960Sstevel@tonic-gate break; 12970Sstevel@tonic-gate default: 12980Sstevel@tonic-gate rv = rsa_sign_common(ctxp->mech_type, ctxp->key, data, 12990Sstevel@tonic-gate signature, KM_SLEEP); 13000Sstevel@tonic-gate break; 13010Sstevel@tonic-gate } 13020Sstevel@tonic-gate 13030Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 13040Sstevel@tonic-gate (void) rsa_free_context(ctx); 13050Sstevel@tonic-gate 13060Sstevel@tonic-gate return (rv); 13070Sstevel@tonic-gate } 13080Sstevel@tonic-gate 13090Sstevel@tonic-gate /* ARGSUSED */ 13100Sstevel@tonic-gate static int 13110Sstevel@tonic-gate rsa_sign_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req) 13120Sstevel@tonic-gate { 13130Sstevel@tonic-gate int rv; 13140Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 13150Sstevel@tonic-gate rsa_mech_type_t mech_type; 13160Sstevel@tonic-gate 13170Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 13180Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 13190Sstevel@tonic-gate mech_type = ctxp->mech_type; 13200Sstevel@tonic-gate 1321676Sizick if (mech_type == RSA_PKCS_MECH_INFO_TYPE || 1322676Sizick mech_type == RSA_X_509_MECH_INFO_TYPE) 13230Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 13240Sstevel@tonic-gate 13250Sstevel@tonic-gate if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE) 13267188Smcpowers rv = crypto_digest_data(data, &(ctxp->md5_ctx), 13277188Smcpowers NULL, MD5Update, MD5Final, 13287188Smcpowers CRYPTO_DO_MD5 | CRYPTO_DO_UPDATE); 1329676Sizick 1330676Sizick else if (mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE) 13317188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha1_ctx), 13327188Smcpowers NULL, SHA1Update, SHA1Final, CRYPTO_DO_SHA1 | 13337188Smcpowers CRYPTO_DO_UPDATE); 1334676Sizick 1335676Sizick else 13367188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha2_ctx), 13377188Smcpowers NULL, SHA2Update, SHA2Final, CRYPTO_DO_SHA2 | 13387188Smcpowers CRYPTO_DO_UPDATE); 1339676Sizick 13400Sstevel@tonic-gate return (rv); 13410Sstevel@tonic-gate } 13420Sstevel@tonic-gate 13430Sstevel@tonic-gate static int 13440Sstevel@tonic-gate rsa_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature, 13450Sstevel@tonic-gate crypto_req_handle_t req) 13460Sstevel@tonic-gate { 13470Sstevel@tonic-gate int rv; 13480Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 13490Sstevel@tonic-gate 13500Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 13510Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 13520Sstevel@tonic-gate 13530Sstevel@tonic-gate rv = rsa_digest_svrfy_common(ctxp, NULL, signature, 13547188Smcpowers crypto_kmflag(req), CRYPTO_DO_SIGN | CRYPTO_DO_FINAL); 13550Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 13560Sstevel@tonic-gate (void) rsa_free_context(ctx); 13570Sstevel@tonic-gate 13580Sstevel@tonic-gate return (rv); 13590Sstevel@tonic-gate } 13600Sstevel@tonic-gate 13610Sstevel@tonic-gate /* ARGSUSED */ 13620Sstevel@tonic-gate static int 13630Sstevel@tonic-gate rsa_sign_atomic(crypto_provider_handle_t provider, 13640Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 13650Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 13660Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 13670Sstevel@tonic-gate { 13680Sstevel@tonic-gate int rv; 13690Sstevel@tonic-gate digest_rsa_ctx_t dctx; 13700Sstevel@tonic-gate 13710Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 13720Sstevel@tonic-gate return (rv); 13730Sstevel@tonic-gate 1374676Sizick if (mechanism->cm_type == RSA_PKCS_MECH_INFO_TYPE || 1375676Sizick mechanism->cm_type == RSA_X_509_MECH_INFO_TYPE) 1376676Sizick rv = rsa_sign_common(mechanism->cm_type, key, data, 1377676Sizick signature, crypto_kmflag(req)); 1378676Sizick 1379676Sizick else { 13800Sstevel@tonic-gate dctx.mech_type = mechanism->cm_type; 13810Sstevel@tonic-gate dctx.key = key; 1382676Sizick switch (mechanism->cm_type) { 1383676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 13840Sstevel@tonic-gate MD5Init(&(dctx.md5_ctx)); 1385676Sizick break; 1386676Sizick 1387676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 13880Sstevel@tonic-gate SHA1Init(&(dctx.sha1_ctx)); 1389676Sizick break; 1390676Sizick 1391676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1392676Sizick SHA2Init(SHA256, &(dctx.sha2_ctx)); 1393676Sizick break; 1394676Sizick 1395676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1396676Sizick SHA2Init(SHA384, &(dctx.sha2_ctx)); 1397676Sizick break; 1398676Sizick 1399676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1400676Sizick SHA2Init(SHA512, &(dctx.sha2_ctx)); 1401676Sizick break; 1402676Sizick } 1403676Sizick 1404676Sizick rv = rsa_digest_svrfy_common(&dctx, data, signature, 14057188Smcpowers crypto_kmflag(req), CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE | 14067188Smcpowers CRYPTO_DO_FINAL); 14070Sstevel@tonic-gate } 14080Sstevel@tonic-gate 14090Sstevel@tonic-gate return (rv); 14100Sstevel@tonic-gate } 14110Sstevel@tonic-gate 14120Sstevel@tonic-gate static int 14130Sstevel@tonic-gate rsa_verify_common(rsa_mech_type_t mech_type, crypto_key_t *key, 14140Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *signature, int kmflag) 14150Sstevel@tonic-gate { 14160Sstevel@tonic-gate int rv = CRYPTO_FAILED; 14170Sstevel@tonic-gate 14180Sstevel@tonic-gate /* EXPORT DELETE START */ 14190Sstevel@tonic-gate 14200Sstevel@tonic-gate uchar_t *sigptr, *modulus; 14210Sstevel@tonic-gate ssize_t modulus_len; 14220Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 14230Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 14240Sstevel@tonic-gate 14257188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 14260Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 14270Sstevel@tonic-gate return (rv); 14280Sstevel@tonic-gate } 14290Sstevel@tonic-gate 14300Sstevel@tonic-gate if (signature->cd_length != modulus_len) 14310Sstevel@tonic-gate return (CRYPTO_SIGNATURE_LEN_RANGE); 14320Sstevel@tonic-gate 14330Sstevel@tonic-gate ASSERT(signature->cd_length <= sizeof (tmp_data)); 14347188Smcpowers if ((rv = crypto_get_input_data(signature, &sigptr, tmp_data)) 14350Sstevel@tonic-gate != CRYPTO_SUCCESS) 14360Sstevel@tonic-gate return (rv); 14370Sstevel@tonic-gate 14380Sstevel@tonic-gate rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1); 14390Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 14400Sstevel@tonic-gate return (rv); 14410Sstevel@tonic-gate 1442676Sizick if (mech_type == RSA_X_509_MECH_INFO_TYPE) { 1443676Sizick if (compare_data(data, (plain_data + modulus_len 1444676Sizick - data->cd_length)) != 0) 1445676Sizick rv = CRYPTO_SIGNATURE_INVALID; 1446676Sizick 1447676Sizick } else { 14480Sstevel@tonic-gate int data_len = modulus_len; 14490Sstevel@tonic-gate 14500Sstevel@tonic-gate /* 14510Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the 14520Sstevel@tonic-gate * recovered data, then compare the recovered data with 14530Sstevel@tonic-gate * the original data. 14540Sstevel@tonic-gate */ 14550Sstevel@tonic-gate rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len); 14560Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 1457676Sizick return (rv); 14580Sstevel@tonic-gate 1459676Sizick if (data_len != data->cd_length) 1460676Sizick return (CRYPTO_SIGNATURE_LEN_RANGE); 14610Sstevel@tonic-gate 14620Sstevel@tonic-gate if (compare_data(data, (plain_data + modulus_len 14630Sstevel@tonic-gate - data_len)) != 0) 14640Sstevel@tonic-gate rv = CRYPTO_SIGNATURE_INVALID; 14650Sstevel@tonic-gate } 14660Sstevel@tonic-gate 14670Sstevel@tonic-gate /* EXPORT DELETE END */ 14680Sstevel@tonic-gate 14690Sstevel@tonic-gate return (rv); 14700Sstevel@tonic-gate } 14710Sstevel@tonic-gate 14720Sstevel@tonic-gate /* ARGSUSED */ 14730Sstevel@tonic-gate static int 14740Sstevel@tonic-gate rsa_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 14750Sstevel@tonic-gate crypto_req_handle_t req) 14760Sstevel@tonic-gate { 14770Sstevel@tonic-gate int rv; 14780Sstevel@tonic-gate rsa_ctx_t *ctxp; 14790Sstevel@tonic-gate 14800Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 14810Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 14820Sstevel@tonic-gate 14830Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 14840Sstevel@tonic-gate switch (ctxp->mech_type) { 14850Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 14860Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1487676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1488676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1489676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 14900Sstevel@tonic-gate rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data, 14917188Smcpowers signature, KM_SLEEP, CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE | 14927188Smcpowers CRYPTO_DO_FINAL); 14930Sstevel@tonic-gate break; 14940Sstevel@tonic-gate default: 14950Sstevel@tonic-gate rv = rsa_verify_common(ctxp->mech_type, ctxp->key, data, 14960Sstevel@tonic-gate signature, KM_SLEEP); 14970Sstevel@tonic-gate break; 14980Sstevel@tonic-gate } 14990Sstevel@tonic-gate 15000Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 15010Sstevel@tonic-gate (void) rsa_free_context(ctx); 15020Sstevel@tonic-gate 15030Sstevel@tonic-gate return (rv); 15040Sstevel@tonic-gate } 15050Sstevel@tonic-gate 15060Sstevel@tonic-gate /* ARGSUSED */ 15070Sstevel@tonic-gate static int 15080Sstevel@tonic-gate rsa_verify_update(crypto_ctx_t *ctx, crypto_data_t *data, 15090Sstevel@tonic-gate crypto_req_handle_t req) 15100Sstevel@tonic-gate { 15110Sstevel@tonic-gate int rv; 15120Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 15130Sstevel@tonic-gate 15140Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 15150Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 15160Sstevel@tonic-gate 1517676Sizick switch (ctxp->mech_type) { 15180Sstevel@tonic-gate 1519676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 15207188Smcpowers rv = crypto_digest_data(data, &(ctxp->md5_ctx), 15217188Smcpowers NULL, MD5Update, MD5Final, CRYPTO_DO_MD5 | 15227188Smcpowers CRYPTO_DO_UPDATE); 1523676Sizick break; 1524676Sizick 1525676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 15267188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha1_ctx), 15277188Smcpowers NULL, SHA1Update, SHA1Final, CRYPTO_DO_SHA1 | 15287188Smcpowers CRYPTO_DO_UPDATE); 1529676Sizick break; 1530676Sizick 1531676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1532676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1533676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 15347188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha2_ctx), 15357188Smcpowers NULL, SHA2Update, SHA2Final, CRYPTO_DO_SHA2 | 15367188Smcpowers CRYPTO_DO_UPDATE); 1537676Sizick break; 1538676Sizick 1539676Sizick default: 1540676Sizick return (CRYPTO_MECHANISM_INVALID); 1541676Sizick } 1542676Sizick 15430Sstevel@tonic-gate return (rv); 15440Sstevel@tonic-gate } 15450Sstevel@tonic-gate 15460Sstevel@tonic-gate static int 15470Sstevel@tonic-gate rsa_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature, 15480Sstevel@tonic-gate crypto_req_handle_t req) 15490Sstevel@tonic-gate { 15500Sstevel@tonic-gate int rv; 15510Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 15520Sstevel@tonic-gate 15530Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 15540Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 15550Sstevel@tonic-gate 15560Sstevel@tonic-gate rv = rsa_digest_svrfy_common(ctxp, NULL, signature, 15577188Smcpowers crypto_kmflag(req), CRYPTO_DO_VERIFY | CRYPTO_DO_FINAL); 15580Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 15590Sstevel@tonic-gate (void) rsa_free_context(ctx); 15600Sstevel@tonic-gate 15610Sstevel@tonic-gate return (rv); 15620Sstevel@tonic-gate } 15630Sstevel@tonic-gate 15640Sstevel@tonic-gate 15650Sstevel@tonic-gate /* ARGSUSED */ 15660Sstevel@tonic-gate static int 15670Sstevel@tonic-gate rsa_verify_atomic(crypto_provider_handle_t provider, 15680Sstevel@tonic-gate crypto_session_id_t session_id, 15690Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data, 15700Sstevel@tonic-gate crypto_data_t *signature, crypto_spi_ctx_template_t ctx_template, 15710Sstevel@tonic-gate crypto_req_handle_t req) 15720Sstevel@tonic-gate { 15730Sstevel@tonic-gate int rv; 15740Sstevel@tonic-gate digest_rsa_ctx_t dctx; 15750Sstevel@tonic-gate 15760Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 15770Sstevel@tonic-gate return (rv); 15780Sstevel@tonic-gate 1579676Sizick if (mechanism->cm_type == RSA_PKCS_MECH_INFO_TYPE || 1580676Sizick mechanism->cm_type == RSA_X_509_MECH_INFO_TYPE) 1581676Sizick rv = rsa_verify_common(mechanism->cm_type, key, data, 1582676Sizick signature, crypto_kmflag(req)); 1583676Sizick 1584676Sizick else { 15850Sstevel@tonic-gate dctx.mech_type = mechanism->cm_type; 15860Sstevel@tonic-gate dctx.key = key; 1587676Sizick 1588676Sizick switch (mechanism->cm_type) { 1589676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 15900Sstevel@tonic-gate MD5Init(&(dctx.md5_ctx)); 1591676Sizick break; 1592676Sizick 1593676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 15940Sstevel@tonic-gate SHA1Init(&(dctx.sha1_ctx)); 1595676Sizick break; 1596676Sizick 1597676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1598676Sizick SHA2Init(SHA256, &(dctx.sha2_ctx)); 1599676Sizick break; 1600676Sizick 1601676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1602676Sizick SHA2Init(SHA384, &(dctx.sha2_ctx)); 1603676Sizick break; 1604676Sizick 1605676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1606676Sizick SHA2Init(SHA512, &(dctx.sha2_ctx)); 1607676Sizick break; 1608676Sizick } 1609676Sizick 16100Sstevel@tonic-gate rv = rsa_digest_svrfy_common(&dctx, data, 16110Sstevel@tonic-gate signature, crypto_kmflag(req), 16127188Smcpowers CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE | CRYPTO_DO_FINAL); 16130Sstevel@tonic-gate } 16140Sstevel@tonic-gate 16150Sstevel@tonic-gate return (rv); 16160Sstevel@tonic-gate } 16170Sstevel@tonic-gate 16180Sstevel@tonic-gate static int 16190Sstevel@tonic-gate rsa_verify_recover_common(rsa_mech_type_t mech_type, crypto_key_t *key, 16200Sstevel@tonic-gate crypto_data_t *signature, crypto_data_t *data, int kmflag) 16210Sstevel@tonic-gate { 16220Sstevel@tonic-gate int rv = CRYPTO_FAILED; 16230Sstevel@tonic-gate 16240Sstevel@tonic-gate /* EXPORT DELETE START */ 16250Sstevel@tonic-gate 16260Sstevel@tonic-gate int data_len; 16270Sstevel@tonic-gate uchar_t *sigptr, *modulus; 16280Sstevel@tonic-gate ssize_t modulus_len; 16290Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 16300Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 16310Sstevel@tonic-gate 16327188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 16330Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 16340Sstevel@tonic-gate return (rv); 16350Sstevel@tonic-gate } 16360Sstevel@tonic-gate 16370Sstevel@tonic-gate if (signature->cd_length != modulus_len) 16380Sstevel@tonic-gate return (CRYPTO_SIGNATURE_LEN_RANGE); 16390Sstevel@tonic-gate 16400Sstevel@tonic-gate ASSERT(signature->cd_length <= sizeof (tmp_data)); 16417188Smcpowers if ((rv = crypto_get_input_data(signature, &sigptr, tmp_data)) 16420Sstevel@tonic-gate != CRYPTO_SUCCESS) 16430Sstevel@tonic-gate return (rv); 16440Sstevel@tonic-gate 16450Sstevel@tonic-gate rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1); 16460Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 16470Sstevel@tonic-gate return (rv); 16480Sstevel@tonic-gate 16490Sstevel@tonic-gate data_len = modulus_len; 16500Sstevel@tonic-gate 16510Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 16520Sstevel@tonic-gate /* 16530Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the 16540Sstevel@tonic-gate * recovered data, then compare the recovered data with 16550Sstevel@tonic-gate * the original data. 16560Sstevel@tonic-gate */ 16570Sstevel@tonic-gate rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len); 16580Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 16590Sstevel@tonic-gate return (rv); 16600Sstevel@tonic-gate } 16610Sstevel@tonic-gate 16620Sstevel@tonic-gate if (data->cd_length < data_len) { 16630Sstevel@tonic-gate data->cd_length = data_len; 16640Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 16650Sstevel@tonic-gate } 16660Sstevel@tonic-gate 16677188Smcpowers if ((rv = crypto_put_output_data(plain_data + modulus_len - data_len, 16680Sstevel@tonic-gate data, data_len)) != CRYPTO_SUCCESS) 16690Sstevel@tonic-gate return (rv); 16700Sstevel@tonic-gate data->cd_length = data_len; 16710Sstevel@tonic-gate 16720Sstevel@tonic-gate /* EXPORT DELETE END */ 16730Sstevel@tonic-gate 16740Sstevel@tonic-gate return (rv); 16750Sstevel@tonic-gate } 16760Sstevel@tonic-gate 16770Sstevel@tonic-gate /* ARGSUSED */ 16780Sstevel@tonic-gate static int 16790Sstevel@tonic-gate rsa_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature, 16800Sstevel@tonic-gate crypto_data_t *data, crypto_req_handle_t req) 16810Sstevel@tonic-gate { 16820Sstevel@tonic-gate int rv; 16830Sstevel@tonic-gate rsa_ctx_t *ctxp; 16840Sstevel@tonic-gate 16850Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 16860Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 16870Sstevel@tonic-gate 16880Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 16890Sstevel@tonic-gate rv = rsa_verify_recover_common(ctxp->mech_type, ctxp->key, 16900Sstevel@tonic-gate signature, data, KM_SLEEP); 16910Sstevel@tonic-gate 16920Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 16930Sstevel@tonic-gate (void) rsa_free_context(ctx); 16940Sstevel@tonic-gate 16950Sstevel@tonic-gate return (rv); 16960Sstevel@tonic-gate } 16970Sstevel@tonic-gate 16980Sstevel@tonic-gate /* ARGSUSED */ 16990Sstevel@tonic-gate static int 17000Sstevel@tonic-gate rsa_verify_recover_atomic(crypto_provider_handle_t provider, 17010Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 17020Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data, 17030Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 17040Sstevel@tonic-gate { 17050Sstevel@tonic-gate int rv; 17060Sstevel@tonic-gate 17070Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 17080Sstevel@tonic-gate return (rv); 17090Sstevel@tonic-gate 17100Sstevel@tonic-gate return (rsa_verify_recover_common(mechanism->cm_type, key, 17110Sstevel@tonic-gate signature, data, crypto_kmflag(req))); 17120Sstevel@tonic-gate } 1713*10500SHai-May.Chao@Sun.COM 1714*10500SHai-May.Chao@Sun.COM /* 1715*10500SHai-May.Chao@Sun.COM * RSA Power-Up Self-Test 1716*10500SHai-May.Chao@Sun.COM */ 1717*10500SHai-May.Chao@Sun.COM void 1718*10500SHai-May.Chao@Sun.COM rsa_POST(int *rc) 1719*10500SHai-May.Chao@Sun.COM { 1720*10500SHai-May.Chao@Sun.COM 1721*10500SHai-May.Chao@Sun.COM *rc = fips_rsa_post(); 1722*10500SHai-May.Chao@Sun.COM 1723*10500SHai-May.Chao@Sun.COM } 1724