int pkcs11_decrypt( pkcs11_context *ctx, int mode, size_t *olen, const unsigned char *input, unsigned char *output, size_t output_max_len ) { size_t input_len, output_len; if( NULL == ctx ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); if( RSA_PUBLIC == mode ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); output_len = input_len = ctx->len; if( input_len < 16 || input_len > output_max_len ) return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); /* Determine size of output buffer */ if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, input_len, NULL, &output_len ) != CKR_OK ) { return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); } if( output_len > output_max_len ) return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE ); if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, input_len, output, &output_len ) != CKR_OK ) { return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); } *olen = output_len; return( 0 ); }
/** Decrypt data (set by SETDATA) with certificate id in line. */ gpg_error_t cmd_pkdecrypt (assuan_context_t ctx, char *line) { gpg_err_code_t error = GPG_ERR_GENERAL; pkcs11h_certificate_id_t cert_id = NULL; pkcs11h_certificate_t cert = NULL; unsigned char *ptext = NULL; size_t ptext_len; int session_locked = 0; cmd_data_t *data = (cmd_data_t *)assuan_get_pointer (ctx); cmd_data_t _data; if ( data == NULL || data->data == NULL ) { error = GPG_ERR_INV_DATA; goto cleanup; } /* * Guess.. taken from openpgp card implementation * and java PKCS#11 provider. */ _data.data = data->data; _data.size = data->size; if ( *_data.data == 0 && ( _data.size == 129 || _data.size == 193 || _data.size == 257 || _data.size == 385 || _data.size == 513 ) ) { _data.data++; _data.size--; } if ( (error = _get_certificate_by_name ( ctx, line, OPENPGP_ENCR, &cert_id, NULL )) != GPG_ERR_NO_ERROR ) { goto cleanup; } if ( (error = common_map_pkcs11_error ( pkcs11h_certificate_create ( cert_id, ctx, PKCS11H_PROMPT_MASK_ALLOW_ALL, PKCS11H_PIN_CACHE_INFINITE, &cert ) )) != GPG_ERR_NO_ERROR ) { goto cleanup; } if ( (error = common_map_pkcs11_error ( pkcs11h_certificate_lockSession (cert) )) != GPG_ERR_NO_ERROR ) { goto cleanup; } session_locked = 1; if ( (error = common_map_pkcs11_error ( pkcs11h_certificate_decryptAny ( cert, CKM_RSA_PKCS, _data.data, _data.size, NULL, &ptext_len ) )) != GPG_ERR_NO_ERROR ) { goto cleanup; } if ((ptext = (unsigned char *)malloc (ptext_len)) == NULL) { error = GPG_ERR_ENOMEM; goto cleanup; } if ( (error = common_map_pkcs11_error ( pkcs11h_certificate_decryptAny ( cert, CKM_RSA_PKCS, _data.data, _data.size, ptext, &ptext_len ) )) != GPG_ERR_NO_ERROR || (error = assuan_write_status(ctx, "PADDING", "0")) != GPG_ERR_NO_ERROR || (error = assuan_send_data(ctx, ptext, ptext_len)) != GPG_ERR_NO_ERROR ) { goto cleanup; } error = GPG_ERR_NO_ERROR; cleanup: if (session_locked) { pkcs11h_certificate_releaseSession (cert); session_locked = 0; } if (cert != NULL) { pkcs11h_certificate_freeCertificate (cert); cert = NULL; } if (cert_id != NULL) { pkcs11h_certificate_freeCertificateId (cert_id); cert_id = NULL; } if (ptext != NULL) { free (ptext); ptext = NULL; } return gpg_error (error); }
static int __pkcs11h_openssl_rsa_dec ( IN int flen, IN unsigned char *from, OUT unsigned char *to, IN OUT RSA *rsa, IN int padding ) { #else static int __pkcs11h_openssl_rsa_dec ( IN int flen, IN const unsigned char *from, OUT unsigned char *to, IN OUT RSA *rsa, IN int padding ) { #endif pkcs11h_certificate_t certificate = __pkcs11h_openssl_rsa_get_pkcs11h_certificate (rsa); PKCS11H_BOOL session_locked = FALSE; CK_MECHANISM_TYPE mech = CKM_RSA_PKCS; CK_RV rv = CKR_FUNCTION_FAILED; size_t tlen = (size_t)flen; _PKCS11H_ASSERT (from!=NULL); _PKCS11H_ASSERT (to!=NULL); _PKCS11H_ASSERT (rsa!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_rsa_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d", flen, from, to, (void *)rsa, padding ); switch (padding) { case RSA_PKCS1_PADDING: mech = CKM_RSA_PKCS; break; case RSA_PKCS1_OAEP_PADDING: mech = CKM_RSA_PKCS_OAEP; break; case RSA_SSLV23_PADDING: rv = CKR_MECHANISM_INVALID; break; case RSA_NO_PADDING: rv = CKR_MECHANISM_INVALID; break; } if (rv == CKR_MECHANISM_INVALID) goto cleanup; if ((rv = pkcs11h_certificate_lockSession (certificate)) != CKR_OK) { goto cleanup; } session_locked = TRUE; _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG1, "PKCS#11: Performing decryption" ); if ( (rv = pkcs11h_certificate_decryptAny ( certificate, mech, from, flen, to, &tlen )) != CKR_OK ) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform decryption %ld:'%s'", rv, pkcs11h_getMessage (rv)); goto cleanup; } rv = CKR_OK; cleanup: if (session_locked) { pkcs11h_certificate_releaseSession (certificate); session_locked = FALSE; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: __pkcs11h_openssl_rsa_dec - return rv=%lu-'%s'", rv, pkcs11h_getMessage (rv) ); return rv == CKR_OK ? (int)tlen : -1; }