1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate /* 30*0Sstevel@tonic-gate * RSA provider for the Kernel Cryptographic Framework (KCF) 31*0Sstevel@tonic-gate */ 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate #include <sys/types.h> 34*0Sstevel@tonic-gate #include <sys/systm.h> 35*0Sstevel@tonic-gate #include <sys/modctl.h> 36*0Sstevel@tonic-gate #include <sys/cmn_err.h> 37*0Sstevel@tonic-gate #include <sys/ddi.h> 38*0Sstevel@tonic-gate #include <sys/crypto/spi.h> 39*0Sstevel@tonic-gate #include <sys/sysmacros.h> 40*0Sstevel@tonic-gate #include <sys/strsun.h> 41*0Sstevel@tonic-gate #include <sys/md5.h> 42*0Sstevel@tonic-gate #include <sys/sha1.h> 43*0Sstevel@tonic-gate #include <sys/random.h> 44*0Sstevel@tonic-gate #include "rsa_impl.h" 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate extern struct mod_ops mod_cryptoops; 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate /* 49*0Sstevel@tonic-gate * Module linkage information for the kernel. 50*0Sstevel@tonic-gate */ 51*0Sstevel@tonic-gate static struct modlcrypto modlcrypto = { 52*0Sstevel@tonic-gate &mod_cryptoops, 53*0Sstevel@tonic-gate "RSA Kernel SW Provider %I%" 54*0Sstevel@tonic-gate }; 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate static struct modlinkage modlinkage = { 57*0Sstevel@tonic-gate MODREV_1, 58*0Sstevel@tonic-gate (void *)&modlcrypto, 59*0Sstevel@tonic-gate NULL 60*0Sstevel@tonic-gate }; 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate /* 63*0Sstevel@tonic-gate * CSPI information (entry points, provider info, etc.) 64*0Sstevel@tonic-gate */ 65*0Sstevel@tonic-gate typedef enum rsa_mech_type { 66*0Sstevel@tonic-gate RSA_PKCS_MECH_INFO_TYPE, /* SUN_CKM_RSA_PKCS */ 67*0Sstevel@tonic-gate RSA_X_509_MECH_INFO_TYPE, /* SUN_CKM_RSA_X_509 */ 68*0Sstevel@tonic-gate MD5_RSA_PKCS_MECH_INFO_TYPE, /* SUN_MD5_RSA_PKCS */ 69*0Sstevel@tonic-gate SHA1_RSA_PKCS_MECH_INFO_TYPE /* SUN_SHA1_RSA_PKCS */ 70*0Sstevel@tonic-gate } rsa_mech_type_t; 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate /* 73*0Sstevel@tonic-gate * Context for RSA_PKCS and RSA_X_509 mechanisms. 74*0Sstevel@tonic-gate */ 75*0Sstevel@tonic-gate typedef struct rsa_ctx { 76*0Sstevel@tonic-gate rsa_mech_type_t mech_type; 77*0Sstevel@tonic-gate crypto_key_t *key; 78*0Sstevel@tonic-gate size_t keychunk_size; 79*0Sstevel@tonic-gate } rsa_ctx_t; 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gate /* 82*0Sstevel@tonic-gate * Context for MD5_RSA_PKCS and SHA1_RSA_PKCS mechanisms. 83*0Sstevel@tonic-gate */ 84*0Sstevel@tonic-gate typedef struct digest_rsa_ctx { 85*0Sstevel@tonic-gate rsa_mech_type_t mech_type; 86*0Sstevel@tonic-gate crypto_key_t *key; 87*0Sstevel@tonic-gate size_t keychunk_size; 88*0Sstevel@tonic-gate union { 89*0Sstevel@tonic-gate MD5_CTX md5ctx; 90*0Sstevel@tonic-gate SHA1_CTX sha1ctx; 91*0Sstevel@tonic-gate } dctx_u; 92*0Sstevel@tonic-gate } digest_rsa_ctx_t; 93*0Sstevel@tonic-gate 94*0Sstevel@tonic-gate #define md5_ctx dctx_u.md5ctx 95*0Sstevel@tonic-gate #define sha1_ctx dctx_u.sha1ctx 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate /* 98*0Sstevel@tonic-gate * Mechanism info structure passed to KCF during registration. 99*0Sstevel@tonic-gate */ 100*0Sstevel@tonic-gate static crypto_mech_info_t rsa_mech_info_tab[] = { 101*0Sstevel@tonic-gate /* RSA_PKCS */ 102*0Sstevel@tonic-gate {SUN_CKM_RSA_PKCS, RSA_PKCS_MECH_INFO_TYPE, 103*0Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 104*0Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC | 105*0Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 106*0Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 107*0Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC | 108*0Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC, 109*0Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gate /* RSA_X_509 */ 112*0Sstevel@tonic-gate {SUN_CKM_RSA_X_509, RSA_X_509_MECH_INFO_TYPE, 113*0Sstevel@tonic-gate CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 114*0Sstevel@tonic-gate CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC | 115*0Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 116*0Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC | 117*0Sstevel@tonic-gate CRYPTO_FG_SIGN_RECOVER | CRYPTO_FG_SIGN_RECOVER_ATOMIC | 118*0Sstevel@tonic-gate CRYPTO_FG_VERIFY_RECOVER | CRYPTO_FG_VERIFY_RECOVER_ATOMIC, 119*0Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate /* MD5_RSA_PKCS */ 122*0Sstevel@tonic-gate {SUN_CKM_MD5_RSA_PKCS, MD5_RSA_PKCS_MECH_INFO_TYPE, 123*0Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 124*0Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 125*0Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS}, 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate /* SHA1_RSA_PKCS */ 128*0Sstevel@tonic-gate {SUN_CKM_SHA1_RSA_PKCS, SHA1_RSA_PKCS_MECH_INFO_TYPE, 129*0Sstevel@tonic-gate CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 130*0Sstevel@tonic-gate CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 131*0Sstevel@tonic-gate RSA_MIN_KEY_LEN, RSA_MAX_KEY_LEN, CRYPTO_KEYSIZE_UNIT_IN_BITS} 132*0Sstevel@tonic-gate }; 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gate #define RSA_VALID_MECH(mech) \ 135*0Sstevel@tonic-gate (((mech)->cm_type == RSA_PKCS_MECH_INFO_TYPE || \ 136*0Sstevel@tonic-gate (mech)->cm_type == RSA_X_509_MECH_INFO_TYPE || \ 137*0Sstevel@tonic-gate (mech)->cm_type == MD5_RSA_PKCS_MECH_INFO_TYPE || \ 138*0Sstevel@tonic-gate (mech)->cm_type == SHA1_RSA_PKCS_MECH_INFO_TYPE) ? 1 : 0) 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate /* operations are in-place if the output buffer is NULL */ 141*0Sstevel@tonic-gate #define RSA_ARG_INPLACE(input, output) \ 142*0Sstevel@tonic-gate if ((output) == NULL) \ 143*0Sstevel@tonic-gate (output) = (input); 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate static void rsa_provider_status(crypto_provider_handle_t, uint_t *); 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate static crypto_control_ops_t rsa_control_ops = { 148*0Sstevel@tonic-gate rsa_provider_status 149*0Sstevel@tonic-gate }; 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate static int rsa_common_init(crypto_ctx_t *, crypto_mechanism_t *, 152*0Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 153*0Sstevel@tonic-gate static int rsa_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 154*0Sstevel@tonic-gate crypto_req_handle_t); 155*0Sstevel@tonic-gate static int rsa_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 156*0Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 157*0Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 158*0Sstevel@tonic-gate static int rsa_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 159*0Sstevel@tonic-gate crypto_req_handle_t); 160*0Sstevel@tonic-gate static int rsa_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 161*0Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 162*0Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate /* 165*0Sstevel@tonic-gate * The RSA mechanisms do not have multiple-part cipher operations. 166*0Sstevel@tonic-gate * So, the update and final routines are set to NULL. 167*0Sstevel@tonic-gate */ 168*0Sstevel@tonic-gate static crypto_cipher_ops_t rsa_cipher_ops = { 169*0Sstevel@tonic-gate rsa_common_init, 170*0Sstevel@tonic-gate rsa_encrypt, 171*0Sstevel@tonic-gate NULL, 172*0Sstevel@tonic-gate NULL, 173*0Sstevel@tonic-gate rsa_encrypt_atomic, 174*0Sstevel@tonic-gate rsa_common_init, 175*0Sstevel@tonic-gate rsa_decrypt, 176*0Sstevel@tonic-gate NULL, 177*0Sstevel@tonic-gate NULL, 178*0Sstevel@tonic-gate rsa_decrypt_atomic 179*0Sstevel@tonic-gate }; 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate static int rsa_sign_verify_common_init(crypto_ctx_t *, crypto_mechanism_t *, 182*0Sstevel@tonic-gate crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 183*0Sstevel@tonic-gate static int rsa_sign(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 184*0Sstevel@tonic-gate crypto_req_handle_t); 185*0Sstevel@tonic-gate static int rsa_sign_update(crypto_ctx_t *, crypto_data_t *, 186*0Sstevel@tonic-gate crypto_req_handle_t); 187*0Sstevel@tonic-gate static int rsa_sign_final(crypto_ctx_t *, crypto_data_t *, 188*0Sstevel@tonic-gate crypto_req_handle_t); 189*0Sstevel@tonic-gate static int rsa_sign_atomic(crypto_provider_handle_t, crypto_session_id_t, 190*0Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, 191*0Sstevel@tonic-gate crypto_spi_ctx_template_t, crypto_req_handle_t); 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate /* 194*0Sstevel@tonic-gate * We use the same routine for sign_init and sign_recover_init fields 195*0Sstevel@tonic-gate * as they do the same thing. Same holds for sign and sign_recover fields, 196*0Sstevel@tonic-gate * and sign_atomic and sign_recover_atomic fields. 197*0Sstevel@tonic-gate */ 198*0Sstevel@tonic-gate static crypto_sign_ops_t rsa_sign_ops = { 199*0Sstevel@tonic-gate rsa_sign_verify_common_init, 200*0Sstevel@tonic-gate rsa_sign, 201*0Sstevel@tonic-gate rsa_sign_update, 202*0Sstevel@tonic-gate rsa_sign_final, 203*0Sstevel@tonic-gate rsa_sign_atomic, 204*0Sstevel@tonic-gate rsa_sign_verify_common_init, 205*0Sstevel@tonic-gate rsa_sign, 206*0Sstevel@tonic-gate rsa_sign_atomic 207*0Sstevel@tonic-gate }; 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate static int rsa_verify(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 210*0Sstevel@tonic-gate crypto_req_handle_t); 211*0Sstevel@tonic-gate static int rsa_verify_update(crypto_ctx_t *, crypto_data_t *, 212*0Sstevel@tonic-gate crypto_req_handle_t); 213*0Sstevel@tonic-gate static int rsa_verify_final(crypto_ctx_t *, crypto_data_t *, 214*0Sstevel@tonic-gate crypto_req_handle_t); 215*0Sstevel@tonic-gate static int rsa_verify_atomic(crypto_provider_handle_t, crypto_session_id_t, 216*0Sstevel@tonic-gate crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 217*0Sstevel@tonic-gate crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 218*0Sstevel@tonic-gate static int rsa_verify_recover(crypto_ctx_t *, crypto_data_t *, 219*0Sstevel@tonic-gate crypto_data_t *, crypto_req_handle_t); 220*0Sstevel@tonic-gate static int rsa_verify_recover_atomic(crypto_provider_handle_t, 221*0Sstevel@tonic-gate crypto_session_id_t, crypto_mechanism_t *, crypto_key_t *, 222*0Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, crypto_spi_ctx_template_t, 223*0Sstevel@tonic-gate crypto_req_handle_t); 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate /* 226*0Sstevel@tonic-gate * We use the same routine (rsa_sign_verify_common_init) for verify_init 227*0Sstevel@tonic-gate * and verify_recover_init fields as they do the same thing. 228*0Sstevel@tonic-gate */ 229*0Sstevel@tonic-gate static crypto_verify_ops_t rsa_verify_ops = { 230*0Sstevel@tonic-gate rsa_sign_verify_common_init, 231*0Sstevel@tonic-gate rsa_verify, 232*0Sstevel@tonic-gate rsa_verify_update, 233*0Sstevel@tonic-gate rsa_verify_final, 234*0Sstevel@tonic-gate rsa_verify_atomic, 235*0Sstevel@tonic-gate rsa_sign_verify_common_init, 236*0Sstevel@tonic-gate rsa_verify_recover, 237*0Sstevel@tonic-gate rsa_verify_recover_atomic 238*0Sstevel@tonic-gate }; 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate static int rsa_free_context(crypto_ctx_t *); 241*0Sstevel@tonic-gate 242*0Sstevel@tonic-gate static crypto_ctx_ops_t rsa_ctx_ops = { 243*0Sstevel@tonic-gate NULL, 244*0Sstevel@tonic-gate rsa_free_context 245*0Sstevel@tonic-gate }; 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate static crypto_ops_t rsa_crypto_ops = { 248*0Sstevel@tonic-gate &rsa_control_ops, 249*0Sstevel@tonic-gate NULL, 250*0Sstevel@tonic-gate &rsa_cipher_ops, 251*0Sstevel@tonic-gate NULL, 252*0Sstevel@tonic-gate &rsa_sign_ops, 253*0Sstevel@tonic-gate &rsa_verify_ops, 254*0Sstevel@tonic-gate NULL, 255*0Sstevel@tonic-gate NULL, 256*0Sstevel@tonic-gate NULL, 257*0Sstevel@tonic-gate NULL, 258*0Sstevel@tonic-gate NULL, 259*0Sstevel@tonic-gate NULL, 260*0Sstevel@tonic-gate NULL, 261*0Sstevel@tonic-gate &rsa_ctx_ops 262*0Sstevel@tonic-gate }; 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate static crypto_provider_info_t rsa_prov_info = { 265*0Sstevel@tonic-gate CRYPTO_SPI_VERSION_1, 266*0Sstevel@tonic-gate "RSA Software Provider", 267*0Sstevel@tonic-gate CRYPTO_SW_PROVIDER, 268*0Sstevel@tonic-gate {&modlinkage}, 269*0Sstevel@tonic-gate NULL, 270*0Sstevel@tonic-gate &rsa_crypto_ops, 271*0Sstevel@tonic-gate sizeof (rsa_mech_info_tab)/sizeof (crypto_mech_info_t), 272*0Sstevel@tonic-gate rsa_mech_info_tab 273*0Sstevel@tonic-gate }; 274*0Sstevel@tonic-gate 275*0Sstevel@tonic-gate static int rsa_encrypt_common(rsa_mech_type_t, crypto_key_t *, 276*0Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 277*0Sstevel@tonic-gate static int rsa_decrypt_common(rsa_mech_type_t, crypto_key_t *, 278*0Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 279*0Sstevel@tonic-gate static int rsa_sign_common(rsa_mech_type_t, crypto_key_t *, 280*0Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 281*0Sstevel@tonic-gate static int rsa_verify_common(rsa_mech_type_t, crypto_key_t *, 282*0Sstevel@tonic-gate crypto_data_t *, crypto_data_t *, int); 283*0Sstevel@tonic-gate static int compare_data(crypto_data_t *, uchar_t *); 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate /* EXPORT DELETE START */ 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate static int core_rsa_encrypt(crypto_key_t *, uchar_t *, 288*0Sstevel@tonic-gate int, uchar_t *, int, int); 289*0Sstevel@tonic-gate static int core_rsa_decrypt(crypto_key_t *, uchar_t *, int, 290*0Sstevel@tonic-gate uchar_t *, int); 291*0Sstevel@tonic-gate 292*0Sstevel@tonic-gate /* EXPORT DELETE END */ 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gate static crypto_kcf_provider_handle_t rsa_prov_handle = NULL; 295*0Sstevel@tonic-gate 296*0Sstevel@tonic-gate int 297*0Sstevel@tonic-gate _init(void) 298*0Sstevel@tonic-gate { 299*0Sstevel@tonic-gate int ret; 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate /* 302*0Sstevel@tonic-gate * Register with KCF. If the registration fails, return error. 303*0Sstevel@tonic-gate */ 304*0Sstevel@tonic-gate if ((ret = crypto_register_provider(&rsa_prov_info, 305*0Sstevel@tonic-gate &rsa_prov_handle)) != CRYPTO_SUCCESS) { 306*0Sstevel@tonic-gate cmn_err(CE_WARN, "rsa _init: crypto_register_provider()" 307*0Sstevel@tonic-gate "failed (0x%x)", ret); 308*0Sstevel@tonic-gate return (EACCES); 309*0Sstevel@tonic-gate } 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gate if ((ret = mod_install(&modlinkage)) != 0) { 312*0Sstevel@tonic-gate int rv; 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate ASSERT(rsa_prov_handle != NULL); 315*0Sstevel@tonic-gate /* We should not return if the unregister returns busy. */ 316*0Sstevel@tonic-gate while ((rv = crypto_unregister_provider(rsa_prov_handle)) 317*0Sstevel@tonic-gate == CRYPTO_BUSY) { 318*0Sstevel@tonic-gate cmn_err(CE_WARN, "rsa _init: " 319*0Sstevel@tonic-gate "crypto_unregister_provider() " 320*0Sstevel@tonic-gate "failed (0x%x). Retrying.", rv); 321*0Sstevel@tonic-gate /* wait 10 seconds and try again. */ 322*0Sstevel@tonic-gate delay(10 * drv_usectohz(1000000)); 323*0Sstevel@tonic-gate } 324*0Sstevel@tonic-gate } 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate return (ret); 327*0Sstevel@tonic-gate } 328*0Sstevel@tonic-gate 329*0Sstevel@tonic-gate int 330*0Sstevel@tonic-gate _fini(void) 331*0Sstevel@tonic-gate { 332*0Sstevel@tonic-gate int ret; 333*0Sstevel@tonic-gate 334*0Sstevel@tonic-gate /* 335*0Sstevel@tonic-gate * Unregister from KCF if previous registration succeeded. 336*0Sstevel@tonic-gate */ 337*0Sstevel@tonic-gate if (rsa_prov_handle != NULL) { 338*0Sstevel@tonic-gate if ((ret = crypto_unregister_provider(rsa_prov_handle)) != 339*0Sstevel@tonic-gate CRYPTO_SUCCESS) { 340*0Sstevel@tonic-gate cmn_err(CE_WARN, "rsa _fini: " 341*0Sstevel@tonic-gate "crypto_unregister_provider() " 342*0Sstevel@tonic-gate "failed (0x%x)", ret); 343*0Sstevel@tonic-gate return (EBUSY); 344*0Sstevel@tonic-gate } 345*0Sstevel@tonic-gate rsa_prov_handle = NULL; 346*0Sstevel@tonic-gate } 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gate return (mod_remove(&modlinkage)); 349*0Sstevel@tonic-gate } 350*0Sstevel@tonic-gate 351*0Sstevel@tonic-gate int 352*0Sstevel@tonic-gate _info(struct modinfo *modinfop) 353*0Sstevel@tonic-gate { 354*0Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 355*0Sstevel@tonic-gate } 356*0Sstevel@tonic-gate 357*0Sstevel@tonic-gate /* ARGSUSED */ 358*0Sstevel@tonic-gate static void 359*0Sstevel@tonic-gate rsa_provider_status(crypto_provider_handle_t provider, uint_t *status) 360*0Sstevel@tonic-gate { 361*0Sstevel@tonic-gate *status = CRYPTO_PROVIDER_READY; 362*0Sstevel@tonic-gate } 363*0Sstevel@tonic-gate 364*0Sstevel@tonic-gate /* 365*0Sstevel@tonic-gate * Utility routine to look up a attribute of type, 'type', 366*0Sstevel@tonic-gate * in the key. 367*0Sstevel@tonic-gate */ 368*0Sstevel@tonic-gate static int 369*0Sstevel@tonic-gate get_key_attr(crypto_key_t *key, crypto_attr_type_t type, 370*0Sstevel@tonic-gate uchar_t **value, ssize_t *value_len) 371*0Sstevel@tonic-gate { 372*0Sstevel@tonic-gate int i; 373*0Sstevel@tonic-gate 374*0Sstevel@tonic-gate ASSERT(key->ck_format == CRYPTO_KEY_ATTR_LIST); 375*0Sstevel@tonic-gate for (i = 0; i < key->ck_count; i++) { 376*0Sstevel@tonic-gate if (key->ck_attrs[i].oa_type == type) { 377*0Sstevel@tonic-gate *value = (uchar_t *)key->ck_attrs[i].oa_value; 378*0Sstevel@tonic-gate *value_len = key->ck_attrs[i].oa_value_len; 379*0Sstevel@tonic-gate return (CRYPTO_SUCCESS); 380*0Sstevel@tonic-gate } 381*0Sstevel@tonic-gate } 382*0Sstevel@tonic-gate 383*0Sstevel@tonic-gate return (CRYPTO_FAILED); 384*0Sstevel@tonic-gate } 385*0Sstevel@tonic-gate 386*0Sstevel@tonic-gate static int 387*0Sstevel@tonic-gate check_mech_and_key(crypto_mechanism_t *mechanism, crypto_key_t *key) 388*0Sstevel@tonic-gate { 389*0Sstevel@tonic-gate int rv = CRYPTO_FAILED; 390*0Sstevel@tonic-gate 391*0Sstevel@tonic-gate /* EXPORT DELETE START */ 392*0Sstevel@tonic-gate 393*0Sstevel@tonic-gate uchar_t *modulus; 394*0Sstevel@tonic-gate ssize_t modulus_len; /* In bytes */ 395*0Sstevel@tonic-gate 396*0Sstevel@tonic-gate if (!RSA_VALID_MECH(mechanism)) 397*0Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 398*0Sstevel@tonic-gate 399*0Sstevel@tonic-gate /* 400*0Sstevel@tonic-gate * We only support RSA keys that are passed as a list of 401*0Sstevel@tonic-gate * object attributes. 402*0Sstevel@tonic-gate */ 403*0Sstevel@tonic-gate if (key->ck_format != CRYPTO_KEY_ATTR_LIST) { 404*0Sstevel@tonic-gate return (CRYPTO_KEY_TYPE_INCONSISTENT); 405*0Sstevel@tonic-gate } 406*0Sstevel@tonic-gate 407*0Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 408*0Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 409*0Sstevel@tonic-gate return (rv); 410*0Sstevel@tonic-gate } 411*0Sstevel@tonic-gate if (modulus_len < MIN_RSA_KEYLENGTH_IN_BYTES || 412*0Sstevel@tonic-gate modulus_len > MAX_RSA_KEYLENGTH_IN_BYTES) 413*0Sstevel@tonic-gate return (CRYPTO_KEY_SIZE_RANGE); 414*0Sstevel@tonic-gate 415*0Sstevel@tonic-gate /* EXPORT DELETE END */ 416*0Sstevel@tonic-gate 417*0Sstevel@tonic-gate return (rv); 418*0Sstevel@tonic-gate } 419*0Sstevel@tonic-gate 420*0Sstevel@tonic-gate void 421*0Sstevel@tonic-gate kmemset(uint8_t *buf, char pattern, size_t len) 422*0Sstevel@tonic-gate { 423*0Sstevel@tonic-gate int i = 0; 424*0Sstevel@tonic-gate 425*0Sstevel@tonic-gate while (i < len) 426*0Sstevel@tonic-gate buf[i++] = pattern; 427*0Sstevel@tonic-gate } 428*0Sstevel@tonic-gate 429*0Sstevel@tonic-gate /* 430*0Sstevel@tonic-gate * This function guarantees to return non-zero random numbers. 431*0Sstevel@tonic-gate * This is needed as the /dev/urandom kernel interface, 432*0Sstevel@tonic-gate * random_get_pseudo_bytes(), may return zeros. 433*0Sstevel@tonic-gate */ 434*0Sstevel@tonic-gate int 435*0Sstevel@tonic-gate knzero_random_generator(uint8_t *ran_out, size_t ran_len) 436*0Sstevel@tonic-gate { 437*0Sstevel@tonic-gate int rv; 438*0Sstevel@tonic-gate size_t ebc = 0; /* count of extra bytes in extrarand */ 439*0Sstevel@tonic-gate size_t i = 0; 440*0Sstevel@tonic-gate uint8_t extrarand[32]; 441*0Sstevel@tonic-gate size_t extrarand_len; 442*0Sstevel@tonic-gate 443*0Sstevel@tonic-gate if ((rv = random_get_pseudo_bytes(ran_out, ran_len)) != 0) 444*0Sstevel@tonic-gate return (rv); 445*0Sstevel@tonic-gate 446*0Sstevel@tonic-gate /* 447*0Sstevel@tonic-gate * Walk through the returned random numbers pointed by ran_out, 448*0Sstevel@tonic-gate * and look for any random number which is zero. 449*0Sstevel@tonic-gate * If we find zero, call random_get_pseudo_bytes() to generate 450*0Sstevel@tonic-gate * another 32 random numbers pool. Replace any zeros in ran_out[] 451*0Sstevel@tonic-gate * from the random number in pool. 452*0Sstevel@tonic-gate */ 453*0Sstevel@tonic-gate while (i < ran_len) { 454*0Sstevel@tonic-gate if (ran_out[i] != 0) { 455*0Sstevel@tonic-gate i++; 456*0Sstevel@tonic-gate continue; 457*0Sstevel@tonic-gate } 458*0Sstevel@tonic-gate 459*0Sstevel@tonic-gate /* 460*0Sstevel@tonic-gate * Note that it is 'while' so we are guaranteed a 461*0Sstevel@tonic-gate * non-zero value on exit. 462*0Sstevel@tonic-gate */ 463*0Sstevel@tonic-gate if (ebc == 0) { 464*0Sstevel@tonic-gate /* refresh extrarand */ 465*0Sstevel@tonic-gate extrarand_len = sizeof (extrarand); 466*0Sstevel@tonic-gate if ((rv = random_get_pseudo_bytes(extrarand, 467*0Sstevel@tonic-gate extrarand_len)) != 0) { 468*0Sstevel@tonic-gate return (rv); 469*0Sstevel@tonic-gate } 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate ebc = extrarand_len; 472*0Sstevel@tonic-gate } 473*0Sstevel@tonic-gate /* Replace zero with byte from extrarand. */ 474*0Sstevel@tonic-gate -- ebc; 475*0Sstevel@tonic-gate 476*0Sstevel@tonic-gate /* 477*0Sstevel@tonic-gate * The new random byte zero/non-zero will be checked in 478*0Sstevel@tonic-gate * the next pass through the loop. 479*0Sstevel@tonic-gate */ 480*0Sstevel@tonic-gate ran_out[i] = extrarand[ebc]; 481*0Sstevel@tonic-gate } 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate return (CRYPTO_SUCCESS); 484*0Sstevel@tonic-gate } 485*0Sstevel@tonic-gate 486*0Sstevel@tonic-gate typedef enum cmd_type { 487*0Sstevel@tonic-gate COPY_FROM_DATA, 488*0Sstevel@tonic-gate COPY_TO_DATA, 489*0Sstevel@tonic-gate COMPARE_TO_DATA, 490*0Sstevel@tonic-gate MD5_DIGEST_DATA, 491*0Sstevel@tonic-gate SHA1_DIGEST_DATA 492*0Sstevel@tonic-gate } cmd_type_t; 493*0Sstevel@tonic-gate 494*0Sstevel@tonic-gate /* 495*0Sstevel@tonic-gate * Utility routine to apply the command, 'cmd', to the 496*0Sstevel@tonic-gate * data in the uio structure. 497*0Sstevel@tonic-gate */ 498*0Sstevel@tonic-gate static int 499*0Sstevel@tonic-gate process_uio_data(crypto_data_t *data, uchar_t *buf, int len, 500*0Sstevel@tonic-gate cmd_type_t cmd, void *digest_ctx) 501*0Sstevel@tonic-gate { 502*0Sstevel@tonic-gate uio_t *uiop = data->cd_uio; 503*0Sstevel@tonic-gate off_t offset = data->cd_offset; 504*0Sstevel@tonic-gate size_t length = len; 505*0Sstevel@tonic-gate uint_t vec_idx; 506*0Sstevel@tonic-gate size_t cur_len; 507*0Sstevel@tonic-gate uchar_t *datap; 508*0Sstevel@tonic-gate 509*0Sstevel@tonic-gate ASSERT(data->cd_format == CRYPTO_DATA_UIO); 510*0Sstevel@tonic-gate if (uiop->uio_segflg != UIO_SYSSPACE) { 511*0Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 512*0Sstevel@tonic-gate } 513*0Sstevel@tonic-gate 514*0Sstevel@tonic-gate /* 515*0Sstevel@tonic-gate * Jump to the first iovec containing data to be 516*0Sstevel@tonic-gate * processed. 517*0Sstevel@tonic-gate */ 518*0Sstevel@tonic-gate for (vec_idx = 0; vec_idx < uiop->uio_iovcnt && 519*0Sstevel@tonic-gate offset >= uiop->uio_iov[vec_idx].iov_len; 520*0Sstevel@tonic-gate offset -= uiop->uio_iov[vec_idx++].iov_len); 521*0Sstevel@tonic-gate 522*0Sstevel@tonic-gate if (vec_idx == uiop->uio_iovcnt) { 523*0Sstevel@tonic-gate /* 524*0Sstevel@tonic-gate * The caller specified an offset that is larger than 525*0Sstevel@tonic-gate * the total size of the buffers it provided. 526*0Sstevel@tonic-gate */ 527*0Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 528*0Sstevel@tonic-gate } 529*0Sstevel@tonic-gate 530*0Sstevel@tonic-gate while (vec_idx < uiop->uio_iovcnt && length > 0) { 531*0Sstevel@tonic-gate cur_len = MIN(uiop->uio_iov[vec_idx].iov_len - 532*0Sstevel@tonic-gate offset, length); 533*0Sstevel@tonic-gate 534*0Sstevel@tonic-gate datap = (uchar_t *)(uiop->uio_iov[vec_idx].iov_base + 535*0Sstevel@tonic-gate offset); 536*0Sstevel@tonic-gate switch (cmd) { 537*0Sstevel@tonic-gate case COPY_FROM_DATA: 538*0Sstevel@tonic-gate bcopy(datap, buf, cur_len); 539*0Sstevel@tonic-gate buf += cur_len; 540*0Sstevel@tonic-gate break; 541*0Sstevel@tonic-gate case COPY_TO_DATA: 542*0Sstevel@tonic-gate bcopy(buf, datap, cur_len); 543*0Sstevel@tonic-gate buf += cur_len; 544*0Sstevel@tonic-gate break; 545*0Sstevel@tonic-gate case COMPARE_TO_DATA: 546*0Sstevel@tonic-gate if (bcmp(datap, buf, cur_len)) 547*0Sstevel@tonic-gate return (CRYPTO_SIGNATURE_INVALID); 548*0Sstevel@tonic-gate buf += cur_len; 549*0Sstevel@tonic-gate break; 550*0Sstevel@tonic-gate case MD5_DIGEST_DATA: 551*0Sstevel@tonic-gate MD5Update(digest_ctx, datap, cur_len); 552*0Sstevel@tonic-gate break; 553*0Sstevel@tonic-gate case SHA1_DIGEST_DATA: 554*0Sstevel@tonic-gate SHA1Update(digest_ctx, datap, cur_len); 555*0Sstevel@tonic-gate break; 556*0Sstevel@tonic-gate } 557*0Sstevel@tonic-gate 558*0Sstevel@tonic-gate length -= cur_len; 559*0Sstevel@tonic-gate vec_idx++; 560*0Sstevel@tonic-gate offset = 0; 561*0Sstevel@tonic-gate } 562*0Sstevel@tonic-gate 563*0Sstevel@tonic-gate if (vec_idx == uiop->uio_iovcnt && length > 0) { 564*0Sstevel@tonic-gate /* 565*0Sstevel@tonic-gate * The end of the specified iovec's was reached but 566*0Sstevel@tonic-gate * the length requested could not be processed. 567*0Sstevel@tonic-gate */ 568*0Sstevel@tonic-gate switch (cmd) { 569*0Sstevel@tonic-gate case COPY_TO_DATA: 570*0Sstevel@tonic-gate data->cd_length = len; 571*0Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 572*0Sstevel@tonic-gate default: 573*0Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 574*0Sstevel@tonic-gate } 575*0Sstevel@tonic-gate } 576*0Sstevel@tonic-gate 577*0Sstevel@tonic-gate return (CRYPTO_SUCCESS); 578*0Sstevel@tonic-gate } 579*0Sstevel@tonic-gate 580*0Sstevel@tonic-gate /* 581*0Sstevel@tonic-gate * Utility routine to apply the command, 'cmd', to the 582*0Sstevel@tonic-gate * data in the mblk structure. 583*0Sstevel@tonic-gate */ 584*0Sstevel@tonic-gate static int 585*0Sstevel@tonic-gate process_mblk_data(crypto_data_t *data, uchar_t *buf, int len, 586*0Sstevel@tonic-gate cmd_type_t cmd, void *digest_ctx) 587*0Sstevel@tonic-gate { 588*0Sstevel@tonic-gate off_t offset = data->cd_offset; 589*0Sstevel@tonic-gate size_t length = len; 590*0Sstevel@tonic-gate mblk_t *mp; 591*0Sstevel@tonic-gate size_t cur_len; 592*0Sstevel@tonic-gate uchar_t *datap; 593*0Sstevel@tonic-gate 594*0Sstevel@tonic-gate ASSERT(data->cd_format == CRYPTO_DATA_MBLK); 595*0Sstevel@tonic-gate /* 596*0Sstevel@tonic-gate * Jump to the first mblk_t containing data to be processed. 597*0Sstevel@tonic-gate */ 598*0Sstevel@tonic-gate for (mp = data->cd_mp; mp != NULL && offset >= MBLKL(mp); 599*0Sstevel@tonic-gate offset -= MBLKL(mp), mp = mp->b_cont); 600*0Sstevel@tonic-gate if (mp == NULL) { 601*0Sstevel@tonic-gate /* 602*0Sstevel@tonic-gate * The caller specified an offset that is larger 603*0Sstevel@tonic-gate * than the total size of the buffers it provided. 604*0Sstevel@tonic-gate */ 605*0Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 606*0Sstevel@tonic-gate } 607*0Sstevel@tonic-gate 608*0Sstevel@tonic-gate /* 609*0Sstevel@tonic-gate * Now do the processing on the mblk chain. 610*0Sstevel@tonic-gate */ 611*0Sstevel@tonic-gate while (mp != NULL && length > 0) { 612*0Sstevel@tonic-gate cur_len = MIN(MBLKL(mp) - offset, length); 613*0Sstevel@tonic-gate 614*0Sstevel@tonic-gate datap = (uchar_t *)(mp->b_rptr + offset); 615*0Sstevel@tonic-gate switch (cmd) { 616*0Sstevel@tonic-gate case COPY_FROM_DATA: 617*0Sstevel@tonic-gate bcopy(datap, buf, cur_len); 618*0Sstevel@tonic-gate buf += cur_len; 619*0Sstevel@tonic-gate break; 620*0Sstevel@tonic-gate case COPY_TO_DATA: 621*0Sstevel@tonic-gate bcopy(buf, datap, cur_len); 622*0Sstevel@tonic-gate buf += cur_len; 623*0Sstevel@tonic-gate break; 624*0Sstevel@tonic-gate case COMPARE_TO_DATA: 625*0Sstevel@tonic-gate if (bcmp(datap, buf, cur_len)) 626*0Sstevel@tonic-gate return (CRYPTO_SIGNATURE_INVALID); 627*0Sstevel@tonic-gate buf += cur_len; 628*0Sstevel@tonic-gate break; 629*0Sstevel@tonic-gate case MD5_DIGEST_DATA: 630*0Sstevel@tonic-gate MD5Update(digest_ctx, datap, cur_len); 631*0Sstevel@tonic-gate break; 632*0Sstevel@tonic-gate case SHA1_DIGEST_DATA: 633*0Sstevel@tonic-gate SHA1Update(digest_ctx, datap, cur_len); 634*0Sstevel@tonic-gate break; 635*0Sstevel@tonic-gate } 636*0Sstevel@tonic-gate 637*0Sstevel@tonic-gate length -= cur_len; 638*0Sstevel@tonic-gate offset = 0; 639*0Sstevel@tonic-gate mp = mp->b_cont; 640*0Sstevel@tonic-gate } 641*0Sstevel@tonic-gate 642*0Sstevel@tonic-gate if (mp == NULL && length > 0) { 643*0Sstevel@tonic-gate /* 644*0Sstevel@tonic-gate * The end of the mblk was reached but the length 645*0Sstevel@tonic-gate * requested could not be processed. 646*0Sstevel@tonic-gate */ 647*0Sstevel@tonic-gate switch (cmd) { 648*0Sstevel@tonic-gate case COPY_TO_DATA: 649*0Sstevel@tonic-gate data->cd_length = len; 650*0Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 651*0Sstevel@tonic-gate default: 652*0Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 653*0Sstevel@tonic-gate } 654*0Sstevel@tonic-gate } 655*0Sstevel@tonic-gate 656*0Sstevel@tonic-gate return (CRYPTO_SUCCESS); 657*0Sstevel@tonic-gate } 658*0Sstevel@tonic-gate 659*0Sstevel@tonic-gate static int 660*0Sstevel@tonic-gate compare_data(crypto_data_t *data, uchar_t *buf) 661*0Sstevel@tonic-gate { 662*0Sstevel@tonic-gate int len; 663*0Sstevel@tonic-gate uchar_t *dptr; 664*0Sstevel@tonic-gate 665*0Sstevel@tonic-gate len = data->cd_length; 666*0Sstevel@tonic-gate switch (data->cd_format) { 667*0Sstevel@tonic-gate case CRYPTO_DATA_RAW: 668*0Sstevel@tonic-gate dptr = (uchar_t *)(data->cd_raw.iov_base + 669*0Sstevel@tonic-gate data->cd_offset); 670*0Sstevel@tonic-gate 671*0Sstevel@tonic-gate return (bcmp(dptr, buf, len)); 672*0Sstevel@tonic-gate 673*0Sstevel@tonic-gate case CRYPTO_DATA_UIO: 674*0Sstevel@tonic-gate return (process_uio_data(data, buf, len, 675*0Sstevel@tonic-gate COMPARE_TO_DATA, NULL)); 676*0Sstevel@tonic-gate 677*0Sstevel@tonic-gate case CRYPTO_DATA_MBLK: 678*0Sstevel@tonic-gate return (process_mblk_data(data, buf, len, 679*0Sstevel@tonic-gate COMPARE_TO_DATA, NULL)); 680*0Sstevel@tonic-gate } 681*0Sstevel@tonic-gate 682*0Sstevel@tonic-gate return (CRYPTO_FAILED); 683*0Sstevel@tonic-gate } 684*0Sstevel@tonic-gate 685*0Sstevel@tonic-gate /* 686*0Sstevel@tonic-gate * Utility routine to copy a buffer to a crypto_data structure. 687*0Sstevel@tonic-gate */ 688*0Sstevel@tonic-gate static int 689*0Sstevel@tonic-gate put_output_data(uchar_t *buf, crypto_data_t *output, int len) 690*0Sstevel@tonic-gate { 691*0Sstevel@tonic-gate switch (output->cd_format) { 692*0Sstevel@tonic-gate case CRYPTO_DATA_RAW: 693*0Sstevel@tonic-gate if (output->cd_raw.iov_len < len) { 694*0Sstevel@tonic-gate output->cd_length = len; 695*0Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 696*0Sstevel@tonic-gate } 697*0Sstevel@tonic-gate bcopy(buf, (uchar_t *)(output->cd_raw.iov_base + 698*0Sstevel@tonic-gate output->cd_offset), len); 699*0Sstevel@tonic-gate break; 700*0Sstevel@tonic-gate 701*0Sstevel@tonic-gate case CRYPTO_DATA_UIO: 702*0Sstevel@tonic-gate return (process_uio_data(output, buf, len, COPY_TO_DATA, NULL)); 703*0Sstevel@tonic-gate 704*0Sstevel@tonic-gate case CRYPTO_DATA_MBLK: 705*0Sstevel@tonic-gate return (process_mblk_data(output, buf, len, 706*0Sstevel@tonic-gate COPY_TO_DATA, NULL)); 707*0Sstevel@tonic-gate 708*0Sstevel@tonic-gate default: 709*0Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 710*0Sstevel@tonic-gate } 711*0Sstevel@tonic-gate 712*0Sstevel@tonic-gate return (CRYPTO_SUCCESS); 713*0Sstevel@tonic-gate } 714*0Sstevel@tonic-gate 715*0Sstevel@tonic-gate /* 716*0Sstevel@tonic-gate * Utility routine to get data from a crypto_data structure. 717*0Sstevel@tonic-gate * 718*0Sstevel@tonic-gate * '*dptr' contains a pointer to a buffer on return. 'buf' 719*0Sstevel@tonic-gate * is allocated by the caller and is ignored for CRYPTO_DATA_RAW case. 720*0Sstevel@tonic-gate */ 721*0Sstevel@tonic-gate static int 722*0Sstevel@tonic-gate get_input_data(crypto_data_t *input, uchar_t **dptr, uchar_t *buf) 723*0Sstevel@tonic-gate { 724*0Sstevel@tonic-gate int rv; 725*0Sstevel@tonic-gate 726*0Sstevel@tonic-gate switch (input->cd_format) { 727*0Sstevel@tonic-gate case CRYPTO_DATA_RAW: 728*0Sstevel@tonic-gate if (input->cd_raw.iov_len < input->cd_length) 729*0Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 730*0Sstevel@tonic-gate *dptr = (uchar_t *)(input->cd_raw.iov_base + 731*0Sstevel@tonic-gate input->cd_offset); 732*0Sstevel@tonic-gate break; 733*0Sstevel@tonic-gate 734*0Sstevel@tonic-gate case CRYPTO_DATA_UIO: 735*0Sstevel@tonic-gate if ((rv = process_uio_data(input, buf, input->cd_length, 736*0Sstevel@tonic-gate COPY_FROM_DATA, NULL)) != CRYPTO_SUCCESS) 737*0Sstevel@tonic-gate return (rv); 738*0Sstevel@tonic-gate *dptr = buf; 739*0Sstevel@tonic-gate break; 740*0Sstevel@tonic-gate 741*0Sstevel@tonic-gate case CRYPTO_DATA_MBLK: 742*0Sstevel@tonic-gate if ((rv = process_mblk_data(input, buf, input->cd_length, 743*0Sstevel@tonic-gate COPY_FROM_DATA, NULL)) != CRYPTO_SUCCESS) 744*0Sstevel@tonic-gate return (rv); 745*0Sstevel@tonic-gate *dptr = buf; 746*0Sstevel@tonic-gate break; 747*0Sstevel@tonic-gate 748*0Sstevel@tonic-gate default: 749*0Sstevel@tonic-gate return (CRYPTO_ARGUMENTS_BAD); 750*0Sstevel@tonic-gate } 751*0Sstevel@tonic-gate 752*0Sstevel@tonic-gate return (CRYPTO_SUCCESS); 753*0Sstevel@tonic-gate } 754*0Sstevel@tonic-gate 755*0Sstevel@tonic-gate static int 756*0Sstevel@tonic-gate copy_key_to_ctx(crypto_key_t *in_key, rsa_ctx_t *ctx, int kmflag) 757*0Sstevel@tonic-gate { 758*0Sstevel@tonic-gate int i, count; 759*0Sstevel@tonic-gate size_t len; 760*0Sstevel@tonic-gate caddr_t attr_val; 761*0Sstevel@tonic-gate crypto_object_attribute_t *k_attrs = NULL; 762*0Sstevel@tonic-gate 763*0Sstevel@tonic-gate ASSERT(in_key->ck_format == CRYPTO_KEY_ATTR_LIST); 764*0Sstevel@tonic-gate 765*0Sstevel@tonic-gate count = in_key->ck_count; 766*0Sstevel@tonic-gate /* figure out how much memory to allocate for everything */ 767*0Sstevel@tonic-gate len = sizeof (crypto_key_t) + 768*0Sstevel@tonic-gate count * sizeof (crypto_object_attribute_t); 769*0Sstevel@tonic-gate for (i = 0; i < count; i++) { 770*0Sstevel@tonic-gate len += roundup(in_key->ck_attrs[i].oa_value_len, 771*0Sstevel@tonic-gate sizeof (caddr_t)); 772*0Sstevel@tonic-gate } 773*0Sstevel@tonic-gate 774*0Sstevel@tonic-gate /* one big allocation for everything */ 775*0Sstevel@tonic-gate ctx->key = kmem_alloc(len, kmflag); 776*0Sstevel@tonic-gate if (ctx->key == NULL) 777*0Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 778*0Sstevel@tonic-gate k_attrs = (crypto_object_attribute_t *)((caddr_t)(ctx->key) + 779*0Sstevel@tonic-gate sizeof (crypto_key_t)); 780*0Sstevel@tonic-gate 781*0Sstevel@tonic-gate attr_val = (caddr_t)k_attrs + 782*0Sstevel@tonic-gate count * sizeof (crypto_object_attribute_t); 783*0Sstevel@tonic-gate for (i = 0; i < count; i++) { 784*0Sstevel@tonic-gate k_attrs[i].oa_type = in_key->ck_attrs[i].oa_type; 785*0Sstevel@tonic-gate bcopy(in_key->ck_attrs[i].oa_value, attr_val, 786*0Sstevel@tonic-gate in_key->ck_attrs[i].oa_value_len); 787*0Sstevel@tonic-gate k_attrs[i].oa_value = attr_val; 788*0Sstevel@tonic-gate k_attrs[i].oa_value_len = in_key->ck_attrs[i].oa_value_len; 789*0Sstevel@tonic-gate attr_val += roundup(k_attrs[i].oa_value_len, sizeof (caddr_t)); 790*0Sstevel@tonic-gate } 791*0Sstevel@tonic-gate 792*0Sstevel@tonic-gate ctx->keychunk_size = len; /* save the size to be freed */ 793*0Sstevel@tonic-gate ctx->key->ck_format = CRYPTO_KEY_ATTR_LIST; 794*0Sstevel@tonic-gate ctx->key->ck_count = count; 795*0Sstevel@tonic-gate ctx->key->ck_attrs = k_attrs; 796*0Sstevel@tonic-gate 797*0Sstevel@tonic-gate return (CRYPTO_SUCCESS); 798*0Sstevel@tonic-gate } 799*0Sstevel@tonic-gate 800*0Sstevel@tonic-gate /* ARGSUSED */ 801*0Sstevel@tonic-gate static int 802*0Sstevel@tonic-gate rsa_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 803*0Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t template, 804*0Sstevel@tonic-gate crypto_req_handle_t req) 805*0Sstevel@tonic-gate { 806*0Sstevel@tonic-gate int rv; 807*0Sstevel@tonic-gate int kmflag; 808*0Sstevel@tonic-gate rsa_ctx_t *ctxp; 809*0Sstevel@tonic-gate 810*0Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 811*0Sstevel@tonic-gate return (rv); 812*0Sstevel@tonic-gate 813*0Sstevel@tonic-gate /* 814*0Sstevel@tonic-gate * Allocate a RSA context. 815*0Sstevel@tonic-gate */ 816*0Sstevel@tonic-gate kmflag = crypto_kmflag(req); 817*0Sstevel@tonic-gate if ((ctxp = kmem_zalloc(sizeof (rsa_ctx_t), kmflag)) == NULL) 818*0Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 819*0Sstevel@tonic-gate 820*0Sstevel@tonic-gate if ((rv = copy_key_to_ctx(key, ctxp, kmflag)) != CRYPTO_SUCCESS) { 821*0Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 822*0Sstevel@tonic-gate return (rv); 823*0Sstevel@tonic-gate } 824*0Sstevel@tonic-gate ctxp->mech_type = mechanism->cm_type; 825*0Sstevel@tonic-gate 826*0Sstevel@tonic-gate ctx->cc_provider_private = ctxp; 827*0Sstevel@tonic-gate 828*0Sstevel@tonic-gate return (CRYPTO_SUCCESS); 829*0Sstevel@tonic-gate } 830*0Sstevel@tonic-gate 831*0Sstevel@tonic-gate /* ARGSUSED */ 832*0Sstevel@tonic-gate static int 833*0Sstevel@tonic-gate rsa_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext, 834*0Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_req_handle_t req) 835*0Sstevel@tonic-gate { 836*0Sstevel@tonic-gate int rv; 837*0Sstevel@tonic-gate rsa_ctx_t *ctxp; 838*0Sstevel@tonic-gate 839*0Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 840*0Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 841*0Sstevel@tonic-gate 842*0Sstevel@tonic-gate RSA_ARG_INPLACE(plaintext, ciphertext); 843*0Sstevel@tonic-gate 844*0Sstevel@tonic-gate /* 845*0Sstevel@tonic-gate * Note on the KM_SLEEP flag passed to the routine below - 846*0Sstevel@tonic-gate * rsa_encrypt() is a single-part encryption routine which is 847*0Sstevel@tonic-gate * currently usable only by /dev/crypto. Since /dev/crypto calls are 848*0Sstevel@tonic-gate * always synchronous, we can safely pass KM_SLEEP here. 849*0Sstevel@tonic-gate */ 850*0Sstevel@tonic-gate rv = rsa_encrypt_common(ctxp->mech_type, ctxp->key, plaintext, 851*0Sstevel@tonic-gate ciphertext, KM_SLEEP); 852*0Sstevel@tonic-gate 853*0Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 854*0Sstevel@tonic-gate (void) rsa_free_context(ctx); 855*0Sstevel@tonic-gate 856*0Sstevel@tonic-gate return (rv); 857*0Sstevel@tonic-gate } 858*0Sstevel@tonic-gate 859*0Sstevel@tonic-gate /* ARGSUSED */ 860*0Sstevel@tonic-gate static int 861*0Sstevel@tonic-gate rsa_encrypt_atomic(crypto_provider_handle_t provider, 862*0Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 863*0Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext, 864*0Sstevel@tonic-gate crypto_spi_ctx_template_t template, crypto_req_handle_t req) 865*0Sstevel@tonic-gate { 866*0Sstevel@tonic-gate int rv; 867*0Sstevel@tonic-gate 868*0Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 869*0Sstevel@tonic-gate return (rv); 870*0Sstevel@tonic-gate RSA_ARG_INPLACE(plaintext, ciphertext); 871*0Sstevel@tonic-gate 872*0Sstevel@tonic-gate return (rsa_encrypt_common(mechanism->cm_type, key, plaintext, 873*0Sstevel@tonic-gate ciphertext, crypto_kmflag(req))); 874*0Sstevel@tonic-gate } 875*0Sstevel@tonic-gate 876*0Sstevel@tonic-gate static int 877*0Sstevel@tonic-gate rsa_free_context(crypto_ctx_t *ctx) 878*0Sstevel@tonic-gate { 879*0Sstevel@tonic-gate rsa_ctx_t *ctxp = ctx->cc_provider_private; 880*0Sstevel@tonic-gate 881*0Sstevel@tonic-gate if (ctxp != NULL) { 882*0Sstevel@tonic-gate bzero(ctxp->key, ctxp->keychunk_size); 883*0Sstevel@tonic-gate kmem_free(ctxp->key, ctxp->keychunk_size); 884*0Sstevel@tonic-gate 885*0Sstevel@tonic-gate if (ctxp->mech_type == RSA_PKCS_MECH_INFO_TYPE || 886*0Sstevel@tonic-gate ctxp->mech_type == RSA_X_509_MECH_INFO_TYPE) 887*0Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 888*0Sstevel@tonic-gate else 889*0Sstevel@tonic-gate kmem_free(ctxp, sizeof (digest_rsa_ctx_t)); 890*0Sstevel@tonic-gate 891*0Sstevel@tonic-gate ctx->cc_provider_private = NULL; 892*0Sstevel@tonic-gate } 893*0Sstevel@tonic-gate 894*0Sstevel@tonic-gate return (CRYPTO_SUCCESS); 895*0Sstevel@tonic-gate } 896*0Sstevel@tonic-gate 897*0Sstevel@tonic-gate static int 898*0Sstevel@tonic-gate rsa_encrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key, 899*0Sstevel@tonic-gate crypto_data_t *plaintext, crypto_data_t *ciphertext, int kmflag) 900*0Sstevel@tonic-gate { 901*0Sstevel@tonic-gate int rv = CRYPTO_FAILED; 902*0Sstevel@tonic-gate 903*0Sstevel@tonic-gate /* EXPORT DELETE START */ 904*0Sstevel@tonic-gate 905*0Sstevel@tonic-gate int plen; 906*0Sstevel@tonic-gate uchar_t *ptptr; 907*0Sstevel@tonic-gate uchar_t *modulus; 908*0Sstevel@tonic-gate ssize_t modulus_len; 909*0Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 910*0Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 911*0Sstevel@tonic-gate uchar_t cipher_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 912*0Sstevel@tonic-gate 913*0Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 914*0Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 915*0Sstevel@tonic-gate return (rv); 916*0Sstevel@tonic-gate } 917*0Sstevel@tonic-gate 918*0Sstevel@tonic-gate plen = plaintext->cd_length; 919*0Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 920*0Sstevel@tonic-gate if (plen > (modulus_len - MIN_PKCS1_PADLEN)) 921*0Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 922*0Sstevel@tonic-gate } else { 923*0Sstevel@tonic-gate if (plen > modulus_len) 924*0Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 925*0Sstevel@tonic-gate } 926*0Sstevel@tonic-gate 927*0Sstevel@tonic-gate /* 928*0Sstevel@tonic-gate * Output buf len must not be less than RSA modulus size. 929*0Sstevel@tonic-gate */ 930*0Sstevel@tonic-gate if (ciphertext->cd_length < modulus_len) { 931*0Sstevel@tonic-gate ciphertext->cd_length = modulus_len; 932*0Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 933*0Sstevel@tonic-gate } 934*0Sstevel@tonic-gate 935*0Sstevel@tonic-gate ASSERT(plaintext->cd_length <= sizeof (tmp_data)); 936*0Sstevel@tonic-gate if ((rv = get_input_data(plaintext, &ptptr, tmp_data)) 937*0Sstevel@tonic-gate != CRYPTO_SUCCESS) 938*0Sstevel@tonic-gate return (rv); 939*0Sstevel@tonic-gate 940*0Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 941*0Sstevel@tonic-gate rv = soft_encrypt_rsa_pkcs_encode(ptptr, plen, 942*0Sstevel@tonic-gate plain_data, modulus_len); 943*0Sstevel@tonic-gate 944*0Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 945*0Sstevel@tonic-gate return (rv); 946*0Sstevel@tonic-gate } else { 947*0Sstevel@tonic-gate bzero(plain_data, modulus_len - plen); 948*0Sstevel@tonic-gate bcopy(ptptr, &plain_data[modulus_len - plen], plen); 949*0Sstevel@tonic-gate } 950*0Sstevel@tonic-gate 951*0Sstevel@tonic-gate rv = core_rsa_encrypt(key, plain_data, modulus_len, 952*0Sstevel@tonic-gate cipher_data, kmflag, 1); 953*0Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 954*0Sstevel@tonic-gate /* copy out to ciphertext */ 955*0Sstevel@tonic-gate if ((rv = put_output_data(cipher_data, 956*0Sstevel@tonic-gate ciphertext, modulus_len)) != CRYPTO_SUCCESS) 957*0Sstevel@tonic-gate return (rv); 958*0Sstevel@tonic-gate 959*0Sstevel@tonic-gate ciphertext->cd_length = modulus_len; 960*0Sstevel@tonic-gate } 961*0Sstevel@tonic-gate 962*0Sstevel@tonic-gate /* EXPORT DELETE END */ 963*0Sstevel@tonic-gate 964*0Sstevel@tonic-gate return (rv); 965*0Sstevel@tonic-gate } 966*0Sstevel@tonic-gate 967*0Sstevel@tonic-gate /* EXPORT DELETE START */ 968*0Sstevel@tonic-gate 969*0Sstevel@tonic-gate static int 970*0Sstevel@tonic-gate core_rsa_encrypt(crypto_key_t *key, uchar_t *in, 971*0Sstevel@tonic-gate int in_len, uchar_t *out, int kmflag, int is_public) 972*0Sstevel@tonic-gate { 973*0Sstevel@tonic-gate int rv; 974*0Sstevel@tonic-gate uchar_t *expo, *modulus; 975*0Sstevel@tonic-gate ssize_t expo_len; 976*0Sstevel@tonic-gate ssize_t modulus_len; 977*0Sstevel@tonic-gate BIGNUM msg; 978*0Sstevel@tonic-gate RSAkey *rsakey; 979*0Sstevel@tonic-gate 980*0Sstevel@tonic-gate if (is_public) { 981*0Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_PUBLIC_EXPONENT, &expo, 982*0Sstevel@tonic-gate &expo_len)) != CRYPTO_SUCCESS) 983*0Sstevel@tonic-gate return (rv); 984*0Sstevel@tonic-gate } else { 985*0Sstevel@tonic-gate /* 986*0Sstevel@tonic-gate * SUN_CKA_PRIVATE_EXPONENT is a required attribute for a 987*0Sstevel@tonic-gate * RSA secret key. See the comments in core_rsa_decrypt 988*0Sstevel@tonic-gate * routine which calls this routine with a private key. 989*0Sstevel@tonic-gate */ 990*0Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_PRIVATE_EXPONENT, &expo, 991*0Sstevel@tonic-gate &expo_len)) != CRYPTO_SUCCESS) 992*0Sstevel@tonic-gate return (rv); 993*0Sstevel@tonic-gate } 994*0Sstevel@tonic-gate 995*0Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 996*0Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 997*0Sstevel@tonic-gate return (rv); 998*0Sstevel@tonic-gate } 999*0Sstevel@tonic-gate 1000*0Sstevel@tonic-gate rsakey = kmem_alloc(sizeof (RSAkey), kmflag); 1001*0Sstevel@tonic-gate if (rsakey == NULL) 1002*0Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 1003*0Sstevel@tonic-gate 1004*0Sstevel@tonic-gate /* psize and qsize for RSA_key_init is in bits. */ 1005*0Sstevel@tonic-gate if (RSA_key_init(rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) { 1006*0Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 1007*0Sstevel@tonic-gate goto clean1; 1008*0Sstevel@tonic-gate } 1009*0Sstevel@tonic-gate 1010*0Sstevel@tonic-gate /* Size for big_init is in (32-bit) words. */ 1011*0Sstevel@tonic-gate if (big_init(&msg, (in_len + (int)sizeof (uint32_t) - 1) / 1012*0Sstevel@tonic-gate (int)sizeof (uint32_t)) != BIG_OK) { 1013*0Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 1014*0Sstevel@tonic-gate goto clean2; 1015*0Sstevel@tonic-gate } 1016*0Sstevel@tonic-gate 1017*0Sstevel@tonic-gate /* Convert octet string exponent to big integer format. */ 1018*0Sstevel@tonic-gate bytestring2bignum(&(rsakey->e), expo, expo_len); 1019*0Sstevel@tonic-gate 1020*0Sstevel@tonic-gate /* Convert octet string modulus to big integer format. */ 1021*0Sstevel@tonic-gate bytestring2bignum(&(rsakey->n), modulus, modulus_len); 1022*0Sstevel@tonic-gate 1023*0Sstevel@tonic-gate /* Convert octet string input data to big integer format. */ 1024*0Sstevel@tonic-gate bytestring2bignum(&msg, in, in_len); 1025*0Sstevel@tonic-gate 1026*0Sstevel@tonic-gate if (big_cmp_abs(&msg, &(rsakey->n)) > 0) { 1027*0Sstevel@tonic-gate rv = CRYPTO_DATA_LEN_RANGE; 1028*0Sstevel@tonic-gate goto clean3; 1029*0Sstevel@tonic-gate } 1030*0Sstevel@tonic-gate 1031*0Sstevel@tonic-gate /* Perform RSA computation on big integer input data. */ 1032*0Sstevel@tonic-gate if (big_modexp(&msg, &msg, &(rsakey->e), &(rsakey->n), NULL) 1033*0Sstevel@tonic-gate != BIG_OK) { 1034*0Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 1035*0Sstevel@tonic-gate goto clean3; 1036*0Sstevel@tonic-gate } 1037*0Sstevel@tonic-gate 1038*0Sstevel@tonic-gate /* Convert the big integer output data to octet string. */ 1039*0Sstevel@tonic-gate bignum2bytestring(out, &msg, modulus_len); 1040*0Sstevel@tonic-gate 1041*0Sstevel@tonic-gate /* 1042*0Sstevel@tonic-gate * Should not free modulus and expo as both are just pointers 1043*0Sstevel@tonic-gate * to an attribute value buffer from the caller. 1044*0Sstevel@tonic-gate */ 1045*0Sstevel@tonic-gate clean3: 1046*0Sstevel@tonic-gate big_finish(&msg); 1047*0Sstevel@tonic-gate clean2: 1048*0Sstevel@tonic-gate RSA_key_finish(rsakey); 1049*0Sstevel@tonic-gate clean1: 1050*0Sstevel@tonic-gate kmem_free(rsakey, sizeof (RSAkey)); 1051*0Sstevel@tonic-gate 1052*0Sstevel@tonic-gate return (rv); 1053*0Sstevel@tonic-gate } 1054*0Sstevel@tonic-gate 1055*0Sstevel@tonic-gate /* EXPORT DELETE END */ 1056*0Sstevel@tonic-gate 1057*0Sstevel@tonic-gate /* ARGSUSED */ 1058*0Sstevel@tonic-gate static int 1059*0Sstevel@tonic-gate rsa_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext, 1060*0Sstevel@tonic-gate crypto_data_t *plaintext, crypto_req_handle_t req) 1061*0Sstevel@tonic-gate { 1062*0Sstevel@tonic-gate int rv; 1063*0Sstevel@tonic-gate rsa_ctx_t *ctxp; 1064*0Sstevel@tonic-gate 1065*0Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 1066*0Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 1067*0Sstevel@tonic-gate 1068*0Sstevel@tonic-gate RSA_ARG_INPLACE(ciphertext, plaintext); 1069*0Sstevel@tonic-gate 1070*0Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 1071*0Sstevel@tonic-gate rv = rsa_decrypt_common(ctxp->mech_type, ctxp->key, 1072*0Sstevel@tonic-gate ciphertext, plaintext, KM_SLEEP); 1073*0Sstevel@tonic-gate 1074*0Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 1075*0Sstevel@tonic-gate (void) rsa_free_context(ctx); 1076*0Sstevel@tonic-gate 1077*0Sstevel@tonic-gate return (rv); 1078*0Sstevel@tonic-gate } 1079*0Sstevel@tonic-gate 1080*0Sstevel@tonic-gate /* ARGSUSED */ 1081*0Sstevel@tonic-gate static int 1082*0Sstevel@tonic-gate rsa_decrypt_atomic(crypto_provider_handle_t provider, 1083*0Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1084*0Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext, 1085*0Sstevel@tonic-gate crypto_spi_ctx_template_t template, crypto_req_handle_t req) 1086*0Sstevel@tonic-gate { 1087*0Sstevel@tonic-gate int rv; 1088*0Sstevel@tonic-gate 1089*0Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 1090*0Sstevel@tonic-gate return (rv); 1091*0Sstevel@tonic-gate RSA_ARG_INPLACE(ciphertext, plaintext); 1092*0Sstevel@tonic-gate 1093*0Sstevel@tonic-gate return (rsa_decrypt_common(mechanism->cm_type, key, ciphertext, 1094*0Sstevel@tonic-gate plaintext, crypto_kmflag(req))); 1095*0Sstevel@tonic-gate } 1096*0Sstevel@tonic-gate 1097*0Sstevel@tonic-gate static int 1098*0Sstevel@tonic-gate rsa_decrypt_common(rsa_mech_type_t mech_type, crypto_key_t *key, 1099*0Sstevel@tonic-gate crypto_data_t *ciphertext, crypto_data_t *plaintext, int kmflag) 1100*0Sstevel@tonic-gate { 1101*0Sstevel@tonic-gate int rv = CRYPTO_FAILED; 1102*0Sstevel@tonic-gate 1103*0Sstevel@tonic-gate /* EXPORT DELETE START */ 1104*0Sstevel@tonic-gate 1105*0Sstevel@tonic-gate int plain_len; 1106*0Sstevel@tonic-gate uchar_t *ctptr; 1107*0Sstevel@tonic-gate uchar_t *modulus; 1108*0Sstevel@tonic-gate ssize_t modulus_len; 1109*0Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 1110*0Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 1111*0Sstevel@tonic-gate 1112*0Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 1113*0Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 1114*0Sstevel@tonic-gate return (rv); 1115*0Sstevel@tonic-gate } 1116*0Sstevel@tonic-gate 1117*0Sstevel@tonic-gate /* 1118*0Sstevel@tonic-gate * Ciphertext length must be equal to RSA modulus size. 1119*0Sstevel@tonic-gate */ 1120*0Sstevel@tonic-gate if (ciphertext->cd_length != modulus_len) 1121*0Sstevel@tonic-gate return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 1122*0Sstevel@tonic-gate 1123*0Sstevel@tonic-gate ASSERT(ciphertext->cd_length <= sizeof (tmp_data)); 1124*0Sstevel@tonic-gate if ((rv = get_input_data(ciphertext, &ctptr, tmp_data)) 1125*0Sstevel@tonic-gate != CRYPTO_SUCCESS) 1126*0Sstevel@tonic-gate return (rv); 1127*0Sstevel@tonic-gate 1128*0Sstevel@tonic-gate rv = core_rsa_decrypt(key, ctptr, modulus_len, plain_data, kmflag); 1129*0Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 1130*0Sstevel@tonic-gate plain_len = modulus_len; 1131*0Sstevel@tonic-gate 1132*0Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 1133*0Sstevel@tonic-gate /* Strip off the PKCS block formatting data. */ 1134*0Sstevel@tonic-gate rv = soft_decrypt_rsa_pkcs_decode(plain_data, 1135*0Sstevel@tonic-gate &plain_len); 1136*0Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 1137*0Sstevel@tonic-gate return (rv); 1138*0Sstevel@tonic-gate } 1139*0Sstevel@tonic-gate 1140*0Sstevel@tonic-gate if (plain_len > plaintext->cd_length) { 1141*0Sstevel@tonic-gate plaintext->cd_length = plain_len; 1142*0Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 1143*0Sstevel@tonic-gate } 1144*0Sstevel@tonic-gate 1145*0Sstevel@tonic-gate if ((rv = put_output_data(plain_data + modulus_len - plain_len, 1146*0Sstevel@tonic-gate plaintext, plain_len)) != CRYPTO_SUCCESS) 1147*0Sstevel@tonic-gate return (rv); 1148*0Sstevel@tonic-gate 1149*0Sstevel@tonic-gate plaintext->cd_length = plain_len; 1150*0Sstevel@tonic-gate } 1151*0Sstevel@tonic-gate 1152*0Sstevel@tonic-gate /* EXPORT DELETE END */ 1153*0Sstevel@tonic-gate 1154*0Sstevel@tonic-gate return (rv); 1155*0Sstevel@tonic-gate } 1156*0Sstevel@tonic-gate 1157*0Sstevel@tonic-gate /* EXPORT DELETE START */ 1158*0Sstevel@tonic-gate 1159*0Sstevel@tonic-gate static int 1160*0Sstevel@tonic-gate core_rsa_decrypt(crypto_key_t *key, uchar_t *in, int in_len, 1161*0Sstevel@tonic-gate uchar_t *out, int kmflag) 1162*0Sstevel@tonic-gate { 1163*0Sstevel@tonic-gate int rv; 1164*0Sstevel@tonic-gate uchar_t *modulus, *prime1, *prime2, *expo1, *expo2, *coef; 1165*0Sstevel@tonic-gate ssize_t modulus_len; 1166*0Sstevel@tonic-gate ssize_t prime1_len, prime2_len; 1167*0Sstevel@tonic-gate ssize_t expo1_len, expo2_len, coef_len; 1168*0Sstevel@tonic-gate BIGNUM msg; 1169*0Sstevel@tonic-gate RSAkey *rsakey; 1170*0Sstevel@tonic-gate 1171*0Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 1172*0Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 1173*0Sstevel@tonic-gate return (rv); 1174*0Sstevel@tonic-gate } 1175*0Sstevel@tonic-gate 1176*0Sstevel@tonic-gate /* 1177*0Sstevel@tonic-gate * The following attributes are not required to be 1178*0Sstevel@tonic-gate * present in a RSA secret key. If any of them is not present 1179*0Sstevel@tonic-gate * we call the encrypt routine with a flag indicating use of 1180*0Sstevel@tonic-gate * private exponent (d). Note that SUN_CKA_PRIVATE_EXPONENT is 1181*0Sstevel@tonic-gate * a required attribute for a RSA secret key. 1182*0Sstevel@tonic-gate */ 1183*0Sstevel@tonic-gate if ((get_key_attr(key, SUN_CKA_PRIME_1, &prime1, &prime1_len) 1184*0Sstevel@tonic-gate != CRYPTO_SUCCESS) || 1185*0Sstevel@tonic-gate (get_key_attr(key, SUN_CKA_PRIME_2, &prime2, &prime2_len) 1186*0Sstevel@tonic-gate != CRYPTO_SUCCESS) || 1187*0Sstevel@tonic-gate (get_key_attr(key, SUN_CKA_EXPONENT_1, &expo1, &expo1_len) 1188*0Sstevel@tonic-gate != CRYPTO_SUCCESS) || 1189*0Sstevel@tonic-gate (get_key_attr(key, SUN_CKA_EXPONENT_2, &expo2, &expo2_len) 1190*0Sstevel@tonic-gate != CRYPTO_SUCCESS) || 1191*0Sstevel@tonic-gate (get_key_attr(key, SUN_CKA_COEFFICIENT, &coef, &coef_len) 1192*0Sstevel@tonic-gate != CRYPTO_SUCCESS)) { 1193*0Sstevel@tonic-gate return (core_rsa_encrypt(key, in, in_len, out, kmflag, 0)); 1194*0Sstevel@tonic-gate } 1195*0Sstevel@tonic-gate 1196*0Sstevel@tonic-gate rsakey = kmem_alloc(sizeof (RSAkey), kmflag); 1197*0Sstevel@tonic-gate if (rsakey == NULL) 1198*0Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 1199*0Sstevel@tonic-gate 1200*0Sstevel@tonic-gate /* psize and qsize for RSA_key_init is in bits. */ 1201*0Sstevel@tonic-gate if (RSA_key_init(rsakey, prime2_len * 8, prime1_len * 8) != BIG_OK) { 1202*0Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 1203*0Sstevel@tonic-gate goto clean1; 1204*0Sstevel@tonic-gate } 1205*0Sstevel@tonic-gate 1206*0Sstevel@tonic-gate /* Size for big_init is in (32-bit) words. */ 1207*0Sstevel@tonic-gate if (big_init(&msg, (in_len + (int)sizeof (uint32_t) - 1) / 1208*0Sstevel@tonic-gate (int)sizeof (uint32_t)) != BIG_OK) { 1209*0Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 1210*0Sstevel@tonic-gate goto clean2; 1211*0Sstevel@tonic-gate } 1212*0Sstevel@tonic-gate 1213*0Sstevel@tonic-gate /* Convert octet string input data to big integer format. */ 1214*0Sstevel@tonic-gate bytestring2bignum(&msg, in, in_len); 1215*0Sstevel@tonic-gate 1216*0Sstevel@tonic-gate /* Convert octet string modulus to big integer format. */ 1217*0Sstevel@tonic-gate bytestring2bignum(&(rsakey->n), modulus, modulus_len); 1218*0Sstevel@tonic-gate 1219*0Sstevel@tonic-gate if (big_cmp_abs(&msg, &(rsakey->n)) > 0) { 1220*0Sstevel@tonic-gate rv = CRYPTO_DATA_LEN_RANGE; 1221*0Sstevel@tonic-gate goto clean3; 1222*0Sstevel@tonic-gate } 1223*0Sstevel@tonic-gate 1224*0Sstevel@tonic-gate /* Convert the rest of private key attributes to big integer format. */ 1225*0Sstevel@tonic-gate bytestring2bignum(&(rsakey->dmodpminus1), expo2, expo2_len); 1226*0Sstevel@tonic-gate bytestring2bignum(&(rsakey->dmodqminus1), expo1, expo1_len); 1227*0Sstevel@tonic-gate bytestring2bignum(&(rsakey->p), prime2, prime2_len); 1228*0Sstevel@tonic-gate bytestring2bignum(&(rsakey->q), prime1, prime1_len); 1229*0Sstevel@tonic-gate bytestring2bignum(&(rsakey->pinvmodq), coef, coef_len); 1230*0Sstevel@tonic-gate 1231*0Sstevel@tonic-gate if ((big_cmp_abs(&(rsakey->dmodpminus1), &(rsakey->p)) > 0) || 1232*0Sstevel@tonic-gate (big_cmp_abs(&(rsakey->dmodqminus1), &(rsakey->q)) > 0) || 1233*0Sstevel@tonic-gate (big_cmp_abs(&(rsakey->pinvmodq), &(rsakey->q)) > 0)) { 1234*0Sstevel@tonic-gate rv = CRYPTO_KEY_SIZE_RANGE; 1235*0Sstevel@tonic-gate goto clean3; 1236*0Sstevel@tonic-gate } 1237*0Sstevel@tonic-gate 1238*0Sstevel@tonic-gate /* Perform RSA computation on big integer input data. */ 1239*0Sstevel@tonic-gate if (big_modexp_crt(&msg, &msg, &(rsakey->dmodpminus1), 1240*0Sstevel@tonic-gate &(rsakey->dmodqminus1), &(rsakey->p), &(rsakey->q), 1241*0Sstevel@tonic-gate &(rsakey->pinvmodq), NULL, NULL) != BIG_OK) { 1242*0Sstevel@tonic-gate rv = CRYPTO_HOST_MEMORY; 1243*0Sstevel@tonic-gate goto clean3; 1244*0Sstevel@tonic-gate } 1245*0Sstevel@tonic-gate 1246*0Sstevel@tonic-gate /* Convert the big integer output data to octet string. */ 1247*0Sstevel@tonic-gate bignum2bytestring(out, &msg, modulus_len); 1248*0Sstevel@tonic-gate 1249*0Sstevel@tonic-gate /* 1250*0Sstevel@tonic-gate * Should not free modulus and friends as they are just pointers 1251*0Sstevel@tonic-gate * to an attribute value buffer from the caller. 1252*0Sstevel@tonic-gate */ 1253*0Sstevel@tonic-gate clean3: 1254*0Sstevel@tonic-gate big_finish(&msg); 1255*0Sstevel@tonic-gate clean2: 1256*0Sstevel@tonic-gate RSA_key_finish(rsakey); 1257*0Sstevel@tonic-gate clean1: 1258*0Sstevel@tonic-gate kmem_free(rsakey, sizeof (RSAkey)); 1259*0Sstevel@tonic-gate 1260*0Sstevel@tonic-gate return (rv); 1261*0Sstevel@tonic-gate } 1262*0Sstevel@tonic-gate 1263*0Sstevel@tonic-gate /* EXPORT DELETE END */ 1264*0Sstevel@tonic-gate 1265*0Sstevel@tonic-gate /* ARGSUSED */ 1266*0Sstevel@tonic-gate static int 1267*0Sstevel@tonic-gate rsa_sign_verify_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 1268*0Sstevel@tonic-gate crypto_key_t *key, crypto_spi_ctx_template_t ctx_template, 1269*0Sstevel@tonic-gate crypto_req_handle_t req) 1270*0Sstevel@tonic-gate { 1271*0Sstevel@tonic-gate int rv; 1272*0Sstevel@tonic-gate int kmflag; 1273*0Sstevel@tonic-gate rsa_ctx_t *ctxp; 1274*0Sstevel@tonic-gate digest_rsa_ctx_t *dctxp; 1275*0Sstevel@tonic-gate 1276*0Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 1277*0Sstevel@tonic-gate return (rv); 1278*0Sstevel@tonic-gate 1279*0Sstevel@tonic-gate /* 1280*0Sstevel@tonic-gate * Allocate a RSA context. 1281*0Sstevel@tonic-gate */ 1282*0Sstevel@tonic-gate kmflag = crypto_kmflag(req); 1283*0Sstevel@tonic-gate switch (mechanism->cm_type) { 1284*0Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 1285*0Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1286*0Sstevel@tonic-gate dctxp = kmem_zalloc(sizeof (digest_rsa_ctx_t), kmflag); 1287*0Sstevel@tonic-gate ctxp = (rsa_ctx_t *)dctxp; 1288*0Sstevel@tonic-gate break; 1289*0Sstevel@tonic-gate default: 1290*0Sstevel@tonic-gate ctxp = kmem_zalloc(sizeof (rsa_ctx_t), kmflag); 1291*0Sstevel@tonic-gate break; 1292*0Sstevel@tonic-gate } 1293*0Sstevel@tonic-gate 1294*0Sstevel@tonic-gate if (ctxp == NULL) 1295*0Sstevel@tonic-gate return (CRYPTO_HOST_MEMORY); 1296*0Sstevel@tonic-gate 1297*0Sstevel@tonic-gate ctxp->mech_type = mechanism->cm_type; 1298*0Sstevel@tonic-gate if ((rv = copy_key_to_ctx(key, ctxp, kmflag)) != CRYPTO_SUCCESS) { 1299*0Sstevel@tonic-gate switch (mechanism->cm_type) { 1300*0Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 1301*0Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1302*0Sstevel@tonic-gate kmem_free(dctxp, sizeof (digest_rsa_ctx_t)); 1303*0Sstevel@tonic-gate break; 1304*0Sstevel@tonic-gate default: 1305*0Sstevel@tonic-gate kmem_free(ctxp, sizeof (rsa_ctx_t)); 1306*0Sstevel@tonic-gate break; 1307*0Sstevel@tonic-gate } 1308*0Sstevel@tonic-gate return (rv); 1309*0Sstevel@tonic-gate } 1310*0Sstevel@tonic-gate 1311*0Sstevel@tonic-gate switch (mechanism->cm_type) { 1312*0Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 1313*0Sstevel@tonic-gate MD5Init(&(dctxp->md5_ctx)); 1314*0Sstevel@tonic-gate break; 1315*0Sstevel@tonic-gate 1316*0Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1317*0Sstevel@tonic-gate SHA1Init(&(dctxp->sha1_ctx)); 1318*0Sstevel@tonic-gate break; 1319*0Sstevel@tonic-gate } 1320*0Sstevel@tonic-gate 1321*0Sstevel@tonic-gate ctx->cc_provider_private = ctxp; 1322*0Sstevel@tonic-gate 1323*0Sstevel@tonic-gate return (CRYPTO_SUCCESS); 1324*0Sstevel@tonic-gate } 1325*0Sstevel@tonic-gate 1326*0Sstevel@tonic-gate #define SHA1_DIGEST_SIZE 20 1327*0Sstevel@tonic-gate #define MD5_DIGEST_SIZE 16 1328*0Sstevel@tonic-gate 1329*0Sstevel@tonic-gate #define INIT_RAW_CRYPTO_DATA(data, base, len, cd_len) \ 1330*0Sstevel@tonic-gate (data).cd_format = CRYPTO_DATA_RAW; \ 1331*0Sstevel@tonic-gate (data).cd_offset = 0; \ 1332*0Sstevel@tonic-gate (data).cd_raw.iov_base = (char *)base; \ 1333*0Sstevel@tonic-gate (data).cd_raw.iov_len = len; \ 1334*0Sstevel@tonic-gate (data).cd_length = cd_len; 1335*0Sstevel@tonic-gate 1336*0Sstevel@tonic-gate #define DO_UPDATE 0x01 1337*0Sstevel@tonic-gate #define DO_FINAL 0x02 1338*0Sstevel@tonic-gate #define DO_MD5 0x04 1339*0Sstevel@tonic-gate #define DO_SHA1 0x08 1340*0Sstevel@tonic-gate #define DO_SIGN 0x10 1341*0Sstevel@tonic-gate #define DO_VERIFY 0x20 1342*0Sstevel@tonic-gate 1343*0Sstevel@tonic-gate static int 1344*0Sstevel@tonic-gate digest_data(crypto_data_t *data, void *dctx, uchar_t *digest, 1345*0Sstevel@tonic-gate uchar_t flag) 1346*0Sstevel@tonic-gate { 1347*0Sstevel@tonic-gate int rv, dlen; 1348*0Sstevel@tonic-gate uchar_t *dptr; 1349*0Sstevel@tonic-gate cmd_type_t cmd; 1350*0Sstevel@tonic-gate 1351*0Sstevel@tonic-gate ASSERT(flag & DO_MD5 || flag & DO_SHA1); 1352*0Sstevel@tonic-gate if (data == NULL) { 1353*0Sstevel@tonic-gate ASSERT((flag & DO_UPDATE) == 0); 1354*0Sstevel@tonic-gate goto dofinal; 1355*0Sstevel@tonic-gate } 1356*0Sstevel@tonic-gate 1357*0Sstevel@tonic-gate dlen = data->cd_length; 1358*0Sstevel@tonic-gate 1359*0Sstevel@tonic-gate switch (data->cd_format) { 1360*0Sstevel@tonic-gate case CRYPTO_DATA_RAW: 1361*0Sstevel@tonic-gate dptr = (uchar_t *)(data->cd_raw.iov_base + 1362*0Sstevel@tonic-gate data->cd_offset); 1363*0Sstevel@tonic-gate 1364*0Sstevel@tonic-gate if (flag & DO_MD5) { 1365*0Sstevel@tonic-gate if (flag & DO_UPDATE) 1366*0Sstevel@tonic-gate MD5Update(dctx, dptr, dlen); 1367*0Sstevel@tonic-gate } else { 1368*0Sstevel@tonic-gate if (flag & DO_UPDATE) 1369*0Sstevel@tonic-gate SHA1Update(dctx, dptr, dlen); 1370*0Sstevel@tonic-gate } 1371*0Sstevel@tonic-gate break; 1372*0Sstevel@tonic-gate 1373*0Sstevel@tonic-gate case CRYPTO_DATA_UIO: 1374*0Sstevel@tonic-gate cmd = ((flag & DO_MD5) ? MD5_DIGEST_DATA : SHA1_DIGEST_DATA); 1375*0Sstevel@tonic-gate if (flag & DO_UPDATE) { 1376*0Sstevel@tonic-gate rv = process_uio_data(data, NULL, dlen, cmd, dctx); 1377*0Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 1378*0Sstevel@tonic-gate return (rv); 1379*0Sstevel@tonic-gate } 1380*0Sstevel@tonic-gate break; 1381*0Sstevel@tonic-gate 1382*0Sstevel@tonic-gate case CRYPTO_DATA_MBLK: 1383*0Sstevel@tonic-gate cmd = ((flag & DO_MD5) ? MD5_DIGEST_DATA : SHA1_DIGEST_DATA); 1384*0Sstevel@tonic-gate if (flag & DO_UPDATE) { 1385*0Sstevel@tonic-gate rv = process_mblk_data(data, NULL, dlen, cmd, dctx); 1386*0Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 1387*0Sstevel@tonic-gate return (rv); 1388*0Sstevel@tonic-gate } 1389*0Sstevel@tonic-gate break; 1390*0Sstevel@tonic-gate } 1391*0Sstevel@tonic-gate 1392*0Sstevel@tonic-gate dofinal: 1393*0Sstevel@tonic-gate if (flag & DO_FINAL) { 1394*0Sstevel@tonic-gate if (flag & DO_MD5) 1395*0Sstevel@tonic-gate MD5Final(digest, dctx); 1396*0Sstevel@tonic-gate else 1397*0Sstevel@tonic-gate SHA1Final(digest, dctx); 1398*0Sstevel@tonic-gate } 1399*0Sstevel@tonic-gate 1400*0Sstevel@tonic-gate return (CRYPTO_SUCCESS); 1401*0Sstevel@tonic-gate } 1402*0Sstevel@tonic-gate 1403*0Sstevel@tonic-gate static int 1404*0Sstevel@tonic-gate rsa_digest_svrfy_common(digest_rsa_ctx_t *ctxp, crypto_data_t *data, 1405*0Sstevel@tonic-gate crypto_data_t *signature, int kmflag, uchar_t flag) 1406*0Sstevel@tonic-gate { 1407*0Sstevel@tonic-gate int rv = CRYPTO_FAILED; 1408*0Sstevel@tonic-gate 1409*0Sstevel@tonic-gate /* EXPORT DELETE START */ 1410*0Sstevel@tonic-gate 1411*0Sstevel@tonic-gate int dlen; 1412*0Sstevel@tonic-gate uchar_t digest[SHA1_DIGEST_SIZE]; 1413*0Sstevel@tonic-gate /* The der_data size is enough for MD5 also */ 1414*0Sstevel@tonic-gate uchar_t der_data[SHA1_DIGEST_SIZE + SHA1_DER_PREFIX_Len]; 1415*0Sstevel@tonic-gate ulong_t der_data_len; 1416*0Sstevel@tonic-gate crypto_data_t der_cd; 1417*0Sstevel@tonic-gate rsa_mech_type_t mech_type; 1418*0Sstevel@tonic-gate 1419*0Sstevel@tonic-gate ASSERT(flag & DO_SIGN || flag & DO_VERIFY); 1420*0Sstevel@tonic-gate ASSERT(data != NULL || (flag & DO_FINAL)); 1421*0Sstevel@tonic-gate 1422*0Sstevel@tonic-gate mech_type = ctxp->mech_type; 1423*0Sstevel@tonic-gate if (!(mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE || 1424*0Sstevel@tonic-gate mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE)) 1425*0Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 1426*0Sstevel@tonic-gate 1427*0Sstevel@tonic-gate /* 1428*0Sstevel@tonic-gate * We need to do the BUFFER_TOO_SMALL check before digesting 1429*0Sstevel@tonic-gate * the data. No check is needed for verify as signature is not 1430*0Sstevel@tonic-gate * an output argument for verify. 1431*0Sstevel@tonic-gate */ 1432*0Sstevel@tonic-gate if (flag & DO_SIGN) { 1433*0Sstevel@tonic-gate uchar_t *modulus; 1434*0Sstevel@tonic-gate ssize_t modulus_len; 1435*0Sstevel@tonic-gate 1436*0Sstevel@tonic-gate if ((rv = get_key_attr(ctxp->key, SUN_CKA_MODULUS, &modulus, 1437*0Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 1438*0Sstevel@tonic-gate return (rv); 1439*0Sstevel@tonic-gate } 1440*0Sstevel@tonic-gate 1441*0Sstevel@tonic-gate if (signature->cd_length < modulus_len) { 1442*0Sstevel@tonic-gate signature->cd_length = modulus_len; 1443*0Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 1444*0Sstevel@tonic-gate } 1445*0Sstevel@tonic-gate } 1446*0Sstevel@tonic-gate 1447*0Sstevel@tonic-gate dlen = ((mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE) ? 1448*0Sstevel@tonic-gate MD5_DIGEST_SIZE : SHA1_DIGEST_SIZE); 1449*0Sstevel@tonic-gate 1450*0Sstevel@tonic-gate if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE) 1451*0Sstevel@tonic-gate rv = digest_data(data, &(ctxp->md5_ctx), 1452*0Sstevel@tonic-gate digest, flag | DO_MD5); 1453*0Sstevel@tonic-gate else 1454*0Sstevel@tonic-gate rv = digest_data(data, &(ctxp->sha1_ctx), 1455*0Sstevel@tonic-gate digest, flag | DO_SHA1); 1456*0Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 1457*0Sstevel@tonic-gate return (rv); 1458*0Sstevel@tonic-gate 1459*0Sstevel@tonic-gate /* 1460*0Sstevel@tonic-gate * Prepare the DER encoding of the DigestInfo value as follows: 1461*0Sstevel@tonic-gate * MD5: MD5_DER_PREFIX || H 1462*0Sstevel@tonic-gate * SHA-1: SHA1_DER_PREFIX || H 1463*0Sstevel@tonic-gate * 1464*0Sstevel@tonic-gate * See rsa_impl.c for more details. 1465*0Sstevel@tonic-gate */ 1466*0Sstevel@tonic-gate if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE) { 1467*0Sstevel@tonic-gate bcopy(MD5_DER_PREFIX, der_data, MD5_DER_PREFIX_Len); 1468*0Sstevel@tonic-gate bcopy(digest, der_data + MD5_DER_PREFIX_Len, dlen); 1469*0Sstevel@tonic-gate der_data_len = MD5_DER_PREFIX_Len + dlen; 1470*0Sstevel@tonic-gate } else { 1471*0Sstevel@tonic-gate bcopy(SHA1_DER_PREFIX, der_data, SHA1_DER_PREFIX_Len); 1472*0Sstevel@tonic-gate bcopy(digest, der_data + SHA1_DER_PREFIX_Len, dlen); 1473*0Sstevel@tonic-gate der_data_len = SHA1_DER_PREFIX_Len + dlen; 1474*0Sstevel@tonic-gate } 1475*0Sstevel@tonic-gate 1476*0Sstevel@tonic-gate INIT_RAW_CRYPTO_DATA(der_cd, der_data, der_data_len, der_data_len); 1477*0Sstevel@tonic-gate /* 1478*0Sstevel@tonic-gate * Now, we are ready to sign or verify the DER_ENCODED data. 1479*0Sstevel@tonic-gate */ 1480*0Sstevel@tonic-gate if (flag & DO_SIGN) 1481*0Sstevel@tonic-gate rv = rsa_sign_common(mech_type, ctxp->key, &der_cd, 1482*0Sstevel@tonic-gate signature, kmflag); 1483*0Sstevel@tonic-gate else 1484*0Sstevel@tonic-gate rv = rsa_verify_common(mech_type, ctxp->key, &der_cd, 1485*0Sstevel@tonic-gate signature, kmflag); 1486*0Sstevel@tonic-gate 1487*0Sstevel@tonic-gate /* EXPORT DELETE END */ 1488*0Sstevel@tonic-gate 1489*0Sstevel@tonic-gate return (rv); 1490*0Sstevel@tonic-gate } 1491*0Sstevel@tonic-gate 1492*0Sstevel@tonic-gate static int 1493*0Sstevel@tonic-gate rsa_sign_common(rsa_mech_type_t mech_type, crypto_key_t *key, 1494*0Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *signature, int kmflag) 1495*0Sstevel@tonic-gate { 1496*0Sstevel@tonic-gate int rv = CRYPTO_FAILED; 1497*0Sstevel@tonic-gate 1498*0Sstevel@tonic-gate /* EXPORT DELETE START */ 1499*0Sstevel@tonic-gate 1500*0Sstevel@tonic-gate int dlen; 1501*0Sstevel@tonic-gate uchar_t *dataptr, *modulus; 1502*0Sstevel@tonic-gate ssize_t modulus_len; 1503*0Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 1504*0Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 1505*0Sstevel@tonic-gate uchar_t signed_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 1506*0Sstevel@tonic-gate 1507*0Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 1508*0Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 1509*0Sstevel@tonic-gate return (rv); 1510*0Sstevel@tonic-gate } 1511*0Sstevel@tonic-gate 1512*0Sstevel@tonic-gate dlen = data->cd_length; 1513*0Sstevel@tonic-gate switch (mech_type) { 1514*0Sstevel@tonic-gate case RSA_PKCS_MECH_INFO_TYPE: 1515*0Sstevel@tonic-gate if (dlen > (modulus_len - MIN_PKCS1_PADLEN)) 1516*0Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 1517*0Sstevel@tonic-gate break; 1518*0Sstevel@tonic-gate case RSA_X_509_MECH_INFO_TYPE: 1519*0Sstevel@tonic-gate if (dlen > modulus_len) 1520*0Sstevel@tonic-gate return (CRYPTO_DATA_LEN_RANGE); 1521*0Sstevel@tonic-gate break; 1522*0Sstevel@tonic-gate } 1523*0Sstevel@tonic-gate 1524*0Sstevel@tonic-gate if (signature->cd_length < modulus_len) { 1525*0Sstevel@tonic-gate signature->cd_length = modulus_len; 1526*0Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 1527*0Sstevel@tonic-gate } 1528*0Sstevel@tonic-gate 1529*0Sstevel@tonic-gate ASSERT(data->cd_length <= sizeof (tmp_data)); 1530*0Sstevel@tonic-gate if ((rv = get_input_data(data, &dataptr, tmp_data)) 1531*0Sstevel@tonic-gate != CRYPTO_SUCCESS) 1532*0Sstevel@tonic-gate return (rv); 1533*0Sstevel@tonic-gate 1534*0Sstevel@tonic-gate switch (mech_type) { 1535*0Sstevel@tonic-gate case RSA_PKCS_MECH_INFO_TYPE: 1536*0Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 1537*0Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1538*0Sstevel@tonic-gate /* 1539*0Sstevel@tonic-gate * Add PKCS padding to the input data to format a block 1540*0Sstevel@tonic-gate * type "01" encryption block. 1541*0Sstevel@tonic-gate */ 1542*0Sstevel@tonic-gate rv = soft_sign_rsa_pkcs_encode(dataptr, dlen, plain_data, 1543*0Sstevel@tonic-gate modulus_len); 1544*0Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 1545*0Sstevel@tonic-gate return (rv); 1546*0Sstevel@tonic-gate 1547*0Sstevel@tonic-gate break; 1548*0Sstevel@tonic-gate 1549*0Sstevel@tonic-gate case RSA_X_509_MECH_INFO_TYPE: 1550*0Sstevel@tonic-gate bzero(plain_data, modulus_len - dlen); 1551*0Sstevel@tonic-gate bcopy(dataptr, &plain_data[modulus_len - dlen], dlen); 1552*0Sstevel@tonic-gate break; 1553*0Sstevel@tonic-gate } 1554*0Sstevel@tonic-gate 1555*0Sstevel@tonic-gate rv = core_rsa_decrypt(key, plain_data, modulus_len, signed_data, 1556*0Sstevel@tonic-gate kmflag); 1557*0Sstevel@tonic-gate if (rv == CRYPTO_SUCCESS) { 1558*0Sstevel@tonic-gate /* copy out to signature */ 1559*0Sstevel@tonic-gate if ((rv = put_output_data(signed_data, 1560*0Sstevel@tonic-gate signature, modulus_len)) != CRYPTO_SUCCESS) 1561*0Sstevel@tonic-gate return (rv); 1562*0Sstevel@tonic-gate 1563*0Sstevel@tonic-gate signature->cd_length = modulus_len; 1564*0Sstevel@tonic-gate } 1565*0Sstevel@tonic-gate 1566*0Sstevel@tonic-gate /* EXPORT DELETE END */ 1567*0Sstevel@tonic-gate 1568*0Sstevel@tonic-gate return (rv); 1569*0Sstevel@tonic-gate } 1570*0Sstevel@tonic-gate 1571*0Sstevel@tonic-gate /* ARGSUSED */ 1572*0Sstevel@tonic-gate static int 1573*0Sstevel@tonic-gate rsa_sign(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 1574*0Sstevel@tonic-gate crypto_req_handle_t req) 1575*0Sstevel@tonic-gate { 1576*0Sstevel@tonic-gate int rv; 1577*0Sstevel@tonic-gate rsa_ctx_t *ctxp; 1578*0Sstevel@tonic-gate 1579*0Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 1580*0Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 1581*0Sstevel@tonic-gate 1582*0Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 1583*0Sstevel@tonic-gate switch (ctxp->mech_type) { 1584*0Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 1585*0Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1586*0Sstevel@tonic-gate rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data, 1587*0Sstevel@tonic-gate signature, KM_SLEEP, DO_SIGN | DO_UPDATE | DO_FINAL); 1588*0Sstevel@tonic-gate break; 1589*0Sstevel@tonic-gate default: 1590*0Sstevel@tonic-gate rv = rsa_sign_common(ctxp->mech_type, ctxp->key, data, 1591*0Sstevel@tonic-gate signature, KM_SLEEP); 1592*0Sstevel@tonic-gate break; 1593*0Sstevel@tonic-gate } 1594*0Sstevel@tonic-gate 1595*0Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 1596*0Sstevel@tonic-gate (void) rsa_free_context(ctx); 1597*0Sstevel@tonic-gate 1598*0Sstevel@tonic-gate return (rv); 1599*0Sstevel@tonic-gate } 1600*0Sstevel@tonic-gate 1601*0Sstevel@tonic-gate /* ARGSUSED */ 1602*0Sstevel@tonic-gate static int 1603*0Sstevel@tonic-gate rsa_sign_update(crypto_ctx_t *ctx, crypto_data_t *data, crypto_req_handle_t req) 1604*0Sstevel@tonic-gate { 1605*0Sstevel@tonic-gate int rv; 1606*0Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 1607*0Sstevel@tonic-gate rsa_mech_type_t mech_type; 1608*0Sstevel@tonic-gate 1609*0Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 1610*0Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 1611*0Sstevel@tonic-gate mech_type = ctxp->mech_type; 1612*0Sstevel@tonic-gate 1613*0Sstevel@tonic-gate if (!(mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE || 1614*0Sstevel@tonic-gate mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE)) 1615*0Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 1616*0Sstevel@tonic-gate 1617*0Sstevel@tonic-gate if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE) 1618*0Sstevel@tonic-gate rv = digest_data(data, &(ctxp->md5_ctx), 1619*0Sstevel@tonic-gate NULL, DO_MD5 | DO_UPDATE); 1620*0Sstevel@tonic-gate else 1621*0Sstevel@tonic-gate rv = digest_data(data, &(ctxp->sha1_ctx), 1622*0Sstevel@tonic-gate NULL, DO_SHA1 | DO_UPDATE); 1623*0Sstevel@tonic-gate return (rv); 1624*0Sstevel@tonic-gate } 1625*0Sstevel@tonic-gate 1626*0Sstevel@tonic-gate static int 1627*0Sstevel@tonic-gate rsa_sign_final(crypto_ctx_t *ctx, crypto_data_t *signature, 1628*0Sstevel@tonic-gate crypto_req_handle_t req) 1629*0Sstevel@tonic-gate { 1630*0Sstevel@tonic-gate int rv; 1631*0Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 1632*0Sstevel@tonic-gate 1633*0Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 1634*0Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 1635*0Sstevel@tonic-gate 1636*0Sstevel@tonic-gate rv = rsa_digest_svrfy_common(ctxp, NULL, signature, 1637*0Sstevel@tonic-gate crypto_kmflag(req), DO_SIGN | DO_FINAL); 1638*0Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 1639*0Sstevel@tonic-gate (void) rsa_free_context(ctx); 1640*0Sstevel@tonic-gate 1641*0Sstevel@tonic-gate return (rv); 1642*0Sstevel@tonic-gate } 1643*0Sstevel@tonic-gate 1644*0Sstevel@tonic-gate /* ARGSUSED */ 1645*0Sstevel@tonic-gate static int 1646*0Sstevel@tonic-gate rsa_sign_atomic(crypto_provider_handle_t provider, 1647*0Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1648*0Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *data, crypto_data_t *signature, 1649*0Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 1650*0Sstevel@tonic-gate { 1651*0Sstevel@tonic-gate int rv; 1652*0Sstevel@tonic-gate digest_rsa_ctx_t dctx; 1653*0Sstevel@tonic-gate 1654*0Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 1655*0Sstevel@tonic-gate return (rv); 1656*0Sstevel@tonic-gate 1657*0Sstevel@tonic-gate switch (mechanism->cm_type) { 1658*0Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 1659*0Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1660*0Sstevel@tonic-gate dctx.mech_type = mechanism->cm_type; 1661*0Sstevel@tonic-gate dctx.key = key; 1662*0Sstevel@tonic-gate if (mechanism->cm_type == MD5_RSA_PKCS_MECH_INFO_TYPE) 1663*0Sstevel@tonic-gate MD5Init(&(dctx.md5_ctx)); 1664*0Sstevel@tonic-gate else 1665*0Sstevel@tonic-gate SHA1Init(&(dctx.sha1_ctx)); 1666*0Sstevel@tonic-gate rv = rsa_digest_svrfy_common(&dctx, data, 1667*0Sstevel@tonic-gate signature, crypto_kmflag(req), 1668*0Sstevel@tonic-gate DO_SIGN | DO_UPDATE | DO_FINAL); 1669*0Sstevel@tonic-gate break; 1670*0Sstevel@tonic-gate default: 1671*0Sstevel@tonic-gate rv = rsa_sign_common(mechanism->cm_type, key, data, 1672*0Sstevel@tonic-gate signature, crypto_kmflag(req)); 1673*0Sstevel@tonic-gate break; 1674*0Sstevel@tonic-gate } 1675*0Sstevel@tonic-gate 1676*0Sstevel@tonic-gate return (rv); 1677*0Sstevel@tonic-gate } 1678*0Sstevel@tonic-gate 1679*0Sstevel@tonic-gate static int 1680*0Sstevel@tonic-gate rsa_verify_common(rsa_mech_type_t mech_type, crypto_key_t *key, 1681*0Sstevel@tonic-gate crypto_data_t *data, crypto_data_t *signature, int kmflag) 1682*0Sstevel@tonic-gate { 1683*0Sstevel@tonic-gate int rv = CRYPTO_FAILED; 1684*0Sstevel@tonic-gate 1685*0Sstevel@tonic-gate /* EXPORT DELETE START */ 1686*0Sstevel@tonic-gate 1687*0Sstevel@tonic-gate uchar_t *sigptr, *modulus; 1688*0Sstevel@tonic-gate ssize_t modulus_len; 1689*0Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 1690*0Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 1691*0Sstevel@tonic-gate 1692*0Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 1693*0Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 1694*0Sstevel@tonic-gate return (rv); 1695*0Sstevel@tonic-gate } 1696*0Sstevel@tonic-gate 1697*0Sstevel@tonic-gate if (signature->cd_length != modulus_len) 1698*0Sstevel@tonic-gate return (CRYPTO_SIGNATURE_LEN_RANGE); 1699*0Sstevel@tonic-gate 1700*0Sstevel@tonic-gate ASSERT(signature->cd_length <= sizeof (tmp_data)); 1701*0Sstevel@tonic-gate if ((rv = get_input_data(signature, &sigptr, tmp_data)) 1702*0Sstevel@tonic-gate != CRYPTO_SUCCESS) 1703*0Sstevel@tonic-gate return (rv); 1704*0Sstevel@tonic-gate 1705*0Sstevel@tonic-gate rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1); 1706*0Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 1707*0Sstevel@tonic-gate return (rv); 1708*0Sstevel@tonic-gate 1709*0Sstevel@tonic-gate switch (mech_type) { 1710*0Sstevel@tonic-gate case RSA_PKCS_MECH_INFO_TYPE: 1711*0Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 1712*0Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: { 1713*0Sstevel@tonic-gate int data_len = modulus_len; 1714*0Sstevel@tonic-gate 1715*0Sstevel@tonic-gate /* 1716*0Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the 1717*0Sstevel@tonic-gate * recovered data, then compare the recovered data with 1718*0Sstevel@tonic-gate * the original data. 1719*0Sstevel@tonic-gate */ 1720*0Sstevel@tonic-gate rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len); 1721*0Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 1722*0Sstevel@tonic-gate break; 1723*0Sstevel@tonic-gate 1724*0Sstevel@tonic-gate if (data_len != data->cd_length) { 1725*0Sstevel@tonic-gate rv = CRYPTO_SIGNATURE_LEN_RANGE; 1726*0Sstevel@tonic-gate break; 1727*0Sstevel@tonic-gate } 1728*0Sstevel@tonic-gate 1729*0Sstevel@tonic-gate if (compare_data(data, (plain_data + modulus_len 1730*0Sstevel@tonic-gate - data_len)) != 0) 1731*0Sstevel@tonic-gate rv = CRYPTO_SIGNATURE_INVALID; 1732*0Sstevel@tonic-gate break; 1733*0Sstevel@tonic-gate } 1734*0Sstevel@tonic-gate 1735*0Sstevel@tonic-gate case RSA_X_509_MECH_INFO_TYPE: 1736*0Sstevel@tonic-gate if (compare_data(data, (plain_data + modulus_len 1737*0Sstevel@tonic-gate - data->cd_length)) != 0) 1738*0Sstevel@tonic-gate rv = CRYPTO_SIGNATURE_INVALID; 1739*0Sstevel@tonic-gate break; 1740*0Sstevel@tonic-gate 1741*0Sstevel@tonic-gate default: 1742*0Sstevel@tonic-gate break; 1743*0Sstevel@tonic-gate } 1744*0Sstevel@tonic-gate 1745*0Sstevel@tonic-gate /* EXPORT DELETE END */ 1746*0Sstevel@tonic-gate 1747*0Sstevel@tonic-gate return (rv); 1748*0Sstevel@tonic-gate } 1749*0Sstevel@tonic-gate 1750*0Sstevel@tonic-gate /* ARGSUSED */ 1751*0Sstevel@tonic-gate static int 1752*0Sstevel@tonic-gate rsa_verify(crypto_ctx_t *ctx, crypto_data_t *data, crypto_data_t *signature, 1753*0Sstevel@tonic-gate crypto_req_handle_t req) 1754*0Sstevel@tonic-gate { 1755*0Sstevel@tonic-gate int rv; 1756*0Sstevel@tonic-gate rsa_ctx_t *ctxp; 1757*0Sstevel@tonic-gate 1758*0Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 1759*0Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 1760*0Sstevel@tonic-gate 1761*0Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 1762*0Sstevel@tonic-gate switch (ctxp->mech_type) { 1763*0Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 1764*0Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1765*0Sstevel@tonic-gate rv = rsa_digest_svrfy_common((digest_rsa_ctx_t *)ctxp, data, 1766*0Sstevel@tonic-gate signature, KM_SLEEP, DO_VERIFY | DO_UPDATE | DO_FINAL); 1767*0Sstevel@tonic-gate break; 1768*0Sstevel@tonic-gate default: 1769*0Sstevel@tonic-gate rv = rsa_verify_common(ctxp->mech_type, ctxp->key, data, 1770*0Sstevel@tonic-gate signature, KM_SLEEP); 1771*0Sstevel@tonic-gate break; 1772*0Sstevel@tonic-gate } 1773*0Sstevel@tonic-gate 1774*0Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 1775*0Sstevel@tonic-gate (void) rsa_free_context(ctx); 1776*0Sstevel@tonic-gate 1777*0Sstevel@tonic-gate return (rv); 1778*0Sstevel@tonic-gate } 1779*0Sstevel@tonic-gate 1780*0Sstevel@tonic-gate /* ARGSUSED */ 1781*0Sstevel@tonic-gate static int 1782*0Sstevel@tonic-gate rsa_verify_update(crypto_ctx_t *ctx, crypto_data_t *data, 1783*0Sstevel@tonic-gate crypto_req_handle_t req) 1784*0Sstevel@tonic-gate { 1785*0Sstevel@tonic-gate int rv; 1786*0Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 1787*0Sstevel@tonic-gate rsa_mech_type_t mech_type; 1788*0Sstevel@tonic-gate 1789*0Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 1790*0Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 1791*0Sstevel@tonic-gate mech_type = ctxp->mech_type; 1792*0Sstevel@tonic-gate 1793*0Sstevel@tonic-gate if (!(mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE || 1794*0Sstevel@tonic-gate mech_type == SHA1_RSA_PKCS_MECH_INFO_TYPE)) 1795*0Sstevel@tonic-gate return (CRYPTO_MECHANISM_INVALID); 1796*0Sstevel@tonic-gate 1797*0Sstevel@tonic-gate if (mech_type == MD5_RSA_PKCS_MECH_INFO_TYPE) 1798*0Sstevel@tonic-gate rv = digest_data(data, &(ctxp->md5_ctx), 1799*0Sstevel@tonic-gate NULL, DO_MD5 | DO_UPDATE); 1800*0Sstevel@tonic-gate else 1801*0Sstevel@tonic-gate rv = digest_data(data, &(ctxp->sha1_ctx), 1802*0Sstevel@tonic-gate NULL, DO_SHA1 | DO_UPDATE); 1803*0Sstevel@tonic-gate return (rv); 1804*0Sstevel@tonic-gate } 1805*0Sstevel@tonic-gate 1806*0Sstevel@tonic-gate static int 1807*0Sstevel@tonic-gate rsa_verify_final(crypto_ctx_t *ctx, crypto_data_t *signature, 1808*0Sstevel@tonic-gate crypto_req_handle_t req) 1809*0Sstevel@tonic-gate { 1810*0Sstevel@tonic-gate int rv; 1811*0Sstevel@tonic-gate digest_rsa_ctx_t *ctxp; 1812*0Sstevel@tonic-gate 1813*0Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 1814*0Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 1815*0Sstevel@tonic-gate 1816*0Sstevel@tonic-gate rv = rsa_digest_svrfy_common(ctxp, NULL, signature, 1817*0Sstevel@tonic-gate crypto_kmflag(req), DO_VERIFY | DO_FINAL); 1818*0Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 1819*0Sstevel@tonic-gate (void) rsa_free_context(ctx); 1820*0Sstevel@tonic-gate 1821*0Sstevel@tonic-gate return (rv); 1822*0Sstevel@tonic-gate } 1823*0Sstevel@tonic-gate 1824*0Sstevel@tonic-gate 1825*0Sstevel@tonic-gate /* ARGSUSED */ 1826*0Sstevel@tonic-gate static int 1827*0Sstevel@tonic-gate rsa_verify_atomic(crypto_provider_handle_t provider, 1828*0Sstevel@tonic-gate crypto_session_id_t session_id, 1829*0Sstevel@tonic-gate crypto_mechanism_t *mechanism, crypto_key_t *key, crypto_data_t *data, 1830*0Sstevel@tonic-gate crypto_data_t *signature, crypto_spi_ctx_template_t ctx_template, 1831*0Sstevel@tonic-gate crypto_req_handle_t req) 1832*0Sstevel@tonic-gate { 1833*0Sstevel@tonic-gate int rv; 1834*0Sstevel@tonic-gate digest_rsa_ctx_t dctx; 1835*0Sstevel@tonic-gate 1836*0Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 1837*0Sstevel@tonic-gate return (rv); 1838*0Sstevel@tonic-gate 1839*0Sstevel@tonic-gate switch (mechanism->cm_type) { 1840*0Sstevel@tonic-gate case MD5_RSA_PKCS_MECH_INFO_TYPE: 1841*0Sstevel@tonic-gate case SHA1_RSA_PKCS_MECH_INFO_TYPE: 1842*0Sstevel@tonic-gate dctx.mech_type = mechanism->cm_type; 1843*0Sstevel@tonic-gate dctx.key = key; 1844*0Sstevel@tonic-gate if (mechanism->cm_type == MD5_RSA_PKCS_MECH_INFO_TYPE) 1845*0Sstevel@tonic-gate MD5Init(&(dctx.md5_ctx)); 1846*0Sstevel@tonic-gate else 1847*0Sstevel@tonic-gate SHA1Init(&(dctx.sha1_ctx)); 1848*0Sstevel@tonic-gate rv = rsa_digest_svrfy_common(&dctx, data, 1849*0Sstevel@tonic-gate signature, crypto_kmflag(req), 1850*0Sstevel@tonic-gate DO_VERIFY | DO_UPDATE | DO_FINAL); 1851*0Sstevel@tonic-gate break; 1852*0Sstevel@tonic-gate default: 1853*0Sstevel@tonic-gate rv = rsa_verify_common(mechanism->cm_type, key, data, 1854*0Sstevel@tonic-gate signature, crypto_kmflag(req)); 1855*0Sstevel@tonic-gate break; 1856*0Sstevel@tonic-gate } 1857*0Sstevel@tonic-gate 1858*0Sstevel@tonic-gate return (rv); 1859*0Sstevel@tonic-gate } 1860*0Sstevel@tonic-gate 1861*0Sstevel@tonic-gate static int 1862*0Sstevel@tonic-gate rsa_verify_recover_common(rsa_mech_type_t mech_type, crypto_key_t *key, 1863*0Sstevel@tonic-gate crypto_data_t *signature, crypto_data_t *data, int kmflag) 1864*0Sstevel@tonic-gate { 1865*0Sstevel@tonic-gate int rv = CRYPTO_FAILED; 1866*0Sstevel@tonic-gate 1867*0Sstevel@tonic-gate /* EXPORT DELETE START */ 1868*0Sstevel@tonic-gate 1869*0Sstevel@tonic-gate int data_len; 1870*0Sstevel@tonic-gate uchar_t *sigptr, *modulus; 1871*0Sstevel@tonic-gate ssize_t modulus_len; 1872*0Sstevel@tonic-gate uchar_t plain_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 1873*0Sstevel@tonic-gate uchar_t tmp_data[MAX_RSA_KEYLENGTH_IN_BYTES]; 1874*0Sstevel@tonic-gate 1875*0Sstevel@tonic-gate if ((rv = get_key_attr(key, SUN_CKA_MODULUS, &modulus, 1876*0Sstevel@tonic-gate &modulus_len)) != CRYPTO_SUCCESS) { 1877*0Sstevel@tonic-gate return (rv); 1878*0Sstevel@tonic-gate } 1879*0Sstevel@tonic-gate 1880*0Sstevel@tonic-gate if (signature->cd_length != modulus_len) 1881*0Sstevel@tonic-gate return (CRYPTO_SIGNATURE_LEN_RANGE); 1882*0Sstevel@tonic-gate 1883*0Sstevel@tonic-gate ASSERT(signature->cd_length <= sizeof (tmp_data)); 1884*0Sstevel@tonic-gate if ((rv = get_input_data(signature, &sigptr, tmp_data)) 1885*0Sstevel@tonic-gate != CRYPTO_SUCCESS) 1886*0Sstevel@tonic-gate return (rv); 1887*0Sstevel@tonic-gate 1888*0Sstevel@tonic-gate rv = core_rsa_encrypt(key, sigptr, modulus_len, plain_data, kmflag, 1); 1889*0Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 1890*0Sstevel@tonic-gate return (rv); 1891*0Sstevel@tonic-gate 1892*0Sstevel@tonic-gate data_len = modulus_len; 1893*0Sstevel@tonic-gate 1894*0Sstevel@tonic-gate if (mech_type == RSA_PKCS_MECH_INFO_TYPE) { 1895*0Sstevel@tonic-gate /* 1896*0Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the 1897*0Sstevel@tonic-gate * recovered data, then compare the recovered data with 1898*0Sstevel@tonic-gate * the original data. 1899*0Sstevel@tonic-gate */ 1900*0Sstevel@tonic-gate rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len); 1901*0Sstevel@tonic-gate if (rv != CRYPTO_SUCCESS) 1902*0Sstevel@tonic-gate return (rv); 1903*0Sstevel@tonic-gate } 1904*0Sstevel@tonic-gate 1905*0Sstevel@tonic-gate if (data->cd_length < data_len) { 1906*0Sstevel@tonic-gate data->cd_length = data_len; 1907*0Sstevel@tonic-gate return (CRYPTO_BUFFER_TOO_SMALL); 1908*0Sstevel@tonic-gate } 1909*0Sstevel@tonic-gate 1910*0Sstevel@tonic-gate if ((rv = put_output_data(plain_data + modulus_len - data_len, 1911*0Sstevel@tonic-gate data, data_len)) != CRYPTO_SUCCESS) 1912*0Sstevel@tonic-gate return (rv); 1913*0Sstevel@tonic-gate data->cd_length = data_len; 1914*0Sstevel@tonic-gate 1915*0Sstevel@tonic-gate /* EXPORT DELETE END */ 1916*0Sstevel@tonic-gate 1917*0Sstevel@tonic-gate return (rv); 1918*0Sstevel@tonic-gate } 1919*0Sstevel@tonic-gate 1920*0Sstevel@tonic-gate /* ARGSUSED */ 1921*0Sstevel@tonic-gate static int 1922*0Sstevel@tonic-gate rsa_verify_recover(crypto_ctx_t *ctx, crypto_data_t *signature, 1923*0Sstevel@tonic-gate crypto_data_t *data, crypto_req_handle_t req) 1924*0Sstevel@tonic-gate { 1925*0Sstevel@tonic-gate int rv; 1926*0Sstevel@tonic-gate rsa_ctx_t *ctxp; 1927*0Sstevel@tonic-gate 1928*0Sstevel@tonic-gate ASSERT(ctx->cc_provider_private != NULL); 1929*0Sstevel@tonic-gate ctxp = ctx->cc_provider_private; 1930*0Sstevel@tonic-gate 1931*0Sstevel@tonic-gate /* See the comments on KM_SLEEP flag in rsa_encrypt() */ 1932*0Sstevel@tonic-gate rv = rsa_verify_recover_common(ctxp->mech_type, ctxp->key, 1933*0Sstevel@tonic-gate signature, data, KM_SLEEP); 1934*0Sstevel@tonic-gate 1935*0Sstevel@tonic-gate if (rv != CRYPTO_BUFFER_TOO_SMALL) 1936*0Sstevel@tonic-gate (void) rsa_free_context(ctx); 1937*0Sstevel@tonic-gate 1938*0Sstevel@tonic-gate return (rv); 1939*0Sstevel@tonic-gate } 1940*0Sstevel@tonic-gate 1941*0Sstevel@tonic-gate /* ARGSUSED */ 1942*0Sstevel@tonic-gate static int 1943*0Sstevel@tonic-gate rsa_verify_recover_atomic(crypto_provider_handle_t provider, 1944*0Sstevel@tonic-gate crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1945*0Sstevel@tonic-gate crypto_key_t *key, crypto_data_t *signature, crypto_data_t *data, 1946*0Sstevel@tonic-gate crypto_spi_ctx_template_t ctx_template, crypto_req_handle_t req) 1947*0Sstevel@tonic-gate { 1948*0Sstevel@tonic-gate int rv; 1949*0Sstevel@tonic-gate 1950*0Sstevel@tonic-gate if ((rv = check_mech_and_key(mechanism, key)) != CRYPTO_SUCCESS) 1951*0Sstevel@tonic-gate return (rv); 1952*0Sstevel@tonic-gate 1953*0Sstevel@tonic-gate return (rsa_verify_recover_common(mechanism->cm_type, key, 1954*0Sstevel@tonic-gate signature, data, crypto_kmflag(req))); 1955*0Sstevel@tonic-gate } 1956