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