1eda14cbcSMatt Macy /* 2eda14cbcSMatt Macy * CDDL HEADER START 3eda14cbcSMatt Macy * 4eda14cbcSMatt Macy * The contents of this file are subject to the terms of the 5eda14cbcSMatt Macy * Common Development and Distribution License (the "License"). 6eda14cbcSMatt Macy * You may not use this file except in compliance with the License. 7eda14cbcSMatt Macy * 8eda14cbcSMatt Macy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9eda14cbcSMatt Macy * or http://www.opensolaris.org/os/licensing. 10eda14cbcSMatt Macy * See the License for the specific language governing permissions 11eda14cbcSMatt Macy * and limitations under the License. 12eda14cbcSMatt Macy * 13eda14cbcSMatt Macy * When distributing Covered Code, include this CDDL HEADER in each 14eda14cbcSMatt Macy * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15eda14cbcSMatt Macy * If applicable, add the following below this CDDL HEADER, with the 16eda14cbcSMatt Macy * fields enclosed by brackets "[]" replaced with your own identifying 17eda14cbcSMatt Macy * information: Portions Copyright [yyyy] [name of copyright owner] 18eda14cbcSMatt Macy * 19eda14cbcSMatt Macy * CDDL HEADER END 20eda14cbcSMatt Macy */ 21eda14cbcSMatt Macy /* 22eda14cbcSMatt Macy * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23eda14cbcSMatt Macy * Use is subject to license terms. 24eda14cbcSMatt Macy */ 25eda14cbcSMatt Macy 26eda14cbcSMatt Macy #include <sys/zfs_context.h> 27eda14cbcSMatt Macy #include <sys/crypto/common.h> 28eda14cbcSMatt Macy #include <sys/crypto/impl.h> 29eda14cbcSMatt Macy #include <sys/crypto/api.h> 30eda14cbcSMatt Macy #include <sys/crypto/spi.h> 31eda14cbcSMatt Macy #include <sys/crypto/sched_impl.h> 32eda14cbcSMatt Macy 33eda14cbcSMatt Macy /* 34eda14cbcSMatt Macy * Encryption and decryption routines. 35eda14cbcSMatt Macy */ 36eda14cbcSMatt Macy 37eda14cbcSMatt Macy 38eda14cbcSMatt Macy /* 39*c03c5b1cSMartin Matuska * crypto_encrypt() 40eda14cbcSMatt Macy * 41eda14cbcSMatt Macy * Arguments: 42eda14cbcSMatt Macy * sid: session id 43eda14cbcSMatt Macy * mech: crypto_mechanism_t pointer. 44eda14cbcSMatt Macy * mech_type is a valid value previously returned by 45eda14cbcSMatt Macy * crypto_mech2id(); 46eda14cbcSMatt Macy * When the mech's parameter is not NULL, its definition depends 47eda14cbcSMatt Macy * on the standard definition of the mechanism. 48eda14cbcSMatt Macy * key: pointer to a crypto_key_t structure. 49eda14cbcSMatt Macy * plaintext: The message to be encrypted 50eda14cbcSMatt Macy * ciphertext: Storage for the encrypted message. The length needed 51eda14cbcSMatt Macy * depends on the mechanism, and the plaintext's size. 52eda14cbcSMatt Macy * tmpl: a crypto_ctx_template_t, opaque template of a context of an 53eda14cbcSMatt Macy * encryption with the 'mech' using 'key'. 'tmpl' is created by 54eda14cbcSMatt Macy * a previous call to crypto_create_ctx_template(). 55eda14cbcSMatt Macy * 56eda14cbcSMatt Macy * Description: 57eda14cbcSMatt Macy * Asynchronously submits a request for, or synchronously performs a 58eda14cbcSMatt Macy * single-part encryption of 'plaintext' with the mechanism 'mech', using 59eda14cbcSMatt Macy * the key 'key'. 60eda14cbcSMatt Macy * When complete and successful, 'ciphertext' will contain the encrypted 61eda14cbcSMatt Macy * message. 62*c03c5b1cSMartin Matuska * Relies on the KCF scheduler to pick a provider. 63eda14cbcSMatt Macy * 64eda14cbcSMatt Macy * Returns: 65eda14cbcSMatt Macy * See comment in the beginning of the file. 66eda14cbcSMatt Macy */ 67eda14cbcSMatt Macy int 68eda14cbcSMatt Macy crypto_encrypt(crypto_mechanism_t *mech, crypto_data_t *plaintext, 69*c03c5b1cSMartin Matuska crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *ciphertext) 70eda14cbcSMatt Macy { 71eda14cbcSMatt Macy int error; 72eda14cbcSMatt Macy kcf_mech_entry_t *me; 73eda14cbcSMatt Macy kcf_provider_desc_t *pd; 74eda14cbcSMatt Macy kcf_ctx_template_t *ctx_tmpl; 75eda14cbcSMatt Macy crypto_spi_ctx_template_t spi_ctx_tmpl = NULL; 76eda14cbcSMatt Macy kcf_prov_tried_t *list = NULL; 77eda14cbcSMatt Macy 78eda14cbcSMatt Macy retry: 79eda14cbcSMatt Macy /* pd is returned held */ 80eda14cbcSMatt Macy if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error, 81*c03c5b1cSMartin Matuska list, CRYPTO_FG_ENCRYPT_ATOMIC)) == NULL) { 82eda14cbcSMatt Macy if (list != NULL) 83eda14cbcSMatt Macy kcf_free_triedlist(list); 84eda14cbcSMatt Macy return (error); 85eda14cbcSMatt Macy } 86eda14cbcSMatt Macy 87*c03c5b1cSMartin Matuska if (((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) 88eda14cbcSMatt Macy spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl; 89eda14cbcSMatt Macy 90*c03c5b1cSMartin Matuska crypto_mechanism_t lmech = *mech; 91eda14cbcSMatt Macy KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech); 92*c03c5b1cSMartin Matuska error = KCF_PROV_ENCRYPT_ATOMIC(pd, &lmech, key, 93*c03c5b1cSMartin Matuska plaintext, ciphertext, spi_ctx_tmpl); 94eda14cbcSMatt Macy 95*c03c5b1cSMartin Matuska if (error != CRYPTO_SUCCESS && IS_RECOVERABLE(error)) { 96eda14cbcSMatt Macy /* Add pd to the linked list of providers tried. */ 97*c03c5b1cSMartin Matuska if (kcf_insert_triedlist(&list, pd, KM_SLEEP) != NULL) 98eda14cbcSMatt Macy goto retry; 99eda14cbcSMatt Macy } 100eda14cbcSMatt Macy 101eda14cbcSMatt Macy if (list != NULL) 102eda14cbcSMatt Macy kcf_free_triedlist(list); 103eda14cbcSMatt Macy 104eda14cbcSMatt Macy KCF_PROV_REFRELE(pd); 105eda14cbcSMatt Macy return (error); 106eda14cbcSMatt Macy } 107eda14cbcSMatt Macy 108eda14cbcSMatt Macy /* 109eda14cbcSMatt Macy * crypto_decrypt_prov() 110eda14cbcSMatt Macy * 111eda14cbcSMatt Macy * Arguments: 112eda14cbcSMatt Macy * pd: provider descriptor 113eda14cbcSMatt Macy * sid: session id 114eda14cbcSMatt Macy * mech: crypto_mechanism_t pointer. 115eda14cbcSMatt Macy * mech_type is a valid value previously returned by 116eda14cbcSMatt Macy * crypto_mech2id(); 117eda14cbcSMatt Macy * When the mech's parameter is not NULL, its definition depends 118eda14cbcSMatt Macy * on the standard definition of the mechanism. 119eda14cbcSMatt Macy * key: pointer to a crypto_key_t structure. 120eda14cbcSMatt Macy * ciphertext: The message to be encrypted 121eda14cbcSMatt Macy * plaintext: Storage for the encrypted message. The length needed 122eda14cbcSMatt Macy * depends on the mechanism, and the plaintext's size. 123eda14cbcSMatt Macy * tmpl: a crypto_ctx_template_t, opaque template of a context of an 124eda14cbcSMatt Macy * encryption with the 'mech' using 'key'. 'tmpl' is created by 125eda14cbcSMatt Macy * a previous call to crypto_create_ctx_template(). 126eda14cbcSMatt Macy * 127eda14cbcSMatt Macy * Description: 128eda14cbcSMatt Macy * Asynchronously submits a request for, or synchronously performs a 129eda14cbcSMatt Macy * single-part decryption of 'ciphertext' with the mechanism 'mech', using 130eda14cbcSMatt Macy * the key 'key'. 131eda14cbcSMatt Macy * When complete and successful, 'plaintext' will contain the decrypted 132eda14cbcSMatt Macy * message. 133*c03c5b1cSMartin Matuska * Relies on the KCF scheduler to choose a provider. 134eda14cbcSMatt Macy * 135eda14cbcSMatt Macy * Returns: 136eda14cbcSMatt Macy * See comment in the beginning of the file. 137eda14cbcSMatt Macy */ 138eda14cbcSMatt Macy int 139eda14cbcSMatt Macy crypto_decrypt(crypto_mechanism_t *mech, crypto_data_t *ciphertext, 140*c03c5b1cSMartin Matuska crypto_key_t *key, crypto_ctx_template_t tmpl, crypto_data_t *plaintext) 141eda14cbcSMatt Macy { 142eda14cbcSMatt Macy int error; 143eda14cbcSMatt Macy kcf_mech_entry_t *me; 144eda14cbcSMatt Macy kcf_provider_desc_t *pd; 145eda14cbcSMatt Macy kcf_ctx_template_t *ctx_tmpl; 146eda14cbcSMatt Macy crypto_spi_ctx_template_t spi_ctx_tmpl = NULL; 147eda14cbcSMatt Macy kcf_prov_tried_t *list = NULL; 148eda14cbcSMatt Macy 149eda14cbcSMatt Macy retry: 150eda14cbcSMatt Macy /* pd is returned held */ 151eda14cbcSMatt Macy if ((pd = kcf_get_mech_provider(mech->cm_type, &me, &error, 152*c03c5b1cSMartin Matuska list, CRYPTO_FG_DECRYPT_ATOMIC)) == NULL) { 153eda14cbcSMatt Macy if (list != NULL) 154eda14cbcSMatt Macy kcf_free_triedlist(list); 155eda14cbcSMatt Macy return (error); 156eda14cbcSMatt Macy } 157eda14cbcSMatt Macy 158*c03c5b1cSMartin Matuska if (((ctx_tmpl = (kcf_ctx_template_t *)tmpl) != NULL)) 159eda14cbcSMatt Macy spi_ctx_tmpl = ctx_tmpl->ct_prov_tmpl; 160eda14cbcSMatt Macy 161*c03c5b1cSMartin Matuska crypto_mechanism_t lmech = *mech; 162eda14cbcSMatt Macy KCF_SET_PROVIDER_MECHNUM(mech->cm_type, pd, &lmech); 163eda14cbcSMatt Macy 164*c03c5b1cSMartin Matuska error = KCF_PROV_DECRYPT_ATOMIC(pd, &lmech, key, 165*c03c5b1cSMartin Matuska ciphertext, plaintext, spi_ctx_tmpl); 166eda14cbcSMatt Macy 167*c03c5b1cSMartin Matuska if (error != CRYPTO_SUCCESS && IS_RECOVERABLE(error)) { 168eda14cbcSMatt Macy /* Add pd to the linked list of providers tried. */ 169*c03c5b1cSMartin Matuska if (kcf_insert_triedlist(&list, pd, KM_SLEEP) != NULL) 170eda14cbcSMatt Macy goto retry; 171eda14cbcSMatt Macy } 172eda14cbcSMatt Macy 173eda14cbcSMatt Macy if (list != NULL) 174eda14cbcSMatt Macy kcf_free_triedlist(list); 175eda14cbcSMatt Macy 176eda14cbcSMatt Macy KCF_PROV_REFRELE(pd); 177eda14cbcSMatt Macy return (error); 178eda14cbcSMatt Macy } 179eda14cbcSMatt Macy 180eda14cbcSMatt Macy #if defined(_KERNEL) 181eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_encrypt); 182eda14cbcSMatt Macy EXPORT_SYMBOL(crypto_decrypt); 183eda14cbcSMatt Macy #endif 184