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 /* 2211413Sopensolaris@drydog.com * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate /* 270Sstevel@tonic-gate * RSA provider for the Kernel Cryptographic Framework (KCF) 280Sstevel@tonic-gate */ 290Sstevel@tonic-gate 300Sstevel@tonic-gate #include <sys/types.h> 310Sstevel@tonic-gate #include <sys/systm.h> 320Sstevel@tonic-gate #include <sys/modctl.h> 330Sstevel@tonic-gate #include <sys/cmn_err.h> 340Sstevel@tonic-gate #include <sys/ddi.h> 350Sstevel@tonic-gate #include <sys/crypto/spi.h> 360Sstevel@tonic-gate #include <sys/sysmacros.h> 370Sstevel@tonic-gate #include <sys/strsun.h> 380Sstevel@tonic-gate #include <sys/md5.h> 390Sstevel@tonic-gate #include <sys/sha1.h> 4010500SHai-May.Chao@Sun.COM #define _SHA2_IMPL 41676Sizick #include <sys/sha2.h> 420Sstevel@tonic-gate #include <sys/random.h> 437188Smcpowers #include <sys/crypto/impl.h> 4410500SHai-May.Chao@Sun.COM #include <sha1/sha1_impl.h> 4510500SHai-May.Chao@Sun.COM #include <sha2/sha2_impl.h> 4610500SHai-May.Chao@Sun.COM #define _RSA_FIPS_POST 4710500SHai-May.Chao@Sun.COM #include <rsa/rsa_impl.h> 480Sstevel@tonic-gate 490Sstevel@tonic-gate extern struct mod_ops mod_cryptoops; 500Sstevel@tonic-gate 510Sstevel@tonic-gate /* 520Sstevel@tonic-gate * Module linkage information for the kernel. 530Sstevel@tonic-gate */ 540Sstevel@tonic-gate static struct modlcrypto modlcrypto = { 550Sstevel@tonic-gate &mod_cryptoops, 565072Smcpowers "RSA Kernel SW Provider" 570Sstevel@tonic-gate }; 580Sstevel@tonic-gate 590Sstevel@tonic-gate static struct modlinkage modlinkage = { 600Sstevel@tonic-gate MODREV_1, 610Sstevel@tonic-gate (void *)&modlcrypto, 620Sstevel@tonic-gate NULL 630Sstevel@tonic-gate }; 640Sstevel@tonic-gate 650Sstevel@tonic-gate /* 660Sstevel@tonic-gate * CSPI information (entry points, provider info, etc.) 670Sstevel@tonic-gate */ 680Sstevel@tonic-gate typedef enum rsa_mech_type { 690Sstevel@tonic-gate RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_RSA_PKCS */ 700Sstevel@tonic-gate RSA_X_509_MECH_INFO_TYPE, /* SUN_CKM_RSA_X_509 */ 710Sstevel@tonic-gate MD5_RSA_PKCS_MECH_INFO_TYPE, /* SUN_MD5_RSA_PKCS */ 72676Sizick SHA1_RSA_PKCS_MECH_INFO_TYPE, /* SUN_SHA1_RSA_PKCS */ 73676Sizick SHA256_RSA_PKCS_MECH_INFO_TYPE, /* SUN_SHA256_RSA_PKCS */ 74676Sizick SHA384_RSA_PKCS_MECH_INFO_TYPE, /* SUN_SHA384_RSA_PKCS */ 75676Sizick SHA512_RSA_PKCS_MECH_INFO_TYPE /* SUN_SHA512_RSA_PKCS */ 760Sstevel@tonic-gate } rsa_mech_type_t; 770Sstevel@tonic-gate 780Sstevel@tonic-gate /* 790Sstevel@tonic-gate * Context for RSA_PKCS and RSA_X_509 mechanisms. 800Sstevel@tonic-gate */ 810Sstevel@tonic-gate typedef struct rsa_ctx { 820Sstevel@tonic-gate rsa_mech_type_t mech_type; 830Sstevel@tonic-gate crypto_key_t *key; 840Sstevel@tonic-gate size_t keychunk_size; 850Sstevel@tonic-gate } rsa_ctx_t; 860Sstevel@tonic-gate 870Sstevel@tonic-gate /* 88676Sizick * Context for MD5_RSA_PKCS and SHA*_RSA_PKCS mechanisms. 890Sstevel@tonic-gate */ 900Sstevel@tonic-gate typedef struct digest_rsa_ctx { 910Sstevel@tonic-gate rsa_mech_type_t mech_type; 920Sstevel@tonic-gate crypto_key_t *key; 930Sstevel@tonic-gate size_t keychunk_size; 940Sstevel@tonic-gate union { 950Sstevel@tonic-gate MD5_CTX md5ctx; 960Sstevel@tonic-gate SHA1_CTX sha1ctx; 97676Sizick SHA2_CTX sha2ctx; 980Sstevel@tonic-gate } dctx_u; 990Sstevel@tonic-gate } digest_rsa_ctx_t; 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate #define md5_ctx dctx_u.md5ctx 1020Sstevel@tonic-gate #define sha1_ctx dctx_u.sha1ctx 103676Sizick #define sha2_ctx dctx_u.sha2ctx 1040Sstevel@tonic-gate 1050Sstevel@tonic-gate /* 1060Sstevel@tonic-gate * Mechanism info structure passed to KCF during registration. 1070Sstevel@tonic-gate */ 1080Sstevel@tonic-gate static crypto_mech_info_t rsa_mech_info_tab[] = { 1090Sstevel@tonic-gate /* RSA_PKCS */ 1100Sstevel@tonic-gate {SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE, 1110Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 1120Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC | 1130Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 1140Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 1150Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC | 1160Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC, 1170Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate /* RSA_X_509 */ 1200Sstevel@tonic-gate {SUN_CKM_RSA_X_509, RSA_X_509_MECH_INFO_TYPE, 1210Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 1220Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC | 1230Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 1240Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 1250Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC | 1260Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC, 1270Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate /* MD5_RSA_PKCS */ 1300Sstevel@tonic-gate {SUN_CKM_MD5_RSA_PKCS, MD5_RSA_PKCS_MECH_INFO_TYPE, 1310Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 1320Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 1330Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate /* SHA1_RSA_PKCS */ 1360Sstevel@tonic-gate {SUN_CKM_SHA1_RSA_PKCS, SHA1_RSA_PKCS_MECH_INFO_TYPE, 1370Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 1380Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 139676Sizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 140676Sizick 141676Sizick /* SHA256_RSA_PKCS */ 142676Sizick {SUN_CKM_SHA256_RSA_PKCS, SHA256_RSA_PKCS_MECH_INFO_TYPE, 143676Sizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 144676Sizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 145676Sizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 146676Sizick 147676Sizick /* SHA384_RSA_PKCS */ 148676Sizick {SUN_CKM_SHA384_RSA_PKCS, SHA384_RSA_PKCS_MECH_INFO_TYPE, 149676Sizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 150676Sizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 151676Sizick RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 152676Sizick 153676Sizick /* SHA512_RSA_PKCS */ 154676Sizick {SUN_CKM_SHA512_RSA_PKCS, SHA512_RSA_PKCS_MECH_INFO_TYPE, 155676Sizick CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 156676Sizick CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 1570Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS} 158676Sizick 1590Sstevel@tonic-gate }; 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate #define RSA_VALID_MECH(mech) \ 1620Sstevel@tonic-gate (((mech)->cm_type == RSA_PKCS_MECH_INFO_TYPE || \ 1630Sstevel@tonic-gate (mech)->cm_type == RSA_X_509_MECH_INFO_TYPE || \ 1640Sstevel@tonic-gate (mech)->cm_type == MD5_RSA_PKCS_MECH_INFO_TYPE || \ 165676Sizick (mech)->cm_type == SHA1_RSA_PKCS_MECH_INFO_TYPE || \ 166676Sizick (mech)->cm_type == SHA256_RSA_PKCS_MECH_INFO_TYPE || \ 167676Sizick (mech)->cm_type == SHA384_RSA_PKCS_MECH_INFO_TYPE || \ 168676Sizick (mech)->cm_type == SHA512_RSA_PKCS_MECH_INFO_TYPE) ? 1 : 0) 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate /* operations are in-place if the output buffer is NULL */ 1710Sstevel@tonic-gate #define RSA_ARG_INPLACE(input, output) \ 1720Sstevel@tonic-gate if ((output) == NULL) \ 1730Sstevel@tonic-gate (output) = (input); 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate static void rsa_provider_status(crypto_provider_handle_t, uint_t *); 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate static crypto_control_ops_t rsa_control_ops = { 1780Sstevel@tonic-gate rsa_provider_status 1790Sstevel@tonic-gate }; 1800Sstevel@tonic-gate 1810Sstevel@tonic-gate static int rsa_common_init(crypto_ctx_t *, crypto_mechanism_t *, 1820Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 1830Sstevel@tonic-gate static int rsa_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 1840Sstevel@tonic-gate crypto_req_handle_t); 1850Sstevel@tonic-gate static int rsa_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 1860Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 1870Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 1880Sstevel@tonic-gate static int rsa_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 1890Sstevel@tonic-gate crypto_req_handle_t); 1900Sstevel@tonic-gate static int rsa_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 1910Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 1920Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate /* 1950Sstevel@tonic-gate * The RSA mechanisms do not have multiple-part cipher operations. 1960Sstevel@tonic-gate * So, the update and final routines are set to NULL. 1970Sstevel@tonic-gate */ 1980Sstevel@tonic-gate static crypto_cipher_ops_t rsa_cipher_ops = { 1990Sstevel@tonic-gate rsa_common_init, 2000Sstevel@tonic-gate rsa_encrypt, 2010Sstevel@tonic-gate NULL, 2020Sstevel@tonic-gate NULL, 2030Sstevel@tonic-gate rsa_encrypt_atomic, 2040Sstevel@tonic-gate rsa_common_init, 2050Sstevel@tonic-gate rsa_decrypt, 2060Sstevel@tonic-gate NULL, 2070Sstevel@tonic-gate NULL, 2080Sstevel@tonic-gate rsa_decrypt_atomic 2090Sstevel@tonic-gate }; 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate static int rsa_sign_verify_common_init(crypto_ctx_t *, crypto_mechanism_t *, 2120Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 2130Sstevel@tonic-gate static int rsa_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 2140Sstevel@tonic-gate crypto_req_handle_t); 2150Sstevel@tonic-gate static int rsa_sign_update(crypto_ctx_t *, crypto_data_t *, 2160Sstevel@tonic-gate crypto_req_handle_t); 2170Sstevel@tonic-gate static int rsa_sign_final(crypto_ctx_t *, crypto_data_t *, 2180Sstevel@tonic-gate crypto_req_handle_t); 2190Sstevel@tonic-gate static int rsa_sign_atomic(crypto_provider_handle_t, crypto_session_id_t, 2200Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, 2210Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t); 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate /* 2240Sstevel@tonic-gate * We use the same routine for sign_init and sign_recover_init fields 2250Sstevel@tonic-gate * as they do the same thing. Same holds for sign and sign_recover fields, 2260Sstevel@tonic-gate * and sign_atomic and sign_recover_atomic fields. 2270Sstevel@tonic-gate */ 2280Sstevel@tonic-gate static crypto_sign_ops_t rsa_sign_ops = { 2290Sstevel@tonic-gate rsa_sign_verify_common_init, 2300Sstevel@tonic-gate rsa_sign, 2310Sstevel@tonic-gate rsa_sign_update, 2320Sstevel@tonic-gate rsa_sign_final, 2330Sstevel@tonic-gate rsa_sign_atomic, 2340Sstevel@tonic-gate rsa_sign_verify_common_init, 2350Sstevel@tonic-gate rsa_sign, 2360Sstevel@tonic-gate rsa_sign_atomic 2370Sstevel@tonic-gate }; 2380Sstevel@tonic-gate 2390Sstevel@tonic-gate static int rsa_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 2400Sstevel@tonic-gate crypto_req_handle_t); 2410Sstevel@tonic-gate static int rsa_verify_update(crypto_ctx_t *, crypto_data_t *, 2420Sstevel@tonic-gate crypto_req_handle_t); 2430Sstevel@tonic-gate static int rsa_verify_final(crypto_ctx_t *, crypto_data_t *, 2440Sstevel@tonic-gate crypto_req_handle_t); 2450Sstevel@tonic-gate static int rsa_verify_atomic(crypto_provider_handle_t, crypto_session_id_t, 2460Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 2470Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 2480Sstevel@tonic-gate static int rsa_verify_recover(crypto_ctx_t *, crypto_data_t *, 2490Sstevel@tonic-gate crypto_data_t *, crypto_req_handle_t); 2500Sstevel@tonic-gate static int rsa_verify_recover_atomic(crypto_provider_handle_t, 2510Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 2520Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 2530Sstevel@tonic-gate crypto_req_handle_t); 2540Sstevel@tonic-gate 2550Sstevel@tonic-gate /* 2560Sstevel@tonic-gate * We use the same routine (rsa_sign_verify_common_init) for verify_init 2570Sstevel@tonic-gate * and verify_recover_init fields as they do the same thing. 2580Sstevel@tonic-gate */ 2590Sstevel@tonic-gate static crypto_verify_ops_t rsa_verify_ops = { 2600Sstevel@tonic-gate rsa_sign_verify_common_init, 2610Sstevel@tonic-gate rsa_verify, 2620Sstevel@tonic-gate rsa_verify_update, 2630Sstevel@tonic-gate rsa_verify_final, 2640Sstevel@tonic-gate rsa_verify_atomic, 2650Sstevel@tonic-gate rsa_sign_verify_common_init, 2660Sstevel@tonic-gate rsa_verify_recover, 2670Sstevel@tonic-gate rsa_verify_recover_atomic 2680Sstevel@tonic-gate }; 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate static int rsa_free_context(crypto_ctx_t *); 2710Sstevel@tonic-gate 2720Sstevel@tonic-gate static crypto_ctx_ops_t rsa_ctx_ops = { 2730Sstevel@tonic-gate NULL, 2740Sstevel@tonic-gate rsa_free_context 2750Sstevel@tonic-gate }; 2760Sstevel@tonic-gate 27710732SAnthony.Scarpino@Sun.COM static void rsa_POST(int *); 27810732SAnthony.Scarpino@Sun.COM 27910732SAnthony.Scarpino@Sun.COM static crypto_fips140_ops_t rsa_fips140_ops = { 28010732SAnthony.Scarpino@Sun.COM rsa_POST 28110732SAnthony.Scarpino@Sun.COM }; 28210732SAnthony.Scarpino@Sun.COM 2830Sstevel@tonic-gate static crypto_ops_t rsa_crypto_ops = { 2840Sstevel@tonic-gate &rsa_control_ops, 2850Sstevel@tonic-gate NULL, 2860Sstevel@tonic-gate &rsa_cipher_ops, 2870Sstevel@tonic-gate NULL, 2880Sstevel@tonic-gate &rsa_sign_ops, 2890Sstevel@tonic-gate &rsa_verify_ops, 2900Sstevel@tonic-gate NULL, 2910Sstevel@tonic-gate NULL, 2920Sstevel@tonic-gate NULL, 2930Sstevel@tonic-gate NULL, 2940Sstevel@tonic-gate NULL, 2950Sstevel@tonic-gate NULL, 2960Sstevel@tonic-gate NULL, 29710732SAnthony.Scarpino@Sun.COM &rsa_ctx_ops, 29810732SAnthony.Scarpino@Sun.COM NULL, 29910732SAnthony.Scarpino@Sun.COM NULL, 30010732SAnthony.Scarpino@Sun.COM &rsa_fips140_ops 3010Sstevel@tonic-gate }; 3020Sstevel@tonic-gate 3030Sstevel@tonic-gate static crypto_provider_info_t rsa_prov_info = { 30410732SAnthony.Scarpino@Sun.COM CRYPTO_SPI_VERSION_4, 3050Sstevel@tonic-gate "RSA Software Provider", 3060Sstevel@tonic-gate CRYPTO_SW_PROVIDER, 3070Sstevel@tonic-gate {&modlinkage}, 3080Sstevel@tonic-gate NULL, 3090Sstevel@tonic-gate &rsa_crypto_ops, 3100Sstevel@tonic-gate sizeof (rsa_mech_info_tab)/sizeof (crypto_mech_info_t), 3110Sstevel@tonic-gate rsa_mech_info_tab 3120Sstevel@tonic-gate }; 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate static int rsa_encrypt_common(rsa_mech_type_t, crypto_key_t *, 3150Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3160Sstevel@tonic-gate static int rsa_decrypt_common(rsa_mech_type_t, crypto_key_t *, 3170Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3180Sstevel@tonic-gate static int rsa_sign_common(rsa_mech_type_t, crypto_key_t *, 3190Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3200Sstevel@tonic-gate static int rsa_verify_common(rsa_mech_type_t, crypto_key_t *, 3210Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 3220Sstevel@tonic-gate static int compare_data(crypto_data_t *, uchar_t *); 3230Sstevel@tonic-gate 3240Sstevel@tonic-gate /* EXPORT DELETE START */ 3250Sstevel@tonic-gate 3260Sstevel@tonic-gate static int core_rsa_encrypt(crypto_key_t *, uchar_t *, 3270Sstevel@tonic-gate int, uchar_t *, int, int); 3280Sstevel@tonic-gate static int core_rsa_decrypt(crypto_key_t *, uchar_t *, int, 3290Sstevel@tonic-gate uchar_t *, int); 3300Sstevel@tonic-gate 3310Sstevel@tonic-gate /* EXPORT DELETE END */ 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate static crypto_kcf_provider_handle_t rsa_prov_handle = NULL; 3340Sstevel@tonic-gate 3350Sstevel@tonic-gate int 3360Sstevel@tonic-gate _init(void) 3370Sstevel@tonic-gate { 3380Sstevel@tonic-gate int ret; 3390Sstevel@tonic-gate 340*11751SAnthony.Scarpino@Sun.COM if ((ret = mod_install(&modlinkage)) != 0) 341*11751SAnthony.Scarpino@Sun.COM return (ret); 342*11751SAnthony.Scarpino@Sun.COM 343*11751SAnthony.Scarpino@Sun.COM /* Register with KCF. If the registration fails, remove the module. */ 344*11751SAnthony.Scarpino@Sun.COM if (crypto_register_provider(&rsa_prov_info, &rsa_prov_handle)) { 345*11751SAnthony.Scarpino@Sun.COM (void) mod_remove(&modlinkage); 3460Sstevel@tonic-gate return (EACCES); 3470Sstevel@tonic-gate } 3480Sstevel@tonic-gate 349*11751SAnthony.Scarpino@Sun.COM return (0); 3500Sstevel@tonic-gate } 3510Sstevel@tonic-gate 3520Sstevel@tonic-gate int 3530Sstevel@tonic-gate _fini(void) 3540Sstevel@tonic-gate { 355*11751SAnthony.Scarpino@Sun.COM /* Unregister from KCF if module is registered */ 3560Sstevel@tonic-gate if (rsa_prov_handle != NULL) { 357*11751SAnthony.Scarpino@Sun.COM if (crypto_unregister_provider(rsa_prov_handle)) 3580Sstevel@tonic-gate return (EBUSY); 359*11751SAnthony.Scarpino@Sun.COM 3600Sstevel@tonic-gate rsa_prov_handle = NULL; 3610Sstevel@tonic-gate } 3620Sstevel@tonic-gate 3630Sstevel@tonic-gate return (mod_remove(&modlinkage)); 3640Sstevel@tonic-gate } 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate int 3670Sstevel@tonic-gate _info(struct modinfo *modinfop) 3680Sstevel@tonic-gate { 3690Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 3700Sstevel@tonic-gate } 3710Sstevel@tonic-gate 3720Sstevel@tonic-gate /* ARGSUSED */ 3730Sstevel@tonic-gate static void 3740Sstevel@tonic-gate rsa_provider_status(crypto_provider_handle_t provider, uint_t *status) 3750Sstevel@tonic-gate { 3760Sstevel@tonic-gate *status = CRYPTO_PROVIDER_READY; 3770Sstevel@tonic-gate } 3780Sstevel@tonic-gate 3790Sstevel@tonic-gate static int 3800Sstevel@tonic-gate check_mech_and_key(crypto_mechanism_t *mechanism, crypto_key_t *key) 3810Sstevel@tonic-gate { 3820Sstevel@tonic-gate int rv = CRYPTO_FAILED; 3830Sstevel@tonic-gate 3840Sstevel@tonic-gate /* EXPORT DELETE START */ 3850Sstevel@tonic-gate 3860Sstevel@tonic-gate uchar_t *modulus; 3870Sstevel@tonic-gate ssize_t modulus_len; /* In bytes */ 3880Sstevel@tonic-gate 3890Sstevel@tonic-gate if (!RSA_VALID_MECH(mechanism)) 3900Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 3910Sstevel@tonic-gate 3920Sstevel@tonic-gate /* 3930Sstevel@tonic-gate * We only support RSA keys that are passed as a list of 3940Sstevel@tonic-gate * object attributes. 3950Sstevel@tonic-gate */ 3960Sstevel@tonic-gate if (key->ck_format != CRYPTO_KEY_ATTR_LIST) { 3970Sstevel@tonic-gate return (CRYPTO_KEY_TYPE_INCONSISTENT); 3980Sstevel@tonic-gate } 3990Sstevel@tonic-gate 4007188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 4010Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 4020Sstevel@tonic-gate return (rv); 4030Sstevel@tonic-gate } 4040Sstevel@tonic-gate if (modulus_len < MIN_RSA_KEYLENGTH_IN_BYTES || 4050Sstevel@tonic-gate modulus_len > MAX_RSA_KEYLENGTH_IN_BYTES) 4060Sstevel@tonic-gate return (CRYPTO_KEY_SIZE_RANGE); 4070Sstevel@tonic-gate 4080Sstevel@tonic-gate /* EXPORT DELETE END */ 4090Sstevel@tonic-gate 4100Sstevel@tonic-gate return (rv); 4110Sstevel@tonic-gate } 4120Sstevel@tonic-gate 4130Sstevel@tonic-gate void 4140Sstevel@tonic-gate kmemset(uint8_t *buf, char pattern, size_t len) 4150Sstevel@tonic-gate { 4160Sstevel@tonic-gate int i = 0; 4170Sstevel@tonic-gate 4180Sstevel@tonic-gate while (i < len) 4190Sstevel@tonic-gate buf[i++] = pattern; 4200Sstevel@tonic-gate } 4210Sstevel@tonic-gate 4220Sstevel@tonic-gate /* 4230Sstevel@tonic-gate * This function guarantees to return non-zero random numbers. 4240Sstevel@tonic-gate * This is needed as the /dev/urandom kernel interface, 4250Sstevel@tonic-gate * random_get_pseudo_bytes(), may return zeros. 4260Sstevel@tonic-gate */ 4270Sstevel@tonic-gate int 4280Sstevel@tonic-gate knzero_random_generator(uint8_t *ran_out, size_t ran_len) 4290Sstevel@tonic-gate { 4300Sstevel@tonic-gate int rv; 4310Sstevel@tonic-gate size_t ebc = 0; /* count of extra bytes in extrarand */ 4320Sstevel@tonic-gate size_t i = 0; 4330Sstevel@tonic-gate uint8_t extrarand[32]; 4340Sstevel@tonic-gate size_t extrarand_len; 4350Sstevel@tonic-gate 43610732SAnthony.Scarpino@Sun.COM if ((rv = random_get_pseudo_bytes_fips140(ran_out, ran_len)) != 0) 4370Sstevel@tonic-gate return (rv); 4380Sstevel@tonic-gate 4390Sstevel@tonic-gate /* 4400Sstevel@tonic-gate * Walk through the returned random numbers pointed by ran_out, 4410Sstevel@tonic-gate * and look for any random number which is zero. 4420Sstevel@tonic-gate * If we find zero, call random_get_pseudo_bytes() to generate 4430Sstevel@tonic-gate * another 32 random numbers pool. Replace any zeros in ran_out[] 4440Sstevel@tonic-gate * from the random number in pool. 4450Sstevel@tonic-gate */ 4460Sstevel@tonic-gate while (i < ran_len) { 4470Sstevel@tonic-gate if (ran_out[i] != 0) { 4480Sstevel@tonic-gate i++; 4490Sstevel@tonic-gate continue; 4500Sstevel@tonic-gate } 4510Sstevel@tonic-gate 4520Sstevel@tonic-gate /* 4530Sstevel@tonic-gate * Note that it is 'while' so we are guaranteed a 4540Sstevel@tonic-gate * non-zero value on exit. 4550Sstevel@tonic-gate */ 4560Sstevel@tonic-gate if (ebc == 0) { 4570Sstevel@tonic-gate /* refresh extrarand */ 4580Sstevel@tonic-gate extrarand_len = sizeof (extrarand); 45910732SAnthony.Scarpino@Sun.COM if ((rv = random_get_pseudo_bytes_fips140(extrarand, 4600Sstevel@tonic-gate extrarand_len)) != 0) { 4610Sstevel@tonic-gate return (rv); 4620Sstevel@tonic-gate } 4630Sstevel@tonic-gate 4640Sstevel@tonic-gate ebc = extrarand_len; 4650Sstevel@tonic-gate } 4660Sstevel@tonic-gate /* Replace zero with byte from extrarand. */ 4670Sstevel@tonic-gate -- ebc; 4680Sstevel@tonic-gate 4690Sstevel@tonic-gate /* 4700Sstevel@tonic-gate * The new random byte zero/non-zero will be checked in 4710Sstevel@tonic-gate * the next pass through the loop. 4720Sstevel@tonic-gate */ 4730Sstevel@tonic-gate ran_out[i] = extrarand[ebc]; 4740Sstevel@tonic-gate } 4750Sstevel@tonic-gate 4760Sstevel@tonic-gate return (CRYPTO_SUCCESS); 4770Sstevel@tonic-gate } 4780Sstevel@tonic-gate 4790Sstevel@tonic-gate static int 4800Sstevel@tonic-gate compare_data(crypto_data_t *data, uchar_t *buf) 4810Sstevel@tonic-gate { 4820Sstevel@tonic-gate int len; 4830Sstevel@tonic-gate uchar_t *dptr; 4840Sstevel@tonic-gate 4850Sstevel@tonic-gate len = data->cd_length; 4860Sstevel@tonic-gate switch (data->cd_format) { 4870Sstevel@tonic-gate case CRYPTO_DATA_RAW: 4880Sstevel@tonic-gate dptr = (uchar_t *)(data->cd_raw.iov_base + 4890Sstevel@tonic-gate data->cd_offset); 4900Sstevel@tonic-gate 4910Sstevel@tonic-gate return (bcmp(dptr, buf, len)); 4920Sstevel@tonic-gate 4930Sstevel@tonic-gate case CRYPTO_DATA_UIO: 4947188Smcpowers return (crypto_uio_data(data, buf, len, 4957188Smcpowers COMPARE_TO_DATA, NULL, NULL)); 4960Sstevel@tonic-gate 4970Sstevel@tonic-gate case CRYPTO_DATA_MBLK: 4987188Smcpowers return (crypto_mblk_data(data, buf, len, 4997188Smcpowers COMPARE_TO_DATA, NULL, NULL)); 5000Sstevel@tonic-gate } 5010Sstevel@tonic-gate 5020Sstevel@tonic-gate return (CRYPTO_FAILED); 5030Sstevel@tonic-gate } 5040Sstevel@tonic-gate 5050Sstevel@tonic-gate /* ARGSUSED */ 5060Sstevel@tonic-gate static int 5070Sstevel@tonic-gate rsa_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 5080Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t template, 5090Sstevel@tonic-gate crypto_req_handle_t req) 5100Sstevel@tonic-gate { 5110Sstevel@tonic-gate int rv; 5120Sstevel@tonic-gate int kmflag; 5130Sstevel@tonic-gate rsa_ctx_t *ctxp; 5140Sstevel@tonic-gate 5150Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 5160Sstevel@tonic-gate return (rv); 5170Sstevel@tonic-gate 5180Sstevel@tonic-gate /* 5190Sstevel@tonic-gate * Allocate a RSA context. 5200Sstevel@tonic-gate */ 5210Sstevel@tonic-gate kmflag = crypto_kmflag(req); 5220Sstevel@tonic-gate if ((ctxp = kmem_zalloc(sizeof (rsa_ctx_t), kmflag)) == NULL) 5230Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 5240Sstevel@tonic-gate 5257188Smcpowers if ((rv = crypto_copy_key_to_ctx(key, &ctxp->key, &ctxp->keychunk_size, 5267188Smcpowers kmflag)) != CRYPTO_SUCCESS) { 5270Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 5280Sstevel@tonic-gate return (rv); 5290Sstevel@tonic-gate } 5300Sstevel@tonic-gate ctxp->mech_type = mechanism->cm_type; 5310Sstevel@tonic-gate 5320Sstevel@tonic-gate ctx->cc_provider_private = ctxp; 5330Sstevel@tonic-gate 5340Sstevel@tonic-gate return (CRYPTO_SUCCESS); 5350Sstevel@tonic-gate } 5360Sstevel@tonic-gate 5370Sstevel@tonic-gate /* ARGSUSED */ 5380Sstevel@tonic-gate static int 5390Sstevel@tonic-gate rsa_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext, 5400Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_req_handle_t req) 5410Sstevel@tonic-gate { 5420Sstevel@tonic-gate int rv; 5430Sstevel@tonic-gate rsa_ctx_t *ctxp; 5440Sstevel@tonic-gate 5450Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 5460Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 5470Sstevel@tonic-gate 5480Sstevel@tonic-gate RSA_ARG_INPLACE(plaintext, ciphertext); 5490Sstevel@tonic-gate 5500Sstevel@tonic-gate /* 5510Sstevel@tonic-gate * Note on the KM_SLEEP flag passed to the routine below - 5520Sstevel@tonic-gate * rsa_encrypt() is a single-part encryption routine which is 5530Sstevel@tonic-gate * currently usable only by /dev/crypto. Since /dev/crypto calls are 5540Sstevel@tonic-gate * always synchronous, we can safely pass KM_SLEEP here. 5550Sstevel@tonic-gate */ 5560Sstevel@tonic-gate rv = rsa_encrypt_common(ctxp->mech_type, ctxp->key, plaintext, 5570Sstevel@tonic-gate ciphertext, KM_SLEEP); 5580Sstevel@tonic-gate 5590Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 5600Sstevel@tonic-gate (void) rsa_free_context(ctx); 5610Sstevel@tonic-gate 5620Sstevel@tonic-gate return (rv); 5630Sstevel@tonic-gate } 5640Sstevel@tonic-gate 5650Sstevel@tonic-gate /* ARGSUSED */ 5660Sstevel@tonic-gate static int 5670Sstevel@tonic-gate rsa_encrypt_atomic(crypto_provider_handle_t provider, 5680Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 5690Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext, 5700Sstevel@tonic-gate crypto_spi_ctx_template_t template, crypto_req_handle_t req) 5710Sstevel@tonic-gate { 5720Sstevel@tonic-gate int rv; 5730Sstevel@tonic-gate 5740Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 5750Sstevel@tonic-gate return (rv); 5760Sstevel@tonic-gate RSA_ARG_INPLACE(plaintext, ciphertext); 5770Sstevel@tonic-gate 5780Sstevel@tonic-gate return (rsa_encrypt_common(mechanism->cm_type, key, plaintext, 5790Sstevel@tonic-gate ciphertext, crypto_kmflag(req))); 5800Sstevel@tonic-gate } 5810Sstevel@tonic-gate 5820Sstevel@tonic-gate static int 5830Sstevel@tonic-gate rsa_free_context(crypto_ctx_t *ctx) 5840Sstevel@tonic-gate { 5850Sstevel@tonic-gate rsa_ctx_t *ctxp = ctx->cc_provider_private; 5860Sstevel@tonic-gate 5870Sstevel@tonic-gate if (ctxp != NULL) { 5880Sstevel@tonic-gate bzero(ctxp->key, ctxp->keychunk_size); 5890Sstevel@tonic-gate kmem_free(ctxp->key, ctxp->keychunk_size); 5900Sstevel@tonic-gate 5910Sstevel@tonic-gate if (ctxp->mech_type == RSA_PKCS_MECH_INFO_TYPE || 5920Sstevel@tonic-gate ctxp->mech_type == RSA_X_509_MECH_INFO_TYPE) 5930Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 5940Sstevel@tonic-gate else 5950Sstevel@tonic-gate kmem_free(ctxp, sizeof (digest_rsa_ctx_t)); 5960Sstevel@tonic-gate 5970Sstevel@tonic-gate ctx->cc_provider_private = NULL; 5980Sstevel@tonic-gate } 5990Sstevel@tonic-gate 6000Sstevel@tonic-gate return (CRYPTO_SUCCESS); 6010Sstevel@tonic-gate } 6020Sstevel@tonic-gate 6030Sstevel@tonic-gate static int 6040Sstevel@tonic-gate rsa_encrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key, 6050Sstevel@tonic-gate crypto_data_t *plaintext, crypto_data_t *ciphertext, int kmflag) 6060Sstevel@tonic-gate { 6070Sstevel@tonic-gate int rv = CRYPTO_FAILED; 6080Sstevel@tonic-gate 6090Sstevel@tonic-gate /* EXPORT DELETE START */ 6100Sstevel@tonic-gate 6110Sstevel@tonic-gate int plen; 6120Sstevel@tonic-gate uchar_t *ptptr; 6130Sstevel@tonic-gate uchar_t *modulus; 6140Sstevel@tonic-gate ssize_t modulus_len; 6150Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 6160Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 6170Sstevel@tonic-gate uchar_t cipher_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 6180Sstevel@tonic-gate 6197188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 6200Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 6210Sstevel@tonic-gate return (rv); 6220Sstevel@tonic-gate } 6230Sstevel@tonic-gate 6240Sstevel@tonic-gate plen = plaintext->cd_length; 6250Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 6260Sstevel@tonic-gate if (plen > (modulus_len - MIN_PKCS1_PADLEN)) 6270Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 6280Sstevel@tonic-gate } else { 6290Sstevel@tonic-gate if (plen > modulus_len) 6300Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 6310Sstevel@tonic-gate } 6320Sstevel@tonic-gate 6330Sstevel@tonic-gate /* 6340Sstevel@tonic-gate * Output buf len must not be less than RSA modulus size. 6350Sstevel@tonic-gate */ 6360Sstevel@tonic-gate if (ciphertext->cd_length < modulus_len) { 6370Sstevel@tonic-gate ciphertext->cd_length = modulus_len; 6380Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 6390Sstevel@tonic-gate } 6400Sstevel@tonic-gate 6410Sstevel@tonic-gate ASSERT(plaintext->cd_length <= sizeof (tmp_data)); 6427188Smcpowers if ((rv = crypto_get_input_data(plaintext, &ptptr, tmp_data)) 6430Sstevel@tonic-gate != CRYPTO_SUCCESS) 6440Sstevel@tonic-gate return (rv); 6450Sstevel@tonic-gate 6460Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 6470Sstevel@tonic-gate rv = soft_encrypt_rsa_pkcs_encode(ptptr, plen, 6480Sstevel@tonic-gate plain_data, modulus_len); 6490Sstevel@tonic-gate 6500Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 6510Sstevel@tonic-gate return (rv); 6520Sstevel@tonic-gate } else { 6530Sstevel@tonic-gate bzero(plain_data, modulus_len - plen); 6540Sstevel@tonic-gate bcopy(ptptr, &plain_data[modulus_len - plen], plen); 6550Sstevel@tonic-gate } 6560Sstevel@tonic-gate 6570Sstevel@tonic-gate rv = core_rsa_encrypt(key, plain_data, modulus_len, 6580Sstevel@tonic-gate cipher_data, kmflag, 1); 6590Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 6600Sstevel@tonic-gate /* copy out to ciphertext */ 6617188Smcpowers if ((rv = crypto_put_output_data(cipher_data, 6620Sstevel@tonic-gate ciphertext, modulus_len)) != CRYPTO_SUCCESS) 6630Sstevel@tonic-gate return (rv); 6640Sstevel@tonic-gate 6650Sstevel@tonic-gate ciphertext->cd_length = modulus_len; 6660Sstevel@tonic-gate } 6670Sstevel@tonic-gate 6680Sstevel@tonic-gate /* EXPORT DELETE END */ 6690Sstevel@tonic-gate 6700Sstevel@tonic-gate return (rv); 6710Sstevel@tonic-gate } 6720Sstevel@tonic-gate 6730Sstevel@tonic-gate /* EXPORT DELETE START */ 6740Sstevel@tonic-gate 6750Sstevel@tonic-gate static int 6760Sstevel@tonic-gate core_rsa_encrypt(crypto_key_t *key, uchar_t *in, 6770Sstevel@tonic-gate int in_len, uchar_t *out, int kmflag, int is_public) 6780Sstevel@tonic-gate { 6790Sstevel@tonic-gate int rv; 6800Sstevel@tonic-gate uchar_t *expo, *modulus; 6810Sstevel@tonic-gate ssize_t expo_len; 6820Sstevel@tonic-gate ssize_t modulus_len; 6830Sstevel@tonic-gate BIGNUM msg; 6840Sstevel@tonic-gate RSAkey *rsakey; 6850Sstevel@tonic-gate 6860Sstevel@tonic-gate if (is_public) { 6877188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_PUBLIC_EXPONENT, 6887188Smcpowers &expo, &expo_len)) != CRYPTO_SUCCESS) 6890Sstevel@tonic-gate return (rv); 6900Sstevel@tonic-gate } else { 6910Sstevel@tonic-gate /* 6920Sstevel@tonic-gate * SUN_CKA_PRIVATE_EXPONENT is a required attribute for a 6930Sstevel@tonic-gate * RSA secret key. See the comments in core_rsa_decrypt 6940Sstevel@tonic-gate * routine which calls this routine with a private key. 6950Sstevel@tonic-gate */ 6967188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_PRIVATE_EXPONENT, 6977188Smcpowers &expo, &expo_len)) != CRYPTO_SUCCESS) 6980Sstevel@tonic-gate return (rv); 6990Sstevel@tonic-gate } 7000Sstevel@tonic-gate 7017188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 7020Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 7030Sstevel@tonic-gate return (rv); 7040Sstevel@tonic-gate } 7050Sstevel@tonic-gate 7060Sstevel@tonic-gate rsakey = kmem_alloc(sizeof (RSAkey), kmflag); 7070Sstevel@tonic-gate if (rsakey == NULL) 7080Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 7090Sstevel@tonic-gate 7100Sstevel@tonic-gate /* psize and qsize for RSA_key_init is in bits. */ 7110Sstevel@tonic-gate if (RSA_key_init(rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) { 7120Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 7130Sstevel@tonic-gate goto clean1; 7140Sstevel@tonic-gate } 7150Sstevel@tonic-gate 7166557Sfr41279 /* Size for big_init is in BIG_CHUNK_TYPE words. */ 7176557Sfr41279 if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) { 7180Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 7190Sstevel@tonic-gate goto clean2; 7200Sstevel@tonic-gate } 7210Sstevel@tonic-gate 7220Sstevel@tonic-gate /* Convert octet string exponent to big integer format. */ 7230Sstevel@tonic-gate bytestring2bignum(&(rsakey->e), expo, expo_len); 7240Sstevel@tonic-gate 7250Sstevel@tonic-gate /* Convert octet string modulus to big integer format. */ 7260Sstevel@tonic-gate bytestring2bignum(&(rsakey->n), modulus, modulus_len); 7270Sstevel@tonic-gate 7280Sstevel@tonic-gate /* Convert octet string input data to big integer format. */ 7290Sstevel@tonic-gate bytestring2bignum(&msg, in, in_len); 7300Sstevel@tonic-gate 7310Sstevel@tonic-gate if (big_cmp_abs(&msg, &(rsakey->n)) > 0) { 7320Sstevel@tonic-gate rv = CRYPTO_DATA_LEN_RANGE; 7330Sstevel@tonic-gate goto clean3; 7340Sstevel@tonic-gate } 7350Sstevel@tonic-gate 7360Sstevel@tonic-gate /* Perform RSA computation on big integer input data. */ 7370Sstevel@tonic-gate if (big_modexp(&msg, &msg, &(rsakey->e), &(rsakey->n), NULL) 7380Sstevel@tonic-gate != BIG_OK) { 7390Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 7400Sstevel@tonic-gate goto clean3; 7410Sstevel@tonic-gate } 7420Sstevel@tonic-gate 7430Sstevel@tonic-gate /* Convert the big integer output data to octet string. */ 7440Sstevel@tonic-gate bignum2bytestring(out, &msg, modulus_len); 7450Sstevel@tonic-gate 7460Sstevel@tonic-gate /* 7470Sstevel@tonic-gate * Should not free modulus and expo as both are just pointers 7480Sstevel@tonic-gate * to an attribute value buffer from the caller. 7490Sstevel@tonic-gate */ 7500Sstevel@tonic-gate clean3: 7510Sstevel@tonic-gate big_finish(&msg); 7520Sstevel@tonic-gate clean2: 7530Sstevel@tonic-gate RSA_key_finish(rsakey); 7540Sstevel@tonic-gate clean1: 7550Sstevel@tonic-gate kmem_free(rsakey, sizeof (RSAkey)); 7560Sstevel@tonic-gate 7570Sstevel@tonic-gate return (rv); 7580Sstevel@tonic-gate } 7590Sstevel@tonic-gate 7600Sstevel@tonic-gate /* EXPORT DELETE END */ 7610Sstevel@tonic-gate 7620Sstevel@tonic-gate /* ARGSUSED */ 7630Sstevel@tonic-gate static int 7640Sstevel@tonic-gate rsa_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext, 7650Sstevel@tonic-gate crypto_data_t *plaintext, crypto_req_handle_t req) 7660Sstevel@tonic-gate { 7670Sstevel@tonic-gate int rv; 7680Sstevel@tonic-gate rsa_ctx_t *ctxp; 7690Sstevel@tonic-gate 7700Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 7710Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 7720Sstevel@tonic-gate 7730Sstevel@tonic-gate RSA_ARG_INPLACE(ciphertext, plaintext); 7740Sstevel@tonic-gate 7750Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 7760Sstevel@tonic-gate rv = rsa_decrypt_common(ctxp->mech_type, ctxp->key, 7770Sstevel@tonic-gate ciphertext, plaintext, KM_SLEEP); 7780Sstevel@tonic-gate 7790Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 7800Sstevel@tonic-gate (void) rsa_free_context(ctx); 7810Sstevel@tonic-gate 7820Sstevel@tonic-gate return (rv); 7830Sstevel@tonic-gate } 7840Sstevel@tonic-gate 7850Sstevel@tonic-gate /* ARGSUSED */ 7860Sstevel@tonic-gate static int 7870Sstevel@tonic-gate rsa_decrypt_atomic(crypto_provider_handle_t provider, 7880Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 7890Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext, 7900Sstevel@tonic-gate crypto_spi_ctx_template_t template, crypto_req_handle_t req) 7910Sstevel@tonic-gate { 7920Sstevel@tonic-gate int rv; 7930Sstevel@tonic-gate 7940Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 7950Sstevel@tonic-gate return (rv); 7960Sstevel@tonic-gate RSA_ARG_INPLACE(ciphertext, plaintext); 7970Sstevel@tonic-gate 7980Sstevel@tonic-gate return (rsa_decrypt_common(mechanism->cm_type, key, ciphertext, 7990Sstevel@tonic-gate plaintext, crypto_kmflag(req))); 8000Sstevel@tonic-gate } 8010Sstevel@tonic-gate 8020Sstevel@tonic-gate static int 8030Sstevel@tonic-gate rsa_decrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key, 8040Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_data_t *plaintext, int kmflag) 8050Sstevel@tonic-gate { 8060Sstevel@tonic-gate int rv = CRYPTO_FAILED; 8070Sstevel@tonic-gate 8080Sstevel@tonic-gate /* EXPORT DELETE START */ 8090Sstevel@tonic-gate 8100Sstevel@tonic-gate int plain_len; 8110Sstevel@tonic-gate uchar_t *ctptr; 8120Sstevel@tonic-gate uchar_t *modulus; 8130Sstevel@tonic-gate ssize_t modulus_len; 8140Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 8150Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 8160Sstevel@tonic-gate 8177188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 8180Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 8190Sstevel@tonic-gate return (rv); 8200Sstevel@tonic-gate } 8210Sstevel@tonic-gate 8220Sstevel@tonic-gate /* 8230Sstevel@tonic-gate * Ciphertext length must be equal to RSA modulus size. 8240Sstevel@tonic-gate */ 8250Sstevel@tonic-gate if (ciphertext->cd_length != modulus_len) 8260Sstevel@tonic-gate return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 8270Sstevel@tonic-gate 8280Sstevel@tonic-gate ASSERT(ciphertext->cd_length <= sizeof (tmp_data)); 8297188Smcpowers if ((rv = crypto_get_input_data(ciphertext, &ctptr, tmp_data)) 8300Sstevel@tonic-gate != CRYPTO_SUCCESS) 8310Sstevel@tonic-gate return (rv); 8320Sstevel@tonic-gate 8330Sstevel@tonic-gate rv = core_rsa_decrypt(key, ctptr, modulus_len, plain_data, kmflag); 8340Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 8350Sstevel@tonic-gate plain_len = modulus_len; 8360Sstevel@tonic-gate 8370Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 8380Sstevel@tonic-gate /* Strip off the PKCS block formatting data. */ 8390Sstevel@tonic-gate rv = soft_decrypt_rsa_pkcs_decode(plain_data, 8400Sstevel@tonic-gate &plain_len); 8410Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 8420Sstevel@tonic-gate return (rv); 8430Sstevel@tonic-gate } 8440Sstevel@tonic-gate 8450Sstevel@tonic-gate if (plain_len > plaintext->cd_length) { 8460Sstevel@tonic-gate plaintext->cd_length = plain_len; 8470Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 8480Sstevel@tonic-gate } 8490Sstevel@tonic-gate 8507188Smcpowers if ((rv = crypto_put_output_data( 8517188Smcpowers plain_data + modulus_len - plain_len, 8520Sstevel@tonic-gate plaintext, plain_len)) != CRYPTO_SUCCESS) 8530Sstevel@tonic-gate return (rv); 8540Sstevel@tonic-gate 8550Sstevel@tonic-gate plaintext->cd_length = plain_len; 8560Sstevel@tonic-gate } 8570Sstevel@tonic-gate 8580Sstevel@tonic-gate /* EXPORT DELETE END */ 8590Sstevel@tonic-gate 8600Sstevel@tonic-gate return (rv); 8610Sstevel@tonic-gate } 8620Sstevel@tonic-gate 8630Sstevel@tonic-gate /* EXPORT DELETE START */ 8640Sstevel@tonic-gate 8650Sstevel@tonic-gate static int 8660Sstevel@tonic-gate core_rsa_decrypt(crypto_key_t *key, uchar_t *in, int in_len, 8670Sstevel@tonic-gate uchar_t *out, int kmflag) 8680Sstevel@tonic-gate { 8690Sstevel@tonic-gate int rv; 8700Sstevel@tonic-gate uchar_t *modulus, *prime1, *prime2, *expo1, *expo2, *coef; 8710Sstevel@tonic-gate ssize_t modulus_len; 8720Sstevel@tonic-gate ssize_t prime1_len, prime2_len; 8730Sstevel@tonic-gate ssize_t expo1_len, expo2_len, coef_len; 8740Sstevel@tonic-gate BIGNUM msg; 8750Sstevel@tonic-gate RSAkey *rsakey; 8760Sstevel@tonic-gate 8777188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 8780Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 8790Sstevel@tonic-gate return (rv); 8800Sstevel@tonic-gate } 8810Sstevel@tonic-gate 8820Sstevel@tonic-gate /* 8830Sstevel@tonic-gate * The following attributes are not required to be 8840Sstevel@tonic-gate * present in a RSA secret key. If any of them is not present 8850Sstevel@tonic-gate * we call the encrypt routine with a flag indicating use of 8860Sstevel@tonic-gate * private exponent (d). Note that SUN_CKA_PRIVATE_EXPONENT is 8870Sstevel@tonic-gate * a required attribute for a RSA secret key. 8880Sstevel@tonic-gate */ 8897188Smcpowers if ((crypto_get_key_attr(key, SUN_CKA_PRIME_1, &prime1, &prime1_len) 8905072Smcpowers != CRYPTO_SUCCESS) || 8917188Smcpowers (crypto_get_key_attr(key, SUN_CKA_PRIME_2, &prime2, &prime2_len) 8925072Smcpowers != CRYPTO_SUCCESS) || 8937188Smcpowers (crypto_get_key_attr(key, SUN_CKA_EXPONENT_1, &expo1, &expo1_len) 8945072Smcpowers != CRYPTO_SUCCESS) || 8957188Smcpowers (crypto_get_key_attr(key, SUN_CKA_EXPONENT_2, &expo2, &expo2_len) 8965072Smcpowers != CRYPTO_SUCCESS) || 8977188Smcpowers (crypto_get_key_attr(key, SUN_CKA_COEFFICIENT, &coef, &coef_len) 8985072Smcpowers != CRYPTO_SUCCESS)) { 8990Sstevel@tonic-gate return (core_rsa_encrypt(key, in, in_len, out, kmflag, 0)); 9000Sstevel@tonic-gate } 9010Sstevel@tonic-gate 9020Sstevel@tonic-gate rsakey = kmem_alloc(sizeof (RSAkey), kmflag); 9030Sstevel@tonic-gate if (rsakey == NULL) 9040Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 9050Sstevel@tonic-gate 9060Sstevel@tonic-gate /* psize and qsize for RSA_key_init is in bits. */ 90711413Sopensolaris@drydog.com if (RSA_key_init(rsakey, CRYPTO_BYTES2BITS(prime2_len), 90811413Sopensolaris@drydog.com CRYPTO_BYTES2BITS(prime1_len)) != BIG_OK) { 9090Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 9100Sstevel@tonic-gate goto clean1; 9110Sstevel@tonic-gate } 9120Sstevel@tonic-gate 9136557Sfr41279 /* Size for big_init is in BIG_CHUNK_TYPE words. */ 9146557Sfr41279 if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) { 9150Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 9160Sstevel@tonic-gate goto clean2; 9170Sstevel@tonic-gate } 9180Sstevel@tonic-gate 9190Sstevel@tonic-gate /* Convert octet string input data to big integer format. */ 9200Sstevel@tonic-gate bytestring2bignum(&msg, in, in_len); 9210Sstevel@tonic-gate 9220Sstevel@tonic-gate /* Convert octet string modulus to big integer format. */ 9230Sstevel@tonic-gate bytestring2bignum(&(rsakey->n), modulus, modulus_len); 9240Sstevel@tonic-gate 9250Sstevel@tonic-gate if (big_cmp_abs(&msg, &(rsakey->n)) > 0) { 9260Sstevel@tonic-gate rv = CRYPTO_DATA_LEN_RANGE; 9270Sstevel@tonic-gate goto clean3; 9280Sstevel@tonic-gate } 9290Sstevel@tonic-gate 9300Sstevel@tonic-gate /* Convert the rest of private key attributes to big integer format. */ 9310Sstevel@tonic-gate bytestring2bignum(&(rsakey->dmodpminus1), expo2, expo2_len); 9320Sstevel@tonic-gate bytestring2bignum(&(rsakey->dmodqminus1), expo1, expo1_len); 9330Sstevel@tonic-gate bytestring2bignum(&(rsakey->p), prime2, prime2_len); 9340Sstevel@tonic-gate bytestring2bignum(&(rsakey->q), prime1, prime1_len); 9350Sstevel@tonic-gate bytestring2bignum(&(rsakey->pinvmodq), coef, coef_len); 9360Sstevel@tonic-gate 9370Sstevel@tonic-gate if ((big_cmp_abs(&(rsakey->dmodpminus1), &(rsakey->p)) > 0) || 9380Sstevel@tonic-gate (big_cmp_abs(&(rsakey->dmodqminus1), &(rsakey->q)) > 0) || 9390Sstevel@tonic-gate (big_cmp_abs(&(rsakey->pinvmodq), &(rsakey->q)) > 0)) { 9400Sstevel@tonic-gate rv = CRYPTO_KEY_SIZE_RANGE; 9410Sstevel@tonic-gate goto clean3; 9420Sstevel@tonic-gate } 9430Sstevel@tonic-gate 9440Sstevel@tonic-gate /* Perform RSA computation on big integer input data. */ 9450Sstevel@tonic-gate if (big_modexp_crt(&msg, &msg, &(rsakey->dmodpminus1), 9460Sstevel@tonic-gate &(rsakey->dmodqminus1), &(rsakey->p), &(rsakey->q), 9470Sstevel@tonic-gate &(rsakey->pinvmodq), NULL, NULL) != BIG_OK) { 9480Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 9490Sstevel@tonic-gate goto clean3; 9500Sstevel@tonic-gate } 9510Sstevel@tonic-gate 9520Sstevel@tonic-gate /* Convert the big integer output data to octet string. */ 9530Sstevel@tonic-gate bignum2bytestring(out, &msg, modulus_len); 9540Sstevel@tonic-gate 9550Sstevel@tonic-gate /* 9560Sstevel@tonic-gate * Should not free modulus and friends as they are just pointers 9570Sstevel@tonic-gate * to an attribute value buffer from the caller. 9580Sstevel@tonic-gate */ 9590Sstevel@tonic-gate clean3: 9600Sstevel@tonic-gate big_finish(&msg); 9610Sstevel@tonic-gate clean2: 9620Sstevel@tonic-gate RSA_key_finish(rsakey); 9630Sstevel@tonic-gate clean1: 9640Sstevel@tonic-gate kmem_free(rsakey, sizeof (RSAkey)); 9650Sstevel@tonic-gate 9660Sstevel@tonic-gate return (rv); 9670Sstevel@tonic-gate } 9680Sstevel@tonic-gate 9690Sstevel@tonic-gate /* EXPORT DELETE END */ 9700Sstevel@tonic-gate 9710Sstevel@tonic-gate /* ARGSUSED */ 9720Sstevel@tonic-gate static int 9730Sstevel@tonic-gate rsa_sign_verify_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 9740Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 9750Sstevel@tonic-gate crypto_req_handle_t req) 9760Sstevel@tonic-gate { 9770Sstevel@tonic-gate int rv; 9780Sstevel@tonic-gate int kmflag; 9790Sstevel@tonic-gate rsa_ctx_t *ctxp; 9800Sstevel@tonic-gate digest_rsa_ctx_t *dctxp; 9810Sstevel@tonic-gate 9820Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 9830Sstevel@tonic-gate return (rv); 9840Sstevel@tonic-gate 9850Sstevel@tonic-gate /* 9860Sstevel@tonic-gate * Allocate a RSA context. 9870Sstevel@tonic-gate */ 9880Sstevel@tonic-gate kmflag = crypto_kmflag(req); 9890Sstevel@tonic-gate switch (mechanism->cm_type) { 9900Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 9910Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 992676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 993676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 994676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 9950Sstevel@tonic-gate dctxp = kmem_zalloc(sizeof (digest_rsa_ctx_t), kmflag); 9960Sstevel@tonic-gate ctxp = (rsa_ctx_t *)dctxp; 9970Sstevel@tonic-gate break; 9980Sstevel@tonic-gate default: 9990Sstevel@tonic-gate ctxp = kmem_zalloc(sizeof (rsa_ctx_t), kmflag); 10000Sstevel@tonic-gate break; 10010Sstevel@tonic-gate } 10020Sstevel@tonic-gate 10030Sstevel@tonic-gate if (ctxp == NULL) 10040Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 10050Sstevel@tonic-gate 10060Sstevel@tonic-gate ctxp->mech_type = mechanism->cm_type; 10077188Smcpowers if ((rv = crypto_copy_key_to_ctx(key, &ctxp->key, &ctxp->keychunk_size, 10087188Smcpowers kmflag)) != CRYPTO_SUCCESS) { 10090Sstevel@tonic-gate switch (mechanism->cm_type) { 10100Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 10110Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1012676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1013676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1014676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 10150Sstevel@tonic-gate kmem_free(dctxp, sizeof (digest_rsa_ctx_t)); 10160Sstevel@tonic-gate break; 10170Sstevel@tonic-gate default: 10180Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 10190Sstevel@tonic-gate break; 10200Sstevel@tonic-gate } 10210Sstevel@tonic-gate return (rv); 10220Sstevel@tonic-gate } 10230Sstevel@tonic-gate 10240Sstevel@tonic-gate switch (mechanism->cm_type) { 10250Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 10260Sstevel@tonic-gate MD5Init(&(dctxp->md5_ctx)); 10270Sstevel@tonic-gate break; 10280Sstevel@tonic-gate 10290Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 10300Sstevel@tonic-gate SHA1Init(&(dctxp->sha1_ctx)); 10310Sstevel@tonic-gate break; 1032676Sizick 1033676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1034676Sizick SHA2Init(SHA256, &(dctxp->sha2_ctx)); 1035676Sizick break; 1036676Sizick 1037676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1038676Sizick SHA2Init(SHA384, &(dctxp->sha2_ctx)); 1039676Sizick break; 1040676Sizick 1041676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1042676Sizick SHA2Init(SHA512, &(dctxp->sha2_ctx)); 1043676Sizick break; 10440Sstevel@tonic-gate } 10450Sstevel@tonic-gate 10460Sstevel@tonic-gate ctx->cc_provider_private = ctxp; 10470Sstevel@tonic-gate 10480Sstevel@tonic-gate return (CRYPTO_SUCCESS); 10490Sstevel@tonic-gate } 10500Sstevel@tonic-gate 10510Sstevel@tonic-gate #define SHA1_DIGEST_SIZE 20 10520Sstevel@tonic-gate #define MD5_DIGEST_SIZE 16 10530Sstevel@tonic-gate 10540Sstevel@tonic-gate #define INIT_RAW_CRYPTO_DATA(data, base, len, cd_len) \ 10550Sstevel@tonic-gate (data).cd_format = CRYPTO_DATA_RAW; \ 10560Sstevel@tonic-gate (data).cd_offset = 0; \ 10570Sstevel@tonic-gate (data).cd_raw.iov_base = (char *)base; \ 10580Sstevel@tonic-gate (data).cd_raw.iov_len = len; \ 10590Sstevel@tonic-gate (data).cd_length = cd_len; 10600Sstevel@tonic-gate 10610Sstevel@tonic-gate static int 10620Sstevel@tonic-gate rsa_digest_svrfy_common(digest_rsa_ctx_t *ctxp, crypto_data_t *data, 10630Sstevel@tonic-gate crypto_data_t *signature, int kmflag, uchar_t flag) 10640Sstevel@tonic-gate { 10650Sstevel@tonic-gate int rv = CRYPTO_FAILED; 10660Sstevel@tonic-gate 10670Sstevel@tonic-gate /* EXPORT DELETE START */ 10680Sstevel@tonic-gate 1069676Sizick uchar_t digest[SHA512_DIGEST_LENGTH]; 10700Sstevel@tonic-gate /* The der_data size is enough for MD5 also */ 1071676Sizick uchar_t der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len]; 10720Sstevel@tonic-gate ulong_t der_data_len; 10730Sstevel@tonic-gate crypto_data_t der_cd; 10740Sstevel@tonic-gate rsa_mech_type_t mech_type; 10750Sstevel@tonic-gate 10767188Smcpowers ASSERT(flag & CRYPTO_DO_SIGN || flag & CRYPTO_DO_VERIFY); 10777188Smcpowers ASSERT(data != NULL || (flag & CRYPTO_DO_FINAL)); 10780Sstevel@tonic-gate 10790Sstevel@tonic-gate mech_type = ctxp->mech_type; 1080676Sizick if (mech_type == RSA_PKCS_MECH_INFO_TYPE || 1081676Sizick mech_type == RSA_X_509_MECH_INFO_TYPE) 10820Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 10830Sstevel@tonic-gate 10840Sstevel@tonic-gate /* 10850Sstevel@tonic-gate * We need to do the BUFFER_TOO_SMALL check before digesting 10860Sstevel@tonic-gate * the data. No check is needed for verify as signature is not 10870Sstevel@tonic-gate * an output argument for verify. 10880Sstevel@tonic-gate */ 10897188Smcpowers if (flag & CRYPTO_DO_SIGN) { 10900Sstevel@tonic-gate uchar_t *modulus; 10910Sstevel@tonic-gate ssize_t modulus_len; 10920Sstevel@tonic-gate 10937188Smcpowers if ((rv = crypto_get_key_attr(ctxp->key, SUN_CKA_MODULUS, 10947188Smcpowers &modulus, &modulus_len)) != CRYPTO_SUCCESS) { 10950Sstevel@tonic-gate return (rv); 10960Sstevel@tonic-gate } 10970Sstevel@tonic-gate 10980Sstevel@tonic-gate if (signature->cd_length < modulus_len) { 10990Sstevel@tonic-gate signature->cd_length = modulus_len; 11000Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 11010Sstevel@tonic-gate } 11020Sstevel@tonic-gate } 11030Sstevel@tonic-gate 11040Sstevel@tonic-gate if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE) 11057188Smcpowers rv = crypto_digest_data(data, &(ctxp->md5_ctx), 11067188Smcpowers digest, MD5Update, MD5Final, flag | CRYPTO_DO_MD5); 1107676Sizick 1108676Sizick else if (mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE) 11097188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha1_ctx), 11107188Smcpowers digest, SHA1Update, SHA1Final, flag | CRYPTO_DO_SHA1); 1111676Sizick 1112676Sizick else 11137188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha2_ctx), 11147188Smcpowers digest, SHA2Update, SHA2Final, flag | CRYPTO_DO_SHA2); 1115676Sizick 11160Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 11170Sstevel@tonic-gate return (rv); 11180Sstevel@tonic-gate 1119676Sizick 11200Sstevel@tonic-gate /* 11210Sstevel@tonic-gate * Prepare the DER encoding of the DigestInfo value as follows: 11220Sstevel@tonic-gate * MD5: MD5_DER_PREFIX || H 11230Sstevel@tonic-gate * SHA-1: SHA1_DER_PREFIX || H 11240Sstevel@tonic-gate * 11250Sstevel@tonic-gate * See rsa_impl.c for more details. 11260Sstevel@tonic-gate */ 1127676Sizick switch (mech_type) { 1128676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 11290Sstevel@tonic-gate bcopy(MD5_DER_PREFIX, der_data, MD5_DER_PREFIX_Len); 1130676Sizick bcopy(digest, der_data + MD5_DER_PREFIX_Len, MD5_DIGEST_SIZE); 1131676Sizick der_data_len = MD5_DER_PREFIX_Len + MD5_DIGEST_SIZE; 1132676Sizick break; 1133676Sizick 1134676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 11350Sstevel@tonic-gate bcopy(SHA1_DER_PREFIX, der_data, SHA1_DER_PREFIX_Len); 1136676Sizick bcopy(digest, der_data + SHA1_DER_PREFIX_Len, 1137676Sizick SHA1_DIGEST_SIZE); 1138676Sizick der_data_len = SHA1_DER_PREFIX_Len + SHA1_DIGEST_SIZE; 1139676Sizick break; 1140676Sizick 1141676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1142676Sizick bcopy(SHA256_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len); 1143676Sizick bcopy(digest, der_data + SHA2_DER_PREFIX_Len, 1144676Sizick SHA256_DIGEST_LENGTH); 1145676Sizick der_data_len = SHA2_DER_PREFIX_Len + SHA256_DIGEST_LENGTH; 1146676Sizick break; 1147676Sizick 1148676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1149676Sizick bcopy(SHA384_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len); 1150676Sizick bcopy(digest, der_data + SHA2_DER_PREFIX_Len, 1151676Sizick SHA384_DIGEST_LENGTH); 1152676Sizick der_data_len = SHA2_DER_PREFIX_Len + SHA384_DIGEST_LENGTH; 1153676Sizick break; 1154676Sizick 1155676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1156676Sizick bcopy(SHA512_DER_PREFIX, der_data, SHA2_DER_PREFIX_Len); 1157676Sizick bcopy(digest, der_data + SHA2_DER_PREFIX_Len, 1158676Sizick SHA512_DIGEST_LENGTH); 1159676Sizick der_data_len = SHA2_DER_PREFIX_Len + SHA512_DIGEST_LENGTH; 1160676Sizick break; 11610Sstevel@tonic-gate } 11620Sstevel@tonic-gate 11630Sstevel@tonic-gate INIT_RAW_CRYPTO_DATA(der_cd, der_data, der_data_len, der_data_len); 11640Sstevel@tonic-gate /* 11650Sstevel@tonic-gate * Now, we are ready to sign or verify the DER_ENCODED data. 11660Sstevel@tonic-gate */ 11677188Smcpowers if (flag & CRYPTO_DO_SIGN) 11680Sstevel@tonic-gate rv = rsa_sign_common(mech_type, ctxp->key, &der_cd, 11690Sstevel@tonic-gate signature, kmflag); 11700Sstevel@tonic-gate else 11710Sstevel@tonic-gate rv = rsa_verify_common(mech_type, ctxp->key, &der_cd, 11720Sstevel@tonic-gate signature, kmflag); 11730Sstevel@tonic-gate 11740Sstevel@tonic-gate /* EXPORT DELETE END */ 11750Sstevel@tonic-gate 11760Sstevel@tonic-gate return (rv); 11770Sstevel@tonic-gate } 11780Sstevel@tonic-gate 11790Sstevel@tonic-gate static int 11800Sstevel@tonic-gate rsa_sign_common(rsa_mech_type_t mech_type, crypto_key_t *key, 11810Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *signature, int kmflag) 11820Sstevel@tonic-gate { 11830Sstevel@tonic-gate int rv = CRYPTO_FAILED; 11840Sstevel@tonic-gate 11850Sstevel@tonic-gate /* EXPORT DELETE START */ 11860Sstevel@tonic-gate 11870Sstevel@tonic-gate int dlen; 11880Sstevel@tonic-gate uchar_t *dataptr, *modulus; 11890Sstevel@tonic-gate ssize_t modulus_len; 11900Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 11910Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 11920Sstevel@tonic-gate uchar_t signed_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 11930Sstevel@tonic-gate 11947188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 11950Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 11960Sstevel@tonic-gate return (rv); 11970Sstevel@tonic-gate } 11980Sstevel@tonic-gate 11990Sstevel@tonic-gate dlen = data->cd_length; 12000Sstevel@tonic-gate switch (mech_type) { 12010Sstevel@tonic-gate case RSA_PKCS_MECH_INFO_TYPE: 12020Sstevel@tonic-gate if (dlen > (modulus_len - MIN_PKCS1_PADLEN)) 12030Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 12040Sstevel@tonic-gate break; 12050Sstevel@tonic-gate case RSA_X_509_MECH_INFO_TYPE: 12060Sstevel@tonic-gate if (dlen > modulus_len) 12070Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 12080Sstevel@tonic-gate break; 12090Sstevel@tonic-gate } 12100Sstevel@tonic-gate 12110Sstevel@tonic-gate if (signature->cd_length < modulus_len) { 12120Sstevel@tonic-gate signature->cd_length = modulus_len; 12130Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 12140Sstevel@tonic-gate } 12150Sstevel@tonic-gate 12160Sstevel@tonic-gate ASSERT(data->cd_length <= sizeof (tmp_data)); 12177188Smcpowers if ((rv = crypto_get_input_data(data, &dataptr, tmp_data)) 12180Sstevel@tonic-gate != CRYPTO_SUCCESS) 12190Sstevel@tonic-gate return (rv); 12200Sstevel@tonic-gate 12210Sstevel@tonic-gate switch (mech_type) { 12220Sstevel@tonic-gate case RSA_PKCS_MECH_INFO_TYPE: 12230Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 12240Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1225676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1226676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1227676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 12280Sstevel@tonic-gate /* 12290Sstevel@tonic-gate * Add PKCS padding to the input data to format a block 12300Sstevel@tonic-gate * type "01" encryption block. 12310Sstevel@tonic-gate */ 12320Sstevel@tonic-gate rv = soft_sign_rsa_pkcs_encode(dataptr, dlen, plain_data, 12330Sstevel@tonic-gate modulus_len); 12340Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 12350Sstevel@tonic-gate return (rv); 12360Sstevel@tonic-gate 12370Sstevel@tonic-gate break; 12380Sstevel@tonic-gate 12390Sstevel@tonic-gate case RSA_X_509_MECH_INFO_TYPE: 12400Sstevel@tonic-gate bzero(plain_data, modulus_len - dlen); 12410Sstevel@tonic-gate bcopy(dataptr, &plain_data[modulus_len - dlen], dlen); 12420Sstevel@tonic-gate break; 12430Sstevel@tonic-gate } 12440Sstevel@tonic-gate 12450Sstevel@tonic-gate rv = core_rsa_decrypt(key, plain_data, modulus_len, signed_data, 12460Sstevel@tonic-gate kmflag); 12470Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 12480Sstevel@tonic-gate /* copy out to signature */ 12497188Smcpowers if ((rv = crypto_put_output_data(signed_data, 12500Sstevel@tonic-gate signature, modulus_len)) != CRYPTO_SUCCESS) 12510Sstevel@tonic-gate return (rv); 12520Sstevel@tonic-gate 12530Sstevel@tonic-gate signature->cd_length = modulus_len; 12540Sstevel@tonic-gate } 12550Sstevel@tonic-gate 12560Sstevel@tonic-gate /* EXPORT DELETE END */ 12570Sstevel@tonic-gate 12580Sstevel@tonic-gate return (rv); 12590Sstevel@tonic-gate } 12600Sstevel@tonic-gate 12610Sstevel@tonic-gate /* ARGSUSED */ 12620Sstevel@tonic-gate static int 12630Sstevel@tonic-gate rsa_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 12640Sstevel@tonic-gate crypto_req_handle_t req) 12650Sstevel@tonic-gate { 12660Sstevel@tonic-gate int rv; 12670Sstevel@tonic-gate rsa_ctx_t *ctxp; 12680Sstevel@tonic-gate 12690Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 12700Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 12710Sstevel@tonic-gate 12720Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 12730Sstevel@tonic-gate switch (ctxp->mech_type) { 12740Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 12750Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1276676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1277676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1278676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 12790Sstevel@tonic-gate rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data, 12807188Smcpowers signature, KM_SLEEP, CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE | 12817188Smcpowers CRYPTO_DO_FINAL); 12820Sstevel@tonic-gate break; 12830Sstevel@tonic-gate default: 12840Sstevel@tonic-gate rv = rsa_sign_common(ctxp->mech_type, ctxp->key, data, 12850Sstevel@tonic-gate signature, KM_SLEEP); 12860Sstevel@tonic-gate break; 12870Sstevel@tonic-gate } 12880Sstevel@tonic-gate 12890Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 12900Sstevel@tonic-gate (void) rsa_free_context(ctx); 12910Sstevel@tonic-gate 12920Sstevel@tonic-gate return (rv); 12930Sstevel@tonic-gate } 12940Sstevel@tonic-gate 12950Sstevel@tonic-gate /* ARGSUSED */ 12960Sstevel@tonic-gate static int 12970Sstevel@tonic-gate rsa_sign_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req) 12980Sstevel@tonic-gate { 12990Sstevel@tonic-gate int rv; 13000Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 13010Sstevel@tonic-gate rsa_mech_type_t mech_type; 13020Sstevel@tonic-gate 13030Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 13040Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 13050Sstevel@tonic-gate mech_type = ctxp->mech_type; 13060Sstevel@tonic-gate 1307676Sizick if (mech_type == RSA_PKCS_MECH_INFO_TYPE || 1308676Sizick mech_type == RSA_X_509_MECH_INFO_TYPE) 13090Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 13100Sstevel@tonic-gate 13110Sstevel@tonic-gate if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE) 13127188Smcpowers rv = crypto_digest_data(data, &(ctxp->md5_ctx), 13137188Smcpowers NULL, MD5Update, MD5Final, 13147188Smcpowers CRYPTO_DO_MD5 | CRYPTO_DO_UPDATE); 1315676Sizick 1316676Sizick else if (mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE) 13177188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha1_ctx), 13187188Smcpowers NULL, SHA1Update, SHA1Final, CRYPTO_DO_SHA1 | 13197188Smcpowers CRYPTO_DO_UPDATE); 1320676Sizick 1321676Sizick else 13227188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha2_ctx), 13237188Smcpowers NULL, SHA2Update, SHA2Final, CRYPTO_DO_SHA2 | 13247188Smcpowers CRYPTO_DO_UPDATE); 1325676Sizick 13260Sstevel@tonic-gate return (rv); 13270Sstevel@tonic-gate } 13280Sstevel@tonic-gate 13290Sstevel@tonic-gate static int 13300Sstevel@tonic-gate rsa_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature, 13310Sstevel@tonic-gate crypto_req_handle_t req) 13320Sstevel@tonic-gate { 13330Sstevel@tonic-gate int rv; 13340Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 13350Sstevel@tonic-gate 13360Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 13370Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 13380Sstevel@tonic-gate 13390Sstevel@tonic-gate rv = rsa_digest_svrfy_common(ctxp, NULL, signature, 13407188Smcpowers crypto_kmflag(req), CRYPTO_DO_SIGN | CRYPTO_DO_FINAL); 13410Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 13420Sstevel@tonic-gate (void) rsa_free_context(ctx); 13430Sstevel@tonic-gate 13440Sstevel@tonic-gate return (rv); 13450Sstevel@tonic-gate } 13460Sstevel@tonic-gate 13470Sstevel@tonic-gate /* ARGSUSED */ 13480Sstevel@tonic-gate static int 13490Sstevel@tonic-gate rsa_sign_atomic(crypto_provider_handle_t provider, 13500Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 13510Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 13520Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 13530Sstevel@tonic-gate { 13540Sstevel@tonic-gate int rv; 13550Sstevel@tonic-gate digest_rsa_ctx_t dctx; 13560Sstevel@tonic-gate 13570Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 13580Sstevel@tonic-gate return (rv); 13590Sstevel@tonic-gate 1360676Sizick if (mechanism->cm_type == RSA_PKCS_MECH_INFO_TYPE || 1361676Sizick mechanism->cm_type == RSA_X_509_MECH_INFO_TYPE) 1362676Sizick rv = rsa_sign_common(mechanism->cm_type, key, data, 1363676Sizick signature, crypto_kmflag(req)); 1364676Sizick 1365676Sizick else { 13660Sstevel@tonic-gate dctx.mech_type = mechanism->cm_type; 13670Sstevel@tonic-gate dctx.key = key; 1368676Sizick switch (mechanism->cm_type) { 1369676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 13700Sstevel@tonic-gate MD5Init(&(dctx.md5_ctx)); 1371676Sizick break; 1372676Sizick 1373676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 13740Sstevel@tonic-gate SHA1Init(&(dctx.sha1_ctx)); 1375676Sizick break; 1376676Sizick 1377676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1378676Sizick SHA2Init(SHA256, &(dctx.sha2_ctx)); 1379676Sizick break; 1380676Sizick 1381676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1382676Sizick SHA2Init(SHA384, &(dctx.sha2_ctx)); 1383676Sizick break; 1384676Sizick 1385676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1386676Sizick SHA2Init(SHA512, &(dctx.sha2_ctx)); 1387676Sizick break; 1388676Sizick } 1389676Sizick 1390676Sizick rv = rsa_digest_svrfy_common(&dctx, data, signature, 13917188Smcpowers crypto_kmflag(req), CRYPTO_DO_SIGN | CRYPTO_DO_UPDATE | 13927188Smcpowers CRYPTO_DO_FINAL); 13930Sstevel@tonic-gate } 13940Sstevel@tonic-gate 13950Sstevel@tonic-gate return (rv); 13960Sstevel@tonic-gate } 13970Sstevel@tonic-gate 13980Sstevel@tonic-gate static int 13990Sstevel@tonic-gate rsa_verify_common(rsa_mech_type_t mech_type, crypto_key_t *key, 14000Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *signature, int kmflag) 14010Sstevel@tonic-gate { 14020Sstevel@tonic-gate int rv = CRYPTO_FAILED; 14030Sstevel@tonic-gate 14040Sstevel@tonic-gate /* EXPORT DELETE START */ 14050Sstevel@tonic-gate 14060Sstevel@tonic-gate uchar_t *sigptr, *modulus; 14070Sstevel@tonic-gate ssize_t modulus_len; 14080Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 14090Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 14100Sstevel@tonic-gate 14117188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 14120Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 14130Sstevel@tonic-gate return (rv); 14140Sstevel@tonic-gate } 14150Sstevel@tonic-gate 14160Sstevel@tonic-gate if (signature->cd_length != modulus_len) 14170Sstevel@tonic-gate return (CRYPTO_SIGNATURE_LEN_RANGE); 14180Sstevel@tonic-gate 14190Sstevel@tonic-gate ASSERT(signature->cd_length <= sizeof (tmp_data)); 14207188Smcpowers if ((rv = crypto_get_input_data(signature, &sigptr, tmp_data)) 14210Sstevel@tonic-gate != CRYPTO_SUCCESS) 14220Sstevel@tonic-gate return (rv); 14230Sstevel@tonic-gate 14240Sstevel@tonic-gate rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1); 14250Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 14260Sstevel@tonic-gate return (rv); 14270Sstevel@tonic-gate 1428676Sizick if (mech_type == RSA_X_509_MECH_INFO_TYPE) { 1429676Sizick if (compare_data(data, (plain_data + modulus_len 1430676Sizick - data->cd_length)) != 0) 1431676Sizick rv = CRYPTO_SIGNATURE_INVALID; 1432676Sizick 1433676Sizick } else { 14340Sstevel@tonic-gate int data_len = modulus_len; 14350Sstevel@tonic-gate 14360Sstevel@tonic-gate /* 14370Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the 14380Sstevel@tonic-gate * recovered data, then compare the recovered data with 14390Sstevel@tonic-gate * the original data. 14400Sstevel@tonic-gate */ 14410Sstevel@tonic-gate rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len); 14420Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 1443676Sizick return (rv); 14440Sstevel@tonic-gate 1445676Sizick if (data_len != data->cd_length) 1446676Sizick return (CRYPTO_SIGNATURE_LEN_RANGE); 14470Sstevel@tonic-gate 14480Sstevel@tonic-gate if (compare_data(data, (plain_data + modulus_len 14490Sstevel@tonic-gate - data_len)) != 0) 14500Sstevel@tonic-gate rv = CRYPTO_SIGNATURE_INVALID; 14510Sstevel@tonic-gate } 14520Sstevel@tonic-gate 14530Sstevel@tonic-gate /* EXPORT DELETE END */ 14540Sstevel@tonic-gate 14550Sstevel@tonic-gate return (rv); 14560Sstevel@tonic-gate } 14570Sstevel@tonic-gate 14580Sstevel@tonic-gate /* ARGSUSED */ 14590Sstevel@tonic-gate static int 14600Sstevel@tonic-gate rsa_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 14610Sstevel@tonic-gate crypto_req_handle_t req) 14620Sstevel@tonic-gate { 14630Sstevel@tonic-gate int rv; 14640Sstevel@tonic-gate rsa_ctx_t *ctxp; 14650Sstevel@tonic-gate 14660Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 14670Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 14680Sstevel@tonic-gate 14690Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 14700Sstevel@tonic-gate switch (ctxp->mech_type) { 14710Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 14720Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1473676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1474676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1475676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 14760Sstevel@tonic-gate rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data, 14777188Smcpowers signature, KM_SLEEP, CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE | 14787188Smcpowers CRYPTO_DO_FINAL); 14790Sstevel@tonic-gate break; 14800Sstevel@tonic-gate default: 14810Sstevel@tonic-gate rv = rsa_verify_common(ctxp->mech_type, ctxp->key, data, 14820Sstevel@tonic-gate signature, KM_SLEEP); 14830Sstevel@tonic-gate break; 14840Sstevel@tonic-gate } 14850Sstevel@tonic-gate 14860Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 14870Sstevel@tonic-gate (void) rsa_free_context(ctx); 14880Sstevel@tonic-gate 14890Sstevel@tonic-gate return (rv); 14900Sstevel@tonic-gate } 14910Sstevel@tonic-gate 14920Sstevel@tonic-gate /* ARGSUSED */ 14930Sstevel@tonic-gate static int 14940Sstevel@tonic-gate rsa_verify_update(crypto_ctx_t *ctx, crypto_data_t *data, 14950Sstevel@tonic-gate crypto_req_handle_t req) 14960Sstevel@tonic-gate { 14970Sstevel@tonic-gate int rv; 14980Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 14990Sstevel@tonic-gate 15000Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 15010Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 15020Sstevel@tonic-gate 1503676Sizick switch (ctxp->mech_type) { 15040Sstevel@tonic-gate 1505676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 15067188Smcpowers rv = crypto_digest_data(data, &(ctxp->md5_ctx), 15077188Smcpowers NULL, MD5Update, MD5Final, CRYPTO_DO_MD5 | 15087188Smcpowers CRYPTO_DO_UPDATE); 1509676Sizick break; 1510676Sizick 1511676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 15127188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha1_ctx), 15137188Smcpowers NULL, SHA1Update, SHA1Final, CRYPTO_DO_SHA1 | 15147188Smcpowers CRYPTO_DO_UPDATE); 1515676Sizick break; 1516676Sizick 1517676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1518676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1519676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 15207188Smcpowers rv = crypto_digest_data(data, &(ctxp->sha2_ctx), 15217188Smcpowers NULL, SHA2Update, SHA2Final, CRYPTO_DO_SHA2 | 15227188Smcpowers CRYPTO_DO_UPDATE); 1523676Sizick break; 1524676Sizick 1525676Sizick default: 1526676Sizick return (CRYPTO_MECHANISM_INVALID); 1527676Sizick } 1528676Sizick 15290Sstevel@tonic-gate return (rv); 15300Sstevel@tonic-gate } 15310Sstevel@tonic-gate 15320Sstevel@tonic-gate static int 15330Sstevel@tonic-gate rsa_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature, 15340Sstevel@tonic-gate crypto_req_handle_t req) 15350Sstevel@tonic-gate { 15360Sstevel@tonic-gate int rv; 15370Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 15380Sstevel@tonic-gate 15390Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 15400Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 15410Sstevel@tonic-gate 15420Sstevel@tonic-gate rv = rsa_digest_svrfy_common(ctxp, NULL, signature, 15437188Smcpowers crypto_kmflag(req), CRYPTO_DO_VERIFY | CRYPTO_DO_FINAL); 15440Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 15450Sstevel@tonic-gate (void) rsa_free_context(ctx); 15460Sstevel@tonic-gate 15470Sstevel@tonic-gate return (rv); 15480Sstevel@tonic-gate } 15490Sstevel@tonic-gate 15500Sstevel@tonic-gate 15510Sstevel@tonic-gate /* ARGSUSED */ 15520Sstevel@tonic-gate static int 15530Sstevel@tonic-gate rsa_verify_atomic(crypto_provider_handle_t provider, 15540Sstevel@tonic-gate crypto_session_id_t session_id, 15550Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data, 15560Sstevel@tonic-gate crypto_data_t *signature, crypto_spi_ctx_template_t ctx_template, 15570Sstevel@tonic-gate crypto_req_handle_t req) 15580Sstevel@tonic-gate { 15590Sstevel@tonic-gate int rv; 15600Sstevel@tonic-gate digest_rsa_ctx_t dctx; 15610Sstevel@tonic-gate 15620Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 15630Sstevel@tonic-gate return (rv); 15640Sstevel@tonic-gate 1565676Sizick if (mechanism->cm_type == RSA_PKCS_MECH_INFO_TYPE || 1566676Sizick mechanism->cm_type == RSA_X_509_MECH_INFO_TYPE) 1567676Sizick rv = rsa_verify_common(mechanism->cm_type, key, data, 1568676Sizick signature, crypto_kmflag(req)); 1569676Sizick 1570676Sizick else { 15710Sstevel@tonic-gate dctx.mech_type = mechanism->cm_type; 15720Sstevel@tonic-gate dctx.key = key; 1573676Sizick 1574676Sizick switch (mechanism->cm_type) { 1575676Sizick case MD5_RSA_PKCS_MECH_INFO_TYPE: 15760Sstevel@tonic-gate MD5Init(&(dctx.md5_ctx)); 1577676Sizick break; 1578676Sizick 1579676Sizick case SHA1_RSA_PKCS_MECH_INFO_TYPE: 15800Sstevel@tonic-gate SHA1Init(&(dctx.sha1_ctx)); 1581676Sizick break; 1582676Sizick 1583676Sizick case SHA256_RSA_PKCS_MECH_INFO_TYPE: 1584676Sizick SHA2Init(SHA256, &(dctx.sha2_ctx)); 1585676Sizick break; 1586676Sizick 1587676Sizick case SHA384_RSA_PKCS_MECH_INFO_TYPE: 1588676Sizick SHA2Init(SHA384, &(dctx.sha2_ctx)); 1589676Sizick break; 1590676Sizick 1591676Sizick case SHA512_RSA_PKCS_MECH_INFO_TYPE: 1592676Sizick SHA2Init(SHA512, &(dctx.sha2_ctx)); 1593676Sizick break; 1594676Sizick } 1595676Sizick 15960Sstevel@tonic-gate rv = rsa_digest_svrfy_common(&dctx, data, 15970Sstevel@tonic-gate signature, crypto_kmflag(req), 15987188Smcpowers CRYPTO_DO_VERIFY | CRYPTO_DO_UPDATE | CRYPTO_DO_FINAL); 15990Sstevel@tonic-gate } 16000Sstevel@tonic-gate 16010Sstevel@tonic-gate return (rv); 16020Sstevel@tonic-gate } 16030Sstevel@tonic-gate 16040Sstevel@tonic-gate static int 16050Sstevel@tonic-gate rsa_verify_recover_common(rsa_mech_type_t mech_type, crypto_key_t *key, 16060Sstevel@tonic-gate crypto_data_t *signature, crypto_data_t *data, int kmflag) 16070Sstevel@tonic-gate { 16080Sstevel@tonic-gate int rv = CRYPTO_FAILED; 16090Sstevel@tonic-gate 16100Sstevel@tonic-gate /* EXPORT DELETE START */ 16110Sstevel@tonic-gate 16120Sstevel@tonic-gate int data_len; 16130Sstevel@tonic-gate uchar_t *sigptr, *modulus; 16140Sstevel@tonic-gate ssize_t modulus_len; 16150Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 16160Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 16170Sstevel@tonic-gate 16187188Smcpowers if ((rv = crypto_get_key_attr(key, SUN_CKA_MODULUS, &modulus, 16190Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 16200Sstevel@tonic-gate return (rv); 16210Sstevel@tonic-gate } 16220Sstevel@tonic-gate 16230Sstevel@tonic-gate if (signature->cd_length != modulus_len) 16240Sstevel@tonic-gate return (CRYPTO_SIGNATURE_LEN_RANGE); 16250Sstevel@tonic-gate 16260Sstevel@tonic-gate ASSERT(signature->cd_length <= sizeof (tmp_data)); 16277188Smcpowers if ((rv = crypto_get_input_data(signature, &sigptr, tmp_data)) 16280Sstevel@tonic-gate != CRYPTO_SUCCESS) 16290Sstevel@tonic-gate return (rv); 16300Sstevel@tonic-gate 16310Sstevel@tonic-gate rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1); 16320Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 16330Sstevel@tonic-gate return (rv); 16340Sstevel@tonic-gate 16350Sstevel@tonic-gate data_len = modulus_len; 16360Sstevel@tonic-gate 16370Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 16380Sstevel@tonic-gate /* 16390Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the 16400Sstevel@tonic-gate * recovered data, then compare the recovered data with 16410Sstevel@tonic-gate * the original data. 16420Sstevel@tonic-gate */ 16430Sstevel@tonic-gate rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len); 16440Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 16450Sstevel@tonic-gate return (rv); 16460Sstevel@tonic-gate } 16470Sstevel@tonic-gate 16480Sstevel@tonic-gate if (data->cd_length < data_len) { 16490Sstevel@tonic-gate data->cd_length = data_len; 16500Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 16510Sstevel@tonic-gate } 16520Sstevel@tonic-gate 16537188Smcpowers if ((rv = crypto_put_output_data(plain_data + modulus_len - data_len, 16540Sstevel@tonic-gate data, data_len)) != CRYPTO_SUCCESS) 16550Sstevel@tonic-gate return (rv); 16560Sstevel@tonic-gate data->cd_length = data_len; 16570Sstevel@tonic-gate 16580Sstevel@tonic-gate /* EXPORT DELETE END */ 16590Sstevel@tonic-gate 16600Sstevel@tonic-gate return (rv); 16610Sstevel@tonic-gate } 16620Sstevel@tonic-gate 16630Sstevel@tonic-gate /* ARGSUSED */ 16640Sstevel@tonic-gate static int 16650Sstevel@tonic-gate rsa_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature, 16660Sstevel@tonic-gate crypto_data_t *data, crypto_req_handle_t req) 16670Sstevel@tonic-gate { 16680Sstevel@tonic-gate int rv; 16690Sstevel@tonic-gate rsa_ctx_t *ctxp; 16700Sstevel@tonic-gate 16710Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 16720Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 16730Sstevel@tonic-gate 16740Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 16750Sstevel@tonic-gate rv = rsa_verify_recover_common(ctxp->mech_type, ctxp->key, 16760Sstevel@tonic-gate signature, data, KM_SLEEP); 16770Sstevel@tonic-gate 16780Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 16790Sstevel@tonic-gate (void) rsa_free_context(ctx); 16800Sstevel@tonic-gate 16810Sstevel@tonic-gate return (rv); 16820Sstevel@tonic-gate } 16830Sstevel@tonic-gate 16840Sstevel@tonic-gate /* ARGSUSED */ 16850Sstevel@tonic-gate static int 16860Sstevel@tonic-gate rsa_verify_recover_atomic(crypto_provider_handle_t provider, 16870Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 16880Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data, 16890Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 16900Sstevel@tonic-gate { 16910Sstevel@tonic-gate int rv; 16920Sstevel@tonic-gate 16930Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 16940Sstevel@tonic-gate return (rv); 16950Sstevel@tonic-gate 16960Sstevel@tonic-gate return (rsa_verify_recover_common(mechanism->cm_type, key, 16970Sstevel@tonic-gate signature, data, crypto_kmflag(req))); 16980Sstevel@tonic-gate } 169910500SHai-May.Chao@Sun.COM 170010500SHai-May.Chao@Sun.COM /* 170110500SHai-May.Chao@Sun.COM * RSA Power-Up Self-Test 170210500SHai-May.Chao@Sun.COM */ 170310500SHai-May.Chao@Sun.COM void 170410500SHai-May.Chao@Sun.COM rsa_POST(int *rc) 170510500SHai-May.Chao@Sun.COM { 170610500SHai-May.Chao@Sun.COM 170710500SHai-May.Chao@Sun.COM *rc = fips_rsa_post(); 170810500SHai-May.Chao@Sun.COM 170910500SHai-May.Chao@Sun.COM } 1710