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 /* 226557Sfr41279 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate /* 290Sstevel@tonic-gate * RSA provider for the Kernel Cryptographic Framework (KCF) 300Sstevel@tonic-gate */ 310Sstevel@tonic-gate 320Sstevel@tonic-gate #include <sys/types.h> 330Sstevel@tonic-gate #include <sys/systm.h> 340Sstevel@tonic-gate #include <sys/modctl.h> 350Sstevel@tonic-gate #include <sys/cmn_err.h> 360Sstevel@tonic-gate #include <sys/ddi.h> 370Sstevel@tonic-gate #include <sys/crypto/spi.h> 380Sstevel@tonic-gate #include <sys/sysmacros.h> 390Sstevel@tonic-gate #include <sys/strsun.h> 400Sstevel@tonic-gate #include <sys/md5.h> 410Sstevel@tonic-gate #include <sys/sha1.h> 42676Sizick #include <sys/sha2.h> 430Sstevel@tonic-gate #include <sys/random.h> 44*7188Smcpowers #include <sys/crypto/impl.h> 450Sstevel@tonic-gate #include "rsa_impl.h" 460Sstevel@tonic-gate 470Sstevel@tonic-gate extern struct mod_ops mod_cryptoops; 480Sstevel@tonic-gate 490Sstevel@tonic-gate /* 500Sstevel@tonic-gate * Module linkage information for the kernel. 510Sstevel@tonic-gate */ 520Sstevel@tonic-gate static struct modlcrypto modlcrypto = { 530Sstevel@tonic-gate &mod_cryptoops, 545072Smcpowers "RSA Kernel SW Provider" 550Sstevel@tonic-gate }; 560Sstevel@tonic-gate 570Sstevel@tonic-gate static struct modlinkage modlinkage = { 580Sstevel@tonic-gate MODREV_1, 590Sstevel@tonic-gate (void *)&modlcrypto, 600Sstevel@tonic-gate NULL 610Sstevel@tonic-gate }; 620Sstevel@tonic-gate 630Sstevel@tonic-gate /* 640Sstevel@tonic-gate * CSPI information (entry points, provider info, etc.) 650Sstevel@tonic-gate */ 660Sstevel@tonic-gate typedef enum rsa_mech_type { 670Sstevel@tonic-gate RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_RSA_PKCS */ 680Sstevel@tonic-gate RSA_X_509_MECH_INFO_TYPE, /* SUN_CKM_RSA_X_509 */ 690Sstevel@tonic-gate MD5_RSA_PKCS_MECH_INFO_TYPE, /* SUN_MD5_RSA_PKCS */ 70676Sizick SHA1_RSA_PKCS_MECH_INFO_TYPE, /* SUN_SHA1_RSA_PKCS */ 71676Sizick SHA256_RSA_PKCS_MECH_INFO_TYPE, /* SUN_SHA256_RSA_PKCS */ 72676Sizick SHA384_RSA_PKCS_MECH_INFO_TYPE, /* SUN_SHA384_RSA_PKCS */ 73676Sizick SHA512_RSA_PKCS_MECH_INFO_TYPE /* SUN_SHA512_RSA_PKCS */ 740Sstevel@tonic-gate } rsa_mech_type_t; 750Sstevel@tonic-gate 760Sstevel@tonic-gate /* 770Sstevel@tonic-gate * Context for RSA_PKCS and RSA_X_509 mechanisms. 780Sstevel@tonic-gate */ 790Sstevel@tonic-gate typedef struct rsa_ctx { 800Sstevel@tonic-gate rsa_mech_type_t mech_type; 810Sstevel@tonic-gate crypto_key_t *key; 820Sstevel@tonic-gate size_t keychunk_size; 830Sstevel@tonic-gate } rsa_ctx_t; 840Sstevel@tonic-gate 850Sstevel@tonic-gate /* 86676Sizick * Context for MD5_RSA_PKCS and SHA*_RSA_PKCS mechanisms. 870Sstevel@tonic-gate */ 880Sstevel@tonic-gate typedef struct digest_rsa_ctx { 890Sstevel@tonic-gate rsa_mech_type_t mech_type; 900Sstevel@tonic-gate crypto_key_t *key; 910Sstevel@tonic-gate size_t keychunk_size; 920Sstevel@tonic-gate union { 930Sstevel@tonic-gate MD5_CTX md5ctx; 940Sstevel@tonic-gate SHA1_CTX sha1ctx; 95676Sizick SHA2_CTX sha2ctx; 960Sstevel@tonic-gate } dctx_u; 970Sstevel@tonic-gate } digest_rsa_ctx_t; 980Sstevel@tonic-gate 990Sstevel@tonic-gate #define md5_ctx dctx_u.md5ctx 1000Sstevel@tonic-gate #define sha1_ctx dctx_u.sha1ctx 101676Sizick #define sha2_ctx dctx_u.sha2ctx 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate /* 1040Sstevel@tonic-gate * Mechanism info structure passed to KCF during registration. 1050Sstevel@tonic-gate */ 1060Sstevel@tonic-gate static crypto_mech_info_t rsa_mech_info_tab[] = { 1070Sstevel@tonic-gate /* RSA_PKCS */ 1080Sstevel@tonic-gate {SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE, 1090Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 1100Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC | 1110Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 1120Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 1130Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC | 1140Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC, 1150Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate /* RSA_X_509 */ 1180Sstevel@tonic-gate {SUN_CKM_RSA_X_509, RSA_X_509_MECH_INFO_TYPE, 1190Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 1200Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC | 1210Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 1220Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 1230Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC | 1240Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC, 1250Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 1260Sstevel@tonic-gate 1270Sstevel@tonic-gate /* MD5_RSA_PKCS */ 1280Sstevel@tonic-gate {SUN_CKM_MD5_RSA_PKCS, MD5_RSA_PKCS_MECH_INFO_TYPE, 1290Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 1300Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 1310Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate /* SHA1_RSA_PKCS */ 1340Sstevel@tonic-gate {SUN_CKM_SHA1_RSA_PKCS, SHA1_RSA_PKCS_MECH_INFO_TYPE, 1350Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 1360Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 137676Sizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 138676Sizick 139676Sizick /* SHA256_RSA_PKCS */ 140676Sizick {SUN_CKM_SHA256_RSA_PKCS, SHA256_RSA_PKCS_MECH_INFO_TYPE, 141676Sizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 142676Sizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 143676Sizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 144676Sizick 145676Sizick /* SHA384_RSA_PKCS */ 146676Sizick {SUN_CKM_SHA384_RSA_PKCS, SHA384_RSA_PKCS_MECH_INFO_TYPE, 147676Sizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 148676Sizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 149676Sizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 150676Sizick 151676Sizick /* SHA512_RSA_PKCS */ 152676Sizick {SUN_CKM_SHA512_RSA_PKCS, SHA512_RSA_PKCS_MECH_INFO_TYPE, 153676Sizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 154676Sizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 1550Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS} 156676Sizick 1570Sstevel@tonic-gate }; 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate #define RSA_VALID_MECH(mech) \ 1600Sstevel@tonic-gate (((mech)->cm_type == RSA_PKCS_MECH_INFO_TYPE || \ 1610Sstevel@tonic-gate (mech)->cm_type == RSA_X_509_MECH_INFO_TYPE || \ 1620Sstevel@tonic-gate (mech)->cm_type == MD5_RSA_PKCS_MECH_INFO_TYPE || \ 163676Sizick (mech)->cm_type == SHA1_RSA_PKCS_MECH_INFO_TYPE || \ 164676Sizick (mech)->cm_type == SHA256_RSA_PKCS_MECH_INFO_TYPE || \ 165676Sizick (mech)->cm_type == SHA384_RSA_PKCS_MECH_INFO_TYPE || \ 166676Sizick (mech)->cm_type == SHA512_RSA_PKCS_MECH_INFO_TYPE) ? 1 : 0) 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate /* operations are in-place if the output buffer is NULL */ 1690Sstevel@tonic-gate #define RSA_ARG_INPLACE(input, output) \ 1700Sstevel@tonic-gate if ((output) == NULL) \ 1710Sstevel@tonic-gate (output) = (input); 1720Sstevel@tonic-gate 1730Sstevel@tonic-gate static void rsa_provider_status(crypto_provider_handle_t, uint_t *); 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate static crypto_control_ops_t rsa_control_ops = { 1760Sstevel@tonic-gate rsa_provider_status 1770Sstevel@tonic-gate }; 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate static int rsa_common_init(crypto_ctx_t *, crypto_mechanism_t *, 1800Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 1810Sstevel@tonic-gate static int rsa_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 1820Sstevel@tonic-gate crypto_req_handle_t); 1830Sstevel@tonic-gate static int rsa_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 1840Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 1850Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 1860Sstevel@tonic-gate static int rsa_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 1870Sstevel@tonic-gate crypto_req_handle_t); 1880Sstevel@tonic-gate static int rsa_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 1890Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 1900Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate /* 1930Sstevel@tonic-gate * The RSA mechanisms do not have multiple-part cipher operations. 1940Sstevel@tonic-gate * So, the update and final routines are set to NULL. 1950Sstevel@tonic-gate */ 1960Sstevel@tonic-gate static crypto_cipher_ops_t rsa_cipher_ops = { 1970Sstevel@tonic-gate rsa_common_init, 1980Sstevel@tonic-gate rsa_encrypt, 1990Sstevel@tonic-gate NULL, 2000Sstevel@tonic-gate NULL, 2010Sstevel@tonic-gate rsa_encrypt_atomic, 2020Sstevel@tonic-gate rsa_common_init, 2030Sstevel@tonic-gate rsa_decrypt, 2040Sstevel@tonic-gate NULL, 2050Sstevel@tonic-gate NULL, 2060Sstevel@tonic-gate rsa_decrypt_atomic 2070Sstevel@tonic-gate }; 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate static int rsa_sign_verify_common_init(crypto_ctx_t *, crypto_mechanism_t *, 2100Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 2110Sstevel@tonic-gate static int rsa_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 2120Sstevel@tonic-gate crypto_req_handle_t); 2130Sstevel@tonic-gate static int rsa_sign_update(crypto_ctx_t *, crypto_data_t *, 2140Sstevel@tonic-gate crypto_req_handle_t); 2150Sstevel@tonic-gate static int rsa_sign_final(crypto_ctx_t *, crypto_data_t *, 2160Sstevel@tonic-gate crypto_req_handle_t); 2170Sstevel@tonic-gate static int rsa_sign_atomic(crypto_provider_handle_t, crypto_session_id_t, 2180Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, 2190Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t); 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate /* 2220Sstevel@tonic-gate * We use the same routine for sign_init and sign_recover_init fields 2230Sstevel@tonic-gate * as they do the same thing. Same holds for sign and sign_recover fields, 2240Sstevel@tonic-gate * and sign_atomic and sign_recover_atomic fields. 2250Sstevel@tonic-gate */ 2260Sstevel@tonic-gate static crypto_sign_ops_t rsa_sign_ops = { 2270Sstevel@tonic-gate rsa_sign_verify_common_init, 2280Sstevel@tonic-gate rsa_sign, 2290Sstevel@tonic-gate rsa_sign_update, 2300Sstevel@tonic-gate rsa_sign_final, 2310Sstevel@tonic-gate rsa_sign_atomic, 2320Sstevel@tonic-gate rsa_sign_verify_common_init, 2330Sstevel@tonic-gate rsa_sign, 2340Sstevel@tonic-gate rsa_sign_atomic 2350Sstevel@tonic-gate }; 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate static int rsa_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 2380Sstevel@tonic-gate crypto_req_handle_t); 2390Sstevel@tonic-gate static int rsa_verify_update(crypto_ctx_t *, crypto_data_t *, 2400Sstevel@tonic-gate crypto_req_handle_t); 2410Sstevel@tonic-gate static int rsa_verify_final(crypto_ctx_t *, crypto_data_t *, 2420Sstevel@tonic-gate crypto_req_handle_t); 2430Sstevel@tonic-gate static int rsa_verify_atomic(crypto_provider_handle_t, crypto_session_id_t, 2440Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 2450Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 2460Sstevel@tonic-gate static int rsa_verify_recover(crypto_ctx_t *, crypto_data_t *, 2470Sstevel@tonic-gate crypto_data_t *, crypto_req_handle_t); 2480Sstevel@tonic-gate static int rsa_verify_recover_atomic(crypto_provider_handle_t, 2490Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 2500Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 2510Sstevel@tonic-gate crypto_req_handle_t); 2520Sstevel@tonic-gate 2530Sstevel@tonic-gate /* 2540Sstevel@tonic-gate * We use the same routine (rsa_sign_verify_common_init) for verify_init 2550Sstevel@tonic-gate * and verify_recover_init fields as they do the same thing. 2560Sstevel@tonic-gate */ 2570Sstevel@tonic-gate static crypto_verify_ops_t rsa_verify_ops = { 2580Sstevel@tonic-gate rsa_sign_verify_common_init, 2590Sstevel@tonic-gate rsa_verify, 2600Sstevel@tonic-gate rsa_verify_update, 2610Sstevel@tonic-gate rsa_verify_final, 2620Sstevel@tonic-gate rsa_verify_atomic, 2630Sstevel@tonic-gate rsa_sign_verify_common_init, 2640Sstevel@tonic-gate rsa_verify_recover, 2650Sstevel@tonic-gate rsa_verify_recover_atomic 2660Sstevel@tonic-gate }; 2670Sstevel@tonic-gate 2680Sstevel@tonic-gate static int rsa_free_context(crypto_ctx_t *); 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate static crypto_ctx_ops_t rsa_ctx_ops = { 2710Sstevel@tonic-gate NULL, 2720Sstevel@tonic-gate rsa_free_context 2730Sstevel@tonic-gate }; 2740Sstevel@tonic-gate 2750Sstevel@tonic-gate static crypto_ops_t rsa_crypto_ops = { 2760Sstevel@tonic-gate &rsa_control_ops, 2770Sstevel@tonic-gate NULL, 2780Sstevel@tonic-gate &rsa_cipher_ops, 2790Sstevel@tonic-gate NULL, 2800Sstevel@tonic-gate &rsa_sign_ops, 2810Sstevel@tonic-gate &rsa_verify_ops, 2820Sstevel@tonic-gate NULL, 2830Sstevel@tonic-gate NULL, 2840Sstevel@tonic-gate NULL, 2850Sstevel@tonic-gate NULL, 2860Sstevel@tonic-gate NULL, 2870Sstevel@tonic-gate NULL, 2880Sstevel@tonic-gate NULL, 2890Sstevel@tonic-gate &rsa_ctx_ops 2900Sstevel@tonic-gate }; 2910Sstevel@tonic-gate 2920Sstevel@tonic-gate static crypto_provider_info_t rsa_prov_info = { 2930Sstevel@tonic-gate CRYPTO_SPI_VERSION_1, 2940Sstevel@tonic-gate "RSA Software Provider", 2950Sstevel@tonic-gate CRYPTO_SW_PROVIDER, 2960Sstevel@tonic-gate {&modlinkage}, 2970Sstevel@tonic-gate NULL, 2980Sstevel@tonic-gate &rsa_crypto_ops, 2990Sstevel@tonic-gate sizeof (rsa_mech_info_tab)/sizeof (crypto_mech_info_t), 3000Sstevel@tonic-gate rsa_mech_info_tab 3010Sstevel@tonic-gate }; 3020Sstevel@tonic-gate 3030Sstevel@tonic-gate static int rsa_encrypt_common(rsa_mech_type_t, crypto_key_t *, 3040Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3050Sstevel@tonic-gate static int rsa_decrypt_common(rsa_mech_type_t, crypto_key_t *, 3060Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3070Sstevel@tonic-gate static int rsa_sign_common(rsa_mech_type_t, crypto_key_t *, 3080Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3090Sstevel@tonic-gate static int rsa_verify_common(rsa_mech_type_t, crypto_key_t *, 3100Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3110Sstevel@tonic-gate static int compare_data(crypto_data_t *, uchar_t *); 3120Sstevel@tonic-gate 3130Sstevel@tonic-gate /* EXPORT DELETE START */ 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate static int core_rsa_encrypt(crypto_key_t *, uchar_t *, 3160Sstevel@tonic-gate int, uchar_t *, int, int); 3170Sstevel@tonic-gate static int core_rsa_decrypt(crypto_key_t *, uchar_t *, int, 3180Sstevel@tonic-gate uchar_t *, int); 3190Sstevel@tonic-gate 3200Sstevel@tonic-gate /* EXPORT DELETE END */ 3210Sstevel@tonic-gate 3220Sstevel@tonic-gate static crypto_kcf_provider_handle_t rsa_prov_handle = NULL; 3230Sstevel@tonic-gate 3240Sstevel@tonic-gate int 3250Sstevel@tonic-gate _init(void) 3260Sstevel@tonic-gate { 3270Sstevel@tonic-gate int ret; 3280Sstevel@tonic-gate 3290Sstevel@tonic-gate /* 3300Sstevel@tonic-gate * Register with KCF. If the registration fails, return error. 3310Sstevel@tonic-gate */ 3320Sstevel@tonic-gate if ((ret = crypto_register_provider(&rsa_prov_info, 3330Sstevel@tonic-gate &rsa_prov_handle)) != CRYPTO_SUCCESS) { 3340Sstevel@tonic-gate cmn_err(CE_WARN, "rsa _init: crypto_register_provider()" 3350Sstevel@tonic-gate "failed (0x%x)", ret); 3360Sstevel@tonic-gate return (EACCES); 3370Sstevel@tonic-gate } 3380Sstevel@tonic-gate 3390Sstevel@tonic-gate if ((ret = mod_install(&modlinkage)) != 0) { 3400Sstevel@tonic-gate int rv; 3410Sstevel@tonic-gate 3420Sstevel@tonic-gate ASSERT(rsa_prov_handle != NULL); 3430Sstevel@tonic-gate /* We should not return if the unregister returns busy. */ 3440Sstevel@tonic-gate while ((rv = crypto_unregister_provider(rsa_prov_handle)) 3450Sstevel@tonic-gate == CRYPTO_BUSY) { 3460Sstevel@tonic-gate cmn_err(CE_WARN, "rsa _init: " 3470Sstevel@tonic-gate "crypto_unregister_provider() " 3480Sstevel@tonic-gate "failed (0x%x). Retrying.", rv); 3490Sstevel@tonic-gate /* wait 10 seconds and try again. */ 3500Sstevel@tonic-gate delay(10 * drv_usectohz(1000000)); 3510Sstevel@tonic-gate } 3520Sstevel@tonic-gate } 3530Sstevel@tonic-gate 3540Sstevel@tonic-gate return (ret); 3550Sstevel@tonic-gate } 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate int 3580Sstevel@tonic-gate _fini(void) 3590Sstevel@tonic-gate { 3600Sstevel@tonic-gate int ret; 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate /* 3630Sstevel@tonic-gate * Unregister from KCF if previous registration succeeded. 3640Sstevel@tonic-gate */ 3650Sstevel@tonic-gate if (rsa_prov_handle != NULL) { 3660Sstevel@tonic-gate if ((ret = crypto_unregister_provider(rsa_prov_handle)) != 3670Sstevel@tonic-gate CRYPTO_SUCCESS) { 3680Sstevel@tonic-gate cmn_err(CE_WARN, "rsa _fini: " 3690Sstevel@tonic-gate "crypto_unregister_provider() " 3700Sstevel@tonic-gate "failed (0x%x)", ret); 3710Sstevel@tonic-gate return (EBUSY); 3720Sstevel@tonic-gate } 3730Sstevel@tonic-gate rsa_prov_handle = NULL; 3740Sstevel@tonic-gate } 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate return (mod_remove(&modlinkage)); 3770Sstevel@tonic-gate } 3780Sstevel@tonic-gate 3790Sstevel@tonic-gate int 3800Sstevel@tonic-gate _info(struct modinfo *modinfop) 3810Sstevel@tonic-gate { 3820Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 3830Sstevel@tonic-gate } 3840Sstevel@tonic-gate 3850Sstevel@tonic-gate /* ARGSUSED */ 3860Sstevel@tonic-gate static void 3870Sstevel@tonic-gate rsa_provider_status(crypto_provider_handle_t provider, uint_t *status) 3880Sstevel@tonic-gate { 3890Sstevel@tonic-gate *status = CRYPTO_PROVIDER_READY; 3900Sstevel@tonic-gate } 3910Sstevel@tonic-gate 3920Sstevel@tonic-gate static int 3930Sstevel@tonic-gate check_mech_and_key(crypto_mechanism_t *mechanism, crypto_key_t *key) 3940Sstevel@tonic-gate { 3950Sstevel@tonic-gate int rv = CRYPTO_FAILED; 3960Sstevel@tonic-gate 3970Sstevel@tonic-gate /* EXPORT DELETE START */ 3980Sstevel@tonic-gate 3990Sstevel@tonic-gate uchar_t *modulus; 4000Sstevel@tonic-gate ssize_t modulus_len; /* In bytes */ 4010Sstevel@tonic-gate 4020Sstevel@tonic-gate if (!RSA_VALID_MECH(mechanism)) 4030Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 4040Sstevel@tonic-gate 4050Sstevel@tonic-gate /* 4060Sstevel@tonic-gate * We only support RSA keys that are passed as a list of 4070Sstevel@tonic-gate * object attributes. 4080Sstevel@tonic-gate */ 4090Sstevel@tonic-gate if (key->ck_format != CRYPTO_KEY_ATTR_LIST) { 4100Sstevel@tonic-gate return (CRYPTO_KEY_TYPE_INCONSISTENT); 4110Sstevel@tonic-gate } 4120Sstevel@tonic-gate 413*7188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 4140Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 4150Sstevel@tonic-gate return (rv); 4160Sstevel@tonic-gate } 4170Sstevel@tonic-gate if (modulus_len < MIN_RSA_KEYLENGTH_IN_BYTES || 4180Sstevel@tonic-gate modulus_len > MAX_RSA_KEYLENGTH_IN_BYTES) 4190Sstevel@tonic-gate return (CRYPTO_KEY_SIZE_RANGE); 4200Sstevel@tonic-gate 4210Sstevel@tonic-gate /* EXPORT DELETE END */ 4220Sstevel@tonic-gate 4230Sstevel@tonic-gate return (rv); 4240Sstevel@tonic-gate } 4250Sstevel@tonic-gate 4260Sstevel@tonic-gate void 4270Sstevel@tonic-gate kmemset(uint8_t *buf, char pattern, size_t len) 4280Sstevel@tonic-gate { 4290Sstevel@tonic-gate int i = 0; 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate while (i < len) 4320Sstevel@tonic-gate buf[i++] = pattern; 4330Sstevel@tonic-gate } 4340Sstevel@tonic-gate 4350Sstevel@tonic-gate /* 4360Sstevel@tonic-gate * This function guarantees to return non-zero random numbers. 4370Sstevel@tonic-gate * This is needed as the /dev/urandom kernel interface, 4380Sstevel@tonic-gate * random_get_pseudo_bytes(), may return zeros. 4390Sstevel@tonic-gate */ 4400Sstevel@tonic-gate int 4410Sstevel@tonic-gate knzero_random_generator(uint8_t *ran_out, size_t ran_len) 4420Sstevel@tonic-gate { 4430Sstevel@tonic-gate int rv; 4440Sstevel@tonic-gate size_t ebc = 0; /* count of extra bytes in extrarand */ 4450Sstevel@tonic-gate size_t i = 0; 4460Sstevel@tonic-gate uint8_t extrarand[32]; 4470Sstevel@tonic-gate size_t extrarand_len; 4480Sstevel@tonic-gate 4490Sstevel@tonic-gate if ((rv = random_get_pseudo_bytes(ran_out, ran_len)) != 0) 4500Sstevel@tonic-gate return (rv); 4510Sstevel@tonic-gate 4520Sstevel@tonic-gate /* 4530Sstevel@tonic-gate * Walk through the returned random numbers pointed by ran_out, 4540Sstevel@tonic-gate * and look for any random number which is zero. 4550Sstevel@tonic-gate * If we find zero, call random_get_pseudo_bytes() to generate 4560Sstevel@tonic-gate * another 32 random numbers pool. Replace any zeros in ran_out[] 4570Sstevel@tonic-gate * from the random number in pool. 4580Sstevel@tonic-gate */ 4590Sstevel@tonic-gate while (i < ran_len) { 4600Sstevel@tonic-gate if (ran_out[i] != 0) { 4610Sstevel@tonic-gate i++; 4620Sstevel@tonic-gate continue; 4630Sstevel@tonic-gate } 4640Sstevel@tonic-gate 4650Sstevel@tonic-gate /* 4660Sstevel@tonic-gate * Note that it is 'while' so we are guaranteed a 4670Sstevel@tonic-gate * non-zero value on exit. 4680Sstevel@tonic-gate */ 4690Sstevel@tonic-gate if (ebc == 0) { 4700Sstevel@tonic-gate /* refresh extrarand */ 4710Sstevel@tonic-gate extrarand_len = sizeof (extrarand); 4720Sstevel@tonic-gate if ((rv = random_get_pseudo_bytes(extrarand, 4730Sstevel@tonic-gate extrarand_len)) != 0) { 4740Sstevel@tonic-gate return (rv); 4750Sstevel@tonic-gate } 4760Sstevel@tonic-gate 4770Sstevel@tonic-gate ebc = extrarand_len; 4780Sstevel@tonic-gate } 4790Sstevel@tonic-gate /* Replace zero with byte from extrarand. */ 4800Sstevel@tonic-gate -- ebc; 4810Sstevel@tonic-gate 4820Sstevel@tonic-gate /* 4830Sstevel@tonic-gate * The new random byte zero/non-zero will be checked in 4840Sstevel@tonic-gate * the next pass through the loop. 4850Sstevel@tonic-gate */ 4860Sstevel@tonic-gate ran_out[i] = extrarand[ebc]; 4870Sstevel@tonic-gate } 4880Sstevel@tonic-gate 4890Sstevel@tonic-gate return (CRYPTO_SUCCESS); 4900Sstevel@tonic-gate } 4910Sstevel@tonic-gate 4920Sstevel@tonic-gate static int 4930Sstevel@tonic-gate compare_data(crypto_data_t *data, uchar_t *buf) 4940Sstevel@tonic-gate { 4950Sstevel@tonic-gate int len; 4960Sstevel@tonic-gate uchar_t *dptr; 4970Sstevel@tonic-gate 4980Sstevel@tonic-gate len = data->cd_length; 4990Sstevel@tonic-gate switch (data->cd_format) { 5000Sstevel@tonic-gate case CRYPTO_DATA_RAW: 5010Sstevel@tonic-gate dptr = (uchar_t *)(data->cd_raw.iov_base + 5020Sstevel@tonic-gate data->cd_offset); 5030Sstevel@tonic-gate 5040Sstevel@tonic-gate return (bcmp(dptr, buf, len)); 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate case CRYPTO_DATA_UIO: 507*7188Smcpowers return (crypto_uio_data(data, buf, len, 508*7188Smcpowers COMPARE_TO_DATA, NULL, NULL)); 5090Sstevel@tonic-gate 5100Sstevel@tonic-gate case CRYPTO_DATA_MBLK: 511*7188Smcpowers return (crypto_mblk_data(data, buf, len, 512*7188Smcpowers COMPARE_TO_DATA, NULL, NULL)); 5130Sstevel@tonic-gate } 5140Sstevel@tonic-gate 5150Sstevel@tonic-gate return (CRYPTO_FAILED); 5160Sstevel@tonic-gate } 5170Sstevel@tonic-gate 5180Sstevel@tonic-gate /* ARGSUSED */ 5190Sstevel@tonic-gate static int 5200Sstevel@tonic-gate rsa_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 5210Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t template, 5220Sstevel@tonic-gate crypto_req_handle_t req) 5230Sstevel@tonic-gate { 5240Sstevel@tonic-gate int rv; 5250Sstevel@tonic-gate int kmflag; 5260Sstevel@tonic-gate rsa_ctx_t *ctxp; 5270Sstevel@tonic-gate 5280Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 5290Sstevel@tonic-gate return (rv); 5300Sstevel@tonic-gate 5310Sstevel@tonic-gate /* 5320Sstevel@tonic-gate * Allocate a RSA context. 5330Sstevel@tonic-gate */ 5340Sstevel@tonic-gate kmflag = crypto_kmflag(req); 5350Sstevel@tonic-gate if ((ctxp = kmem_zalloc(sizeof (rsa_ctx_t), kmflag)) == NULL) 5360Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 5370Sstevel@tonic-gate 538*7188Smcpowers if ((rv = crypto_copy_key_to_ctx(key, &ctxp->key, &ctxp->keychunk_size, 539*7188Smcpowers kmflag)) != CRYPTO_SUCCESS) { 5400Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 5410Sstevel@tonic-gate return (rv); 5420Sstevel@tonic-gate } 5430Sstevel@tonic-gate ctxp->mech_type = mechanism->cm_type; 5440Sstevel@tonic-gate 5450Sstevel@tonic-gate ctx->cc_provider_private = ctxp; 5460Sstevel@tonic-gate 5470Sstevel@tonic-gate return (CRYPTO_SUCCESS); 5480Sstevel@tonic-gate } 5490Sstevel@tonic-gate 5500Sstevel@tonic-gate /* ARGSUSED */ 5510Sstevel@tonic-gate static int 5520Sstevel@tonic-gate rsa_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext, 5530Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_req_handle_t req) 5540Sstevel@tonic-gate { 5550Sstevel@tonic-gate int rv; 5560Sstevel@tonic-gate rsa_ctx_t *ctxp; 5570Sstevel@tonic-gate 5580Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 5590Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 5600Sstevel@tonic-gate 5610Sstevel@tonic-gate RSA_ARG_INPLACE(plaintext, ciphertext); 5620Sstevel@tonic-gate 5630Sstevel@tonic-gate /* 5640Sstevel@tonic-gate * Note on the KM_SLEEP flag passed to the routine below - 5650Sstevel@tonic-gate * rsa_encrypt() is a single-part encryption routine which is 5660Sstevel@tonic-gate * currently usable only by /dev/crypto. Since /dev/crypto calls are 5670Sstevel@tonic-gate * always synchronous, we can safely pass KM_SLEEP here. 5680Sstevel@tonic-gate */ 5690Sstevel@tonic-gate rv = rsa_encrypt_common(ctxp->mech_type, ctxp->key, plaintext, 5700Sstevel@tonic-gate ciphertext, KM_SLEEP); 5710Sstevel@tonic-gate 5720Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 5730Sstevel@tonic-gate (void) rsa_free_context(ctx); 5740Sstevel@tonic-gate 5750Sstevel@tonic-gate return (rv); 5760Sstevel@tonic-gate } 5770Sstevel@tonic-gate 5780Sstevel@tonic-gate /* ARGSUSED */ 5790Sstevel@tonic-gate static int 5800Sstevel@tonic-gate rsa_encrypt_atomic(crypto_provider_handle_t provider, 5810Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 5820Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext, 5830Sstevel@tonic-gate crypto_spi_ctx_template_t template, crypto_req_handle_t req) 5840Sstevel@tonic-gate { 5850Sstevel@tonic-gate int rv; 5860Sstevel@tonic-gate 5870Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 5880Sstevel@tonic-gate return (rv); 5890Sstevel@tonic-gate RSA_ARG_INPLACE(plaintext, ciphertext); 5900Sstevel@tonic-gate 5910Sstevel@tonic-gate return (rsa_encrypt_common(mechanism->cm_type, key, plaintext, 5920Sstevel@tonic-gate ciphertext, crypto_kmflag(req))); 5930Sstevel@tonic-gate } 5940Sstevel@tonic-gate 5950Sstevel@tonic-gate static int 5960Sstevel@tonic-gate rsa_free_context(crypto_ctx_t *ctx) 5970Sstevel@tonic-gate { 5980Sstevel@tonic-gate rsa_ctx_t *ctxp = ctx->cc_provider_private; 5990Sstevel@tonic-gate 6000Sstevel@tonic-gate if (ctxp != NULL) { 6010Sstevel@tonic-gate bzero(ctxp->key, ctxp->keychunk_size); 6020Sstevel@tonic-gate kmem_free(ctxp->key, ctxp->keychunk_size); 6030Sstevel@tonic-gate 6040Sstevel@tonic-gate if (ctxp->mech_type == RSA_PKCS_MECH_INFO_TYPE || 6050Sstevel@tonic-gate ctxp->mech_type == RSA_X_509_MECH_INFO_TYPE) 6060Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 6070Sstevel@tonic-gate else 6080Sstevel@tonic-gate kmem_free(ctxp, sizeof (digest_rsa_ctx_t)); 6090Sstevel@tonic-gate 6100Sstevel@tonic-gate ctx->cc_provider_private = NULL; 6110Sstevel@tonic-gate } 6120Sstevel@tonic-gate 6130Sstevel@tonic-gate return (CRYPTO_SUCCESS); 6140Sstevel@tonic-gate } 6150Sstevel@tonic-gate 6160Sstevel@tonic-gate static int 6170Sstevel@tonic-gate rsa_encrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key, 6180Sstevel@tonic-gate crypto_data_t *plaintext, crypto_data_t *ciphertext, int kmflag) 6190Sstevel@tonic-gate { 6200Sstevel@tonic-gate int rv = CRYPTO_FAILED; 6210Sstevel@tonic-gate 6220Sstevel@tonic-gate /* EXPORT DELETE START */ 6230Sstevel@tonic-gate 6240Sstevel@tonic-gate int plen; 6250Sstevel@tonic-gate uchar_t *ptptr; 6260Sstevel@tonic-gate uchar_t *modulus; 6270Sstevel@tonic-gate ssize_t modulus_len; 6280Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 6290Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 6300Sstevel@tonic-gate uchar_t cipher_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 6310Sstevel@tonic-gate 632*7188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 6330Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 6340Sstevel@tonic-gate return (rv); 6350Sstevel@tonic-gate } 6360Sstevel@tonic-gate 6370Sstevel@tonic-gate plen = plaintext->cd_length; 6380Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 6390Sstevel@tonic-gate if (plen > (modulus_len - MIN_PKCS1_PADLEN)) 6400Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 6410Sstevel@tonic-gate } else { 6420Sstevel@tonic-gate if (plen > modulus_len) 6430Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 6440Sstevel@tonic-gate } 6450Sstevel@tonic-gate 6460Sstevel@tonic-gate /* 6470Sstevel@tonic-gate * Output buf len must not be less than RSA modulus size. 6480Sstevel@tonic-gate */ 6490Sstevel@tonic-gate if (ciphertext->cd_length < modulus_len) { 6500Sstevel@tonic-gate ciphertext->cd_length = modulus_len; 6510Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 6520Sstevel@tonic-gate } 6530Sstevel@tonic-gate 6540Sstevel@tonic-gate ASSERT(plaintext->cd_length <= sizeof (tmp_data)); 655*7188Smcpowers if ((rv = crypto_get_input_data(plaintext, &ptptr, tmp_data)) 6560Sstevel@tonic-gate != CRYPTO_SUCCESS) 6570Sstevel@tonic-gate return (rv); 6580Sstevel@tonic-gate 6590Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 6600Sstevel@tonic-gate rv = soft_encrypt_rsa_pkcs_encode(ptptr, plen, 6610Sstevel@tonic-gate plain_data, modulus_len); 6620Sstevel@tonic-gate 6630Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 6640Sstevel@tonic-gate return (rv); 6650Sstevel@tonic-gate } else { 6660Sstevel@tonic-gate bzero(plain_data, modulus_len - plen); 6670Sstevel@tonic-gate bcopy(ptptr, &plain_data[modulus_len - plen], plen); 6680Sstevel@tonic-gate } 6690Sstevel@tonic-gate 6700Sstevel@tonic-gate rv = core_rsa_encrypt(key, plain_data, modulus_len, 6710Sstevel@tonic-gate cipher_data, kmflag, 1); 6720Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 6730Sstevel@tonic-gate /* copy out to ciphertext */ 674*7188Smcpowers if ((rv = crypto_put_output_data(cipher_data, 6750Sstevel@tonic-gate ciphertext, modulus_len)) != CRYPTO_SUCCESS) 6760Sstevel@tonic-gate return (rv); 6770Sstevel@tonic-gate 6780Sstevel@tonic-gate ciphertext->cd_length = modulus_len; 6790Sstevel@tonic-gate } 6800Sstevel@tonic-gate 6810Sstevel@tonic-gate /* EXPORT DELETE END */ 6820Sstevel@tonic-gate 6830Sstevel@tonic-gate return (rv); 6840Sstevel@tonic-gate } 6850Sstevel@tonic-gate 6860Sstevel@tonic-gate /* EXPORT DELETE START */ 6870Sstevel@tonic-gate 6880Sstevel@tonic-gate static int 6890Sstevel@tonic-gate core_rsa_encrypt(crypto_key_t *key, uchar_t *in, 6900Sstevel@tonic-gate int in_len, uchar_t *out, int kmflag, int is_public) 6910Sstevel@tonic-gate { 6920Sstevel@tonic-gate int rv; 6930Sstevel@tonic-gate uchar_t *expo, *modulus; 6940Sstevel@tonic-gate ssize_t expo_len; 6950Sstevel@tonic-gate ssize_t modulus_len; 6960Sstevel@tonic-gate BIGNUM msg; 6970Sstevel@tonic-gate RSAkey *rsakey; 6980Sstevel@tonic-gate 6990Sstevel@tonic-gate if (is_public) { 700*7188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_PUBLIC_EXPONENT, 701*7188Smcpowers &expo, &expo_len)) != CRYPTO_SUCCESS) 7020Sstevel@tonic-gate return (rv); 7030Sstevel@tonic-gate } else { 7040Sstevel@tonic-gate /* 7050Sstevel@tonic-gate * SUN_CKA_PRIVATE_EXPONENT is a required attribute for a 7060Sstevel@tonic-gate * RSA secret key. See the comments in core_rsa_decrypt 7070Sstevel@tonic-gate * routine which calls this routine with a private key. 7080Sstevel@tonic-gate */ 709*7188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_PRIVATE_EXPONENT, 710*7188Smcpowers &expo, &expo_len)) != CRYPTO_SUCCESS) 7110Sstevel@tonic-gate return (rv); 7120Sstevel@tonic-gate } 7130Sstevel@tonic-gate 714*7188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 7150Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 7160Sstevel@tonic-gate return (rv); 7170Sstevel@tonic-gate } 7180Sstevel@tonic-gate 7190Sstevel@tonic-gate rsakey = kmem_alloc(sizeof (RSAkey), kmflag); 7200Sstevel@tonic-gate if (rsakey == NULL) 7210Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 7220Sstevel@tonic-gate 7230Sstevel@tonic-gate /* psize and qsize for RSA_key_init is in bits. */ 7240Sstevel@tonic-gate if (RSA_key_init(rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) { 7250Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 7260Sstevel@tonic-gate goto clean1; 7270Sstevel@tonic-gate } 7280Sstevel@tonic-gate 7296557Sfr41279 /* Size for big_init is in BIG_CHUNK_TYPE words. */ 7306557Sfr41279 if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) { 7310Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 7320Sstevel@tonic-gate goto clean2; 7330Sstevel@tonic-gate } 7340Sstevel@tonic-gate 7350Sstevel@tonic-gate /* Convert octet string exponent to big integer format. */ 7360Sstevel@tonic-gate bytestring2bignum(&(rsakey->e), expo, expo_len); 7370Sstevel@tonic-gate 7380Sstevel@tonic-gate /* Convert octet string modulus to big integer format. */ 7390Sstevel@tonic-gate bytestring2bignum(&(rsakey->n), modulus, modulus_len); 7400Sstevel@tonic-gate 7410Sstevel@tonic-gate /* Convert octet string input data to big integer format. */ 7420Sstevel@tonic-gate bytestring2bignum(&msg, in, in_len); 7430Sstevel@tonic-gate 7440Sstevel@tonic-gate if (big_cmp_abs(&msg, &(rsakey->n)) > 0) { 7450Sstevel@tonic-gate rv = CRYPTO_DATA_LEN_RANGE; 7460Sstevel@tonic-gate goto clean3; 7470Sstevel@tonic-gate } 7480Sstevel@tonic-gate 7490Sstevel@tonic-gate /* Perform RSA computation on big integer input data. */ 7500Sstevel@tonic-gate if (big_modexp(&msg, &msg, &(rsakey->e), &(rsakey->n), NULL) 7510Sstevel@tonic-gate != BIG_OK) { 7520Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 7530Sstevel@tonic-gate goto clean3; 7540Sstevel@tonic-gate } 7550Sstevel@tonic-gate 7560Sstevel@tonic-gate /* Convert the big integer output data to octet string. */ 7570Sstevel@tonic-gate bignum2bytestring(out, &msg, modulus_len); 7580Sstevel@tonic-gate 7590Sstevel@tonic-gate /* 7600Sstevel@tonic-gate * Should not free modulus and expo as both are just pointers 7610Sstevel@tonic-gate * to an attribute value buffer from the caller. 7620Sstevel@tonic-gate */ 7630Sstevel@tonic-gate clean3: 7640Sstevel@tonic-gate big_finish(&msg); 7650Sstevel@tonic-gate clean2: 7660Sstevel@tonic-gate RSA_key_finish(rsakey); 7670Sstevel@tonic-gate clean1: 7680Sstevel@tonic-gate kmem_free(rsakey, sizeof (RSAkey)); 7690Sstevel@tonic-gate 7700Sstevel@tonic-gate return (rv); 7710Sstevel@tonic-gate } 7720Sstevel@tonic-gate 7730Sstevel@tonic-gate /* EXPORT DELETE END */ 7740Sstevel@tonic-gate 7750Sstevel@tonic-gate /* ARGSUSED */ 7760Sstevel@tonic-gate static int 7770Sstevel@tonic-gate rsa_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext, 7780Sstevel@tonic-gate crypto_data_t *plaintext, crypto_req_handle_t req) 7790Sstevel@tonic-gate { 7800Sstevel@tonic-gate int rv; 7810Sstevel@tonic-gate rsa_ctx_t *ctxp; 7820Sstevel@tonic-gate 7830Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 7840Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 7850Sstevel@tonic-gate 7860Sstevel@tonic-gate RSA_ARG_INPLACE(ciphertext, plaintext); 7870Sstevel@tonic-gate 7880Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 7890Sstevel@tonic-gate rv = rsa_decrypt_common(ctxp->mech_type, ctxp->key, 7900Sstevel@tonic-gate ciphertext, plaintext, KM_SLEEP); 7910Sstevel@tonic-gate 7920Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 7930Sstevel@tonic-gate (void) rsa_free_context(ctx); 7940Sstevel@tonic-gate 7950Sstevel@tonic-gate return (rv); 7960Sstevel@tonic-gate } 7970Sstevel@tonic-gate 7980Sstevel@tonic-gate /* ARGSUSED */ 7990Sstevel@tonic-gate static int 8000Sstevel@tonic-gate rsa_decrypt_atomic(crypto_provider_handle_t provider, 8010Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 8020Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext, 8030Sstevel@tonic-gate crypto_spi_ctx_template_t template, crypto_req_handle_t req) 8040Sstevel@tonic-gate { 8050Sstevel@tonic-gate int rv; 8060Sstevel@tonic-gate 8070Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 8080Sstevel@tonic-gate return (rv); 8090Sstevel@tonic-gate RSA_ARG_INPLACE(ciphertext, plaintext); 8100Sstevel@tonic-gate 8110Sstevel@tonic-gate return (rsa_decrypt_common(mechanism->cm_type, key, ciphertext, 8120Sstevel@tonic-gate plaintext, crypto_kmflag(req))); 8130Sstevel@tonic-gate } 8140Sstevel@tonic-gate 8150Sstevel@tonic-gate static int 8160Sstevel@tonic-gate rsa_decrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key, 8170Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_data_t *plaintext, int kmflag) 8180Sstevel@tonic-gate { 8190Sstevel@tonic-gate int rv = CRYPTO_FAILED; 8200Sstevel@tonic-gate 8210Sstevel@tonic-gate /* EXPORT DELETE START */ 8220Sstevel@tonic-gate 8230Sstevel@tonic-gate int plain_len; 8240Sstevel@tonic-gate uchar_t *ctptr; 8250Sstevel@tonic-gate uchar_t *modulus; 8260Sstevel@tonic-gate ssize_t modulus_len; 8270Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 8280Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 8290Sstevel@tonic-gate 830*7188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 8310Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 8320Sstevel@tonic-gate return (rv); 8330Sstevel@tonic-gate } 8340Sstevel@tonic-gate 8350Sstevel@tonic-gate /* 8360Sstevel@tonic-gate * Ciphertext length must be equal to RSA modulus size. 8370Sstevel@tonic-gate */ 8380Sstevel@tonic-gate if (ciphertext->cd_length != modulus_len) 8390Sstevel@tonic-gate return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 8400Sstevel@tonic-gate 8410Sstevel@tonic-gate ASSERT(ciphertext->cd_length <= sizeof (tmp_data)); 842*7188Smcpowers if ((rv = crypto_get_input_data(ciphertext, &ctptr, tmp_data)) 8430Sstevel@tonic-gate != CRYPTO_SUCCESS) 8440Sstevel@tonic-gate return (rv); 8450Sstevel@tonic-gate 8460Sstevel@tonic-gate rv = core_rsa_decrypt(key, ctptr, modulus_len, plain_data, kmflag); 8470Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 8480Sstevel@tonic-gate plain_len = modulus_len; 8490Sstevel@tonic-gate 8500Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 8510Sstevel@tonic-gate /* Strip off the PKCS block formatting data. */ 8520Sstevel@tonic-gate rv = soft_decrypt_rsa_pkcs_decode(plain_data, 8530Sstevel@tonic-gate &plain_len); 8540Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 8550Sstevel@tonic-gate return (rv); 8560Sstevel@tonic-gate } 8570Sstevel@tonic-gate 8580Sstevel@tonic-gate if (plain_len > plaintext->cd_length) { 8590Sstevel@tonic-gate plaintext->cd_length = plain_len; 8600Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 8610Sstevel@tonic-gate } 8620Sstevel@tonic-gate 863*7188Smcpowers if ((rv = crypto_put_output_data( 864*7188Smcpowers plain_data + modulus_len - plain_len, 8650Sstevel@tonic-gate plaintext, plain_len)) != CRYPTO_SUCCESS) 8660Sstevel@tonic-gate return (rv); 8670Sstevel@tonic-gate 8680Sstevel@tonic-gate plaintext->cd_length = plain_len; 8690Sstevel@tonic-gate } 8700Sstevel@tonic-gate 8710Sstevel@tonic-gate /* EXPORT DELETE END */ 8720Sstevel@tonic-gate 8730Sstevel@tonic-gate return (rv); 8740Sstevel@tonic-gate } 8750Sstevel@tonic-gate 8760Sstevel@tonic-gate /* EXPORT DELETE START */ 8770Sstevel@tonic-gate 8780Sstevel@tonic-gate static int 8790Sstevel@tonic-gate core_rsa_decrypt(crypto_key_t *key, uchar_t *in, int in_len, 8800Sstevel@tonic-gate uchar_t *out, int kmflag) 8810Sstevel@tonic-gate { 8820Sstevel@tonic-gate int rv; 8830Sstevel@tonic-gate uchar_t *modulus, *prime1, *prime2, *expo1, *expo2, *coef; 8840Sstevel@tonic-gate ssize_t modulus_len; 8850Sstevel@tonic-gate ssize_t prime1_len, prime2_len; 8860Sstevel@tonic-gate ssize_t expo1_len, expo2_len, coef_len; 8870Sstevel@tonic-gate BIGNUM msg; 8880Sstevel@tonic-gate RSAkey *rsakey; 8890Sstevel@tonic-gate 890*7188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 8910Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 8920Sstevel@tonic-gate return (rv); 8930Sstevel@tonic-gate } 8940Sstevel@tonic-gate 8950Sstevel@tonic-gate /* 8960Sstevel@tonic-gate * The following attributes are not required to be 8970Sstevel@tonic-gate * present in a RSA secret key. If any of them is not present 8980Sstevel@tonic-gate * we call the encrypt routine with a flag indicating use of 8990Sstevel@tonic-gate * private exponent (d). Note that SUN_CKA_PRIVATE_EXPONENT is 9000Sstevel@tonic-gate * a required attribute for a RSA secret key. 9010Sstevel@tonic-gate */ 902*7188Smcpowers if ((crypto_get_key_attr(key, SUN_CKA_PRIME_1, &prime1, &prime1_len) 9035072Smcpowers != CRYPTO_SUCCESS) || 904*7188Smcpowers (crypto_get_key_attr(key, SUN_CKA_PRIME_2, &prime2, &prime2_len) 9055072Smcpowers != CRYPTO_SUCCESS) || 906*7188Smcpowers (crypto_get_key_attr(key, SUN_CKA_EXPONENT_1, &expo1, &expo1_len) 9075072Smcpowers != CRYPTO_SUCCESS) || 908*7188Smcpowers (crypto_get_key_attr(key, SUN_CKA_EXPONENT_2, &expo2, &expo2_len) 9095072Smcpowers != CRYPTO_SUCCESS) || 910*7188Smcpowers (crypto_get_key_attr(key, SUN_CKA_COEFFICIENT, &coef, &coef_len) 9115072Smcpowers != CRYPTO_SUCCESS)) { 9120Sstevel@tonic-gate return (core_rsa_encrypt(key, in, in_len, out, kmflag, 0)); 9130Sstevel@tonic-gate } 9140Sstevel@tonic-gate 9150Sstevel@tonic-gate rsakey = kmem_alloc(sizeof (RSAkey), kmflag); 9160Sstevel@tonic-gate if (rsakey == NULL) 9170Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 9180Sstevel@tonic-gate 9190Sstevel@tonic-gate /* psize and qsize for RSA_key_init is in bits. */ 9200Sstevel@tonic-gate if (RSA_key_init(rsakey, prime2_len * 8, prime1_len * 8) != BIG_OK) { 9210Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 9220Sstevel@tonic-gate goto clean1; 9230Sstevel@tonic-gate } 9240Sstevel@tonic-gate 9256557Sfr41279 /* Size for big_init is in BIG_CHUNK_TYPE words. */ 9266557Sfr41279 if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) { 9270Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 9280Sstevel@tonic-gate goto clean2; 9290Sstevel@tonic-gate } 9300Sstevel@tonic-gate 9310Sstevel@tonic-gate /* Convert octet string input data to big integer format. */ 9320Sstevel@tonic-gate bytestring2bignum(&msg, in, in_len); 9330Sstevel@tonic-gate 9340Sstevel@tonic-gate /* Convert octet string modulus to big integer format. */ 9350Sstevel@tonic-gate bytestring2bignum(&(rsakey->n), modulus, modulus_len); 9360Sstevel@tonic-gate 9370Sstevel@tonic-gate if (big_cmp_abs(&msg, &(rsakey->n)) > 0) { 9380Sstevel@tonic-gate rv = CRYPTO_DATA_LEN_RANGE; 9390Sstevel@tonic-gate goto clean3; 9400Sstevel@tonic-gate } 9410Sstevel@tonic-gate 9420Sstevel@tonic-gate /* Convert the rest of private key attributes to big integer format. */ 9430Sstevel@tonic-gate bytestring2bignum(&(rsakey->dmodpminus1), expo2, expo2_len); 9440Sstevel@tonic-gate bytestring2bignum(&(rsakey->dmodqminus1), expo1, expo1_len); 9450Sstevel@tonic-gate bytestring2bignum(&(rsakey->p), prime2, prime2_len); 9460Sstevel@tonic-gate bytestring2bignum(&(rsakey->q), prime1, prime1_len); 9470Sstevel@tonic-gate bytestring2bignum(&(rsakey->pinvmodq), coef, coef_len); 9480Sstevel@tonic-gate 9490Sstevel@tonic-gate if ((big_cmp_abs(&(rsakey->dmodpminus1), &(rsakey->p)) > 0) || 9500Sstevel@tonic-gate (big_cmp_abs(&(rsakey->dmodqminus1), &(rsakey->q)) > 0) || 9510Sstevel@tonic-gate (big_cmp_abs(&(rsakey->pinvmodq), &(rsakey->q)) > 0)) { 9520Sstevel@tonic-gate rv = CRYPTO_KEY_SIZE_RANGE; 9530Sstevel@tonic-gate goto clean3; 9540Sstevel@tonic-gate } 9550Sstevel@tonic-gate 9560Sstevel@tonic-gate /* Perform RSA computation on big integer input data. */ 9570Sstevel@tonic-gate if (big_modexp_crt(&msg, &msg, &(rsakey->dmodpminus1), 9580Sstevel@tonic-gate &(rsakey->dmodqminus1), &(rsakey->p), &(rsakey->q), 9590Sstevel@tonic-gate &(rsakey->pinvmodq), NULL, NULL) != BIG_OK) { 9600Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 9610Sstevel@tonic-gate goto clean3; 9620Sstevel@tonic-gate } 9630Sstevel@tonic-gate 9640Sstevel@tonic-gate /* Convert the big integer output data to octet string. */ 9650Sstevel@tonic-gate bignum2bytestring(out, &msg, modulus_len); 9660Sstevel@tonic-gate 9670Sstevel@tonic-gate /* 9680Sstevel@tonic-gate * Should not free modulus and friends as they are just pointers 9690Sstevel@tonic-gate * to an attribute value buffer from the caller. 9700Sstevel@tonic-gate */ 9710Sstevel@tonic-gate clean3: 9720Sstevel@tonic-gate big_finish(&msg); 9730Sstevel@tonic-gate clean2: 9740Sstevel@tonic-gate RSA_key_finish(rsakey); 9750Sstevel@tonic-gate clean1: 9760Sstevel@tonic-gate kmem_free(rsakey, sizeof (RSAkey)); 9770Sstevel@tonic-gate 9780Sstevel@tonic-gate return (rv); 9790Sstevel@tonic-gate } 9800Sstevel@tonic-gate 9810Sstevel@tonic-gate /* EXPORT DELETE END */ 9820Sstevel@tonic-gate 9830Sstevel@tonic-gate /* ARGSUSED */ 9840Sstevel@tonic-gate static int 9850Sstevel@tonic-gate rsa_sign_verify_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 9860Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 9870Sstevel@tonic-gate crypto_req_handle_t req) 9880Sstevel@tonic-gate { 9890Sstevel@tonic-gate int rv; 9900Sstevel@tonic-gate int kmflag; 9910Sstevel@tonic-gate rsa_ctx_t *ctxp; 9920Sstevel@tonic-gate digest_rsa_ctx_t *dctxp; 9930Sstevel@tonic-gate 9940Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 9950Sstevel@tonic-gate return (rv); 9960Sstevel@tonic-gate 9970Sstevel@tonic-gate /* 9980Sstevel@tonic-gate * Allocate a RSA context. 9990Sstevel@tonic-gate */ 10000Sstevel@tonic-gate kmflag = crypto_kmflag(req); 10010Sstevel@tonic-gate switch (mechanism->cm_type) { 10020Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 10030Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1004676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1005676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1006676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 10070Sstevel@tonic-gate dctxp = kmem_zalloc(sizeof (digest_rsa_ctx_t), kmflag); 10080Sstevel@tonic-gate ctxp = (rsa_ctx_t *)dctxp; 10090Sstevel@tonic-gate break; 10100Sstevel@tonic-gate default: 10110Sstevel@tonic-gate ctxp = kmem_zalloc(sizeof (rsa_ctx_t), kmflag); 10120Sstevel@tonic-gate break; 10130Sstevel@tonic-gate } 10140Sstevel@tonic-gate 10150Sstevel@tonic-gate if (ctxp == NULL) 10160Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 10170Sstevel@tonic-gate 10180Sstevel@tonic-gate ctxp->mech_type = mechanism->cm_type; 1019*7188Smcpowers if ((rv = crypto_copy_key_to_ctx(key, &ctxp->key, &ctxp->keychunk_size, 1020*7188Smcpowers kmflag)) != CRYPTO_SUCCESS) { 10210Sstevel@tonic-gate switch (mechanism->cm_type) { 10220Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 10230Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1024676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1025676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1026676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 10270Sstevel@tonic-gate kmem_free(dctxp, sizeof (digest_rsa_ctx_t)); 10280Sstevel@tonic-gate break; 10290Sstevel@tonic-gate default: 10300Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 10310Sstevel@tonic-gate break; 10320Sstevel@tonic-gate } 10330Sstevel@tonic-gate return (rv); 10340Sstevel@tonic-gate } 10350Sstevel@tonic-gate 10360Sstevel@tonic-gate switch (mechanism->cm_type) { 10370Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 10380Sstevel@tonic-gate MD5Init(&(dctxp->md5_ctx)); 10390Sstevel@tonic-gate break; 10400Sstevel@tonic-gate 10410Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 10420Sstevel@tonic-gate SHA1Init(&(dctxp->sha1_ctx)); 10430Sstevel@tonic-gate break; 1044676Sizick 1045676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1046676Sizick SHA2Init(SHA256, &(dctxp->sha2_ctx)); 1047676Sizick break; 1048676Sizick 1049676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1050676Sizick SHA2Init(SHA384, &(dctxp->sha2_ctx)); 1051676Sizick break; 1052676Sizick 1053676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1054676Sizick SHA2Init(SHA512, &(dctxp->sha2_ctx)); 1055676Sizick break; 10560Sstevel@tonic-gate } 10570Sstevel@tonic-gate 10580Sstevel@tonic-gate ctx->cc_provider_private = ctxp; 10590Sstevel@tonic-gate 10600Sstevel@tonic-gate return (CRYPTO_SUCCESS); 10610Sstevel@tonic-gate } 10620Sstevel@tonic-gate 10630Sstevel@tonic-gate #define SHA1_DIGEST_SIZE 20 10640Sstevel@tonic-gate #define MD5_DIGEST_SIZE 16 10650Sstevel@tonic-gate 10660Sstevel@tonic-gate #define INIT_RAW_CRYPTO_DATA(data, base, len, cd_len) \ 10670Sstevel@tonic-gate (data).cd_format = CRYPTO_DATA_RAW; \ 10680Sstevel@tonic-gate (data).cd_offset = 0; \ 10690Sstevel@tonic-gate (data).cd_raw.iov_base = (char *)base; \ 10700Sstevel@tonic-gate (data).cd_raw.iov_len = len; \ 10710Sstevel@tonic-gate (data).cd_length = cd_len; 10720Sstevel@tonic-gate 10730Sstevel@tonic-gate static int 10740Sstevel@tonic-gate rsa_digest_svrfy_common(digest_rsa_ctx_t *ctxp, crypto_data_t *data, 10750Sstevel@tonic-gate crypto_data_t *signature, int kmflag, uchar_t flag) 10760Sstevel@tonic-gate { 10770Sstevel@tonic-gate int rv = CRYPTO_FAILED; 10780Sstevel@tonic-gate 10790Sstevel@tonic-gate /* EXPORT DELETE START */ 10800Sstevel@tonic-gate 1081676Sizick uchar_t digest[SHA512_DIGEST_LENGTH]; 10820Sstevel@tonic-gate /* The der_data size is enough for MD5 also */ 1083676Sizick uchar_t der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len]; 10840Sstevel@tonic-gate ulong_t der_data_len; 10850Sstevel@tonic-gate crypto_data_t der_cd; 10860Sstevel@tonic-gate rsa_mech_type_t mech_type; 10870Sstevel@tonic-gate 1088*7188Smcpowers ASSERT(flag & CRYPTO_DO_SIGN || flag & CRYPTO_DO_VERIFY); 1089*7188Smcpowers ASSERT(data != NULL || (flag & CRYPTO_DO_FINAL)); 10900Sstevel@tonic-gate 10910Sstevel@tonic-gate mech_type = ctxp->mech_type; 1092676Sizick if (mech_type == RSA_PKCS_MECH_INFO_TYPE || 1093676Sizick mech_type == RSA_X_509_MECH_INFO_TYPE) 10940Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 10950Sstevel@tonic-gate 10960Sstevel@tonic-gate /* 10970Sstevel@tonic-gate * We need to do the BUFFER_TOO_SMALL check before digesting 10980Sstevel@tonic-gate * the data. No check is needed for verify as signature is not 10990Sstevel@tonic-gate * an output argument for verify. 11000Sstevel@tonic-gate */ 1101*7188Smcpowers if (flag & CRYPTO_DO_SIGN) { 11020Sstevel@tonic-gate uchar_t *modulus; 11030Sstevel@tonic-gate ssize_t modulus_len; 11040Sstevel@tonic-gate 1105*7188Smcpowers if ((rv = crypto_get_key_attr(ctxp->key, SUN_CKA_MODULUS, 1106*7188Smcpowers &modulus, &modulus_len)) != CRYPTO_SUCCESS) { 11070Sstevel@tonic-gate return (rv); 11080Sstevel@tonic-gate } 11090Sstevel@tonic-gate 11100Sstevel@tonic-gate if (signature->cd_length < modulus_len) { 11110Sstevel@tonic-gate signature->cd_length = modulus_len; 11120Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 11130Sstevel@tonic-gate } 11140Sstevel@tonic-gate } 11150Sstevel@tonic-gate 11160Sstevel@tonic-gate if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE) 1117*7188Smcpowers rv = crypto_digest_data(data, &(ctxp->md5_ctx), 1118*7188Smcpowers digest, MD5Update, MD5Final, flag | CRYPTO_DO_MD5); 1119676Sizick 1120676Sizick else if (mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE) 1121*7188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha1_ctx), 1122*7188Smcpowers digest, SHA1Update, SHA1Final, flag | CRYPTO_DO_SHA1); 1123676Sizick 1124676Sizick else 1125*7188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha2_ctx), 1126*7188Smcpowers digest, SHA2Update, SHA2Final, flag | CRYPTO_DO_SHA2); 1127676Sizick 11280Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 11290Sstevel@tonic-gate return (rv); 11300Sstevel@tonic-gate 1131676Sizick 11320Sstevel@tonic-gate /* 11330Sstevel@tonic-gate * Prepare the DER encoding of the DigestInfo value as follows: 11340Sstevel@tonic-gate * MD5: MD5_DER_PREFIX || H 11350Sstevel@tonic-gate * SHA-1: SHA1_DER_PREFIX || H 11360Sstevel@tonic-gate * 11370Sstevel@tonic-gate * See rsa_impl.c for more details. 11380Sstevel@tonic-gate */ 1139676Sizick switch (mech_type) { 1140676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 11410Sstevel@tonic-gate bcopy(MD5_DER_PREFIX, der_data, MD5_DER_PREFIX_Len); 1142676Sizick bcopy(digest, der_data + MD5_DER_PREFIX_Len, MD5_DIGEST_SIZE); 1143676Sizick der_data_len = MD5_DER_PREFIX_Len + MD5_DIGEST_SIZE; 1144676Sizick break; 1145676Sizick 1146676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 11470Sstevel@tonic-gate bcopy(SHA1_DER_PREFIX, der_data, SHA1_DER_PREFIX_Len); 1148676Sizick bcopy(digest, der_data + SHA1_DER_PREFIX_Len, 1149676Sizick SHA1_DIGEST_SIZE); 1150676Sizick der_data_len = SHA1_DER_PREFIX_Len + SHA1_DIGEST_SIZE; 1151676Sizick break; 1152676Sizick 1153676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1154676Sizick bcopy(SHA256_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len); 1155676Sizick bcopy(digest, der_data + SHA2_DER_PREFIX_Len, 1156676Sizick SHA256_DIGEST_LENGTH); 1157676Sizick der_data_len = SHA2_DER_PREFIX_Len + SHA256_DIGEST_LENGTH; 1158676Sizick break; 1159676Sizick 1160676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1161676Sizick bcopy(SHA384_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len); 1162676Sizick bcopy(digest, der_data + SHA2_DER_PREFIX_Len, 1163676Sizick SHA384_DIGEST_LENGTH); 1164676Sizick der_data_len = SHA2_DER_PREFIX_Len + SHA384_DIGEST_LENGTH; 1165676Sizick break; 1166676Sizick 1167676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1168676Sizick bcopy(SHA512_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len); 1169676Sizick bcopy(digest, der_data + SHA2_DER_PREFIX_Len, 1170676Sizick SHA512_DIGEST_LENGTH); 1171676Sizick der_data_len = SHA2_DER_PREFIX_Len + SHA512_DIGEST_LENGTH; 1172676Sizick break; 11730Sstevel@tonic-gate } 11740Sstevel@tonic-gate 11750Sstevel@tonic-gate INIT_RAW_CRYPTO_DATA(der_cd, der_data, der_data_len, der_data_len); 11760Sstevel@tonic-gate /* 11770Sstevel@tonic-gate * Now, we are ready to sign or verify the DER_ENCODED data. 11780Sstevel@tonic-gate */ 1179*7188Smcpowers if (flag & CRYPTO_DO_SIGN) 11800Sstevel@tonic-gate rv = rsa_sign_common(mech_type, ctxp->key, &der_cd, 11810Sstevel@tonic-gate signature, kmflag); 11820Sstevel@tonic-gate else 11830Sstevel@tonic-gate rv = rsa_verify_common(mech_type, ctxp->key, &der_cd, 11840Sstevel@tonic-gate signature, kmflag); 11850Sstevel@tonic-gate 11860Sstevel@tonic-gate /* EXPORT DELETE END */ 11870Sstevel@tonic-gate 11880Sstevel@tonic-gate return (rv); 11890Sstevel@tonic-gate } 11900Sstevel@tonic-gate 11910Sstevel@tonic-gate static int 11920Sstevel@tonic-gate rsa_sign_common(rsa_mech_type_t mech_type, crypto_key_t *key, 11930Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *signature, int kmflag) 11940Sstevel@tonic-gate { 11950Sstevel@tonic-gate int rv = CRYPTO_FAILED; 11960Sstevel@tonic-gate 11970Sstevel@tonic-gate /* EXPORT DELETE START */ 11980Sstevel@tonic-gate 11990Sstevel@tonic-gate int dlen; 12000Sstevel@tonic-gate uchar_t *dataptr, *modulus; 12010Sstevel@tonic-gate ssize_t modulus_len; 12020Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 12030Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 12040Sstevel@tonic-gate uchar_t signed_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 12050Sstevel@tonic-gate 1206*7188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 12070Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 12080Sstevel@tonic-gate return (rv); 12090Sstevel@tonic-gate } 12100Sstevel@tonic-gate 12110Sstevel@tonic-gate dlen = data->cd_length; 12120Sstevel@tonic-gate switch (mech_type) { 12130Sstevel@tonic-gate case RSA_PKCS_MECH_INFO_TYPE: 12140Sstevel@tonic-gate if (dlen > (modulus_len - MIN_PKCS1_PADLEN)) 12150Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 12160Sstevel@tonic-gate break; 12170Sstevel@tonic-gate case RSA_X_509_MECH_INFO_TYPE: 12180Sstevel@tonic-gate if (dlen > modulus_len) 12190Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 12200Sstevel@tonic-gate break; 12210Sstevel@tonic-gate } 12220Sstevel@tonic-gate 12230Sstevel@tonic-gate if (signature->cd_length < modulus_len) { 12240Sstevel@tonic-gate signature->cd_length = modulus_len; 12250Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 12260Sstevel@tonic-gate } 12270Sstevel@tonic-gate 12280Sstevel@tonic-gate ASSERT(data->cd_length <= sizeof (tmp_data)); 1229*7188Smcpowers if ((rv = crypto_get_input_data(data, &dataptr, tmp_data)) 12300Sstevel@tonic-gate != CRYPTO_SUCCESS) 12310Sstevel@tonic-gate return (rv); 12320Sstevel@tonic-gate 12330Sstevel@tonic-gate switch (mech_type) { 12340Sstevel@tonic-gate case RSA_PKCS_MECH_INFO_TYPE: 12350Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 12360Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1237676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1238676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1239676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 12400Sstevel@tonic-gate /* 12410Sstevel@tonic-gate * Add PKCS padding to the input data to format a block 12420Sstevel@tonic-gate * type "01" encryption block. 12430Sstevel@tonic-gate */ 12440Sstevel@tonic-gate rv = soft_sign_rsa_pkcs_encode(dataptr, dlen, plain_data, 12450Sstevel@tonic-gate modulus_len); 12460Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 12470Sstevel@tonic-gate return (rv); 12480Sstevel@tonic-gate 12490Sstevel@tonic-gate break; 12500Sstevel@tonic-gate 12510Sstevel@tonic-gate case RSA_X_509_MECH_INFO_TYPE: 12520Sstevel@tonic-gate bzero(plain_data, modulus_len - dlen); 12530Sstevel@tonic-gate bcopy(dataptr, &plain_data[modulus_len - dlen], dlen); 12540Sstevel@tonic-gate break; 12550Sstevel@tonic-gate } 12560Sstevel@tonic-gate 12570Sstevel@tonic-gate rv = core_rsa_decrypt(key, plain_data, modulus_len, signed_data, 12580Sstevel@tonic-gate kmflag); 12590Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 12600Sstevel@tonic-gate /* copy out to signature */ 1261*7188Smcpowers if ((rv = crypto_put_output_data(signed_data, 12620Sstevel@tonic-gate signature, modulus_len)) != CRYPTO_SUCCESS) 12630Sstevel@tonic-gate return (rv); 12640Sstevel@tonic-gate 12650Sstevel@tonic-gate signature->cd_length = modulus_len; 12660Sstevel@tonic-gate } 12670Sstevel@tonic-gate 12680Sstevel@tonic-gate /* EXPORT DELETE END */ 12690Sstevel@tonic-gate 12700Sstevel@tonic-gate return (rv); 12710Sstevel@tonic-gate } 12720Sstevel@tonic-gate 12730Sstevel@tonic-gate /* ARGSUSED */ 12740Sstevel@tonic-gate static int 12750Sstevel@tonic-gate rsa_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 12760Sstevel@tonic-gate crypto_req_handle_t req) 12770Sstevel@tonic-gate { 12780Sstevel@tonic-gate int rv; 12790Sstevel@tonic-gate rsa_ctx_t *ctxp; 12800Sstevel@tonic-gate 12810Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 12820Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 12830Sstevel@tonic-gate 12840Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 12850Sstevel@tonic-gate switch (ctxp->mech_type) { 12860Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 12870Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1288676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1289676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1290676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 12910Sstevel@tonic-gate rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data, 1292*7188Smcpowers signature, KM_SLEEP, CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE | 1293*7188Smcpowers CRYPTO_DO_FINAL); 12940Sstevel@tonic-gate break; 12950Sstevel@tonic-gate default: 12960Sstevel@tonic-gate rv = rsa_sign_common(ctxp->mech_type, ctxp->key, data, 12970Sstevel@tonic-gate signature, KM_SLEEP); 12980Sstevel@tonic-gate break; 12990Sstevel@tonic-gate } 13000Sstevel@tonic-gate 13010Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 13020Sstevel@tonic-gate (void) rsa_free_context(ctx); 13030Sstevel@tonic-gate 13040Sstevel@tonic-gate return (rv); 13050Sstevel@tonic-gate } 13060Sstevel@tonic-gate 13070Sstevel@tonic-gate /* ARGSUSED */ 13080Sstevel@tonic-gate static int 13090Sstevel@tonic-gate rsa_sign_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req) 13100Sstevel@tonic-gate { 13110Sstevel@tonic-gate int rv; 13120Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 13130Sstevel@tonic-gate rsa_mech_type_t mech_type; 13140Sstevel@tonic-gate 13150Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 13160Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 13170Sstevel@tonic-gate mech_type = ctxp->mech_type; 13180Sstevel@tonic-gate 1319676Sizick if (mech_type == RSA_PKCS_MECH_INFO_TYPE || 1320676Sizick mech_type == RSA_X_509_MECH_INFO_TYPE) 13210Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 13220Sstevel@tonic-gate 13230Sstevel@tonic-gate if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE) 1324*7188Smcpowers rv = crypto_digest_data(data, &(ctxp->md5_ctx), 1325*7188Smcpowers NULL, MD5Update, MD5Final, 1326*7188Smcpowers CRYPTO_DO_MD5 | CRYPTO_DO_UPDATE); 1327676Sizick 1328676Sizick else if (mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE) 1329*7188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha1_ctx), 1330*7188Smcpowers NULL, SHA1Update, SHA1Final, CRYPTO_DO_SHA1 | 1331*7188Smcpowers CRYPTO_DO_UPDATE); 1332676Sizick 1333676Sizick else 1334*7188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha2_ctx), 1335*7188Smcpowers NULL, SHA2Update, SHA2Final, CRYPTO_DO_SHA2 | 1336*7188Smcpowers CRYPTO_DO_UPDATE); 1337676Sizick 13380Sstevel@tonic-gate return (rv); 13390Sstevel@tonic-gate } 13400Sstevel@tonic-gate 13410Sstevel@tonic-gate static int 13420Sstevel@tonic-gate rsa_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature, 13430Sstevel@tonic-gate crypto_req_handle_t req) 13440Sstevel@tonic-gate { 13450Sstevel@tonic-gate int rv; 13460Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 13470Sstevel@tonic-gate 13480Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 13490Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 13500Sstevel@tonic-gate 13510Sstevel@tonic-gate rv = rsa_digest_svrfy_common(ctxp, NULL, signature, 1352*7188Smcpowers crypto_kmflag(req), CRYPTO_DO_SIGN | CRYPTO_DO_FINAL); 13530Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 13540Sstevel@tonic-gate (void) rsa_free_context(ctx); 13550Sstevel@tonic-gate 13560Sstevel@tonic-gate return (rv); 13570Sstevel@tonic-gate } 13580Sstevel@tonic-gate 13590Sstevel@tonic-gate /* ARGSUSED */ 13600Sstevel@tonic-gate static int 13610Sstevel@tonic-gate rsa_sign_atomic(crypto_provider_handle_t provider, 13620Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 13630Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 13640Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 13650Sstevel@tonic-gate { 13660Sstevel@tonic-gate int rv; 13670Sstevel@tonic-gate digest_rsa_ctx_t dctx; 13680Sstevel@tonic-gate 13690Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 13700Sstevel@tonic-gate return (rv); 13710Sstevel@tonic-gate 1372676Sizick if (mechanism->cm_type == RSA_PKCS_MECH_INFO_TYPE || 1373676Sizick mechanism->cm_type == RSA_X_509_MECH_INFO_TYPE) 1374676Sizick rv = rsa_sign_common(mechanism->cm_type, key, data, 1375676Sizick signature, crypto_kmflag(req)); 1376676Sizick 1377676Sizick else { 13780Sstevel@tonic-gate dctx.mech_type = mechanism->cm_type; 13790Sstevel@tonic-gate dctx.key = key; 1380676Sizick switch (mechanism->cm_type) { 1381676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 13820Sstevel@tonic-gate MD5Init(&(dctx.md5_ctx)); 1383676Sizick break; 1384676Sizick 1385676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 13860Sstevel@tonic-gate SHA1Init(&(dctx.sha1_ctx)); 1387676Sizick break; 1388676Sizick 1389676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1390676Sizick SHA2Init(SHA256, &(dctx.sha2_ctx)); 1391676Sizick break; 1392676Sizick 1393676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1394676Sizick SHA2Init(SHA384, &(dctx.sha2_ctx)); 1395676Sizick break; 1396676Sizick 1397676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1398676Sizick SHA2Init(SHA512, &(dctx.sha2_ctx)); 1399676Sizick break; 1400676Sizick } 1401676Sizick 1402676Sizick rv = rsa_digest_svrfy_common(&dctx, data, signature, 1403*7188Smcpowers crypto_kmflag(req), CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE | 1404*7188Smcpowers CRYPTO_DO_FINAL); 14050Sstevel@tonic-gate } 14060Sstevel@tonic-gate 14070Sstevel@tonic-gate return (rv); 14080Sstevel@tonic-gate } 14090Sstevel@tonic-gate 14100Sstevel@tonic-gate static int 14110Sstevel@tonic-gate rsa_verify_common(rsa_mech_type_t mech_type, crypto_key_t *key, 14120Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *signature, int kmflag) 14130Sstevel@tonic-gate { 14140Sstevel@tonic-gate int rv = CRYPTO_FAILED; 14150Sstevel@tonic-gate 14160Sstevel@tonic-gate /* EXPORT DELETE START */ 14170Sstevel@tonic-gate 14180Sstevel@tonic-gate uchar_t *sigptr, *modulus; 14190Sstevel@tonic-gate ssize_t modulus_len; 14200Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 14210Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 14220Sstevel@tonic-gate 1423*7188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 14240Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 14250Sstevel@tonic-gate return (rv); 14260Sstevel@tonic-gate } 14270Sstevel@tonic-gate 14280Sstevel@tonic-gate if (signature->cd_length != modulus_len) 14290Sstevel@tonic-gate return (CRYPTO_SIGNATURE_LEN_RANGE); 14300Sstevel@tonic-gate 14310Sstevel@tonic-gate ASSERT(signature->cd_length <= sizeof (tmp_data)); 1432*7188Smcpowers if ((rv = crypto_get_input_data(signature, &sigptr, tmp_data)) 14330Sstevel@tonic-gate != CRYPTO_SUCCESS) 14340Sstevel@tonic-gate return (rv); 14350Sstevel@tonic-gate 14360Sstevel@tonic-gate rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1); 14370Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 14380Sstevel@tonic-gate return (rv); 14390Sstevel@tonic-gate 1440676Sizick if (mech_type == RSA_X_509_MECH_INFO_TYPE) { 1441676Sizick if (compare_data(data, (plain_data + modulus_len 1442676Sizick - data->cd_length)) != 0) 1443676Sizick rv = CRYPTO_SIGNATURE_INVALID; 1444676Sizick 1445676Sizick } else { 14460Sstevel@tonic-gate int data_len = modulus_len; 14470Sstevel@tonic-gate 14480Sstevel@tonic-gate /* 14490Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the 14500Sstevel@tonic-gate * recovered data, then compare the recovered data with 14510Sstevel@tonic-gate * the original data. 14520Sstevel@tonic-gate */ 14530Sstevel@tonic-gate rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len); 14540Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 1455676Sizick return (rv); 14560Sstevel@tonic-gate 1457676Sizick if (data_len != data->cd_length) 1458676Sizick return (CRYPTO_SIGNATURE_LEN_RANGE); 14590Sstevel@tonic-gate 14600Sstevel@tonic-gate if (compare_data(data, (plain_data + modulus_len 14610Sstevel@tonic-gate - data_len)) != 0) 14620Sstevel@tonic-gate rv = CRYPTO_SIGNATURE_INVALID; 14630Sstevel@tonic-gate } 14640Sstevel@tonic-gate 14650Sstevel@tonic-gate /* EXPORT DELETE END */ 14660Sstevel@tonic-gate 14670Sstevel@tonic-gate return (rv); 14680Sstevel@tonic-gate } 14690Sstevel@tonic-gate 14700Sstevel@tonic-gate /* ARGSUSED */ 14710Sstevel@tonic-gate static int 14720Sstevel@tonic-gate rsa_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 14730Sstevel@tonic-gate crypto_req_handle_t req) 14740Sstevel@tonic-gate { 14750Sstevel@tonic-gate int rv; 14760Sstevel@tonic-gate rsa_ctx_t *ctxp; 14770Sstevel@tonic-gate 14780Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 14790Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 14800Sstevel@tonic-gate 14810Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 14820Sstevel@tonic-gate switch (ctxp->mech_type) { 14830Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 14840Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1485676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1486676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1487676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 14880Sstevel@tonic-gate rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data, 1489*7188Smcpowers signature, KM_SLEEP, CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE | 1490*7188Smcpowers CRYPTO_DO_FINAL); 14910Sstevel@tonic-gate break; 14920Sstevel@tonic-gate default: 14930Sstevel@tonic-gate rv = rsa_verify_common(ctxp->mech_type, ctxp->key, data, 14940Sstevel@tonic-gate signature, KM_SLEEP); 14950Sstevel@tonic-gate break; 14960Sstevel@tonic-gate } 14970Sstevel@tonic-gate 14980Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 14990Sstevel@tonic-gate (void) rsa_free_context(ctx); 15000Sstevel@tonic-gate 15010Sstevel@tonic-gate return (rv); 15020Sstevel@tonic-gate } 15030Sstevel@tonic-gate 15040Sstevel@tonic-gate /* ARGSUSED */ 15050Sstevel@tonic-gate static int 15060Sstevel@tonic-gate rsa_verify_update(crypto_ctx_t *ctx, crypto_data_t *data, 15070Sstevel@tonic-gate crypto_req_handle_t req) 15080Sstevel@tonic-gate { 15090Sstevel@tonic-gate int rv; 15100Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 15110Sstevel@tonic-gate 15120Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 15130Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 15140Sstevel@tonic-gate 1515676Sizick switch (ctxp->mech_type) { 15160Sstevel@tonic-gate 1517676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 1518*7188Smcpowers rv = crypto_digest_data(data, &(ctxp->md5_ctx), 1519*7188Smcpowers NULL, MD5Update, MD5Final, CRYPTO_DO_MD5 | 1520*7188Smcpowers CRYPTO_DO_UPDATE); 1521676Sizick break; 1522676Sizick 1523676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1524*7188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha1_ctx), 1525*7188Smcpowers NULL, SHA1Update, SHA1Final, CRYPTO_DO_SHA1 | 1526*7188Smcpowers CRYPTO_DO_UPDATE); 1527676Sizick break; 1528676Sizick 1529676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1530676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1531676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1532*7188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha2_ctx), 1533*7188Smcpowers NULL, SHA2Update, SHA2Final, CRYPTO_DO_SHA2 | 1534*7188Smcpowers CRYPTO_DO_UPDATE); 1535676Sizick break; 1536676Sizick 1537676Sizick default: 1538676Sizick return (CRYPTO_MECHANISM_INVALID); 1539676Sizick } 1540676Sizick 15410Sstevel@tonic-gate return (rv); 15420Sstevel@tonic-gate } 15430Sstevel@tonic-gate 15440Sstevel@tonic-gate static int 15450Sstevel@tonic-gate rsa_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature, 15460Sstevel@tonic-gate crypto_req_handle_t req) 15470Sstevel@tonic-gate { 15480Sstevel@tonic-gate int rv; 15490Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 15500Sstevel@tonic-gate 15510Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 15520Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 15530Sstevel@tonic-gate 15540Sstevel@tonic-gate rv = rsa_digest_svrfy_common(ctxp, NULL, signature, 1555*7188Smcpowers crypto_kmflag(req), CRYPTO_DO_VERIFY | CRYPTO_DO_FINAL); 15560Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 15570Sstevel@tonic-gate (void) rsa_free_context(ctx); 15580Sstevel@tonic-gate 15590Sstevel@tonic-gate return (rv); 15600Sstevel@tonic-gate } 15610Sstevel@tonic-gate 15620Sstevel@tonic-gate 15630Sstevel@tonic-gate /* ARGSUSED */ 15640Sstevel@tonic-gate static int 15650Sstevel@tonic-gate rsa_verify_atomic(crypto_provider_handle_t provider, 15660Sstevel@tonic-gate crypto_session_id_t session_id, 15670Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data, 15680Sstevel@tonic-gate crypto_data_t *signature, crypto_spi_ctx_template_t ctx_template, 15690Sstevel@tonic-gate crypto_req_handle_t req) 15700Sstevel@tonic-gate { 15710Sstevel@tonic-gate int rv; 15720Sstevel@tonic-gate digest_rsa_ctx_t dctx; 15730Sstevel@tonic-gate 15740Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 15750Sstevel@tonic-gate return (rv); 15760Sstevel@tonic-gate 1577676Sizick if (mechanism->cm_type == RSA_PKCS_MECH_INFO_TYPE || 1578676Sizick mechanism->cm_type == RSA_X_509_MECH_INFO_TYPE) 1579676Sizick rv = rsa_verify_common(mechanism->cm_type, key, data, 1580676Sizick signature, crypto_kmflag(req)); 1581676Sizick 1582676Sizick else { 15830Sstevel@tonic-gate dctx.mech_type = mechanism->cm_type; 15840Sstevel@tonic-gate dctx.key = key; 1585676Sizick 1586676Sizick switch (mechanism->cm_type) { 1587676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 15880Sstevel@tonic-gate MD5Init(&(dctx.md5_ctx)); 1589676Sizick break; 1590676Sizick 1591676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 15920Sstevel@tonic-gate SHA1Init(&(dctx.sha1_ctx)); 1593676Sizick break; 1594676Sizick 1595676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1596676Sizick SHA2Init(SHA256, &(dctx.sha2_ctx)); 1597676Sizick break; 1598676Sizick 1599676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1600676Sizick SHA2Init(SHA384, &(dctx.sha2_ctx)); 1601676Sizick break; 1602676Sizick 1603676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1604676Sizick SHA2Init(SHA512, &(dctx.sha2_ctx)); 1605676Sizick break; 1606676Sizick } 1607676Sizick 16080Sstevel@tonic-gate rv = rsa_digest_svrfy_common(&dctx, data, 16090Sstevel@tonic-gate signature, crypto_kmflag(req), 1610*7188Smcpowers CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE | CRYPTO_DO_FINAL); 16110Sstevel@tonic-gate } 16120Sstevel@tonic-gate 16130Sstevel@tonic-gate return (rv); 16140Sstevel@tonic-gate } 16150Sstevel@tonic-gate 16160Sstevel@tonic-gate static int 16170Sstevel@tonic-gate rsa_verify_recover_common(rsa_mech_type_t mech_type, crypto_key_t *key, 16180Sstevel@tonic-gate crypto_data_t *signature, crypto_data_t *data, int kmflag) 16190Sstevel@tonic-gate { 16200Sstevel@tonic-gate int rv = CRYPTO_FAILED; 16210Sstevel@tonic-gate 16220Sstevel@tonic-gate /* EXPORT DELETE START */ 16230Sstevel@tonic-gate 16240Sstevel@tonic-gate int data_len; 16250Sstevel@tonic-gate uchar_t *sigptr, *modulus; 16260Sstevel@tonic-gate ssize_t modulus_len; 16270Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 16280Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 16290Sstevel@tonic-gate 1630*7188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 16310Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 16320Sstevel@tonic-gate return (rv); 16330Sstevel@tonic-gate } 16340Sstevel@tonic-gate 16350Sstevel@tonic-gate if (signature->cd_length != modulus_len) 16360Sstevel@tonic-gate return (CRYPTO_SIGNATURE_LEN_RANGE); 16370Sstevel@tonic-gate 16380Sstevel@tonic-gate ASSERT(signature->cd_length <= sizeof (tmp_data)); 1639*7188Smcpowers if ((rv = crypto_get_input_data(signature, &sigptr, tmp_data)) 16400Sstevel@tonic-gate != CRYPTO_SUCCESS) 16410Sstevel@tonic-gate return (rv); 16420Sstevel@tonic-gate 16430Sstevel@tonic-gate rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1); 16440Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 16450Sstevel@tonic-gate return (rv); 16460Sstevel@tonic-gate 16470Sstevel@tonic-gate data_len = modulus_len; 16480Sstevel@tonic-gate 16490Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 16500Sstevel@tonic-gate /* 16510Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the 16520Sstevel@tonic-gate * recovered data, then compare the recovered data with 16530Sstevel@tonic-gate * the original data. 16540Sstevel@tonic-gate */ 16550Sstevel@tonic-gate rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len); 16560Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 16570Sstevel@tonic-gate return (rv); 16580Sstevel@tonic-gate } 16590Sstevel@tonic-gate 16600Sstevel@tonic-gate if (data->cd_length < data_len) { 16610Sstevel@tonic-gate data->cd_length = data_len; 16620Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 16630Sstevel@tonic-gate } 16640Sstevel@tonic-gate 1665*7188Smcpowers if ((rv = crypto_put_output_data(plain_data + modulus_len - data_len, 16660Sstevel@tonic-gate data, data_len)) != CRYPTO_SUCCESS) 16670Sstevel@tonic-gate return (rv); 16680Sstevel@tonic-gate data->cd_length = data_len; 16690Sstevel@tonic-gate 16700Sstevel@tonic-gate /* EXPORT DELETE END */ 16710Sstevel@tonic-gate 16720Sstevel@tonic-gate return (rv); 16730Sstevel@tonic-gate } 16740Sstevel@tonic-gate 16750Sstevel@tonic-gate /* ARGSUSED */ 16760Sstevel@tonic-gate static int 16770Sstevel@tonic-gate rsa_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature, 16780Sstevel@tonic-gate crypto_data_t *data, crypto_req_handle_t req) 16790Sstevel@tonic-gate { 16800Sstevel@tonic-gate int rv; 16810Sstevel@tonic-gate rsa_ctx_t *ctxp; 16820Sstevel@tonic-gate 16830Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 16840Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 16850Sstevel@tonic-gate 16860Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 16870Sstevel@tonic-gate rv = rsa_verify_recover_common(ctxp->mech_type, ctxp->key, 16880Sstevel@tonic-gate signature, data, KM_SLEEP); 16890Sstevel@tonic-gate 16900Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 16910Sstevel@tonic-gate (void) rsa_free_context(ctx); 16920Sstevel@tonic-gate 16930Sstevel@tonic-gate return (rv); 16940Sstevel@tonic-gate } 16950Sstevel@tonic-gate 16960Sstevel@tonic-gate /* ARGSUSED */ 16970Sstevel@tonic-gate static int 16980Sstevel@tonic-gate rsa_verify_recover_atomic(crypto_provider_handle_t provider, 16990Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 17000Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data, 17010Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 17020Sstevel@tonic-gate { 17030Sstevel@tonic-gate int rv; 17040Sstevel@tonic-gate 17050Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 17060Sstevel@tonic-gate return (rv); 17070Sstevel@tonic-gate 17080Sstevel@tonic-gate return (rsa_verify_recover_common(mechanism->cm_type, key, 17090Sstevel@tonic-gate signature, data, crypto_kmflag(req))); 17100Sstevel@tonic-gate } 1711