10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 55072Smcpowers * Common Development and Distribution License (the "License"). 65072Smcpowers * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*6557Sfr41279 * 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> 440Sstevel@tonic-gate #include "rsa_impl.h" 450Sstevel@tonic-gate 460Sstevel@tonic-gate extern struct mod_ops mod_cryptoops; 470Sstevel@tonic-gate 480Sstevel@tonic-gate /* 490Sstevel@tonic-gate * Module linkage information for the kernel. 500Sstevel@tonic-gate */ 510Sstevel@tonic-gate static struct modlcrypto modlcrypto = { 520Sstevel@tonic-gate &mod_cryptoops, 535072Smcpowers "RSA Kernel SW Provider" 540Sstevel@tonic-gate }; 550Sstevel@tonic-gate 560Sstevel@tonic-gate static struct modlinkage modlinkage = { 570Sstevel@tonic-gate MODREV_1, 580Sstevel@tonic-gate (void *)&modlcrypto, 590Sstevel@tonic-gate NULL 600Sstevel@tonic-gate }; 610Sstevel@tonic-gate 620Sstevel@tonic-gate /* 630Sstevel@tonic-gate * CSPI information (entry points, provider info, etc.) 640Sstevel@tonic-gate */ 650Sstevel@tonic-gate typedef enum rsa_mech_type { 660Sstevel@tonic-gate RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_RSA_PKCS */ 670Sstevel@tonic-gate RSA_X_509_MECH_INFO_TYPE, /* SUN_CKM_RSA_X_509 */ 680Sstevel@tonic-gate MD5_RSA_PKCS_MECH_INFO_TYPE, /* SUN_MD5_RSA_PKCS */ 69676Sizick SHA1_RSA_PKCS_MECH_INFO_TYPE, /* SUN_SHA1_RSA_PKCS */ 70676Sizick SHA256_RSA_PKCS_MECH_INFO_TYPE, /* SUN_SHA256_RSA_PKCS */ 71676Sizick SHA384_RSA_PKCS_MECH_INFO_TYPE, /* SUN_SHA384_RSA_PKCS */ 72676Sizick SHA512_RSA_PKCS_MECH_INFO_TYPE /* SUN_SHA512_RSA_PKCS */ 730Sstevel@tonic-gate } rsa_mech_type_t; 740Sstevel@tonic-gate 750Sstevel@tonic-gate /* 760Sstevel@tonic-gate * Context for RSA_PKCS and RSA_X_509 mechanisms. 770Sstevel@tonic-gate */ 780Sstevel@tonic-gate typedef struct rsa_ctx { 790Sstevel@tonic-gate rsa_mech_type_t mech_type; 800Sstevel@tonic-gate crypto_key_t *key; 810Sstevel@tonic-gate size_t keychunk_size; 820Sstevel@tonic-gate } rsa_ctx_t; 830Sstevel@tonic-gate 840Sstevel@tonic-gate /* 85676Sizick * Context for MD5_RSA_PKCS and SHA*_RSA_PKCS mechanisms. 860Sstevel@tonic-gate */ 870Sstevel@tonic-gate typedef struct digest_rsa_ctx { 880Sstevel@tonic-gate rsa_mech_type_t mech_type; 890Sstevel@tonic-gate crypto_key_t *key; 900Sstevel@tonic-gate size_t keychunk_size; 910Sstevel@tonic-gate union { 920Sstevel@tonic-gate MD5_CTX md5ctx; 930Sstevel@tonic-gate SHA1_CTX sha1ctx; 94676Sizick SHA2_CTX sha2ctx; 950Sstevel@tonic-gate } dctx_u; 960Sstevel@tonic-gate } digest_rsa_ctx_t; 970Sstevel@tonic-gate 980Sstevel@tonic-gate #define md5_ctx dctx_u.md5ctx 990Sstevel@tonic-gate #define sha1_ctx dctx_u.sha1ctx 100676Sizick #define sha2_ctx dctx_u.sha2ctx 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate /* 1030Sstevel@tonic-gate * Mechanism info structure passed to KCF during registration. 1040Sstevel@tonic-gate */ 1050Sstevel@tonic-gate static crypto_mech_info_t rsa_mech_info_tab[] = { 1060Sstevel@tonic-gate /* RSA_PKCS */ 1070Sstevel@tonic-gate {SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE, 1080Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 1090Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC | 1100Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 1110Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 1120Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC | 1130Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC, 1140Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate /* RSA_X_509 */ 1170Sstevel@tonic-gate {SUN_CKM_RSA_X_509, RSA_X_509_MECH_INFO_TYPE, 1180Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 1190Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC | 1200Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 1210Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 1220Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC | 1230Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC, 1240Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate /* MD5_RSA_PKCS */ 1270Sstevel@tonic-gate {SUN_CKM_MD5_RSA_PKCS, MD5_RSA_PKCS_MECH_INFO_TYPE, 1280Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 1290Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 1300Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 1310Sstevel@tonic-gate 1320Sstevel@tonic-gate /* SHA1_RSA_PKCS */ 1330Sstevel@tonic-gate {SUN_CKM_SHA1_RSA_PKCS, SHA1_RSA_PKCS_MECH_INFO_TYPE, 1340Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 1350Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 136676Sizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 137676Sizick 138676Sizick /* SHA256_RSA_PKCS */ 139676Sizick {SUN_CKM_SHA256_RSA_PKCS, SHA256_RSA_PKCS_MECH_INFO_TYPE, 140676Sizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 141676Sizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 142676Sizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 143676Sizick 144676Sizick /* SHA384_RSA_PKCS */ 145676Sizick {SUN_CKM_SHA384_RSA_PKCS, SHA384_RSA_PKCS_MECH_INFO_TYPE, 146676Sizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 147676Sizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 148676Sizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 149676Sizick 150676Sizick /* SHA512_RSA_PKCS */ 151676Sizick {SUN_CKM_SHA512_RSA_PKCS, SHA512_RSA_PKCS_MECH_INFO_TYPE, 152676Sizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 153676Sizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 1540Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS} 155676Sizick 1560Sstevel@tonic-gate }; 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate #define RSA_VALID_MECH(mech) \ 1590Sstevel@tonic-gate (((mech)->cm_type == RSA_PKCS_MECH_INFO_TYPE || \ 1600Sstevel@tonic-gate (mech)->cm_type == RSA_X_509_MECH_INFO_TYPE || \ 1610Sstevel@tonic-gate (mech)->cm_type == MD5_RSA_PKCS_MECH_INFO_TYPE || \ 162676Sizick (mech)->cm_type == SHA1_RSA_PKCS_MECH_INFO_TYPE || \ 163676Sizick (mech)->cm_type == SHA256_RSA_PKCS_MECH_INFO_TYPE || \ 164676Sizick (mech)->cm_type == SHA384_RSA_PKCS_MECH_INFO_TYPE || \ 165676Sizick (mech)->cm_type == SHA512_RSA_PKCS_MECH_INFO_TYPE) ? 1 : 0) 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate /* operations are in-place if the output buffer is NULL */ 1680Sstevel@tonic-gate #define RSA_ARG_INPLACE(input, output) \ 1690Sstevel@tonic-gate if ((output) == NULL) \ 1700Sstevel@tonic-gate (output) = (input); 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate static void rsa_provider_status(crypto_provider_handle_t, uint_t *); 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate static crypto_control_ops_t rsa_control_ops = { 1750Sstevel@tonic-gate rsa_provider_status 1760Sstevel@tonic-gate }; 1770Sstevel@tonic-gate 1780Sstevel@tonic-gate static int rsa_common_init(crypto_ctx_t *, crypto_mechanism_t *, 1790Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 1800Sstevel@tonic-gate static int rsa_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 1810Sstevel@tonic-gate crypto_req_handle_t); 1820Sstevel@tonic-gate static int rsa_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 1830Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 1840Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 1850Sstevel@tonic-gate static int rsa_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 1860Sstevel@tonic-gate crypto_req_handle_t); 1870Sstevel@tonic-gate static int rsa_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 1880Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 1890Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate /* 1920Sstevel@tonic-gate * The RSA mechanisms do not have multiple-part cipher operations. 1930Sstevel@tonic-gate * So, the update and final routines are set to NULL. 1940Sstevel@tonic-gate */ 1950Sstevel@tonic-gate static crypto_cipher_ops_t rsa_cipher_ops = { 1960Sstevel@tonic-gate rsa_common_init, 1970Sstevel@tonic-gate rsa_encrypt, 1980Sstevel@tonic-gate NULL, 1990Sstevel@tonic-gate NULL, 2000Sstevel@tonic-gate rsa_encrypt_atomic, 2010Sstevel@tonic-gate rsa_common_init, 2020Sstevel@tonic-gate rsa_decrypt, 2030Sstevel@tonic-gate NULL, 2040Sstevel@tonic-gate NULL, 2050Sstevel@tonic-gate rsa_decrypt_atomic 2060Sstevel@tonic-gate }; 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate static int rsa_sign_verify_common_init(crypto_ctx_t *, crypto_mechanism_t *, 2090Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 2100Sstevel@tonic-gate static int rsa_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 2110Sstevel@tonic-gate crypto_req_handle_t); 2120Sstevel@tonic-gate static int rsa_sign_update(crypto_ctx_t *, crypto_data_t *, 2130Sstevel@tonic-gate crypto_req_handle_t); 2140Sstevel@tonic-gate static int rsa_sign_final(crypto_ctx_t *, crypto_data_t *, 2150Sstevel@tonic-gate crypto_req_handle_t); 2160Sstevel@tonic-gate static int rsa_sign_atomic(crypto_provider_handle_t, crypto_session_id_t, 2170Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, 2180Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t); 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate /* 2210Sstevel@tonic-gate * We use the same routine for sign_init and sign_recover_init fields 2220Sstevel@tonic-gate * as they do the same thing. Same holds for sign and sign_recover fields, 2230Sstevel@tonic-gate * and sign_atomic and sign_recover_atomic fields. 2240Sstevel@tonic-gate */ 2250Sstevel@tonic-gate static crypto_sign_ops_t rsa_sign_ops = { 2260Sstevel@tonic-gate rsa_sign_verify_common_init, 2270Sstevel@tonic-gate rsa_sign, 2280Sstevel@tonic-gate rsa_sign_update, 2290Sstevel@tonic-gate rsa_sign_final, 2300Sstevel@tonic-gate rsa_sign_atomic, 2310Sstevel@tonic-gate rsa_sign_verify_common_init, 2320Sstevel@tonic-gate rsa_sign, 2330Sstevel@tonic-gate rsa_sign_atomic 2340Sstevel@tonic-gate }; 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate static int rsa_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 2370Sstevel@tonic-gate crypto_req_handle_t); 2380Sstevel@tonic-gate static int rsa_verify_update(crypto_ctx_t *, crypto_data_t *, 2390Sstevel@tonic-gate crypto_req_handle_t); 2400Sstevel@tonic-gate static int rsa_verify_final(crypto_ctx_t *, crypto_data_t *, 2410Sstevel@tonic-gate crypto_req_handle_t); 2420Sstevel@tonic-gate static int rsa_verify_atomic(crypto_provider_handle_t, crypto_session_id_t, 2430Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 2440Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 2450Sstevel@tonic-gate static int rsa_verify_recover(crypto_ctx_t *, crypto_data_t *, 2460Sstevel@tonic-gate crypto_data_t *, crypto_req_handle_t); 2470Sstevel@tonic-gate static int rsa_verify_recover_atomic(crypto_provider_handle_t, 2480Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 2490Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 2500Sstevel@tonic-gate crypto_req_handle_t); 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate /* 2530Sstevel@tonic-gate * We use the same routine (rsa_sign_verify_common_init) for verify_init 2540Sstevel@tonic-gate * and verify_recover_init fields as they do the same thing. 2550Sstevel@tonic-gate */ 2560Sstevel@tonic-gate static crypto_verify_ops_t rsa_verify_ops = { 2570Sstevel@tonic-gate rsa_sign_verify_common_init, 2580Sstevel@tonic-gate rsa_verify, 2590Sstevel@tonic-gate rsa_verify_update, 2600Sstevel@tonic-gate rsa_verify_final, 2610Sstevel@tonic-gate rsa_verify_atomic, 2620Sstevel@tonic-gate rsa_sign_verify_common_init, 2630Sstevel@tonic-gate rsa_verify_recover, 2640Sstevel@tonic-gate rsa_verify_recover_atomic 2650Sstevel@tonic-gate }; 2660Sstevel@tonic-gate 2670Sstevel@tonic-gate static int rsa_free_context(crypto_ctx_t *); 2680Sstevel@tonic-gate 2690Sstevel@tonic-gate static crypto_ctx_ops_t rsa_ctx_ops = { 2700Sstevel@tonic-gate NULL, 2710Sstevel@tonic-gate rsa_free_context 2720Sstevel@tonic-gate }; 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate static crypto_ops_t rsa_crypto_ops = { 2750Sstevel@tonic-gate &rsa_control_ops, 2760Sstevel@tonic-gate NULL, 2770Sstevel@tonic-gate &rsa_cipher_ops, 2780Sstevel@tonic-gate NULL, 2790Sstevel@tonic-gate &rsa_sign_ops, 2800Sstevel@tonic-gate &rsa_verify_ops, 2810Sstevel@tonic-gate NULL, 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 &rsa_ctx_ops 2890Sstevel@tonic-gate }; 2900Sstevel@tonic-gate 2910Sstevel@tonic-gate static crypto_provider_info_t rsa_prov_info = { 2920Sstevel@tonic-gate CRYPTO_SPI_VERSION_1, 2930Sstevel@tonic-gate "RSA Software Provider", 2940Sstevel@tonic-gate CRYPTO_SW_PROVIDER, 2950Sstevel@tonic-gate {&modlinkage}, 2960Sstevel@tonic-gate NULL, 2970Sstevel@tonic-gate &rsa_crypto_ops, 2980Sstevel@tonic-gate sizeof (rsa_mech_info_tab)/sizeof (crypto_mech_info_t), 2990Sstevel@tonic-gate rsa_mech_info_tab 3000Sstevel@tonic-gate }; 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate static int rsa_encrypt_common(rsa_mech_type_t, crypto_key_t *, 3030Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3040Sstevel@tonic-gate static int rsa_decrypt_common(rsa_mech_type_t, crypto_key_t *, 3050Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3060Sstevel@tonic-gate static int rsa_sign_common(rsa_mech_type_t, crypto_key_t *, 3070Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3080Sstevel@tonic-gate static int rsa_verify_common(rsa_mech_type_t, crypto_key_t *, 3090Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3100Sstevel@tonic-gate static int compare_data(crypto_data_t *, uchar_t *); 3110Sstevel@tonic-gate 3120Sstevel@tonic-gate /* EXPORT DELETE START */ 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate static int core_rsa_encrypt(crypto_key_t *, uchar_t *, 3150Sstevel@tonic-gate int, uchar_t *, int, int); 3160Sstevel@tonic-gate static int core_rsa_decrypt(crypto_key_t *, uchar_t *, int, 3170Sstevel@tonic-gate uchar_t *, int); 3180Sstevel@tonic-gate 3190Sstevel@tonic-gate /* EXPORT DELETE END */ 3200Sstevel@tonic-gate 3210Sstevel@tonic-gate static crypto_kcf_provider_handle_t rsa_prov_handle = NULL; 3220Sstevel@tonic-gate 3230Sstevel@tonic-gate int 3240Sstevel@tonic-gate _init(void) 3250Sstevel@tonic-gate { 3260Sstevel@tonic-gate int ret; 3270Sstevel@tonic-gate 3280Sstevel@tonic-gate /* 3290Sstevel@tonic-gate * Register with KCF. If the registration fails, return error. 3300Sstevel@tonic-gate */ 3310Sstevel@tonic-gate if ((ret = crypto_register_provider(&rsa_prov_info, 3320Sstevel@tonic-gate &rsa_prov_handle)) != CRYPTO_SUCCESS) { 3330Sstevel@tonic-gate cmn_err(CE_WARN, "rsa _init: crypto_register_provider()" 3340Sstevel@tonic-gate "failed (0x%x)", ret); 3350Sstevel@tonic-gate return (EACCES); 3360Sstevel@tonic-gate } 3370Sstevel@tonic-gate 3380Sstevel@tonic-gate if ((ret = mod_install(&modlinkage)) != 0) { 3390Sstevel@tonic-gate int rv; 3400Sstevel@tonic-gate 3410Sstevel@tonic-gate ASSERT(rsa_prov_handle != NULL); 3420Sstevel@tonic-gate /* We should not return if the unregister returns busy. */ 3430Sstevel@tonic-gate while ((rv = crypto_unregister_provider(rsa_prov_handle)) 3440Sstevel@tonic-gate == CRYPTO_BUSY) { 3450Sstevel@tonic-gate cmn_err(CE_WARN, "rsa _init: " 3460Sstevel@tonic-gate "crypto_unregister_provider() " 3470Sstevel@tonic-gate "failed (0x%x). Retrying.", rv); 3480Sstevel@tonic-gate /* wait 10 seconds and try again. */ 3490Sstevel@tonic-gate delay(10 * drv_usectohz(1000000)); 3500Sstevel@tonic-gate } 3510Sstevel@tonic-gate } 3520Sstevel@tonic-gate 3530Sstevel@tonic-gate return (ret); 3540Sstevel@tonic-gate } 3550Sstevel@tonic-gate 3560Sstevel@tonic-gate int 3570Sstevel@tonic-gate _fini(void) 3580Sstevel@tonic-gate { 3590Sstevel@tonic-gate int ret; 3600Sstevel@tonic-gate 3610Sstevel@tonic-gate /* 3620Sstevel@tonic-gate * Unregister from KCF if previous registration succeeded. 3630Sstevel@tonic-gate */ 3640Sstevel@tonic-gate if (rsa_prov_handle != NULL) { 3650Sstevel@tonic-gate if ((ret = crypto_unregister_provider(rsa_prov_handle)) != 3660Sstevel@tonic-gate CRYPTO_SUCCESS) { 3670Sstevel@tonic-gate cmn_err(CE_WARN, "rsa _fini: " 3680Sstevel@tonic-gate "crypto_unregister_provider() " 3690Sstevel@tonic-gate "failed (0x%x)", ret); 3700Sstevel@tonic-gate return (EBUSY); 3710Sstevel@tonic-gate } 3720Sstevel@tonic-gate rsa_prov_handle = NULL; 3730Sstevel@tonic-gate } 3740Sstevel@tonic-gate 3750Sstevel@tonic-gate return (mod_remove(&modlinkage)); 3760Sstevel@tonic-gate } 3770Sstevel@tonic-gate 3780Sstevel@tonic-gate int 3790Sstevel@tonic-gate _info(struct modinfo *modinfop) 3800Sstevel@tonic-gate { 3810Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 3820Sstevel@tonic-gate } 3830Sstevel@tonic-gate 3840Sstevel@tonic-gate /* ARGSUSED */ 3850Sstevel@tonic-gate static void 3860Sstevel@tonic-gate rsa_provider_status(crypto_provider_handle_t provider, uint_t *status) 3870Sstevel@tonic-gate { 3880Sstevel@tonic-gate *status = CRYPTO_PROVIDER_READY; 3890Sstevel@tonic-gate } 3900Sstevel@tonic-gate 3910Sstevel@tonic-gate /* 3920Sstevel@tonic-gate * Utility routine to look up a attribute of type, 'type', 3930Sstevel@tonic-gate * in the key. 3940Sstevel@tonic-gate */ 3950Sstevel@tonic-gate static int 3960Sstevel@tonic-gate get_key_attr(crypto_key_t *key, crypto_attr_type_t type, 3970Sstevel@tonic-gate uchar_t **value, ssize_t *value_len) 3980Sstevel@tonic-gate { 3990Sstevel@tonic-gate int i; 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST); 4020Sstevel@tonic-gate for (i = 0; i < key->ck_count; i++) { 4030Sstevel@tonic-gate if (key->ck_attrs[i].oa_type == type) { 4040Sstevel@tonic-gate *value = (uchar_t *)key->ck_attrs[i].oa_value; 4050Sstevel@tonic-gate *value_len = key->ck_attrs[i].oa_value_len; 4060Sstevel@tonic-gate return (CRYPTO_SUCCESS); 4070Sstevel@tonic-gate } 4080Sstevel@tonic-gate } 4090Sstevel@tonic-gate 4100Sstevel@tonic-gate return (CRYPTO_FAILED); 4110Sstevel@tonic-gate } 4120Sstevel@tonic-gate 4130Sstevel@tonic-gate static int 4140Sstevel@tonic-gate check_mech_and_key(crypto_mechanism_t *mechanism, crypto_key_t *key) 4150Sstevel@tonic-gate { 4160Sstevel@tonic-gate int rv = CRYPTO_FAILED; 4170Sstevel@tonic-gate 4180Sstevel@tonic-gate /* EXPORT DELETE START */ 4190Sstevel@tonic-gate 4200Sstevel@tonic-gate uchar_t *modulus; 4210Sstevel@tonic-gate ssize_t modulus_len; /* In bytes */ 4220Sstevel@tonic-gate 4230Sstevel@tonic-gate if (!RSA_VALID_MECH(mechanism)) 4240Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 4250Sstevel@tonic-gate 4260Sstevel@tonic-gate /* 4270Sstevel@tonic-gate * We only support RSA keys that are passed as a list of 4280Sstevel@tonic-gate * object attributes. 4290Sstevel@tonic-gate */ 4300Sstevel@tonic-gate if (key->ck_format != CRYPTO_KEY_ATTR_LIST) { 4310Sstevel@tonic-gate return (CRYPTO_KEY_TYPE_INCONSISTENT); 4320Sstevel@tonic-gate } 4330Sstevel@tonic-gate 4340Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 4350Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 4360Sstevel@tonic-gate return (rv); 4370Sstevel@tonic-gate } 4380Sstevel@tonic-gate if (modulus_len < MIN_RSA_KEYLENGTH_IN_BYTES || 4390Sstevel@tonic-gate modulus_len > MAX_RSA_KEYLENGTH_IN_BYTES) 4400Sstevel@tonic-gate return (CRYPTO_KEY_SIZE_RANGE); 4410Sstevel@tonic-gate 4420Sstevel@tonic-gate /* EXPORT DELETE END */ 4430Sstevel@tonic-gate 4440Sstevel@tonic-gate return (rv); 4450Sstevel@tonic-gate } 4460Sstevel@tonic-gate 4470Sstevel@tonic-gate void 4480Sstevel@tonic-gate kmemset(uint8_t *buf, char pattern, size_t len) 4490Sstevel@tonic-gate { 4500Sstevel@tonic-gate int i = 0; 4510Sstevel@tonic-gate 4520Sstevel@tonic-gate while (i < len) 4530Sstevel@tonic-gate buf[i++] = pattern; 4540Sstevel@tonic-gate } 4550Sstevel@tonic-gate 4560Sstevel@tonic-gate /* 4570Sstevel@tonic-gate * This function guarantees to return non-zero random numbers. 4580Sstevel@tonic-gate * This is needed as the /dev/urandom kernel interface, 4590Sstevel@tonic-gate * random_get_pseudo_bytes(), may return zeros. 4600Sstevel@tonic-gate */ 4610Sstevel@tonic-gate int 4620Sstevel@tonic-gate knzero_random_generator(uint8_t *ran_out, size_t ran_len) 4630Sstevel@tonic-gate { 4640Sstevel@tonic-gate int rv; 4650Sstevel@tonic-gate size_t ebc = 0; /* count of extra bytes in extrarand */ 4660Sstevel@tonic-gate size_t i = 0; 4670Sstevel@tonic-gate uint8_t extrarand[32]; 4680Sstevel@tonic-gate size_t extrarand_len; 4690Sstevel@tonic-gate 4700Sstevel@tonic-gate if ((rv = random_get_pseudo_bytes(ran_out, ran_len)) != 0) 4710Sstevel@tonic-gate return (rv); 4720Sstevel@tonic-gate 4730Sstevel@tonic-gate /* 4740Sstevel@tonic-gate * Walk through the returned random numbers pointed by ran_out, 4750Sstevel@tonic-gate * and look for any random number which is zero. 4760Sstevel@tonic-gate * If we find zero, call random_get_pseudo_bytes() to generate 4770Sstevel@tonic-gate * another 32 random numbers pool. Replace any zeros in ran_out[] 4780Sstevel@tonic-gate * from the random number in pool. 4790Sstevel@tonic-gate */ 4800Sstevel@tonic-gate while (i < ran_len) { 4810Sstevel@tonic-gate if (ran_out[i] != 0) { 4820Sstevel@tonic-gate i++; 4830Sstevel@tonic-gate continue; 4840Sstevel@tonic-gate } 4850Sstevel@tonic-gate 4860Sstevel@tonic-gate /* 4870Sstevel@tonic-gate * Note that it is 'while' so we are guaranteed a 4880Sstevel@tonic-gate * non-zero value on exit. 4890Sstevel@tonic-gate */ 4900Sstevel@tonic-gate if (ebc == 0) { 4910Sstevel@tonic-gate /* refresh extrarand */ 4920Sstevel@tonic-gate extrarand_len = sizeof (extrarand); 4930Sstevel@tonic-gate if ((rv = random_get_pseudo_bytes(extrarand, 4940Sstevel@tonic-gate extrarand_len)) != 0) { 4950Sstevel@tonic-gate return (rv); 4960Sstevel@tonic-gate } 4970Sstevel@tonic-gate 4980Sstevel@tonic-gate ebc = extrarand_len; 4990Sstevel@tonic-gate } 5000Sstevel@tonic-gate /* Replace zero with byte from extrarand. */ 5010Sstevel@tonic-gate -- ebc; 5020Sstevel@tonic-gate 5030Sstevel@tonic-gate /* 5040Sstevel@tonic-gate * The new random byte zero/non-zero will be checked in 5050Sstevel@tonic-gate * the next pass through the loop. 5060Sstevel@tonic-gate */ 5070Sstevel@tonic-gate ran_out[i] = extrarand[ebc]; 5080Sstevel@tonic-gate } 5090Sstevel@tonic-gate 5100Sstevel@tonic-gate return (CRYPTO_SUCCESS); 5110Sstevel@tonic-gate } 5120Sstevel@tonic-gate 5130Sstevel@tonic-gate typedef enum cmd_type { 5140Sstevel@tonic-gate COPY_FROM_DATA, 5150Sstevel@tonic-gate COPY_TO_DATA, 5160Sstevel@tonic-gate COMPARE_TO_DATA, 5170Sstevel@tonic-gate MD5_DIGEST_DATA, 518676Sizick SHA1_DIGEST_DATA, 519676Sizick SHA2_DIGEST_DATA 5200Sstevel@tonic-gate } cmd_type_t; 5210Sstevel@tonic-gate 5220Sstevel@tonic-gate /* 5230Sstevel@tonic-gate * Utility routine to apply the command, 'cmd', to the 5240Sstevel@tonic-gate * data in the uio structure. 5250Sstevel@tonic-gate */ 5260Sstevel@tonic-gate static int 5270Sstevel@tonic-gate process_uio_data(crypto_data_t *data, uchar_t *buf, int len, 5280Sstevel@tonic-gate cmd_type_t cmd, void *digest_ctx) 5290Sstevel@tonic-gate { 5300Sstevel@tonic-gate uio_t *uiop = data->cd_uio; 5310Sstevel@tonic-gate off_t offset = data->cd_offset; 5320Sstevel@tonic-gate size_t length = len; 5330Sstevel@tonic-gate uint_t vec_idx; 5340Sstevel@tonic-gate size_t cur_len; 5350Sstevel@tonic-gate uchar_t *datap; 5360Sstevel@tonic-gate 5370Sstevel@tonic-gate ASSERT(data->cd_format == CRYPTO_DATA_UIO); 5380Sstevel@tonic-gate if (uiop->uio_segflg != UIO_SYSSPACE) { 5390Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 5400Sstevel@tonic-gate } 5410Sstevel@tonic-gate 5420Sstevel@tonic-gate /* 5430Sstevel@tonic-gate * Jump to the first iovec containing data to be 5440Sstevel@tonic-gate * processed. 5450Sstevel@tonic-gate */ 5460Sstevel@tonic-gate for (vec_idx = 0; vec_idx < uiop->uio_iovcnt && 5470Sstevel@tonic-gate offset >= uiop->uio_iov[vec_idx].iov_len; 5485072Smcpowers offset -= uiop->uio_iov[vec_idx++].iov_len) 5495072Smcpowers ; 5500Sstevel@tonic-gate 5510Sstevel@tonic-gate if (vec_idx == uiop->uio_iovcnt) { 5520Sstevel@tonic-gate /* 5530Sstevel@tonic-gate * The caller specified an offset that is larger than 5540Sstevel@tonic-gate * the total size of the buffers it provided. 5550Sstevel@tonic-gate */ 5560Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 5570Sstevel@tonic-gate } 5580Sstevel@tonic-gate 5590Sstevel@tonic-gate while (vec_idx < uiop->uio_iovcnt && length > 0) { 5600Sstevel@tonic-gate cur_len = MIN(uiop->uio_iov[vec_idx].iov_len - 5610Sstevel@tonic-gate offset, length); 5620Sstevel@tonic-gate 5630Sstevel@tonic-gate datap = (uchar_t *)(uiop->uio_iov[vec_idx].iov_base + 5640Sstevel@tonic-gate offset); 5650Sstevel@tonic-gate switch (cmd) { 5660Sstevel@tonic-gate case COPY_FROM_DATA: 5670Sstevel@tonic-gate bcopy(datap, buf, cur_len); 5680Sstevel@tonic-gate buf += cur_len; 5690Sstevel@tonic-gate break; 5700Sstevel@tonic-gate case COPY_TO_DATA: 5710Sstevel@tonic-gate bcopy(buf, datap, cur_len); 5720Sstevel@tonic-gate buf += cur_len; 5730Sstevel@tonic-gate break; 5740Sstevel@tonic-gate case COMPARE_TO_DATA: 5750Sstevel@tonic-gate if (bcmp(datap, buf, cur_len)) 5760Sstevel@tonic-gate return (CRYPTO_SIGNATURE_INVALID); 5770Sstevel@tonic-gate buf += cur_len; 5780Sstevel@tonic-gate break; 5790Sstevel@tonic-gate case MD5_DIGEST_DATA: 5800Sstevel@tonic-gate MD5Update(digest_ctx, datap, cur_len); 5810Sstevel@tonic-gate break; 5820Sstevel@tonic-gate case SHA1_DIGEST_DATA: 5830Sstevel@tonic-gate SHA1Update(digest_ctx, datap, cur_len); 5840Sstevel@tonic-gate break; 585676Sizick case SHA2_DIGEST_DATA: 586676Sizick SHA2Update(digest_ctx, datap, cur_len); 587676Sizick break; 5880Sstevel@tonic-gate } 5890Sstevel@tonic-gate 5900Sstevel@tonic-gate length -= cur_len; 5910Sstevel@tonic-gate vec_idx++; 5920Sstevel@tonic-gate offset = 0; 5930Sstevel@tonic-gate } 5940Sstevel@tonic-gate 5950Sstevel@tonic-gate if (vec_idx == uiop->uio_iovcnt && length > 0) { 5960Sstevel@tonic-gate /* 5970Sstevel@tonic-gate * The end of the specified iovec's was reached but 5980Sstevel@tonic-gate * the length requested could not be processed. 5990Sstevel@tonic-gate */ 6000Sstevel@tonic-gate switch (cmd) { 6010Sstevel@tonic-gate case COPY_TO_DATA: 6020Sstevel@tonic-gate data->cd_length = len; 6030Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 6040Sstevel@tonic-gate default: 6050Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 6060Sstevel@tonic-gate } 6070Sstevel@tonic-gate } 6080Sstevel@tonic-gate 6090Sstevel@tonic-gate return (CRYPTO_SUCCESS); 6100Sstevel@tonic-gate } 6110Sstevel@tonic-gate 6120Sstevel@tonic-gate /* 6130Sstevel@tonic-gate * Utility routine to apply the command, 'cmd', to the 6140Sstevel@tonic-gate * data in the mblk structure. 6150Sstevel@tonic-gate */ 6160Sstevel@tonic-gate static int 6170Sstevel@tonic-gate process_mblk_data(crypto_data_t *data, uchar_t *buf, int len, 6180Sstevel@tonic-gate cmd_type_t cmd, void *digest_ctx) 6190Sstevel@tonic-gate { 6200Sstevel@tonic-gate off_t offset = data->cd_offset; 6210Sstevel@tonic-gate size_t length = len; 6220Sstevel@tonic-gate mblk_t *mp; 6230Sstevel@tonic-gate size_t cur_len; 6240Sstevel@tonic-gate uchar_t *datap; 6250Sstevel@tonic-gate 6260Sstevel@tonic-gate ASSERT(data->cd_format == CRYPTO_DATA_MBLK); 6270Sstevel@tonic-gate /* 6280Sstevel@tonic-gate * Jump to the first mblk_t containing data to be processed. 6290Sstevel@tonic-gate */ 6300Sstevel@tonic-gate for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp); 6315072Smcpowers offset -= MBLKL(mp), mp = mp->b_cont) 6325072Smcpowers ; 6330Sstevel@tonic-gate if (mp == NULL) { 6340Sstevel@tonic-gate /* 6350Sstevel@tonic-gate * The caller specified an offset that is larger 6360Sstevel@tonic-gate * than the total size of the buffers it provided. 6370Sstevel@tonic-gate */ 6380Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 6390Sstevel@tonic-gate } 6400Sstevel@tonic-gate 6410Sstevel@tonic-gate /* 6420Sstevel@tonic-gate * Now do the processing on the mblk chain. 6430Sstevel@tonic-gate */ 6440Sstevel@tonic-gate while (mp != NULL && length > 0) { 6450Sstevel@tonic-gate cur_len = MIN(MBLKL(mp) - offset, length); 6460Sstevel@tonic-gate 6470Sstevel@tonic-gate datap = (uchar_t *)(mp->b_rptr + offset); 6480Sstevel@tonic-gate switch (cmd) { 6490Sstevel@tonic-gate case COPY_FROM_DATA: 6500Sstevel@tonic-gate bcopy(datap, buf, cur_len); 6510Sstevel@tonic-gate buf += cur_len; 6520Sstevel@tonic-gate break; 6530Sstevel@tonic-gate case COPY_TO_DATA: 6540Sstevel@tonic-gate bcopy(buf, datap, cur_len); 6550Sstevel@tonic-gate buf += cur_len; 6560Sstevel@tonic-gate break; 6570Sstevel@tonic-gate case COMPARE_TO_DATA: 6580Sstevel@tonic-gate if (bcmp(datap, buf, cur_len)) 6590Sstevel@tonic-gate return (CRYPTO_SIGNATURE_INVALID); 6600Sstevel@tonic-gate buf += cur_len; 6610Sstevel@tonic-gate break; 6620Sstevel@tonic-gate case MD5_DIGEST_DATA: 6630Sstevel@tonic-gate MD5Update(digest_ctx, datap, cur_len); 6640Sstevel@tonic-gate break; 6650Sstevel@tonic-gate case SHA1_DIGEST_DATA: 6660Sstevel@tonic-gate SHA1Update(digest_ctx, datap, cur_len); 6670Sstevel@tonic-gate break; 668676Sizick case SHA2_DIGEST_DATA: 669676Sizick SHA2Update(digest_ctx, datap, cur_len); 670676Sizick break; 6710Sstevel@tonic-gate } 6720Sstevel@tonic-gate 6730Sstevel@tonic-gate length -= cur_len; 6740Sstevel@tonic-gate offset = 0; 6750Sstevel@tonic-gate mp = mp->b_cont; 6760Sstevel@tonic-gate } 6770Sstevel@tonic-gate 6780Sstevel@tonic-gate if (mp == NULL && length > 0) { 6790Sstevel@tonic-gate /* 6800Sstevel@tonic-gate * The end of the mblk was reached but the length 6810Sstevel@tonic-gate * requested could not be processed. 6820Sstevel@tonic-gate */ 6830Sstevel@tonic-gate switch (cmd) { 6840Sstevel@tonic-gate case COPY_TO_DATA: 6850Sstevel@tonic-gate data->cd_length = len; 6860Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 6870Sstevel@tonic-gate default: 6880Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 6890Sstevel@tonic-gate } 6900Sstevel@tonic-gate } 6910Sstevel@tonic-gate 6920Sstevel@tonic-gate return (CRYPTO_SUCCESS); 6930Sstevel@tonic-gate } 6940Sstevel@tonic-gate 6950Sstevel@tonic-gate static int 6960Sstevel@tonic-gate compare_data(crypto_data_t *data, uchar_t *buf) 6970Sstevel@tonic-gate { 6980Sstevel@tonic-gate int len; 6990Sstevel@tonic-gate uchar_t *dptr; 7000Sstevel@tonic-gate 7010Sstevel@tonic-gate len = data->cd_length; 7020Sstevel@tonic-gate switch (data->cd_format) { 7030Sstevel@tonic-gate case CRYPTO_DATA_RAW: 7040Sstevel@tonic-gate dptr = (uchar_t *)(data->cd_raw.iov_base + 7050Sstevel@tonic-gate data->cd_offset); 7060Sstevel@tonic-gate 7070Sstevel@tonic-gate return (bcmp(dptr, buf, len)); 7080Sstevel@tonic-gate 7090Sstevel@tonic-gate case CRYPTO_DATA_UIO: 7100Sstevel@tonic-gate return (process_uio_data(data, buf, len, 7110Sstevel@tonic-gate COMPARE_TO_DATA, NULL)); 7120Sstevel@tonic-gate 7130Sstevel@tonic-gate case CRYPTO_DATA_MBLK: 7140Sstevel@tonic-gate return (process_mblk_data(data, buf, len, 7150Sstevel@tonic-gate COMPARE_TO_DATA, NULL)); 7160Sstevel@tonic-gate } 7170Sstevel@tonic-gate 7180Sstevel@tonic-gate return (CRYPTO_FAILED); 7190Sstevel@tonic-gate } 7200Sstevel@tonic-gate 7210Sstevel@tonic-gate /* 7220Sstevel@tonic-gate * Utility routine to copy a buffer to a crypto_data structure. 7230Sstevel@tonic-gate */ 7240Sstevel@tonic-gate static int 7250Sstevel@tonic-gate put_output_data(uchar_t *buf, crypto_data_t *output, int len) 7260Sstevel@tonic-gate { 7270Sstevel@tonic-gate switch (output->cd_format) { 7280Sstevel@tonic-gate case CRYPTO_DATA_RAW: 7290Sstevel@tonic-gate if (output->cd_raw.iov_len < len) { 7300Sstevel@tonic-gate output->cd_length = len; 7310Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 7320Sstevel@tonic-gate } 7330Sstevel@tonic-gate bcopy(buf, (uchar_t *)(output->cd_raw.iov_base + 7340Sstevel@tonic-gate output->cd_offset), len); 7350Sstevel@tonic-gate break; 7360Sstevel@tonic-gate 7370Sstevel@tonic-gate case CRYPTO_DATA_UIO: 7380Sstevel@tonic-gate return (process_uio_data(output, buf, len, COPY_TO_DATA, NULL)); 7390Sstevel@tonic-gate 7400Sstevel@tonic-gate case CRYPTO_DATA_MBLK: 7410Sstevel@tonic-gate return (process_mblk_data(output, buf, len, 7420Sstevel@tonic-gate COPY_TO_DATA, NULL)); 7430Sstevel@tonic-gate 7440Sstevel@tonic-gate default: 7450Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 7460Sstevel@tonic-gate } 7470Sstevel@tonic-gate 7480Sstevel@tonic-gate return (CRYPTO_SUCCESS); 7490Sstevel@tonic-gate } 7500Sstevel@tonic-gate 7510Sstevel@tonic-gate /* 7520Sstevel@tonic-gate * Utility routine to get data from a crypto_data structure. 7530Sstevel@tonic-gate * 7540Sstevel@tonic-gate * '*dptr' contains a pointer to a buffer on return. 'buf' 7550Sstevel@tonic-gate * is allocated by the caller and is ignored for CRYPTO_DATA_RAW case. 7560Sstevel@tonic-gate */ 7570Sstevel@tonic-gate static int 7580Sstevel@tonic-gate get_input_data(crypto_data_t *input, uchar_t **dptr, uchar_t *buf) 7590Sstevel@tonic-gate { 7600Sstevel@tonic-gate int rv; 7610Sstevel@tonic-gate 7620Sstevel@tonic-gate switch (input->cd_format) { 7630Sstevel@tonic-gate case CRYPTO_DATA_RAW: 7640Sstevel@tonic-gate if (input->cd_raw.iov_len < input->cd_length) 7650Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 7660Sstevel@tonic-gate *dptr = (uchar_t *)(input->cd_raw.iov_base + 7670Sstevel@tonic-gate input->cd_offset); 7680Sstevel@tonic-gate break; 7690Sstevel@tonic-gate 7700Sstevel@tonic-gate case CRYPTO_DATA_UIO: 7710Sstevel@tonic-gate if ((rv = process_uio_data(input, buf, input->cd_length, 7720Sstevel@tonic-gate COPY_FROM_DATA, NULL)) != CRYPTO_SUCCESS) 7730Sstevel@tonic-gate return (rv); 7740Sstevel@tonic-gate *dptr = buf; 7750Sstevel@tonic-gate break; 7760Sstevel@tonic-gate 7770Sstevel@tonic-gate case CRYPTO_DATA_MBLK: 7780Sstevel@tonic-gate if ((rv = process_mblk_data(input, buf, input->cd_length, 7790Sstevel@tonic-gate COPY_FROM_DATA, NULL)) != CRYPTO_SUCCESS) 7800Sstevel@tonic-gate return (rv); 7810Sstevel@tonic-gate *dptr = buf; 7820Sstevel@tonic-gate break; 7830Sstevel@tonic-gate 7840Sstevel@tonic-gate default: 7850Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 7860Sstevel@tonic-gate } 7870Sstevel@tonic-gate 7880Sstevel@tonic-gate return (CRYPTO_SUCCESS); 7890Sstevel@tonic-gate } 7900Sstevel@tonic-gate 7910Sstevel@tonic-gate static int 7920Sstevel@tonic-gate copy_key_to_ctx(crypto_key_t *in_key, rsa_ctx_t *ctx, int kmflag) 7930Sstevel@tonic-gate { 7940Sstevel@tonic-gate int i, count; 7950Sstevel@tonic-gate size_t len; 7960Sstevel@tonic-gate caddr_t attr_val; 7970Sstevel@tonic-gate crypto_object_attribute_t *k_attrs = NULL; 7980Sstevel@tonic-gate 7990Sstevel@tonic-gate ASSERT(in_key->ck_format == CRYPTO_KEY_ATTR_LIST); 8000Sstevel@tonic-gate 8010Sstevel@tonic-gate count = in_key->ck_count; 8020Sstevel@tonic-gate /* figure out how much memory to allocate for everything */ 8030Sstevel@tonic-gate len = sizeof (crypto_key_t) + 8040Sstevel@tonic-gate count * sizeof (crypto_object_attribute_t); 8050Sstevel@tonic-gate for (i = 0; i < count; i++) { 8060Sstevel@tonic-gate len += roundup(in_key->ck_attrs[i].oa_value_len, 8070Sstevel@tonic-gate sizeof (caddr_t)); 8080Sstevel@tonic-gate } 8090Sstevel@tonic-gate 8100Sstevel@tonic-gate /* one big allocation for everything */ 8110Sstevel@tonic-gate ctx->key = kmem_alloc(len, kmflag); 8120Sstevel@tonic-gate if (ctx->key == NULL) 8130Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 8140Sstevel@tonic-gate k_attrs = (crypto_object_attribute_t *)((caddr_t)(ctx->key) + 8150Sstevel@tonic-gate sizeof (crypto_key_t)); 8160Sstevel@tonic-gate 8170Sstevel@tonic-gate attr_val = (caddr_t)k_attrs + 8180Sstevel@tonic-gate count * sizeof (crypto_object_attribute_t); 8190Sstevel@tonic-gate for (i = 0; i < count; i++) { 8200Sstevel@tonic-gate k_attrs[i].oa_type = in_key->ck_attrs[i].oa_type; 8210Sstevel@tonic-gate bcopy(in_key->ck_attrs[i].oa_value, attr_val, 8220Sstevel@tonic-gate in_key->ck_attrs[i].oa_value_len); 8230Sstevel@tonic-gate k_attrs[i].oa_value = attr_val; 8240Sstevel@tonic-gate k_attrs[i].oa_value_len = in_key->ck_attrs[i].oa_value_len; 8250Sstevel@tonic-gate attr_val += roundup(k_attrs[i].oa_value_len, sizeof (caddr_t)); 8260Sstevel@tonic-gate } 8270Sstevel@tonic-gate 8280Sstevel@tonic-gate ctx->keychunk_size = len; /* save the size to be freed */ 8290Sstevel@tonic-gate ctx->key->ck_format = CRYPTO_KEY_ATTR_LIST; 8300Sstevel@tonic-gate ctx->key->ck_count = count; 8310Sstevel@tonic-gate ctx->key->ck_attrs = k_attrs; 8320Sstevel@tonic-gate 8330Sstevel@tonic-gate return (CRYPTO_SUCCESS); 8340Sstevel@tonic-gate } 8350Sstevel@tonic-gate 8360Sstevel@tonic-gate /* ARGSUSED */ 8370Sstevel@tonic-gate static int 8380Sstevel@tonic-gate rsa_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 8390Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t template, 8400Sstevel@tonic-gate crypto_req_handle_t req) 8410Sstevel@tonic-gate { 8420Sstevel@tonic-gate int rv; 8430Sstevel@tonic-gate int kmflag; 8440Sstevel@tonic-gate rsa_ctx_t *ctxp; 8450Sstevel@tonic-gate 8460Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 8470Sstevel@tonic-gate return (rv); 8480Sstevel@tonic-gate 8490Sstevel@tonic-gate /* 8500Sstevel@tonic-gate * Allocate a RSA context. 8510Sstevel@tonic-gate */ 8520Sstevel@tonic-gate kmflag = crypto_kmflag(req); 8530Sstevel@tonic-gate if ((ctxp = kmem_zalloc(sizeof (rsa_ctx_t), kmflag)) == NULL) 8540Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 8550Sstevel@tonic-gate 8560Sstevel@tonic-gate if ((rv = copy_key_to_ctx(key, ctxp, kmflag)) != CRYPTO_SUCCESS) { 8570Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 8580Sstevel@tonic-gate return (rv); 8590Sstevel@tonic-gate } 8600Sstevel@tonic-gate ctxp->mech_type = mechanism->cm_type; 8610Sstevel@tonic-gate 8620Sstevel@tonic-gate ctx->cc_provider_private = ctxp; 8630Sstevel@tonic-gate 8640Sstevel@tonic-gate return (CRYPTO_SUCCESS); 8650Sstevel@tonic-gate } 8660Sstevel@tonic-gate 8670Sstevel@tonic-gate /* ARGSUSED */ 8680Sstevel@tonic-gate static int 8690Sstevel@tonic-gate rsa_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext, 8700Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_req_handle_t req) 8710Sstevel@tonic-gate { 8720Sstevel@tonic-gate int rv; 8730Sstevel@tonic-gate rsa_ctx_t *ctxp; 8740Sstevel@tonic-gate 8750Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 8760Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 8770Sstevel@tonic-gate 8780Sstevel@tonic-gate RSA_ARG_INPLACE(plaintext, ciphertext); 8790Sstevel@tonic-gate 8800Sstevel@tonic-gate /* 8810Sstevel@tonic-gate * Note on the KM_SLEEP flag passed to the routine below - 8820Sstevel@tonic-gate * rsa_encrypt() is a single-part encryption routine which is 8830Sstevel@tonic-gate * currently usable only by /dev/crypto. Since /dev/crypto calls are 8840Sstevel@tonic-gate * always synchronous, we can safely pass KM_SLEEP here. 8850Sstevel@tonic-gate */ 8860Sstevel@tonic-gate rv = rsa_encrypt_common(ctxp->mech_type, ctxp->key, plaintext, 8870Sstevel@tonic-gate ciphertext, KM_SLEEP); 8880Sstevel@tonic-gate 8890Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 8900Sstevel@tonic-gate (void) rsa_free_context(ctx); 8910Sstevel@tonic-gate 8920Sstevel@tonic-gate return (rv); 8930Sstevel@tonic-gate } 8940Sstevel@tonic-gate 8950Sstevel@tonic-gate /* ARGSUSED */ 8960Sstevel@tonic-gate static int 8970Sstevel@tonic-gate rsa_encrypt_atomic(crypto_provider_handle_t provider, 8980Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 8990Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext, 9000Sstevel@tonic-gate crypto_spi_ctx_template_t template, crypto_req_handle_t req) 9010Sstevel@tonic-gate { 9020Sstevel@tonic-gate int rv; 9030Sstevel@tonic-gate 9040Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 9050Sstevel@tonic-gate return (rv); 9060Sstevel@tonic-gate RSA_ARG_INPLACE(plaintext, ciphertext); 9070Sstevel@tonic-gate 9080Sstevel@tonic-gate return (rsa_encrypt_common(mechanism->cm_type, key, plaintext, 9090Sstevel@tonic-gate ciphertext, crypto_kmflag(req))); 9100Sstevel@tonic-gate } 9110Sstevel@tonic-gate 9120Sstevel@tonic-gate static int 9130Sstevel@tonic-gate rsa_free_context(crypto_ctx_t *ctx) 9140Sstevel@tonic-gate { 9150Sstevel@tonic-gate rsa_ctx_t *ctxp = ctx->cc_provider_private; 9160Sstevel@tonic-gate 9170Sstevel@tonic-gate if (ctxp != NULL) { 9180Sstevel@tonic-gate bzero(ctxp->key, ctxp->keychunk_size); 9190Sstevel@tonic-gate kmem_free(ctxp->key, ctxp->keychunk_size); 9200Sstevel@tonic-gate 9210Sstevel@tonic-gate if (ctxp->mech_type == RSA_PKCS_MECH_INFO_TYPE || 9220Sstevel@tonic-gate ctxp->mech_type == RSA_X_509_MECH_INFO_TYPE) 9230Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 9240Sstevel@tonic-gate else 9250Sstevel@tonic-gate kmem_free(ctxp, sizeof (digest_rsa_ctx_t)); 9260Sstevel@tonic-gate 9270Sstevel@tonic-gate ctx->cc_provider_private = NULL; 9280Sstevel@tonic-gate } 9290Sstevel@tonic-gate 9300Sstevel@tonic-gate return (CRYPTO_SUCCESS); 9310Sstevel@tonic-gate } 9320Sstevel@tonic-gate 9330Sstevel@tonic-gate static int 9340Sstevel@tonic-gate rsa_encrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key, 9350Sstevel@tonic-gate crypto_data_t *plaintext, crypto_data_t *ciphertext, int kmflag) 9360Sstevel@tonic-gate { 9370Sstevel@tonic-gate int rv = CRYPTO_FAILED; 9380Sstevel@tonic-gate 9390Sstevel@tonic-gate /* EXPORT DELETE START */ 9400Sstevel@tonic-gate 9410Sstevel@tonic-gate int plen; 9420Sstevel@tonic-gate uchar_t *ptptr; 9430Sstevel@tonic-gate uchar_t *modulus; 9440Sstevel@tonic-gate ssize_t modulus_len; 9450Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 9460Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 9470Sstevel@tonic-gate uchar_t cipher_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 9480Sstevel@tonic-gate 9490Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 9500Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 9510Sstevel@tonic-gate return (rv); 9520Sstevel@tonic-gate } 9530Sstevel@tonic-gate 9540Sstevel@tonic-gate plen = plaintext->cd_length; 9550Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 9560Sstevel@tonic-gate if (plen > (modulus_len - MIN_PKCS1_PADLEN)) 9570Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 9580Sstevel@tonic-gate } else { 9590Sstevel@tonic-gate if (plen > modulus_len) 9600Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 9610Sstevel@tonic-gate } 9620Sstevel@tonic-gate 9630Sstevel@tonic-gate /* 9640Sstevel@tonic-gate * Output buf len must not be less than RSA modulus size. 9650Sstevel@tonic-gate */ 9660Sstevel@tonic-gate if (ciphertext->cd_length < modulus_len) { 9670Sstevel@tonic-gate ciphertext->cd_length = modulus_len; 9680Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 9690Sstevel@tonic-gate } 9700Sstevel@tonic-gate 9710Sstevel@tonic-gate ASSERT(plaintext->cd_length <= sizeof (tmp_data)); 9720Sstevel@tonic-gate if ((rv = get_input_data(plaintext, &ptptr, tmp_data)) 9730Sstevel@tonic-gate != CRYPTO_SUCCESS) 9740Sstevel@tonic-gate return (rv); 9750Sstevel@tonic-gate 9760Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 9770Sstevel@tonic-gate rv = soft_encrypt_rsa_pkcs_encode(ptptr, plen, 9780Sstevel@tonic-gate plain_data, modulus_len); 9790Sstevel@tonic-gate 9800Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 9810Sstevel@tonic-gate return (rv); 9820Sstevel@tonic-gate } else { 9830Sstevel@tonic-gate bzero(plain_data, modulus_len - plen); 9840Sstevel@tonic-gate bcopy(ptptr, &plain_data[modulus_len - plen], plen); 9850Sstevel@tonic-gate } 9860Sstevel@tonic-gate 9870Sstevel@tonic-gate rv = core_rsa_encrypt(key, plain_data, modulus_len, 9880Sstevel@tonic-gate cipher_data, kmflag, 1); 9890Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 9900Sstevel@tonic-gate /* copy out to ciphertext */ 9910Sstevel@tonic-gate if ((rv = put_output_data(cipher_data, 9920Sstevel@tonic-gate ciphertext, modulus_len)) != CRYPTO_SUCCESS) 9930Sstevel@tonic-gate return (rv); 9940Sstevel@tonic-gate 9950Sstevel@tonic-gate ciphertext->cd_length = modulus_len; 9960Sstevel@tonic-gate } 9970Sstevel@tonic-gate 9980Sstevel@tonic-gate /* EXPORT DELETE END */ 9990Sstevel@tonic-gate 10000Sstevel@tonic-gate return (rv); 10010Sstevel@tonic-gate } 10020Sstevel@tonic-gate 10030Sstevel@tonic-gate /* EXPORT DELETE START */ 10040Sstevel@tonic-gate 10050Sstevel@tonic-gate static int 10060Sstevel@tonic-gate core_rsa_encrypt(crypto_key_t *key, uchar_t *in, 10070Sstevel@tonic-gate int in_len, uchar_t *out, int kmflag, int is_public) 10080Sstevel@tonic-gate { 10090Sstevel@tonic-gate int rv; 10100Sstevel@tonic-gate uchar_t *expo, *modulus; 10110Sstevel@tonic-gate ssize_t expo_len; 10120Sstevel@tonic-gate ssize_t modulus_len; 10130Sstevel@tonic-gate BIGNUM msg; 10140Sstevel@tonic-gate RSAkey *rsakey; 10150Sstevel@tonic-gate 10160Sstevel@tonic-gate if (is_public) { 10170Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_PUBLIC_EXPONENT, &expo, 10180Sstevel@tonic-gate &expo_len)) != CRYPTO_SUCCESS) 10190Sstevel@tonic-gate return (rv); 10200Sstevel@tonic-gate } else { 10210Sstevel@tonic-gate /* 10220Sstevel@tonic-gate * SUN_CKA_PRIVATE_EXPONENT is a required attribute for a 10230Sstevel@tonic-gate * RSA secret key. See the comments in core_rsa_decrypt 10240Sstevel@tonic-gate * routine which calls this routine with a private key. 10250Sstevel@tonic-gate */ 10260Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_PRIVATE_EXPONENT, &expo, 10270Sstevel@tonic-gate &expo_len)) != CRYPTO_SUCCESS) 10280Sstevel@tonic-gate return (rv); 10290Sstevel@tonic-gate } 10300Sstevel@tonic-gate 10310Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 10320Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 10330Sstevel@tonic-gate return (rv); 10340Sstevel@tonic-gate } 10350Sstevel@tonic-gate 10360Sstevel@tonic-gate rsakey = kmem_alloc(sizeof (RSAkey), kmflag); 10370Sstevel@tonic-gate if (rsakey == NULL) 10380Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 10390Sstevel@tonic-gate 10400Sstevel@tonic-gate /* psize and qsize for RSA_key_init is in bits. */ 10410Sstevel@tonic-gate if (RSA_key_init(rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) { 10420Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 10430Sstevel@tonic-gate goto clean1; 10440Sstevel@tonic-gate } 10450Sstevel@tonic-gate 1046*6557Sfr41279 /* Size for big_init is in BIG_CHUNK_TYPE words. */ 1047*6557Sfr41279 if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) { 10480Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 10490Sstevel@tonic-gate goto clean2; 10500Sstevel@tonic-gate } 10510Sstevel@tonic-gate 10520Sstevel@tonic-gate /* Convert octet string exponent to big integer format. */ 10530Sstevel@tonic-gate bytestring2bignum(&(rsakey->e), expo, expo_len); 10540Sstevel@tonic-gate 10550Sstevel@tonic-gate /* Convert octet string modulus to big integer format. */ 10560Sstevel@tonic-gate bytestring2bignum(&(rsakey->n), modulus, modulus_len); 10570Sstevel@tonic-gate 10580Sstevel@tonic-gate /* Convert octet string input data to big integer format. */ 10590Sstevel@tonic-gate bytestring2bignum(&msg, in, in_len); 10600Sstevel@tonic-gate 10610Sstevel@tonic-gate if (big_cmp_abs(&msg, &(rsakey->n)) > 0) { 10620Sstevel@tonic-gate rv = CRYPTO_DATA_LEN_RANGE; 10630Sstevel@tonic-gate goto clean3; 10640Sstevel@tonic-gate } 10650Sstevel@tonic-gate 10660Sstevel@tonic-gate /* Perform RSA computation on big integer input data. */ 10670Sstevel@tonic-gate if (big_modexp(&msg, &msg, &(rsakey->e), &(rsakey->n), NULL) 10680Sstevel@tonic-gate != BIG_OK) { 10690Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 10700Sstevel@tonic-gate goto clean3; 10710Sstevel@tonic-gate } 10720Sstevel@tonic-gate 10730Sstevel@tonic-gate /* Convert the big integer output data to octet string. */ 10740Sstevel@tonic-gate bignum2bytestring(out, &msg, modulus_len); 10750Sstevel@tonic-gate 10760Sstevel@tonic-gate /* 10770Sstevel@tonic-gate * Should not free modulus and expo as both are just pointers 10780Sstevel@tonic-gate * to an attribute value buffer from the caller. 10790Sstevel@tonic-gate */ 10800Sstevel@tonic-gate clean3: 10810Sstevel@tonic-gate big_finish(&msg); 10820Sstevel@tonic-gate clean2: 10830Sstevel@tonic-gate RSA_key_finish(rsakey); 10840Sstevel@tonic-gate clean1: 10850Sstevel@tonic-gate kmem_free(rsakey, sizeof (RSAkey)); 10860Sstevel@tonic-gate 10870Sstevel@tonic-gate return (rv); 10880Sstevel@tonic-gate } 10890Sstevel@tonic-gate 10900Sstevel@tonic-gate /* EXPORT DELETE END */ 10910Sstevel@tonic-gate 10920Sstevel@tonic-gate /* ARGSUSED */ 10930Sstevel@tonic-gate static int 10940Sstevel@tonic-gate rsa_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext, 10950Sstevel@tonic-gate crypto_data_t *plaintext, crypto_req_handle_t req) 10960Sstevel@tonic-gate { 10970Sstevel@tonic-gate int rv; 10980Sstevel@tonic-gate rsa_ctx_t *ctxp; 10990Sstevel@tonic-gate 11000Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 11010Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 11020Sstevel@tonic-gate 11030Sstevel@tonic-gate RSA_ARG_INPLACE(ciphertext, plaintext); 11040Sstevel@tonic-gate 11050Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 11060Sstevel@tonic-gate rv = rsa_decrypt_common(ctxp->mech_type, ctxp->key, 11070Sstevel@tonic-gate ciphertext, plaintext, KM_SLEEP); 11080Sstevel@tonic-gate 11090Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 11100Sstevel@tonic-gate (void) rsa_free_context(ctx); 11110Sstevel@tonic-gate 11120Sstevel@tonic-gate return (rv); 11130Sstevel@tonic-gate } 11140Sstevel@tonic-gate 11150Sstevel@tonic-gate /* ARGSUSED */ 11160Sstevel@tonic-gate static int 11170Sstevel@tonic-gate rsa_decrypt_atomic(crypto_provider_handle_t provider, 11180Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 11190Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext, 11200Sstevel@tonic-gate crypto_spi_ctx_template_t template, crypto_req_handle_t req) 11210Sstevel@tonic-gate { 11220Sstevel@tonic-gate int rv; 11230Sstevel@tonic-gate 11240Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 11250Sstevel@tonic-gate return (rv); 11260Sstevel@tonic-gate RSA_ARG_INPLACE(ciphertext, plaintext); 11270Sstevel@tonic-gate 11280Sstevel@tonic-gate return (rsa_decrypt_common(mechanism->cm_type, key, ciphertext, 11290Sstevel@tonic-gate plaintext, crypto_kmflag(req))); 11300Sstevel@tonic-gate } 11310Sstevel@tonic-gate 11320Sstevel@tonic-gate static int 11330Sstevel@tonic-gate rsa_decrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key, 11340Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_data_t *plaintext, int kmflag) 11350Sstevel@tonic-gate { 11360Sstevel@tonic-gate int rv = CRYPTO_FAILED; 11370Sstevel@tonic-gate 11380Sstevel@tonic-gate /* EXPORT DELETE START */ 11390Sstevel@tonic-gate 11400Sstevel@tonic-gate int plain_len; 11410Sstevel@tonic-gate uchar_t *ctptr; 11420Sstevel@tonic-gate uchar_t *modulus; 11430Sstevel@tonic-gate ssize_t modulus_len; 11440Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 11450Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 11460Sstevel@tonic-gate 11470Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 11480Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 11490Sstevel@tonic-gate return (rv); 11500Sstevel@tonic-gate } 11510Sstevel@tonic-gate 11520Sstevel@tonic-gate /* 11530Sstevel@tonic-gate * Ciphertext length must be equal to RSA modulus size. 11540Sstevel@tonic-gate */ 11550Sstevel@tonic-gate if (ciphertext->cd_length != modulus_len) 11560Sstevel@tonic-gate return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 11570Sstevel@tonic-gate 11580Sstevel@tonic-gate ASSERT(ciphertext->cd_length <= sizeof (tmp_data)); 11590Sstevel@tonic-gate if ((rv = get_input_data(ciphertext, &ctptr, tmp_data)) 11600Sstevel@tonic-gate != CRYPTO_SUCCESS) 11610Sstevel@tonic-gate return (rv); 11620Sstevel@tonic-gate 11630Sstevel@tonic-gate rv = core_rsa_decrypt(key, ctptr, modulus_len, plain_data, kmflag); 11640Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 11650Sstevel@tonic-gate plain_len = modulus_len; 11660Sstevel@tonic-gate 11670Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 11680Sstevel@tonic-gate /* Strip off the PKCS block formatting data. */ 11690Sstevel@tonic-gate rv = soft_decrypt_rsa_pkcs_decode(plain_data, 11700Sstevel@tonic-gate &plain_len); 11710Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 11720Sstevel@tonic-gate return (rv); 11730Sstevel@tonic-gate } 11740Sstevel@tonic-gate 11750Sstevel@tonic-gate if (plain_len > plaintext->cd_length) { 11760Sstevel@tonic-gate plaintext->cd_length = plain_len; 11770Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 11780Sstevel@tonic-gate } 11790Sstevel@tonic-gate 11800Sstevel@tonic-gate if ((rv = put_output_data(plain_data + modulus_len - plain_len, 11810Sstevel@tonic-gate plaintext, plain_len)) != CRYPTO_SUCCESS) 11820Sstevel@tonic-gate return (rv); 11830Sstevel@tonic-gate 11840Sstevel@tonic-gate plaintext->cd_length = plain_len; 11850Sstevel@tonic-gate } 11860Sstevel@tonic-gate 11870Sstevel@tonic-gate /* EXPORT DELETE END */ 11880Sstevel@tonic-gate 11890Sstevel@tonic-gate return (rv); 11900Sstevel@tonic-gate } 11910Sstevel@tonic-gate 11920Sstevel@tonic-gate /* EXPORT DELETE START */ 11930Sstevel@tonic-gate 11940Sstevel@tonic-gate static int 11950Sstevel@tonic-gate core_rsa_decrypt(crypto_key_t *key, uchar_t *in, int in_len, 11960Sstevel@tonic-gate uchar_t *out, int kmflag) 11970Sstevel@tonic-gate { 11980Sstevel@tonic-gate int rv; 11990Sstevel@tonic-gate uchar_t *modulus, *prime1, *prime2, *expo1, *expo2, *coef; 12000Sstevel@tonic-gate ssize_t modulus_len; 12010Sstevel@tonic-gate ssize_t prime1_len, prime2_len; 12020Sstevel@tonic-gate ssize_t expo1_len, expo2_len, coef_len; 12030Sstevel@tonic-gate BIGNUM msg; 12040Sstevel@tonic-gate RSAkey *rsakey; 12050Sstevel@tonic-gate 12060Sstevel@tonic-gate if ((rv = 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 /* 12120Sstevel@tonic-gate * The following attributes are not required to be 12130Sstevel@tonic-gate * present in a RSA secret key. If any of them is not present 12140Sstevel@tonic-gate * we call the encrypt routine with a flag indicating use of 12150Sstevel@tonic-gate * private exponent (d). Note that SUN_CKA_PRIVATE_EXPONENT is 12160Sstevel@tonic-gate * a required attribute for a RSA secret key. 12170Sstevel@tonic-gate */ 12180Sstevel@tonic-gate if ((get_key_attr(key, SUN_CKA_PRIME_1, &prime1, &prime1_len) 12195072Smcpowers != CRYPTO_SUCCESS) || 12200Sstevel@tonic-gate (get_key_attr(key, SUN_CKA_PRIME_2, &prime2, &prime2_len) 12215072Smcpowers != CRYPTO_SUCCESS) || 12220Sstevel@tonic-gate (get_key_attr(key, SUN_CKA_EXPONENT_1, &expo1, &expo1_len) 12235072Smcpowers != CRYPTO_SUCCESS) || 12240Sstevel@tonic-gate (get_key_attr(key, SUN_CKA_EXPONENT_2, &expo2, &expo2_len) 12255072Smcpowers != CRYPTO_SUCCESS) || 12260Sstevel@tonic-gate (get_key_attr(key, SUN_CKA_COEFFICIENT, &coef, &coef_len) 12275072Smcpowers != CRYPTO_SUCCESS)) { 12280Sstevel@tonic-gate return (core_rsa_encrypt(key, in, in_len, out, kmflag, 0)); 12290Sstevel@tonic-gate } 12300Sstevel@tonic-gate 12310Sstevel@tonic-gate rsakey = kmem_alloc(sizeof (RSAkey), kmflag); 12320Sstevel@tonic-gate if (rsakey == NULL) 12330Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 12340Sstevel@tonic-gate 12350Sstevel@tonic-gate /* psize and qsize for RSA_key_init is in bits. */ 12360Sstevel@tonic-gate if (RSA_key_init(rsakey, prime2_len * 8, prime1_len * 8) != BIG_OK) { 12370Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 12380Sstevel@tonic-gate goto clean1; 12390Sstevel@tonic-gate } 12400Sstevel@tonic-gate 1241*6557Sfr41279 /* Size for big_init is in BIG_CHUNK_TYPE words. */ 1242*6557Sfr41279 if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) { 12430Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 12440Sstevel@tonic-gate goto clean2; 12450Sstevel@tonic-gate } 12460Sstevel@tonic-gate 12470Sstevel@tonic-gate /* Convert octet string input data to big integer format. */ 12480Sstevel@tonic-gate bytestring2bignum(&msg, in, in_len); 12490Sstevel@tonic-gate 12500Sstevel@tonic-gate /* Convert octet string modulus to big integer format. */ 12510Sstevel@tonic-gate bytestring2bignum(&(rsakey->n), modulus, modulus_len); 12520Sstevel@tonic-gate 12530Sstevel@tonic-gate if (big_cmp_abs(&msg, &(rsakey->n)) > 0) { 12540Sstevel@tonic-gate rv = CRYPTO_DATA_LEN_RANGE; 12550Sstevel@tonic-gate goto clean3; 12560Sstevel@tonic-gate } 12570Sstevel@tonic-gate 12580Sstevel@tonic-gate /* Convert the rest of private key attributes to big integer format. */ 12590Sstevel@tonic-gate bytestring2bignum(&(rsakey->dmodpminus1), expo2, expo2_len); 12600Sstevel@tonic-gate bytestring2bignum(&(rsakey->dmodqminus1), expo1, expo1_len); 12610Sstevel@tonic-gate bytestring2bignum(&(rsakey->p), prime2, prime2_len); 12620Sstevel@tonic-gate bytestring2bignum(&(rsakey->q), prime1, prime1_len); 12630Sstevel@tonic-gate bytestring2bignum(&(rsakey->pinvmodq), coef, coef_len); 12640Sstevel@tonic-gate 12650Sstevel@tonic-gate if ((big_cmp_abs(&(rsakey->dmodpminus1), &(rsakey->p)) > 0) || 12660Sstevel@tonic-gate (big_cmp_abs(&(rsakey->dmodqminus1), &(rsakey->q)) > 0) || 12670Sstevel@tonic-gate (big_cmp_abs(&(rsakey->pinvmodq), &(rsakey->q)) > 0)) { 12680Sstevel@tonic-gate rv = CRYPTO_KEY_SIZE_RANGE; 12690Sstevel@tonic-gate goto clean3; 12700Sstevel@tonic-gate } 12710Sstevel@tonic-gate 12720Sstevel@tonic-gate /* Perform RSA computation on big integer input data. */ 12730Sstevel@tonic-gate if (big_modexp_crt(&msg, &msg, &(rsakey->dmodpminus1), 12740Sstevel@tonic-gate &(rsakey->dmodqminus1), &(rsakey->p), &(rsakey->q), 12750Sstevel@tonic-gate &(rsakey->pinvmodq), NULL, NULL) != BIG_OK) { 12760Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 12770Sstevel@tonic-gate goto clean3; 12780Sstevel@tonic-gate } 12790Sstevel@tonic-gate 12800Sstevel@tonic-gate /* Convert the big integer output data to octet string. */ 12810Sstevel@tonic-gate bignum2bytestring(out, &msg, modulus_len); 12820Sstevel@tonic-gate 12830Sstevel@tonic-gate /* 12840Sstevel@tonic-gate * Should not free modulus and friends as they are just pointers 12850Sstevel@tonic-gate * to an attribute value buffer from the caller. 12860Sstevel@tonic-gate */ 12870Sstevel@tonic-gate clean3: 12880Sstevel@tonic-gate big_finish(&msg); 12890Sstevel@tonic-gate clean2: 12900Sstevel@tonic-gate RSA_key_finish(rsakey); 12910Sstevel@tonic-gate clean1: 12920Sstevel@tonic-gate kmem_free(rsakey, sizeof (RSAkey)); 12930Sstevel@tonic-gate 12940Sstevel@tonic-gate return (rv); 12950Sstevel@tonic-gate } 12960Sstevel@tonic-gate 12970Sstevel@tonic-gate /* EXPORT DELETE END */ 12980Sstevel@tonic-gate 12990Sstevel@tonic-gate /* ARGSUSED */ 13000Sstevel@tonic-gate static int 13010Sstevel@tonic-gate rsa_sign_verify_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 13020Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 13030Sstevel@tonic-gate crypto_req_handle_t req) 13040Sstevel@tonic-gate { 13050Sstevel@tonic-gate int rv; 13060Sstevel@tonic-gate int kmflag; 13070Sstevel@tonic-gate rsa_ctx_t *ctxp; 13080Sstevel@tonic-gate digest_rsa_ctx_t *dctxp; 13090Sstevel@tonic-gate 13100Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 13110Sstevel@tonic-gate return (rv); 13120Sstevel@tonic-gate 13130Sstevel@tonic-gate /* 13140Sstevel@tonic-gate * Allocate a RSA context. 13150Sstevel@tonic-gate */ 13160Sstevel@tonic-gate kmflag = crypto_kmflag(req); 13170Sstevel@tonic-gate switch (mechanism->cm_type) { 13180Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 13190Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1320676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1321676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1322676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 13230Sstevel@tonic-gate dctxp = kmem_zalloc(sizeof (digest_rsa_ctx_t), kmflag); 13240Sstevel@tonic-gate ctxp = (rsa_ctx_t *)dctxp; 13250Sstevel@tonic-gate break; 13260Sstevel@tonic-gate default: 13270Sstevel@tonic-gate ctxp = kmem_zalloc(sizeof (rsa_ctx_t), kmflag); 13280Sstevel@tonic-gate break; 13290Sstevel@tonic-gate } 13300Sstevel@tonic-gate 13310Sstevel@tonic-gate if (ctxp == NULL) 13320Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 13330Sstevel@tonic-gate 13340Sstevel@tonic-gate ctxp->mech_type = mechanism->cm_type; 13350Sstevel@tonic-gate if ((rv = copy_key_to_ctx(key, ctxp, kmflag)) != CRYPTO_SUCCESS) { 13360Sstevel@tonic-gate switch (mechanism->cm_type) { 13370Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 13380Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1339676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1340676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1341676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 13420Sstevel@tonic-gate kmem_free(dctxp, sizeof (digest_rsa_ctx_t)); 13430Sstevel@tonic-gate break; 13440Sstevel@tonic-gate default: 13450Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 13460Sstevel@tonic-gate break; 13470Sstevel@tonic-gate } 13480Sstevel@tonic-gate return (rv); 13490Sstevel@tonic-gate } 13500Sstevel@tonic-gate 13510Sstevel@tonic-gate switch (mechanism->cm_type) { 13520Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 13530Sstevel@tonic-gate MD5Init(&(dctxp->md5_ctx)); 13540Sstevel@tonic-gate break; 13550Sstevel@tonic-gate 13560Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 13570Sstevel@tonic-gate SHA1Init(&(dctxp->sha1_ctx)); 13580Sstevel@tonic-gate break; 1359676Sizick 1360676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1361676Sizick SHA2Init(SHA256, &(dctxp->sha2_ctx)); 1362676Sizick break; 1363676Sizick 1364676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1365676Sizick SHA2Init(SHA384, &(dctxp->sha2_ctx)); 1366676Sizick break; 1367676Sizick 1368676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1369676Sizick SHA2Init(SHA512, &(dctxp->sha2_ctx)); 1370676Sizick break; 13710Sstevel@tonic-gate } 13720Sstevel@tonic-gate 13730Sstevel@tonic-gate ctx->cc_provider_private = ctxp; 13740Sstevel@tonic-gate 13750Sstevel@tonic-gate return (CRYPTO_SUCCESS); 13760Sstevel@tonic-gate } 13770Sstevel@tonic-gate 13780Sstevel@tonic-gate #define SHA1_DIGEST_SIZE 20 13790Sstevel@tonic-gate #define MD5_DIGEST_SIZE 16 13800Sstevel@tonic-gate 13810Sstevel@tonic-gate #define INIT_RAW_CRYPTO_DATA(data, base, len, cd_len) \ 13820Sstevel@tonic-gate (data).cd_format = CRYPTO_DATA_RAW; \ 13830Sstevel@tonic-gate (data).cd_offset = 0; \ 13840Sstevel@tonic-gate (data).cd_raw.iov_base = (char *)base; \ 13850Sstevel@tonic-gate (data).cd_raw.iov_len = len; \ 13860Sstevel@tonic-gate (data).cd_length = cd_len; 13870Sstevel@tonic-gate 13880Sstevel@tonic-gate #define DO_UPDATE 0x01 13890Sstevel@tonic-gate #define DO_FINAL 0x02 13900Sstevel@tonic-gate #define DO_MD5 0x04 13910Sstevel@tonic-gate #define DO_SHA1 0x08 13920Sstevel@tonic-gate #define DO_SIGN 0x10 13930Sstevel@tonic-gate #define DO_VERIFY 0x20 1394676Sizick #define DO_SHA2 0x40 13950Sstevel@tonic-gate 13960Sstevel@tonic-gate static int 13970Sstevel@tonic-gate digest_data(crypto_data_t *data, void *dctx, uchar_t *digest, 13980Sstevel@tonic-gate uchar_t flag) 13990Sstevel@tonic-gate { 14000Sstevel@tonic-gate int rv, dlen; 14010Sstevel@tonic-gate uchar_t *dptr; 14020Sstevel@tonic-gate 1403676Sizick ASSERT(flag & DO_MD5 || flag & DO_SHA1 || flag & DO_SHA2); 14040Sstevel@tonic-gate if (data == NULL) { 14050Sstevel@tonic-gate ASSERT((flag & DO_UPDATE) == 0); 14060Sstevel@tonic-gate goto dofinal; 14070Sstevel@tonic-gate } 14080Sstevel@tonic-gate 14090Sstevel@tonic-gate dlen = data->cd_length; 14100Sstevel@tonic-gate 1411676Sizick if (flag & DO_UPDATE) { 1412676Sizick 1413676Sizick switch (data->cd_format) { 1414676Sizick case CRYPTO_DATA_RAW: 1415676Sizick dptr = (uchar_t *)(data->cd_raw.iov_base + 1416676Sizick data->cd_offset); 14170Sstevel@tonic-gate 1418676Sizick if (flag & DO_MD5) 14190Sstevel@tonic-gate MD5Update(dctx, dptr, dlen); 1420676Sizick 1421676Sizick else if (flag & DO_SHA1) 14220Sstevel@tonic-gate SHA1Update(dctx, dptr, dlen); 1423676Sizick 1424676Sizick else 1425676Sizick SHA2Update(dctx, dptr, dlen); 1426676Sizick 14270Sstevel@tonic-gate break; 14280Sstevel@tonic-gate 1429676Sizick case CRYPTO_DATA_UIO: 1430676Sizick if (flag & DO_MD5) 1431676Sizick rv = process_uio_data(data, NULL, dlen, 1432676Sizick MD5_DIGEST_DATA, dctx); 1433676Sizick 1434676Sizick else if (flag & DO_SHA1) 1435676Sizick rv = process_uio_data(data, NULL, dlen, 1436676Sizick SHA1_DIGEST_DATA, dctx); 1437676Sizick 1438676Sizick else 1439676Sizick rv = process_uio_data(data, NULL, dlen, 1440676Sizick SHA2_DIGEST_DATA, dctx); 1441676Sizick 14420Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 14430Sstevel@tonic-gate return (rv); 1444676Sizick 1445676Sizick break; 1446676Sizick 1447676Sizick case CRYPTO_DATA_MBLK: 1448676Sizick if (flag & DO_MD5) 1449676Sizick rv = process_mblk_data(data, NULL, dlen, 1450676Sizick MD5_DIGEST_DATA, dctx); 14510Sstevel@tonic-gate 1452676Sizick else if (flag & DO_SHA1) 1453676Sizick rv = process_mblk_data(data, NULL, dlen, 1454676Sizick SHA1_DIGEST_DATA, dctx); 1455676Sizick 1456676Sizick else 1457676Sizick rv = process_mblk_data(data, NULL, dlen, 1458676Sizick SHA2_DIGEST_DATA, dctx); 1459676Sizick 14600Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 14610Sstevel@tonic-gate return (rv); 1462676Sizick 1463676Sizick break; 14640Sstevel@tonic-gate } 14650Sstevel@tonic-gate } 14660Sstevel@tonic-gate 14670Sstevel@tonic-gate dofinal: 14680Sstevel@tonic-gate if (flag & DO_FINAL) { 14690Sstevel@tonic-gate if (flag & DO_MD5) 14700Sstevel@tonic-gate MD5Final(digest, dctx); 1471676Sizick 1472676Sizick else if (flag & DO_SHA1) 1473676Sizick SHA1Final(digest, dctx); 1474676Sizick 14750Sstevel@tonic-gate else 1476676Sizick SHA2Final(digest, dctx); 14770Sstevel@tonic-gate } 14780Sstevel@tonic-gate 14790Sstevel@tonic-gate return (CRYPTO_SUCCESS); 14800Sstevel@tonic-gate } 14810Sstevel@tonic-gate 14820Sstevel@tonic-gate static int 14830Sstevel@tonic-gate rsa_digest_svrfy_common(digest_rsa_ctx_t *ctxp, crypto_data_t *data, 14840Sstevel@tonic-gate crypto_data_t *signature, int kmflag, uchar_t flag) 14850Sstevel@tonic-gate { 14860Sstevel@tonic-gate int rv = CRYPTO_FAILED; 14870Sstevel@tonic-gate 14880Sstevel@tonic-gate /* EXPORT DELETE START */ 14890Sstevel@tonic-gate 1490676Sizick uchar_t digest[SHA512_DIGEST_LENGTH]; 14910Sstevel@tonic-gate /* The der_data size is enough for MD5 also */ 1492676Sizick uchar_t der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len]; 14930Sstevel@tonic-gate ulong_t der_data_len; 14940Sstevel@tonic-gate crypto_data_t der_cd; 14950Sstevel@tonic-gate rsa_mech_type_t mech_type; 14960Sstevel@tonic-gate 14970Sstevel@tonic-gate ASSERT(flag & DO_SIGN || flag & DO_VERIFY); 14980Sstevel@tonic-gate ASSERT(data != NULL || (flag & DO_FINAL)); 14990Sstevel@tonic-gate 15000Sstevel@tonic-gate mech_type = ctxp->mech_type; 1501676Sizick if (mech_type == RSA_PKCS_MECH_INFO_TYPE || 1502676Sizick mech_type == RSA_X_509_MECH_INFO_TYPE) 15030Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 15040Sstevel@tonic-gate 15050Sstevel@tonic-gate /* 15060Sstevel@tonic-gate * We need to do the BUFFER_TOO_SMALL check before digesting 15070Sstevel@tonic-gate * the data. No check is needed for verify as signature is not 15080Sstevel@tonic-gate * an output argument for verify. 15090Sstevel@tonic-gate */ 15100Sstevel@tonic-gate if (flag & DO_SIGN) { 15110Sstevel@tonic-gate uchar_t *modulus; 15120Sstevel@tonic-gate ssize_t modulus_len; 15130Sstevel@tonic-gate 15140Sstevel@tonic-gate if ((rv = get_key_attr(ctxp->key, SUN_CKA_MODULUS, &modulus, 15150Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 15160Sstevel@tonic-gate return (rv); 15170Sstevel@tonic-gate } 15180Sstevel@tonic-gate 15190Sstevel@tonic-gate if (signature->cd_length < modulus_len) { 15200Sstevel@tonic-gate signature->cd_length = modulus_len; 15210Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 15220Sstevel@tonic-gate } 15230Sstevel@tonic-gate } 15240Sstevel@tonic-gate 15250Sstevel@tonic-gate if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE) 15260Sstevel@tonic-gate rv = digest_data(data, &(ctxp->md5_ctx), 15270Sstevel@tonic-gate digest, flag | DO_MD5); 1528676Sizick 1529676Sizick else if (mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE) 15300Sstevel@tonic-gate rv = digest_data(data, &(ctxp->sha1_ctx), 15310Sstevel@tonic-gate digest, flag | DO_SHA1); 1532676Sizick 1533676Sizick else 1534676Sizick rv = digest_data(data, &(ctxp->sha2_ctx), 1535676Sizick digest, flag | DO_SHA2); 1536676Sizick 15370Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 15380Sstevel@tonic-gate return (rv); 15390Sstevel@tonic-gate 1540676Sizick 15410Sstevel@tonic-gate /* 15420Sstevel@tonic-gate * Prepare the DER encoding of the DigestInfo value as follows: 15430Sstevel@tonic-gate * MD5: MD5_DER_PREFIX || H 15440Sstevel@tonic-gate * SHA-1: SHA1_DER_PREFIX || H 15450Sstevel@tonic-gate * 15460Sstevel@tonic-gate * See rsa_impl.c for more details. 15470Sstevel@tonic-gate */ 1548676Sizick switch (mech_type) { 1549676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 15500Sstevel@tonic-gate bcopy(MD5_DER_PREFIX, der_data, MD5_DER_PREFIX_Len); 1551676Sizick bcopy(digest, der_data + MD5_DER_PREFIX_Len, MD5_DIGEST_SIZE); 1552676Sizick der_data_len = MD5_DER_PREFIX_Len + MD5_DIGEST_SIZE; 1553676Sizick break; 1554676Sizick 1555676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 15560Sstevel@tonic-gate bcopy(SHA1_DER_PREFIX, der_data, SHA1_DER_PREFIX_Len); 1557676Sizick bcopy(digest, der_data + SHA1_DER_PREFIX_Len, 1558676Sizick SHA1_DIGEST_SIZE); 1559676Sizick der_data_len = SHA1_DER_PREFIX_Len + SHA1_DIGEST_SIZE; 1560676Sizick break; 1561676Sizick 1562676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1563676Sizick bcopy(SHA256_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len); 1564676Sizick bcopy(digest, der_data + SHA2_DER_PREFIX_Len, 1565676Sizick SHA256_DIGEST_LENGTH); 1566676Sizick der_data_len = SHA2_DER_PREFIX_Len + SHA256_DIGEST_LENGTH; 1567676Sizick break; 1568676Sizick 1569676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1570676Sizick bcopy(SHA384_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len); 1571676Sizick bcopy(digest, der_data + SHA2_DER_PREFIX_Len, 1572676Sizick SHA384_DIGEST_LENGTH); 1573676Sizick der_data_len = SHA2_DER_PREFIX_Len + SHA384_DIGEST_LENGTH; 1574676Sizick break; 1575676Sizick 1576676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1577676Sizick bcopy(SHA512_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len); 1578676Sizick bcopy(digest, der_data + SHA2_DER_PREFIX_Len, 1579676Sizick SHA512_DIGEST_LENGTH); 1580676Sizick der_data_len = SHA2_DER_PREFIX_Len + SHA512_DIGEST_LENGTH; 1581676Sizick break; 15820Sstevel@tonic-gate } 15830Sstevel@tonic-gate 15840Sstevel@tonic-gate INIT_RAW_CRYPTO_DATA(der_cd, der_data, der_data_len, der_data_len); 15850Sstevel@tonic-gate /* 15860Sstevel@tonic-gate * Now, we are ready to sign or verify the DER_ENCODED data. 15870Sstevel@tonic-gate */ 15880Sstevel@tonic-gate if (flag & DO_SIGN) 15890Sstevel@tonic-gate rv = rsa_sign_common(mech_type, ctxp->key, &der_cd, 15900Sstevel@tonic-gate signature, kmflag); 15910Sstevel@tonic-gate else 15920Sstevel@tonic-gate rv = rsa_verify_common(mech_type, ctxp->key, &der_cd, 15930Sstevel@tonic-gate signature, kmflag); 15940Sstevel@tonic-gate 15950Sstevel@tonic-gate /* EXPORT DELETE END */ 15960Sstevel@tonic-gate 15970Sstevel@tonic-gate return (rv); 15980Sstevel@tonic-gate } 15990Sstevel@tonic-gate 16000Sstevel@tonic-gate static int 16010Sstevel@tonic-gate rsa_sign_common(rsa_mech_type_t mech_type, crypto_key_t *key, 16020Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *signature, int kmflag) 16030Sstevel@tonic-gate { 16040Sstevel@tonic-gate int rv = CRYPTO_FAILED; 16050Sstevel@tonic-gate 16060Sstevel@tonic-gate /* EXPORT DELETE START */ 16070Sstevel@tonic-gate 16080Sstevel@tonic-gate int dlen; 16090Sstevel@tonic-gate uchar_t *dataptr, *modulus; 16100Sstevel@tonic-gate ssize_t modulus_len; 16110Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 16120Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 16130Sstevel@tonic-gate uchar_t signed_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 16140Sstevel@tonic-gate 16150Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 16160Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 16170Sstevel@tonic-gate return (rv); 16180Sstevel@tonic-gate } 16190Sstevel@tonic-gate 16200Sstevel@tonic-gate dlen = data->cd_length; 16210Sstevel@tonic-gate switch (mech_type) { 16220Sstevel@tonic-gate case RSA_PKCS_MECH_INFO_TYPE: 16230Sstevel@tonic-gate if (dlen > (modulus_len - MIN_PKCS1_PADLEN)) 16240Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 16250Sstevel@tonic-gate break; 16260Sstevel@tonic-gate case RSA_X_509_MECH_INFO_TYPE: 16270Sstevel@tonic-gate if (dlen > modulus_len) 16280Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 16290Sstevel@tonic-gate break; 16300Sstevel@tonic-gate } 16310Sstevel@tonic-gate 16320Sstevel@tonic-gate if (signature->cd_length < modulus_len) { 16330Sstevel@tonic-gate signature->cd_length = modulus_len; 16340Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 16350Sstevel@tonic-gate } 16360Sstevel@tonic-gate 16370Sstevel@tonic-gate ASSERT(data->cd_length <= sizeof (tmp_data)); 16380Sstevel@tonic-gate if ((rv = get_input_data(data, &dataptr, tmp_data)) 16390Sstevel@tonic-gate != CRYPTO_SUCCESS) 16400Sstevel@tonic-gate return (rv); 16410Sstevel@tonic-gate 16420Sstevel@tonic-gate switch (mech_type) { 16430Sstevel@tonic-gate case RSA_PKCS_MECH_INFO_TYPE: 16440Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 16450Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1646676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1647676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1648676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 16490Sstevel@tonic-gate /* 16500Sstevel@tonic-gate * Add PKCS padding to the input data to format a block 16510Sstevel@tonic-gate * type "01" encryption block. 16520Sstevel@tonic-gate */ 16530Sstevel@tonic-gate rv = soft_sign_rsa_pkcs_encode(dataptr, dlen, plain_data, 16540Sstevel@tonic-gate modulus_len); 16550Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 16560Sstevel@tonic-gate return (rv); 16570Sstevel@tonic-gate 16580Sstevel@tonic-gate break; 16590Sstevel@tonic-gate 16600Sstevel@tonic-gate case RSA_X_509_MECH_INFO_TYPE: 16610Sstevel@tonic-gate bzero(plain_data, modulus_len - dlen); 16620Sstevel@tonic-gate bcopy(dataptr, &plain_data[modulus_len - dlen], dlen); 16630Sstevel@tonic-gate break; 16640Sstevel@tonic-gate } 16650Sstevel@tonic-gate 16660Sstevel@tonic-gate rv = core_rsa_decrypt(key, plain_data, modulus_len, signed_data, 16670Sstevel@tonic-gate kmflag); 16680Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 16690Sstevel@tonic-gate /* copy out to signature */ 16700Sstevel@tonic-gate if ((rv = put_output_data(signed_data, 16710Sstevel@tonic-gate signature, modulus_len)) != CRYPTO_SUCCESS) 16720Sstevel@tonic-gate return (rv); 16730Sstevel@tonic-gate 16740Sstevel@tonic-gate signature->cd_length = modulus_len; 16750Sstevel@tonic-gate } 16760Sstevel@tonic-gate 16770Sstevel@tonic-gate /* EXPORT DELETE END */ 16780Sstevel@tonic-gate 16790Sstevel@tonic-gate return (rv); 16800Sstevel@tonic-gate } 16810Sstevel@tonic-gate 16820Sstevel@tonic-gate /* ARGSUSED */ 16830Sstevel@tonic-gate static int 16840Sstevel@tonic-gate rsa_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 16850Sstevel@tonic-gate crypto_req_handle_t req) 16860Sstevel@tonic-gate { 16870Sstevel@tonic-gate int rv; 16880Sstevel@tonic-gate rsa_ctx_t *ctxp; 16890Sstevel@tonic-gate 16900Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 16910Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 16920Sstevel@tonic-gate 16930Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 16940Sstevel@tonic-gate switch (ctxp->mech_type) { 16950Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 16960Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1697676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1698676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1699676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 17000Sstevel@tonic-gate rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data, 17010Sstevel@tonic-gate signature, KM_SLEEP, DO_SIGN | DO_UPDATE | DO_FINAL); 17020Sstevel@tonic-gate break; 17030Sstevel@tonic-gate default: 17040Sstevel@tonic-gate rv = rsa_sign_common(ctxp->mech_type, ctxp->key, data, 17050Sstevel@tonic-gate signature, KM_SLEEP); 17060Sstevel@tonic-gate break; 17070Sstevel@tonic-gate } 17080Sstevel@tonic-gate 17090Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 17100Sstevel@tonic-gate (void) rsa_free_context(ctx); 17110Sstevel@tonic-gate 17120Sstevel@tonic-gate return (rv); 17130Sstevel@tonic-gate } 17140Sstevel@tonic-gate 17150Sstevel@tonic-gate /* ARGSUSED */ 17160Sstevel@tonic-gate static int 17170Sstevel@tonic-gate rsa_sign_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req) 17180Sstevel@tonic-gate { 17190Sstevel@tonic-gate int rv; 17200Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 17210Sstevel@tonic-gate rsa_mech_type_t mech_type; 17220Sstevel@tonic-gate 17230Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 17240Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 17250Sstevel@tonic-gate mech_type = ctxp->mech_type; 17260Sstevel@tonic-gate 1727676Sizick if (mech_type == RSA_PKCS_MECH_INFO_TYPE || 1728676Sizick mech_type == RSA_X_509_MECH_INFO_TYPE) 17290Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 17300Sstevel@tonic-gate 17310Sstevel@tonic-gate if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE) 17320Sstevel@tonic-gate rv = digest_data(data, &(ctxp->md5_ctx), 17330Sstevel@tonic-gate NULL, DO_MD5 | DO_UPDATE); 1734676Sizick 1735676Sizick else if (mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE) 17360Sstevel@tonic-gate rv = digest_data(data, &(ctxp->sha1_ctx), 17370Sstevel@tonic-gate NULL, DO_SHA1 | DO_UPDATE); 1738676Sizick 1739676Sizick else 1740676Sizick rv = digest_data(data, &(ctxp->sha2_ctx), 1741676Sizick NULL, DO_SHA2 | DO_UPDATE); 1742676Sizick 17430Sstevel@tonic-gate return (rv); 17440Sstevel@tonic-gate } 17450Sstevel@tonic-gate 17460Sstevel@tonic-gate static int 17470Sstevel@tonic-gate rsa_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature, 17480Sstevel@tonic-gate crypto_req_handle_t req) 17490Sstevel@tonic-gate { 17500Sstevel@tonic-gate int rv; 17510Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 17520Sstevel@tonic-gate 17530Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 17540Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 17550Sstevel@tonic-gate 17560Sstevel@tonic-gate rv = rsa_digest_svrfy_common(ctxp, NULL, signature, 17570Sstevel@tonic-gate crypto_kmflag(req), DO_SIGN | DO_FINAL); 17580Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 17590Sstevel@tonic-gate (void) rsa_free_context(ctx); 17600Sstevel@tonic-gate 17610Sstevel@tonic-gate return (rv); 17620Sstevel@tonic-gate } 17630Sstevel@tonic-gate 17640Sstevel@tonic-gate /* ARGSUSED */ 17650Sstevel@tonic-gate static int 17660Sstevel@tonic-gate rsa_sign_atomic(crypto_provider_handle_t provider, 17670Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 17680Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 17690Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 17700Sstevel@tonic-gate { 17710Sstevel@tonic-gate int rv; 17720Sstevel@tonic-gate digest_rsa_ctx_t dctx; 17730Sstevel@tonic-gate 17740Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 17750Sstevel@tonic-gate return (rv); 17760Sstevel@tonic-gate 1777676Sizick if (mechanism->cm_type == RSA_PKCS_MECH_INFO_TYPE || 1778676Sizick mechanism->cm_type == RSA_X_509_MECH_INFO_TYPE) 1779676Sizick rv = rsa_sign_common(mechanism->cm_type, key, data, 1780676Sizick signature, crypto_kmflag(req)); 1781676Sizick 1782676Sizick else { 17830Sstevel@tonic-gate dctx.mech_type = mechanism->cm_type; 17840Sstevel@tonic-gate dctx.key = key; 1785676Sizick switch (mechanism->cm_type) { 1786676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 17870Sstevel@tonic-gate MD5Init(&(dctx.md5_ctx)); 1788676Sizick break; 1789676Sizick 1790676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 17910Sstevel@tonic-gate SHA1Init(&(dctx.sha1_ctx)); 1792676Sizick break; 1793676Sizick 1794676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1795676Sizick SHA2Init(SHA256, &(dctx.sha2_ctx)); 1796676Sizick break; 1797676Sizick 1798676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1799676Sizick SHA2Init(SHA384, &(dctx.sha2_ctx)); 1800676Sizick break; 1801676Sizick 1802676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1803676Sizick SHA2Init(SHA512, &(dctx.sha2_ctx)); 1804676Sizick break; 1805676Sizick } 1806676Sizick 1807676Sizick rv = rsa_digest_svrfy_common(&dctx, data, signature, 1808676Sizick crypto_kmflag(req), DO_SIGN | DO_UPDATE | DO_FINAL); 18090Sstevel@tonic-gate } 18100Sstevel@tonic-gate 18110Sstevel@tonic-gate return (rv); 18120Sstevel@tonic-gate } 18130Sstevel@tonic-gate 18140Sstevel@tonic-gate static int 18150Sstevel@tonic-gate rsa_verify_common(rsa_mech_type_t mech_type, crypto_key_t *key, 18160Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *signature, int kmflag) 18170Sstevel@tonic-gate { 18180Sstevel@tonic-gate int rv = CRYPTO_FAILED; 18190Sstevel@tonic-gate 18200Sstevel@tonic-gate /* EXPORT DELETE START */ 18210Sstevel@tonic-gate 18220Sstevel@tonic-gate uchar_t *sigptr, *modulus; 18230Sstevel@tonic-gate ssize_t modulus_len; 18240Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 18250Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 18260Sstevel@tonic-gate 18270Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 18280Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 18290Sstevel@tonic-gate return (rv); 18300Sstevel@tonic-gate } 18310Sstevel@tonic-gate 18320Sstevel@tonic-gate if (signature->cd_length != modulus_len) 18330Sstevel@tonic-gate return (CRYPTO_SIGNATURE_LEN_RANGE); 18340Sstevel@tonic-gate 18350Sstevel@tonic-gate ASSERT(signature->cd_length <= sizeof (tmp_data)); 18360Sstevel@tonic-gate if ((rv = get_input_data(signature, &sigptr, tmp_data)) 18370Sstevel@tonic-gate != CRYPTO_SUCCESS) 18380Sstevel@tonic-gate return (rv); 18390Sstevel@tonic-gate 18400Sstevel@tonic-gate rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1); 18410Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 18420Sstevel@tonic-gate return (rv); 18430Sstevel@tonic-gate 1844676Sizick if (mech_type == RSA_X_509_MECH_INFO_TYPE) { 1845676Sizick if (compare_data(data, (plain_data + modulus_len 1846676Sizick - data->cd_length)) != 0) 1847676Sizick rv = CRYPTO_SIGNATURE_INVALID; 1848676Sizick 1849676Sizick } else { 18500Sstevel@tonic-gate int data_len = modulus_len; 18510Sstevel@tonic-gate 18520Sstevel@tonic-gate /* 18530Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the 18540Sstevel@tonic-gate * recovered data, then compare the recovered data with 18550Sstevel@tonic-gate * the original data. 18560Sstevel@tonic-gate */ 18570Sstevel@tonic-gate rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len); 18580Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 1859676Sizick return (rv); 18600Sstevel@tonic-gate 1861676Sizick if (data_len != data->cd_length) 1862676Sizick return (CRYPTO_SIGNATURE_LEN_RANGE); 18630Sstevel@tonic-gate 18640Sstevel@tonic-gate if (compare_data(data, (plain_data + modulus_len 18650Sstevel@tonic-gate - data_len)) != 0) 18660Sstevel@tonic-gate rv = CRYPTO_SIGNATURE_INVALID; 18670Sstevel@tonic-gate } 18680Sstevel@tonic-gate 18690Sstevel@tonic-gate /* EXPORT DELETE END */ 18700Sstevel@tonic-gate 18710Sstevel@tonic-gate return (rv); 18720Sstevel@tonic-gate } 18730Sstevel@tonic-gate 18740Sstevel@tonic-gate /* ARGSUSED */ 18750Sstevel@tonic-gate static int 18760Sstevel@tonic-gate rsa_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 18770Sstevel@tonic-gate crypto_req_handle_t req) 18780Sstevel@tonic-gate { 18790Sstevel@tonic-gate int rv; 18800Sstevel@tonic-gate rsa_ctx_t *ctxp; 18810Sstevel@tonic-gate 18820Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 18830Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 18840Sstevel@tonic-gate 18850Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 18860Sstevel@tonic-gate switch (ctxp->mech_type) { 18870Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 18880Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1889676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1890676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1891676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 18920Sstevel@tonic-gate rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data, 18930Sstevel@tonic-gate signature, KM_SLEEP, DO_VERIFY | DO_UPDATE | DO_FINAL); 18940Sstevel@tonic-gate break; 18950Sstevel@tonic-gate default: 18960Sstevel@tonic-gate rv = rsa_verify_common(ctxp->mech_type, ctxp->key, data, 18970Sstevel@tonic-gate signature, KM_SLEEP); 18980Sstevel@tonic-gate break; 18990Sstevel@tonic-gate } 19000Sstevel@tonic-gate 19010Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 19020Sstevel@tonic-gate (void) rsa_free_context(ctx); 19030Sstevel@tonic-gate 19040Sstevel@tonic-gate return (rv); 19050Sstevel@tonic-gate } 19060Sstevel@tonic-gate 19070Sstevel@tonic-gate /* ARGSUSED */ 19080Sstevel@tonic-gate static int 19090Sstevel@tonic-gate rsa_verify_update(crypto_ctx_t *ctx, crypto_data_t *data, 19100Sstevel@tonic-gate crypto_req_handle_t req) 19110Sstevel@tonic-gate { 19120Sstevel@tonic-gate int rv; 19130Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 19140Sstevel@tonic-gate 19150Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 19160Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 19170Sstevel@tonic-gate 1918676Sizick switch (ctxp->mech_type) { 19190Sstevel@tonic-gate 1920676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 19210Sstevel@tonic-gate rv = digest_data(data, &(ctxp->md5_ctx), 19220Sstevel@tonic-gate NULL, DO_MD5 | DO_UPDATE); 1923676Sizick break; 1924676Sizick 1925676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 19260Sstevel@tonic-gate rv = digest_data(data, &(ctxp->sha1_ctx), 19270Sstevel@tonic-gate NULL, DO_SHA1 | DO_UPDATE); 1928676Sizick break; 1929676Sizick 1930676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1931676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1932676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1933676Sizick rv = digest_data(data, &(ctxp->sha2_ctx), 1934676Sizick NULL, DO_SHA2 | DO_UPDATE); 1935676Sizick break; 1936676Sizick 1937676Sizick default: 1938676Sizick return (CRYPTO_MECHANISM_INVALID); 1939676Sizick } 1940676Sizick 19410Sstevel@tonic-gate return (rv); 19420Sstevel@tonic-gate } 19430Sstevel@tonic-gate 19440Sstevel@tonic-gate static int 19450Sstevel@tonic-gate rsa_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature, 19460Sstevel@tonic-gate crypto_req_handle_t req) 19470Sstevel@tonic-gate { 19480Sstevel@tonic-gate int rv; 19490Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 19500Sstevel@tonic-gate 19510Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 19520Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 19530Sstevel@tonic-gate 19540Sstevel@tonic-gate rv = rsa_digest_svrfy_common(ctxp, NULL, signature, 19550Sstevel@tonic-gate crypto_kmflag(req), DO_VERIFY | DO_FINAL); 19560Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 19570Sstevel@tonic-gate (void) rsa_free_context(ctx); 19580Sstevel@tonic-gate 19590Sstevel@tonic-gate return (rv); 19600Sstevel@tonic-gate } 19610Sstevel@tonic-gate 19620Sstevel@tonic-gate 19630Sstevel@tonic-gate /* ARGSUSED */ 19640Sstevel@tonic-gate static int 19650Sstevel@tonic-gate rsa_verify_atomic(crypto_provider_handle_t provider, 19660Sstevel@tonic-gate crypto_session_id_t session_id, 19670Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data, 19680Sstevel@tonic-gate crypto_data_t *signature, crypto_spi_ctx_template_t ctx_template, 19690Sstevel@tonic-gate crypto_req_handle_t req) 19700Sstevel@tonic-gate { 19710Sstevel@tonic-gate int rv; 19720Sstevel@tonic-gate digest_rsa_ctx_t dctx; 19730Sstevel@tonic-gate 19740Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 19750Sstevel@tonic-gate return (rv); 19760Sstevel@tonic-gate 1977676Sizick if (mechanism->cm_type == RSA_PKCS_MECH_INFO_TYPE || 1978676Sizick mechanism->cm_type == RSA_X_509_MECH_INFO_TYPE) 1979676Sizick rv = rsa_verify_common(mechanism->cm_type, key, data, 1980676Sizick signature, crypto_kmflag(req)); 1981676Sizick 1982676Sizick else { 19830Sstevel@tonic-gate dctx.mech_type = mechanism->cm_type; 19840Sstevel@tonic-gate dctx.key = key; 1985676Sizick 1986676Sizick switch (mechanism->cm_type) { 1987676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 19880Sstevel@tonic-gate MD5Init(&(dctx.md5_ctx)); 1989676Sizick break; 1990676Sizick 1991676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 19920Sstevel@tonic-gate SHA1Init(&(dctx.sha1_ctx)); 1993676Sizick break; 1994676Sizick 1995676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1996676Sizick SHA2Init(SHA256, &(dctx.sha2_ctx)); 1997676Sizick break; 1998676Sizick 1999676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 2000676Sizick SHA2Init(SHA384, &(dctx.sha2_ctx)); 2001676Sizick break; 2002676Sizick 2003676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 2004676Sizick SHA2Init(SHA512, &(dctx.sha2_ctx)); 2005676Sizick break; 2006676Sizick } 2007676Sizick 20080Sstevel@tonic-gate rv = rsa_digest_svrfy_common(&dctx, data, 20090Sstevel@tonic-gate signature, crypto_kmflag(req), 20100Sstevel@tonic-gate DO_VERIFY | DO_UPDATE | DO_FINAL); 20110Sstevel@tonic-gate } 20120Sstevel@tonic-gate 20130Sstevel@tonic-gate return (rv); 20140Sstevel@tonic-gate } 20150Sstevel@tonic-gate 20160Sstevel@tonic-gate static int 20170Sstevel@tonic-gate rsa_verify_recover_common(rsa_mech_type_t mech_type, crypto_key_t *key, 20180Sstevel@tonic-gate crypto_data_t *signature, crypto_data_t *data, int kmflag) 20190Sstevel@tonic-gate { 20200Sstevel@tonic-gate int rv = CRYPTO_FAILED; 20210Sstevel@tonic-gate 20220Sstevel@tonic-gate /* EXPORT DELETE START */ 20230Sstevel@tonic-gate 20240Sstevel@tonic-gate int data_len; 20250Sstevel@tonic-gate uchar_t *sigptr, *modulus; 20260Sstevel@tonic-gate ssize_t modulus_len; 20270Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 20280Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 20290Sstevel@tonic-gate 20300Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 20310Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 20320Sstevel@tonic-gate return (rv); 20330Sstevel@tonic-gate } 20340Sstevel@tonic-gate 20350Sstevel@tonic-gate if (signature->cd_length != modulus_len) 20360Sstevel@tonic-gate return (CRYPTO_SIGNATURE_LEN_RANGE); 20370Sstevel@tonic-gate 20380Sstevel@tonic-gate ASSERT(signature->cd_length <= sizeof (tmp_data)); 20390Sstevel@tonic-gate if ((rv = get_input_data(signature, &sigptr, tmp_data)) 20400Sstevel@tonic-gate != CRYPTO_SUCCESS) 20410Sstevel@tonic-gate return (rv); 20420Sstevel@tonic-gate 20430Sstevel@tonic-gate rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1); 20440Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 20450Sstevel@tonic-gate return (rv); 20460Sstevel@tonic-gate 20470Sstevel@tonic-gate data_len = modulus_len; 20480Sstevel@tonic-gate 20490Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 20500Sstevel@tonic-gate /* 20510Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the 20520Sstevel@tonic-gate * recovered data, then compare the recovered data with 20530Sstevel@tonic-gate * the original data. 20540Sstevel@tonic-gate */ 20550Sstevel@tonic-gate rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len); 20560Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 20570Sstevel@tonic-gate return (rv); 20580Sstevel@tonic-gate } 20590Sstevel@tonic-gate 20600Sstevel@tonic-gate if (data->cd_length < data_len) { 20610Sstevel@tonic-gate data->cd_length = data_len; 20620Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 20630Sstevel@tonic-gate } 20640Sstevel@tonic-gate 20650Sstevel@tonic-gate if ((rv = put_output_data(plain_data + modulus_len - data_len, 20660Sstevel@tonic-gate data, data_len)) != CRYPTO_SUCCESS) 20670Sstevel@tonic-gate return (rv); 20680Sstevel@tonic-gate data->cd_length = data_len; 20690Sstevel@tonic-gate 20700Sstevel@tonic-gate /* EXPORT DELETE END */ 20710Sstevel@tonic-gate 20720Sstevel@tonic-gate return (rv); 20730Sstevel@tonic-gate } 20740Sstevel@tonic-gate 20750Sstevel@tonic-gate /* ARGSUSED */ 20760Sstevel@tonic-gate static int 20770Sstevel@tonic-gate rsa_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature, 20780Sstevel@tonic-gate crypto_data_t *data, crypto_req_handle_t req) 20790Sstevel@tonic-gate { 20800Sstevel@tonic-gate int rv; 20810Sstevel@tonic-gate rsa_ctx_t *ctxp; 20820Sstevel@tonic-gate 20830Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 20840Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 20850Sstevel@tonic-gate 20860Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 20870Sstevel@tonic-gate rv = rsa_verify_recover_common(ctxp->mech_type, ctxp->key, 20880Sstevel@tonic-gate signature, data, KM_SLEEP); 20890Sstevel@tonic-gate 20900Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 20910Sstevel@tonic-gate (void) rsa_free_context(ctx); 20920Sstevel@tonic-gate 20930Sstevel@tonic-gate return (rv); 20940Sstevel@tonic-gate } 20950Sstevel@tonic-gate 20960Sstevel@tonic-gate /* ARGSUSED */ 20970Sstevel@tonic-gate static int 20980Sstevel@tonic-gate rsa_verify_recover_atomic(crypto_provider_handle_t provider, 20990Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 21000Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data, 21010Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 21020Sstevel@tonic-gate { 21030Sstevel@tonic-gate int rv; 21040Sstevel@tonic-gate 21050Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 21060Sstevel@tonic-gate return (rv); 21070Sstevel@tonic-gate 21080Sstevel@tonic-gate return (rsa_verify_recover_common(mechanism->cm_type, key, 21090Sstevel@tonic-gate signature, data, crypto_kmflag(req))); 21100Sstevel@tonic-gate } 2111