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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 23eda14cbcSMatt Macy */ 24eda14cbcSMatt Macy 25eda14cbcSMatt Macy /* 26eda14cbcSMatt Macy * AES provider for the Kernel Cryptographic Framework (KCF) 27eda14cbcSMatt Macy */ 28eda14cbcSMatt Macy 29eda14cbcSMatt Macy #include <sys/zfs_context.h> 30eda14cbcSMatt Macy #include <sys/crypto/common.h> 31eda14cbcSMatt Macy #include <sys/crypto/impl.h> 32eda14cbcSMatt Macy #include <sys/crypto/spi.h> 33eda14cbcSMatt Macy #include <sys/crypto/icp.h> 34eda14cbcSMatt Macy #include <modes/modes.h> 35eda14cbcSMatt Macy #define _AES_IMPL 36eda14cbcSMatt Macy #include <aes/aes_impl.h> 37eda14cbcSMatt Macy #include <modes/gcm_impl.h> 38eda14cbcSMatt Macy 39eda14cbcSMatt Macy /* 40eda14cbcSMatt Macy * Mechanism info structure passed to KCF during registration. 41eda14cbcSMatt Macy */ 42*e92ffd9bSMartin Matuska static const crypto_mech_info_t aes_mech_info_tab[] = { 43eda14cbcSMatt Macy /* AES_ECB */ 44eda14cbcSMatt Macy {SUN_CKM_AES_ECB, AES_ECB_MECH_INFO_TYPE, 45eda14cbcSMatt Macy CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 46eda14cbcSMatt Macy CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC, 47eda14cbcSMatt Macy AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 48eda14cbcSMatt Macy /* AES_CBC */ 49eda14cbcSMatt Macy {SUN_CKM_AES_CBC, AES_CBC_MECH_INFO_TYPE, 50eda14cbcSMatt Macy CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 51eda14cbcSMatt Macy CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC, 52eda14cbcSMatt Macy AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 53eda14cbcSMatt Macy /* AES_CTR */ 54eda14cbcSMatt Macy {SUN_CKM_AES_CTR, AES_CTR_MECH_INFO_TYPE, 55eda14cbcSMatt Macy CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 56eda14cbcSMatt Macy CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC, 57eda14cbcSMatt Macy AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 58eda14cbcSMatt Macy /* AES_CCM */ 59eda14cbcSMatt Macy {SUN_CKM_AES_CCM, AES_CCM_MECH_INFO_TYPE, 60eda14cbcSMatt Macy CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 61eda14cbcSMatt Macy CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC, 62eda14cbcSMatt Macy AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 63eda14cbcSMatt Macy /* AES_GCM */ 64eda14cbcSMatt Macy {SUN_CKM_AES_GCM, AES_GCM_MECH_INFO_TYPE, 65eda14cbcSMatt Macy CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 66eda14cbcSMatt Macy CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC, 67eda14cbcSMatt Macy AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES}, 68eda14cbcSMatt Macy /* AES_GMAC */ 69eda14cbcSMatt Macy {SUN_CKM_AES_GMAC, AES_GMAC_MECH_INFO_TYPE, 70eda14cbcSMatt Macy CRYPTO_FG_ENCRYPT | CRYPTO_FG_ENCRYPT_ATOMIC | 71eda14cbcSMatt Macy CRYPTO_FG_DECRYPT | CRYPTO_FG_DECRYPT_ATOMIC | 72eda14cbcSMatt Macy CRYPTO_FG_MAC | CRYPTO_FG_MAC_ATOMIC | 73eda14cbcSMatt Macy CRYPTO_FG_SIGN | CRYPTO_FG_SIGN_ATOMIC | 74eda14cbcSMatt Macy CRYPTO_FG_VERIFY | CRYPTO_FG_VERIFY_ATOMIC, 75eda14cbcSMatt Macy AES_MIN_KEY_BYTES, AES_MAX_KEY_BYTES, CRYPTO_KEYSIZE_UNIT_IN_BYTES} 76eda14cbcSMatt Macy }; 77eda14cbcSMatt Macy 78eda14cbcSMatt Macy static void aes_provider_status(crypto_provider_handle_t, uint_t *); 79eda14cbcSMatt Macy 80*e92ffd9bSMartin Matuska static const crypto_control_ops_t aes_control_ops = { 81eda14cbcSMatt Macy aes_provider_status 82eda14cbcSMatt Macy }; 83eda14cbcSMatt Macy 84eda14cbcSMatt Macy static int aes_encrypt_init(crypto_ctx_t *, crypto_mechanism_t *, 85eda14cbcSMatt Macy crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 86eda14cbcSMatt Macy static int aes_decrypt_init(crypto_ctx_t *, crypto_mechanism_t *, 87eda14cbcSMatt Macy crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 88eda14cbcSMatt Macy static int aes_common_init(crypto_ctx_t *, crypto_mechanism_t *, 89eda14cbcSMatt Macy crypto_key_t *, crypto_spi_ctx_template_t, crypto_req_handle_t, boolean_t); 90eda14cbcSMatt Macy static int aes_common_init_ctx(aes_ctx_t *, crypto_spi_ctx_template_t *, 91eda14cbcSMatt Macy crypto_mechanism_t *, crypto_key_t *, int, boolean_t); 92eda14cbcSMatt Macy static int aes_encrypt_final(crypto_ctx_t *, crypto_data_t *, 93eda14cbcSMatt Macy crypto_req_handle_t); 94eda14cbcSMatt Macy static int aes_decrypt_final(crypto_ctx_t *, crypto_data_t *, 95eda14cbcSMatt Macy crypto_req_handle_t); 96eda14cbcSMatt Macy 97eda14cbcSMatt Macy static int aes_encrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 98eda14cbcSMatt Macy crypto_req_handle_t); 99eda14cbcSMatt Macy static int aes_encrypt_update(crypto_ctx_t *, crypto_data_t *, 100eda14cbcSMatt Macy crypto_data_t *, crypto_req_handle_t); 101eda14cbcSMatt Macy static int aes_encrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 102eda14cbcSMatt Macy crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 103eda14cbcSMatt Macy crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 104eda14cbcSMatt Macy 105eda14cbcSMatt Macy static int aes_decrypt(crypto_ctx_t *, crypto_data_t *, crypto_data_t *, 106eda14cbcSMatt Macy crypto_req_handle_t); 107eda14cbcSMatt Macy static int aes_decrypt_update(crypto_ctx_t *, crypto_data_t *, 108eda14cbcSMatt Macy crypto_data_t *, crypto_req_handle_t); 109eda14cbcSMatt Macy static int aes_decrypt_atomic(crypto_provider_handle_t, crypto_session_id_t, 110eda14cbcSMatt Macy crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, 111eda14cbcSMatt Macy crypto_data_t *, crypto_spi_ctx_template_t, crypto_req_handle_t); 112eda14cbcSMatt Macy 113*e92ffd9bSMartin Matuska static const crypto_cipher_ops_t aes_cipher_ops = { 114eda14cbcSMatt Macy .encrypt_init = aes_encrypt_init, 115eda14cbcSMatt Macy .encrypt = aes_encrypt, 116eda14cbcSMatt Macy .encrypt_update = aes_encrypt_update, 117eda14cbcSMatt Macy .encrypt_final = aes_encrypt_final, 118eda14cbcSMatt Macy .encrypt_atomic = aes_encrypt_atomic, 119eda14cbcSMatt Macy .decrypt_init = aes_decrypt_init, 120eda14cbcSMatt Macy .decrypt = aes_decrypt, 121eda14cbcSMatt Macy .decrypt_update = aes_decrypt_update, 122eda14cbcSMatt Macy .decrypt_final = aes_decrypt_final, 123eda14cbcSMatt Macy .decrypt_atomic = aes_decrypt_atomic 124eda14cbcSMatt Macy }; 125eda14cbcSMatt Macy 126eda14cbcSMatt Macy static int aes_mac_atomic(crypto_provider_handle_t, crypto_session_id_t, 127eda14cbcSMatt Macy crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, 128eda14cbcSMatt Macy crypto_spi_ctx_template_t, crypto_req_handle_t); 129eda14cbcSMatt Macy static int aes_mac_verify_atomic(crypto_provider_handle_t, crypto_session_id_t, 130eda14cbcSMatt Macy crypto_mechanism_t *, crypto_key_t *, crypto_data_t *, crypto_data_t *, 131eda14cbcSMatt Macy crypto_spi_ctx_template_t, crypto_req_handle_t); 132eda14cbcSMatt Macy 133*e92ffd9bSMartin Matuska static const crypto_mac_ops_t aes_mac_ops = { 134eda14cbcSMatt Macy .mac_init = NULL, 135eda14cbcSMatt Macy .mac = NULL, 136eda14cbcSMatt Macy .mac_update = NULL, 137eda14cbcSMatt Macy .mac_final = NULL, 138eda14cbcSMatt Macy .mac_atomic = aes_mac_atomic, 139eda14cbcSMatt Macy .mac_verify_atomic = aes_mac_verify_atomic 140eda14cbcSMatt Macy }; 141eda14cbcSMatt Macy 142eda14cbcSMatt Macy static int aes_create_ctx_template(crypto_provider_handle_t, 143eda14cbcSMatt Macy crypto_mechanism_t *, crypto_key_t *, crypto_spi_ctx_template_t *, 144eda14cbcSMatt Macy size_t *, crypto_req_handle_t); 145eda14cbcSMatt Macy static int aes_free_context(crypto_ctx_t *); 146eda14cbcSMatt Macy 147*e92ffd9bSMartin Matuska static const crypto_ctx_ops_t aes_ctx_ops = { 148eda14cbcSMatt Macy .create_ctx_template = aes_create_ctx_template, 149eda14cbcSMatt Macy .free_context = aes_free_context 150eda14cbcSMatt Macy }; 151eda14cbcSMatt Macy 152*e92ffd9bSMartin Matuska static const crypto_ops_t aes_crypto_ops = {{{{{ 153eda14cbcSMatt Macy &aes_control_ops, 154eda14cbcSMatt Macy NULL, 155eda14cbcSMatt Macy &aes_cipher_ops, 156eda14cbcSMatt Macy &aes_mac_ops, 157eda14cbcSMatt Macy NULL, 158eda14cbcSMatt Macy NULL, 159eda14cbcSMatt Macy NULL, 160eda14cbcSMatt Macy NULL, 161eda14cbcSMatt Macy NULL, 162eda14cbcSMatt Macy NULL, 163eda14cbcSMatt Macy NULL, 164eda14cbcSMatt Macy NULL, 165eda14cbcSMatt Macy NULL, 166eda14cbcSMatt Macy &aes_ctx_ops 167eda14cbcSMatt Macy }}}}}; 168eda14cbcSMatt Macy 169*e92ffd9bSMartin Matuska static const crypto_provider_info_t aes_prov_info = {{{{ 170eda14cbcSMatt Macy CRYPTO_SPI_VERSION_1, 171eda14cbcSMatt Macy "AES Software Provider", 172eda14cbcSMatt Macy CRYPTO_SW_PROVIDER, 173eda14cbcSMatt Macy NULL, 174eda14cbcSMatt Macy &aes_crypto_ops, 175eda14cbcSMatt Macy sizeof (aes_mech_info_tab) / sizeof (crypto_mech_info_t), 176eda14cbcSMatt Macy aes_mech_info_tab 177eda14cbcSMatt Macy }}}}; 178eda14cbcSMatt Macy 179eda14cbcSMatt Macy static crypto_kcf_provider_handle_t aes_prov_handle = 0; 180eda14cbcSMatt Macy static crypto_data_t null_crypto_data = { CRYPTO_DATA_RAW }; 181eda14cbcSMatt Macy 182eda14cbcSMatt Macy int 183eda14cbcSMatt Macy aes_mod_init(void) 184eda14cbcSMatt Macy { 185eda14cbcSMatt Macy /* Determine the fastest available implementation. */ 186eda14cbcSMatt Macy aes_impl_init(); 187eda14cbcSMatt Macy gcm_impl_init(); 188eda14cbcSMatt Macy 189eda14cbcSMatt Macy /* Register with KCF. If the registration fails, remove the module. */ 190*e92ffd9bSMartin Matuska if (crypto_register_provider(&aes_prov_info, &aes_prov_handle)) 191eda14cbcSMatt Macy return (EACCES); 192eda14cbcSMatt Macy 193eda14cbcSMatt Macy return (0); 194eda14cbcSMatt Macy } 195eda14cbcSMatt Macy 196eda14cbcSMatt Macy int 197eda14cbcSMatt Macy aes_mod_fini(void) 198eda14cbcSMatt Macy { 199eda14cbcSMatt Macy /* Unregister from KCF if module is registered */ 200eda14cbcSMatt Macy if (aes_prov_handle != 0) { 201eda14cbcSMatt Macy if (crypto_unregister_provider(aes_prov_handle)) 202eda14cbcSMatt Macy return (EBUSY); 203eda14cbcSMatt Macy 204eda14cbcSMatt Macy aes_prov_handle = 0; 205eda14cbcSMatt Macy } 206eda14cbcSMatt Macy 207*e92ffd9bSMartin Matuska return (0); 208eda14cbcSMatt Macy } 209eda14cbcSMatt Macy 210eda14cbcSMatt Macy static int 211eda14cbcSMatt Macy aes_check_mech_param(crypto_mechanism_t *mechanism, aes_ctx_t **ctx, int kmflag) 212eda14cbcSMatt Macy { 213eda14cbcSMatt Macy void *p = NULL; 214eda14cbcSMatt Macy boolean_t param_required = B_TRUE; 215eda14cbcSMatt Macy size_t param_len; 216eda14cbcSMatt Macy void *(*alloc_fun)(int); 217eda14cbcSMatt Macy int rv = CRYPTO_SUCCESS; 218eda14cbcSMatt Macy 219eda14cbcSMatt Macy switch (mechanism->cm_type) { 220eda14cbcSMatt Macy case AES_ECB_MECH_INFO_TYPE: 221eda14cbcSMatt Macy param_required = B_FALSE; 222eda14cbcSMatt Macy alloc_fun = ecb_alloc_ctx; 223eda14cbcSMatt Macy break; 224eda14cbcSMatt Macy case AES_CBC_MECH_INFO_TYPE: 225eda14cbcSMatt Macy param_len = AES_BLOCK_LEN; 226eda14cbcSMatt Macy alloc_fun = cbc_alloc_ctx; 227eda14cbcSMatt Macy break; 228eda14cbcSMatt Macy case AES_CTR_MECH_INFO_TYPE: 229eda14cbcSMatt Macy param_len = sizeof (CK_AES_CTR_PARAMS); 230eda14cbcSMatt Macy alloc_fun = ctr_alloc_ctx; 231eda14cbcSMatt Macy break; 232eda14cbcSMatt Macy case AES_CCM_MECH_INFO_TYPE: 233eda14cbcSMatt Macy param_len = sizeof (CK_AES_CCM_PARAMS); 234eda14cbcSMatt Macy alloc_fun = ccm_alloc_ctx; 235eda14cbcSMatt Macy break; 236eda14cbcSMatt Macy case AES_GCM_MECH_INFO_TYPE: 237eda14cbcSMatt Macy param_len = sizeof (CK_AES_GCM_PARAMS); 238eda14cbcSMatt Macy alloc_fun = gcm_alloc_ctx; 239eda14cbcSMatt Macy break; 240eda14cbcSMatt Macy case AES_GMAC_MECH_INFO_TYPE: 241eda14cbcSMatt Macy param_len = sizeof (CK_AES_GMAC_PARAMS); 242eda14cbcSMatt Macy alloc_fun = gmac_alloc_ctx; 243eda14cbcSMatt Macy break; 244eda14cbcSMatt Macy default: 245eda14cbcSMatt Macy rv = CRYPTO_MECHANISM_INVALID; 246eda14cbcSMatt Macy return (rv); 247eda14cbcSMatt Macy } 248eda14cbcSMatt Macy if (param_required && mechanism->cm_param != NULL && 249eda14cbcSMatt Macy mechanism->cm_param_len != param_len) { 250eda14cbcSMatt Macy rv = CRYPTO_MECHANISM_PARAM_INVALID; 251eda14cbcSMatt Macy } 252eda14cbcSMatt Macy if (ctx != NULL) { 253eda14cbcSMatt Macy p = (alloc_fun)(kmflag); 254eda14cbcSMatt Macy *ctx = p; 255eda14cbcSMatt Macy } 256eda14cbcSMatt Macy return (rv); 257eda14cbcSMatt Macy } 258eda14cbcSMatt Macy 259eda14cbcSMatt Macy /* 260eda14cbcSMatt Macy * Initialize key schedules for AES 261eda14cbcSMatt Macy */ 262eda14cbcSMatt Macy static int 263eda14cbcSMatt Macy init_keysched(crypto_key_t *key, void *newbie) 264eda14cbcSMatt Macy { 265eda14cbcSMatt Macy /* 266eda14cbcSMatt Macy * Only keys by value are supported by this module. 267eda14cbcSMatt Macy */ 268eda14cbcSMatt Macy switch (key->ck_format) { 269eda14cbcSMatt Macy case CRYPTO_KEY_RAW: 270eda14cbcSMatt Macy if (key->ck_length < AES_MINBITS || 271eda14cbcSMatt Macy key->ck_length > AES_MAXBITS) { 272eda14cbcSMatt Macy return (CRYPTO_KEY_SIZE_RANGE); 273eda14cbcSMatt Macy } 274eda14cbcSMatt Macy 275eda14cbcSMatt Macy /* key length must be either 128, 192, or 256 */ 276eda14cbcSMatt Macy if ((key->ck_length & 63) != 0) 277eda14cbcSMatt Macy return (CRYPTO_KEY_SIZE_RANGE); 278eda14cbcSMatt Macy break; 279eda14cbcSMatt Macy default: 280eda14cbcSMatt Macy return (CRYPTO_KEY_TYPE_INCONSISTENT); 281eda14cbcSMatt Macy } 282eda14cbcSMatt Macy 283eda14cbcSMatt Macy aes_init_keysched(key->ck_data, key->ck_length, newbie); 284eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 285eda14cbcSMatt Macy } 286eda14cbcSMatt Macy 287eda14cbcSMatt Macy /* 288eda14cbcSMatt Macy * KCF software provider control entry points. 289eda14cbcSMatt Macy */ 290eda14cbcSMatt Macy static void 291eda14cbcSMatt Macy aes_provider_status(crypto_provider_handle_t provider, uint_t *status) 292eda14cbcSMatt Macy { 293*e92ffd9bSMartin Matuska (void) provider; 294eda14cbcSMatt Macy *status = CRYPTO_PROVIDER_READY; 295eda14cbcSMatt Macy } 296eda14cbcSMatt Macy 297eda14cbcSMatt Macy static int 298eda14cbcSMatt Macy aes_encrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 299eda14cbcSMatt Macy crypto_key_t *key, crypto_spi_ctx_template_t template, 300eda14cbcSMatt Macy crypto_req_handle_t req) 301eda14cbcSMatt Macy { 302eda14cbcSMatt Macy return (aes_common_init(ctx, mechanism, key, template, req, B_TRUE)); 303eda14cbcSMatt Macy } 304eda14cbcSMatt Macy 305eda14cbcSMatt Macy static int 306eda14cbcSMatt Macy aes_decrypt_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 307eda14cbcSMatt Macy crypto_key_t *key, crypto_spi_ctx_template_t template, 308eda14cbcSMatt Macy crypto_req_handle_t req) 309eda14cbcSMatt Macy { 310eda14cbcSMatt Macy return (aes_common_init(ctx, mechanism, key, template, req, B_FALSE)); 311eda14cbcSMatt Macy } 312eda14cbcSMatt Macy 313eda14cbcSMatt Macy 314eda14cbcSMatt Macy 315eda14cbcSMatt Macy /* 316eda14cbcSMatt Macy * KCF software provider encrypt entry points. 317eda14cbcSMatt Macy */ 318eda14cbcSMatt Macy static int 319eda14cbcSMatt Macy aes_common_init(crypto_ctx_t *ctx, crypto_mechanism_t *mechanism, 320eda14cbcSMatt Macy crypto_key_t *key, crypto_spi_ctx_template_t template, 321eda14cbcSMatt Macy crypto_req_handle_t req, boolean_t is_encrypt_init) 322eda14cbcSMatt Macy { 323eda14cbcSMatt Macy aes_ctx_t *aes_ctx; 324eda14cbcSMatt Macy int rv; 325eda14cbcSMatt Macy int kmflag; 326eda14cbcSMatt Macy 327eda14cbcSMatt Macy /* 328eda14cbcSMatt Macy * Only keys by value are supported by this module. 329eda14cbcSMatt Macy */ 330eda14cbcSMatt Macy if (key->ck_format != CRYPTO_KEY_RAW) { 331eda14cbcSMatt Macy return (CRYPTO_KEY_TYPE_INCONSISTENT); 332eda14cbcSMatt Macy } 333eda14cbcSMatt Macy 334eda14cbcSMatt Macy kmflag = crypto_kmflag(req); 335eda14cbcSMatt Macy if ((rv = aes_check_mech_param(mechanism, &aes_ctx, kmflag)) 336eda14cbcSMatt Macy != CRYPTO_SUCCESS) 337eda14cbcSMatt Macy return (rv); 338eda14cbcSMatt Macy 339eda14cbcSMatt Macy rv = aes_common_init_ctx(aes_ctx, template, mechanism, key, kmflag, 340eda14cbcSMatt Macy is_encrypt_init); 341eda14cbcSMatt Macy if (rv != CRYPTO_SUCCESS) { 342eda14cbcSMatt Macy crypto_free_mode_ctx(aes_ctx); 343eda14cbcSMatt Macy return (rv); 344eda14cbcSMatt Macy } 345eda14cbcSMatt Macy 346eda14cbcSMatt Macy ctx->cc_provider_private = aes_ctx; 347eda14cbcSMatt Macy 348eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 349eda14cbcSMatt Macy } 350eda14cbcSMatt Macy 351eda14cbcSMatt Macy static void 352eda14cbcSMatt Macy aes_copy_block64(uint8_t *in, uint64_t *out) 353eda14cbcSMatt Macy { 354eda14cbcSMatt Macy if (IS_P2ALIGNED(in, sizeof (uint64_t))) { 355eda14cbcSMatt Macy /* LINTED: pointer alignment */ 356eda14cbcSMatt Macy out[0] = *(uint64_t *)&in[0]; 357eda14cbcSMatt Macy /* LINTED: pointer alignment */ 358eda14cbcSMatt Macy out[1] = *(uint64_t *)&in[8]; 359eda14cbcSMatt Macy } else { 360eda14cbcSMatt Macy uint8_t *iv8 = (uint8_t *)&out[0]; 361eda14cbcSMatt Macy 362eda14cbcSMatt Macy AES_COPY_BLOCK(in, iv8); 363eda14cbcSMatt Macy } 364eda14cbcSMatt Macy } 365eda14cbcSMatt Macy 366eda14cbcSMatt Macy 367eda14cbcSMatt Macy static int 368eda14cbcSMatt Macy aes_encrypt(crypto_ctx_t *ctx, crypto_data_t *plaintext, 369eda14cbcSMatt Macy crypto_data_t *ciphertext, crypto_req_handle_t req) 370eda14cbcSMatt Macy { 371eda14cbcSMatt Macy int ret = CRYPTO_FAILED; 372eda14cbcSMatt Macy 373eda14cbcSMatt Macy aes_ctx_t *aes_ctx; 374eda14cbcSMatt Macy size_t saved_length, saved_offset, length_needed; 375eda14cbcSMatt Macy 376eda14cbcSMatt Macy ASSERT(ctx->cc_provider_private != NULL); 377eda14cbcSMatt Macy aes_ctx = ctx->cc_provider_private; 378eda14cbcSMatt Macy 379eda14cbcSMatt Macy /* 380eda14cbcSMatt Macy * For block ciphers, plaintext must be a multiple of AES block size. 381eda14cbcSMatt Macy * This test is only valid for ciphers whose blocksize is a power of 2. 382eda14cbcSMatt Macy */ 383eda14cbcSMatt Macy if (((aes_ctx->ac_flags & (CTR_MODE|CCM_MODE|GCM_MODE|GMAC_MODE)) 384eda14cbcSMatt Macy == 0) && (plaintext->cd_length & (AES_BLOCK_LEN - 1)) != 0) 385eda14cbcSMatt Macy return (CRYPTO_DATA_LEN_RANGE); 386eda14cbcSMatt Macy 387eda14cbcSMatt Macy ASSERT(ciphertext != NULL); 388eda14cbcSMatt Macy 389eda14cbcSMatt Macy /* 390eda14cbcSMatt Macy * We need to just return the length needed to store the output. 391eda14cbcSMatt Macy * We should not destroy the context for the following case. 392eda14cbcSMatt Macy */ 393eda14cbcSMatt Macy switch (aes_ctx->ac_flags & (CCM_MODE|GCM_MODE|GMAC_MODE)) { 394eda14cbcSMatt Macy case CCM_MODE: 395eda14cbcSMatt Macy length_needed = plaintext->cd_length + aes_ctx->ac_mac_len; 396eda14cbcSMatt Macy break; 397eda14cbcSMatt Macy case GCM_MODE: 398eda14cbcSMatt Macy length_needed = plaintext->cd_length + aes_ctx->ac_tag_len; 399eda14cbcSMatt Macy break; 400eda14cbcSMatt Macy case GMAC_MODE: 401eda14cbcSMatt Macy if (plaintext->cd_length != 0) 402eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 403eda14cbcSMatt Macy 404eda14cbcSMatt Macy length_needed = aes_ctx->ac_tag_len; 405eda14cbcSMatt Macy break; 406eda14cbcSMatt Macy default: 407eda14cbcSMatt Macy length_needed = plaintext->cd_length; 408eda14cbcSMatt Macy } 409eda14cbcSMatt Macy 410eda14cbcSMatt Macy if (ciphertext->cd_length < length_needed) { 411eda14cbcSMatt Macy ciphertext->cd_length = length_needed; 412eda14cbcSMatt Macy return (CRYPTO_BUFFER_TOO_SMALL); 413eda14cbcSMatt Macy } 414eda14cbcSMatt Macy 415eda14cbcSMatt Macy saved_length = ciphertext->cd_length; 416eda14cbcSMatt Macy saved_offset = ciphertext->cd_offset; 417eda14cbcSMatt Macy 418eda14cbcSMatt Macy /* 419eda14cbcSMatt Macy * Do an update on the specified input data. 420eda14cbcSMatt Macy */ 421eda14cbcSMatt Macy ret = aes_encrypt_update(ctx, plaintext, ciphertext, req); 422eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) { 423eda14cbcSMatt Macy return (ret); 424eda14cbcSMatt Macy } 425eda14cbcSMatt Macy 426eda14cbcSMatt Macy /* 427eda14cbcSMatt Macy * For CCM mode, aes_ccm_encrypt_final() will take care of any 428eda14cbcSMatt Macy * left-over unprocessed data, and compute the MAC 429eda14cbcSMatt Macy */ 430eda14cbcSMatt Macy if (aes_ctx->ac_flags & CCM_MODE) { 431eda14cbcSMatt Macy /* 432eda14cbcSMatt Macy * ccm_encrypt_final() will compute the MAC and append 433eda14cbcSMatt Macy * it to existing ciphertext. So, need to adjust the left over 434eda14cbcSMatt Macy * length value accordingly 435eda14cbcSMatt Macy */ 436eda14cbcSMatt Macy 437eda14cbcSMatt Macy /* order of following 2 lines MUST not be reversed */ 438eda14cbcSMatt Macy ciphertext->cd_offset = ciphertext->cd_length; 439eda14cbcSMatt Macy ciphertext->cd_length = saved_length - ciphertext->cd_length; 440eda14cbcSMatt Macy ret = ccm_encrypt_final((ccm_ctx_t *)aes_ctx, ciphertext, 441eda14cbcSMatt Macy AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block); 442eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) { 443eda14cbcSMatt Macy return (ret); 444eda14cbcSMatt Macy } 445eda14cbcSMatt Macy 446eda14cbcSMatt Macy if (plaintext != ciphertext) { 447eda14cbcSMatt Macy ciphertext->cd_length = 448eda14cbcSMatt Macy ciphertext->cd_offset - saved_offset; 449eda14cbcSMatt Macy } 450eda14cbcSMatt Macy ciphertext->cd_offset = saved_offset; 451eda14cbcSMatt Macy } else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) { 452eda14cbcSMatt Macy /* 453eda14cbcSMatt Macy * gcm_encrypt_final() will compute the MAC and append 454eda14cbcSMatt Macy * it to existing ciphertext. So, need to adjust the left over 455eda14cbcSMatt Macy * length value accordingly 456eda14cbcSMatt Macy */ 457eda14cbcSMatt Macy 458eda14cbcSMatt Macy /* order of following 2 lines MUST not be reversed */ 459eda14cbcSMatt Macy ciphertext->cd_offset = ciphertext->cd_length; 460eda14cbcSMatt Macy ciphertext->cd_length = saved_length - ciphertext->cd_length; 461eda14cbcSMatt Macy ret = gcm_encrypt_final((gcm_ctx_t *)aes_ctx, ciphertext, 462eda14cbcSMatt Macy AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block, 463eda14cbcSMatt Macy aes_xor_block); 464eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) { 465eda14cbcSMatt Macy return (ret); 466eda14cbcSMatt Macy } 467eda14cbcSMatt Macy 468eda14cbcSMatt Macy if (plaintext != ciphertext) { 469eda14cbcSMatt Macy ciphertext->cd_length = 470eda14cbcSMatt Macy ciphertext->cd_offset - saved_offset; 471eda14cbcSMatt Macy } 472eda14cbcSMatt Macy ciphertext->cd_offset = saved_offset; 473eda14cbcSMatt Macy } 474eda14cbcSMatt Macy 475eda14cbcSMatt Macy ASSERT(aes_ctx->ac_remainder_len == 0); 476eda14cbcSMatt Macy (void) aes_free_context(ctx); 477eda14cbcSMatt Macy 478eda14cbcSMatt Macy return (ret); 479eda14cbcSMatt Macy } 480eda14cbcSMatt Macy 481eda14cbcSMatt Macy 482eda14cbcSMatt Macy static int 483eda14cbcSMatt Macy aes_decrypt(crypto_ctx_t *ctx, crypto_data_t *ciphertext, 484eda14cbcSMatt Macy crypto_data_t *plaintext, crypto_req_handle_t req) 485eda14cbcSMatt Macy { 486eda14cbcSMatt Macy int ret = CRYPTO_FAILED; 487eda14cbcSMatt Macy 488eda14cbcSMatt Macy aes_ctx_t *aes_ctx; 489eda14cbcSMatt Macy off_t saved_offset; 490eda14cbcSMatt Macy size_t saved_length, length_needed; 491eda14cbcSMatt Macy 492eda14cbcSMatt Macy ASSERT(ctx->cc_provider_private != NULL); 493eda14cbcSMatt Macy aes_ctx = ctx->cc_provider_private; 494eda14cbcSMatt Macy 495eda14cbcSMatt Macy /* 496eda14cbcSMatt Macy * For block ciphers, plaintext must be a multiple of AES block size. 497eda14cbcSMatt Macy * This test is only valid for ciphers whose blocksize is a power of 2. 498eda14cbcSMatt Macy */ 499eda14cbcSMatt Macy if (((aes_ctx->ac_flags & (CTR_MODE|CCM_MODE|GCM_MODE|GMAC_MODE)) 500eda14cbcSMatt Macy == 0) && (ciphertext->cd_length & (AES_BLOCK_LEN - 1)) != 0) { 501eda14cbcSMatt Macy return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 502eda14cbcSMatt Macy } 503eda14cbcSMatt Macy 504eda14cbcSMatt Macy ASSERT(plaintext != NULL); 505eda14cbcSMatt Macy 506eda14cbcSMatt Macy /* 507eda14cbcSMatt Macy * Return length needed to store the output. 508eda14cbcSMatt Macy * Do not destroy context when plaintext buffer is too small. 509eda14cbcSMatt Macy * 510eda14cbcSMatt Macy * CCM: plaintext is MAC len smaller than cipher text 511eda14cbcSMatt Macy * GCM: plaintext is TAG len smaller than cipher text 512eda14cbcSMatt Macy * GMAC: plaintext length must be zero 513eda14cbcSMatt Macy */ 514eda14cbcSMatt Macy switch (aes_ctx->ac_flags & (CCM_MODE|GCM_MODE|GMAC_MODE)) { 515eda14cbcSMatt Macy case CCM_MODE: 516eda14cbcSMatt Macy length_needed = aes_ctx->ac_processed_data_len; 517eda14cbcSMatt Macy break; 518eda14cbcSMatt Macy case GCM_MODE: 519eda14cbcSMatt Macy length_needed = ciphertext->cd_length - aes_ctx->ac_tag_len; 520eda14cbcSMatt Macy break; 521eda14cbcSMatt Macy case GMAC_MODE: 522eda14cbcSMatt Macy if (plaintext->cd_length != 0) 523eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 524eda14cbcSMatt Macy 525eda14cbcSMatt Macy length_needed = 0; 526eda14cbcSMatt Macy break; 527eda14cbcSMatt Macy default: 528eda14cbcSMatt Macy length_needed = ciphertext->cd_length; 529eda14cbcSMatt Macy } 530eda14cbcSMatt Macy 531eda14cbcSMatt Macy if (plaintext->cd_length < length_needed) { 532eda14cbcSMatt Macy plaintext->cd_length = length_needed; 533eda14cbcSMatt Macy return (CRYPTO_BUFFER_TOO_SMALL); 534eda14cbcSMatt Macy } 535eda14cbcSMatt Macy 536eda14cbcSMatt Macy saved_offset = plaintext->cd_offset; 537eda14cbcSMatt Macy saved_length = plaintext->cd_length; 538eda14cbcSMatt Macy 539eda14cbcSMatt Macy /* 540eda14cbcSMatt Macy * Do an update on the specified input data. 541eda14cbcSMatt Macy */ 542eda14cbcSMatt Macy ret = aes_decrypt_update(ctx, ciphertext, plaintext, req); 543eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) { 544eda14cbcSMatt Macy goto cleanup; 545eda14cbcSMatt Macy } 546eda14cbcSMatt Macy 547eda14cbcSMatt Macy if (aes_ctx->ac_flags & CCM_MODE) { 548eda14cbcSMatt Macy ASSERT(aes_ctx->ac_processed_data_len == aes_ctx->ac_data_len); 549eda14cbcSMatt Macy ASSERT(aes_ctx->ac_processed_mac_len == aes_ctx->ac_mac_len); 550eda14cbcSMatt Macy 551eda14cbcSMatt Macy /* order of following 2 lines MUST not be reversed */ 552eda14cbcSMatt Macy plaintext->cd_offset = plaintext->cd_length; 553eda14cbcSMatt Macy plaintext->cd_length = saved_length - plaintext->cd_length; 554eda14cbcSMatt Macy 555eda14cbcSMatt Macy ret = ccm_decrypt_final((ccm_ctx_t *)aes_ctx, plaintext, 556eda14cbcSMatt Macy AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block, 557eda14cbcSMatt Macy aes_xor_block); 558eda14cbcSMatt Macy if (ret == CRYPTO_SUCCESS) { 559eda14cbcSMatt Macy if (plaintext != ciphertext) { 560eda14cbcSMatt Macy plaintext->cd_length = 561eda14cbcSMatt Macy plaintext->cd_offset - saved_offset; 562eda14cbcSMatt Macy } 563eda14cbcSMatt Macy } else { 564eda14cbcSMatt Macy plaintext->cd_length = saved_length; 565eda14cbcSMatt Macy } 566eda14cbcSMatt Macy 567eda14cbcSMatt Macy plaintext->cd_offset = saved_offset; 568eda14cbcSMatt Macy } else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) { 569eda14cbcSMatt Macy /* order of following 2 lines MUST not be reversed */ 570eda14cbcSMatt Macy plaintext->cd_offset = plaintext->cd_length; 571eda14cbcSMatt Macy plaintext->cd_length = saved_length - plaintext->cd_length; 572eda14cbcSMatt Macy 573eda14cbcSMatt Macy ret = gcm_decrypt_final((gcm_ctx_t *)aes_ctx, plaintext, 574eda14cbcSMatt Macy AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block); 575eda14cbcSMatt Macy if (ret == CRYPTO_SUCCESS) { 576eda14cbcSMatt Macy if (plaintext != ciphertext) { 577eda14cbcSMatt Macy plaintext->cd_length = 578eda14cbcSMatt Macy plaintext->cd_offset - saved_offset; 579eda14cbcSMatt Macy } 580eda14cbcSMatt Macy } else { 581eda14cbcSMatt Macy plaintext->cd_length = saved_length; 582eda14cbcSMatt Macy } 583eda14cbcSMatt Macy 584eda14cbcSMatt Macy plaintext->cd_offset = saved_offset; 585eda14cbcSMatt Macy } 586eda14cbcSMatt Macy 587eda14cbcSMatt Macy ASSERT(aes_ctx->ac_remainder_len == 0); 588eda14cbcSMatt Macy 589eda14cbcSMatt Macy cleanup: 590eda14cbcSMatt Macy (void) aes_free_context(ctx); 591eda14cbcSMatt Macy 592eda14cbcSMatt Macy return (ret); 593eda14cbcSMatt Macy } 594eda14cbcSMatt Macy 595eda14cbcSMatt Macy 596eda14cbcSMatt Macy static int 597eda14cbcSMatt Macy aes_encrypt_update(crypto_ctx_t *ctx, crypto_data_t *plaintext, 598eda14cbcSMatt Macy crypto_data_t *ciphertext, crypto_req_handle_t req) 599eda14cbcSMatt Macy { 600*e92ffd9bSMartin Matuska (void) req; 601eda14cbcSMatt Macy off_t saved_offset; 602eda14cbcSMatt Macy size_t saved_length, out_len; 603eda14cbcSMatt Macy int ret = CRYPTO_SUCCESS; 604eda14cbcSMatt Macy aes_ctx_t *aes_ctx; 605eda14cbcSMatt Macy 606eda14cbcSMatt Macy ASSERT(ctx->cc_provider_private != NULL); 607eda14cbcSMatt Macy aes_ctx = ctx->cc_provider_private; 608eda14cbcSMatt Macy 609eda14cbcSMatt Macy ASSERT(ciphertext != NULL); 610eda14cbcSMatt Macy 611eda14cbcSMatt Macy /* compute number of bytes that will hold the ciphertext */ 612eda14cbcSMatt Macy out_len = aes_ctx->ac_remainder_len; 613eda14cbcSMatt Macy out_len += plaintext->cd_length; 614eda14cbcSMatt Macy out_len &= ~(AES_BLOCK_LEN - 1); 615eda14cbcSMatt Macy 616eda14cbcSMatt Macy /* return length needed to store the output */ 617eda14cbcSMatt Macy if (ciphertext->cd_length < out_len) { 618eda14cbcSMatt Macy ciphertext->cd_length = out_len; 619eda14cbcSMatt Macy return (CRYPTO_BUFFER_TOO_SMALL); 620eda14cbcSMatt Macy } 621eda14cbcSMatt Macy 622eda14cbcSMatt Macy saved_offset = ciphertext->cd_offset; 623eda14cbcSMatt Macy saved_length = ciphertext->cd_length; 624eda14cbcSMatt Macy 625eda14cbcSMatt Macy /* 626eda14cbcSMatt Macy * Do the AES update on the specified input data. 627eda14cbcSMatt Macy */ 628eda14cbcSMatt Macy switch (plaintext->cd_format) { 629eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 630eda14cbcSMatt Macy ret = crypto_update_iov(ctx->cc_provider_private, 631eda14cbcSMatt Macy plaintext, ciphertext, aes_encrypt_contiguous_blocks, 632eda14cbcSMatt Macy aes_copy_block64); 633eda14cbcSMatt Macy break; 634eda14cbcSMatt Macy case CRYPTO_DATA_UIO: 635eda14cbcSMatt Macy ret = crypto_update_uio(ctx->cc_provider_private, 636eda14cbcSMatt Macy plaintext, ciphertext, aes_encrypt_contiguous_blocks, 637eda14cbcSMatt Macy aes_copy_block64); 638eda14cbcSMatt Macy break; 639eda14cbcSMatt Macy default: 640eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 641eda14cbcSMatt Macy } 642eda14cbcSMatt Macy 643eda14cbcSMatt Macy /* 644eda14cbcSMatt Macy * Since AES counter mode is a stream cipher, we call 645eda14cbcSMatt Macy * ctr_mode_final() to pick up any remaining bytes. 646eda14cbcSMatt Macy * It is an internal function that does not destroy 647eda14cbcSMatt Macy * the context like *normal* final routines. 648eda14cbcSMatt Macy */ 649eda14cbcSMatt Macy if ((aes_ctx->ac_flags & CTR_MODE) && (aes_ctx->ac_remainder_len > 0)) { 650eda14cbcSMatt Macy ret = ctr_mode_final((ctr_ctx_t *)aes_ctx, 651eda14cbcSMatt Macy ciphertext, aes_encrypt_block); 652eda14cbcSMatt Macy } 653eda14cbcSMatt Macy 654eda14cbcSMatt Macy if (ret == CRYPTO_SUCCESS) { 655eda14cbcSMatt Macy if (plaintext != ciphertext) 656eda14cbcSMatt Macy ciphertext->cd_length = 657eda14cbcSMatt Macy ciphertext->cd_offset - saved_offset; 658eda14cbcSMatt Macy } else { 659eda14cbcSMatt Macy ciphertext->cd_length = saved_length; 660eda14cbcSMatt Macy } 661eda14cbcSMatt Macy ciphertext->cd_offset = saved_offset; 662eda14cbcSMatt Macy 663eda14cbcSMatt Macy return (ret); 664eda14cbcSMatt Macy } 665eda14cbcSMatt Macy 666eda14cbcSMatt Macy 667eda14cbcSMatt Macy static int 668eda14cbcSMatt Macy aes_decrypt_update(crypto_ctx_t *ctx, crypto_data_t *ciphertext, 669eda14cbcSMatt Macy crypto_data_t *plaintext, crypto_req_handle_t req) 670eda14cbcSMatt Macy { 671eda14cbcSMatt Macy off_t saved_offset; 672eda14cbcSMatt Macy size_t saved_length, out_len; 673eda14cbcSMatt Macy int ret = CRYPTO_SUCCESS; 674eda14cbcSMatt Macy aes_ctx_t *aes_ctx; 675eda14cbcSMatt Macy 676eda14cbcSMatt Macy ASSERT(ctx->cc_provider_private != NULL); 677eda14cbcSMatt Macy aes_ctx = ctx->cc_provider_private; 678eda14cbcSMatt Macy 679eda14cbcSMatt Macy ASSERT(plaintext != NULL); 680eda14cbcSMatt Macy 681eda14cbcSMatt Macy /* 682eda14cbcSMatt Macy * Compute number of bytes that will hold the plaintext. 683eda14cbcSMatt Macy * This is not necessary for CCM, GCM, and GMAC since these 684eda14cbcSMatt Macy * mechanisms never return plaintext for update operations. 685eda14cbcSMatt Macy */ 686eda14cbcSMatt Macy if ((aes_ctx->ac_flags & (CCM_MODE|GCM_MODE|GMAC_MODE)) == 0) { 687eda14cbcSMatt Macy out_len = aes_ctx->ac_remainder_len; 688eda14cbcSMatt Macy out_len += ciphertext->cd_length; 689eda14cbcSMatt Macy out_len &= ~(AES_BLOCK_LEN - 1); 690eda14cbcSMatt Macy 691eda14cbcSMatt Macy /* return length needed to store the output */ 692eda14cbcSMatt Macy if (plaintext->cd_length < out_len) { 693eda14cbcSMatt Macy plaintext->cd_length = out_len; 694eda14cbcSMatt Macy return (CRYPTO_BUFFER_TOO_SMALL); 695eda14cbcSMatt Macy } 696eda14cbcSMatt Macy } 697eda14cbcSMatt Macy 698eda14cbcSMatt Macy saved_offset = plaintext->cd_offset; 699eda14cbcSMatt Macy saved_length = plaintext->cd_length; 700eda14cbcSMatt Macy 701eda14cbcSMatt Macy if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) 702eda14cbcSMatt Macy gcm_set_kmflag((gcm_ctx_t *)aes_ctx, crypto_kmflag(req)); 703eda14cbcSMatt Macy 704eda14cbcSMatt Macy /* 705eda14cbcSMatt Macy * Do the AES update on the specified input data. 706eda14cbcSMatt Macy */ 707eda14cbcSMatt Macy switch (ciphertext->cd_format) { 708eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 709eda14cbcSMatt Macy ret = crypto_update_iov(ctx->cc_provider_private, 710eda14cbcSMatt Macy ciphertext, plaintext, aes_decrypt_contiguous_blocks, 711eda14cbcSMatt Macy aes_copy_block64); 712eda14cbcSMatt Macy break; 713eda14cbcSMatt Macy case CRYPTO_DATA_UIO: 714eda14cbcSMatt Macy ret = crypto_update_uio(ctx->cc_provider_private, 715eda14cbcSMatt Macy ciphertext, plaintext, aes_decrypt_contiguous_blocks, 716eda14cbcSMatt Macy aes_copy_block64); 717eda14cbcSMatt Macy break; 718eda14cbcSMatt Macy default: 719eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 720eda14cbcSMatt Macy } 721eda14cbcSMatt Macy 722eda14cbcSMatt Macy /* 723eda14cbcSMatt Macy * Since AES counter mode is a stream cipher, we call 724eda14cbcSMatt Macy * ctr_mode_final() to pick up any remaining bytes. 725eda14cbcSMatt Macy * It is an internal function that does not destroy 726eda14cbcSMatt Macy * the context like *normal* final routines. 727eda14cbcSMatt Macy */ 728eda14cbcSMatt Macy if ((aes_ctx->ac_flags & CTR_MODE) && (aes_ctx->ac_remainder_len > 0)) { 729eda14cbcSMatt Macy ret = ctr_mode_final((ctr_ctx_t *)aes_ctx, plaintext, 730eda14cbcSMatt Macy aes_encrypt_block); 731eda14cbcSMatt Macy if (ret == CRYPTO_DATA_LEN_RANGE) 732eda14cbcSMatt Macy ret = CRYPTO_ENCRYPTED_DATA_LEN_RANGE; 733eda14cbcSMatt Macy } 734eda14cbcSMatt Macy 735eda14cbcSMatt Macy if (ret == CRYPTO_SUCCESS) { 736eda14cbcSMatt Macy if (ciphertext != plaintext) 737eda14cbcSMatt Macy plaintext->cd_length = 738eda14cbcSMatt Macy plaintext->cd_offset - saved_offset; 739eda14cbcSMatt Macy } else { 740eda14cbcSMatt Macy plaintext->cd_length = saved_length; 741eda14cbcSMatt Macy } 742eda14cbcSMatt Macy plaintext->cd_offset = saved_offset; 743eda14cbcSMatt Macy 744eda14cbcSMatt Macy 745eda14cbcSMatt Macy return (ret); 746eda14cbcSMatt Macy } 747eda14cbcSMatt Macy 748eda14cbcSMatt Macy static int 749eda14cbcSMatt Macy aes_encrypt_final(crypto_ctx_t *ctx, crypto_data_t *data, 750eda14cbcSMatt Macy crypto_req_handle_t req) 751eda14cbcSMatt Macy { 752*e92ffd9bSMartin Matuska (void) req; 753eda14cbcSMatt Macy aes_ctx_t *aes_ctx; 754eda14cbcSMatt Macy int ret; 755eda14cbcSMatt Macy 756eda14cbcSMatt Macy ASSERT(ctx->cc_provider_private != NULL); 757eda14cbcSMatt Macy aes_ctx = ctx->cc_provider_private; 758eda14cbcSMatt Macy 759eda14cbcSMatt Macy if (data->cd_format != CRYPTO_DATA_RAW && 760eda14cbcSMatt Macy data->cd_format != CRYPTO_DATA_UIO) { 761eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 762eda14cbcSMatt Macy } 763eda14cbcSMatt Macy 764eda14cbcSMatt Macy if (aes_ctx->ac_flags & CTR_MODE) { 765eda14cbcSMatt Macy if (aes_ctx->ac_remainder_len > 0) { 766eda14cbcSMatt Macy ret = ctr_mode_final((ctr_ctx_t *)aes_ctx, data, 767eda14cbcSMatt Macy aes_encrypt_block); 768eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) 769eda14cbcSMatt Macy return (ret); 770eda14cbcSMatt Macy } 771eda14cbcSMatt Macy } else if (aes_ctx->ac_flags & CCM_MODE) { 772eda14cbcSMatt Macy ret = ccm_encrypt_final((ccm_ctx_t *)aes_ctx, data, 773eda14cbcSMatt Macy AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block); 774eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) { 775eda14cbcSMatt Macy return (ret); 776eda14cbcSMatt Macy } 777eda14cbcSMatt Macy } else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) { 778eda14cbcSMatt Macy size_t saved_offset = data->cd_offset; 779eda14cbcSMatt Macy 780eda14cbcSMatt Macy ret = gcm_encrypt_final((gcm_ctx_t *)aes_ctx, data, 781eda14cbcSMatt Macy AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block, 782eda14cbcSMatt Macy aes_xor_block); 783eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) { 784eda14cbcSMatt Macy return (ret); 785eda14cbcSMatt Macy } 786eda14cbcSMatt Macy data->cd_length = data->cd_offset - saved_offset; 787eda14cbcSMatt Macy data->cd_offset = saved_offset; 788eda14cbcSMatt Macy } else { 789eda14cbcSMatt Macy /* 790eda14cbcSMatt Macy * There must be no unprocessed plaintext. 791eda14cbcSMatt Macy * This happens if the length of the last data is 792eda14cbcSMatt Macy * not a multiple of the AES block length. 793eda14cbcSMatt Macy */ 794eda14cbcSMatt Macy if (aes_ctx->ac_remainder_len > 0) { 795eda14cbcSMatt Macy return (CRYPTO_DATA_LEN_RANGE); 796eda14cbcSMatt Macy } 797eda14cbcSMatt Macy data->cd_length = 0; 798eda14cbcSMatt Macy } 799eda14cbcSMatt Macy 800eda14cbcSMatt Macy (void) aes_free_context(ctx); 801eda14cbcSMatt Macy 802eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 803eda14cbcSMatt Macy } 804eda14cbcSMatt Macy 805eda14cbcSMatt Macy static int 806eda14cbcSMatt Macy aes_decrypt_final(crypto_ctx_t *ctx, crypto_data_t *data, 807eda14cbcSMatt Macy crypto_req_handle_t req) 808eda14cbcSMatt Macy { 809*e92ffd9bSMartin Matuska (void) req; 810eda14cbcSMatt Macy aes_ctx_t *aes_ctx; 811eda14cbcSMatt Macy int ret; 812eda14cbcSMatt Macy off_t saved_offset; 813eda14cbcSMatt Macy size_t saved_length; 814eda14cbcSMatt Macy 815eda14cbcSMatt Macy ASSERT(ctx->cc_provider_private != NULL); 816eda14cbcSMatt Macy aes_ctx = ctx->cc_provider_private; 817eda14cbcSMatt Macy 818eda14cbcSMatt Macy if (data->cd_format != CRYPTO_DATA_RAW && 819eda14cbcSMatt Macy data->cd_format != CRYPTO_DATA_UIO) { 820eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 821eda14cbcSMatt Macy } 822eda14cbcSMatt Macy 823eda14cbcSMatt Macy /* 824eda14cbcSMatt Macy * There must be no unprocessed ciphertext. 825eda14cbcSMatt Macy * This happens if the length of the last ciphertext is 826eda14cbcSMatt Macy * not a multiple of the AES block length. 827eda14cbcSMatt Macy */ 828eda14cbcSMatt Macy if (aes_ctx->ac_remainder_len > 0) { 829eda14cbcSMatt Macy if ((aes_ctx->ac_flags & CTR_MODE) == 0) 830eda14cbcSMatt Macy return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 831eda14cbcSMatt Macy else { 832eda14cbcSMatt Macy ret = ctr_mode_final((ctr_ctx_t *)aes_ctx, data, 833eda14cbcSMatt Macy aes_encrypt_block); 834eda14cbcSMatt Macy if (ret == CRYPTO_DATA_LEN_RANGE) 835eda14cbcSMatt Macy ret = CRYPTO_ENCRYPTED_DATA_LEN_RANGE; 836eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) 837eda14cbcSMatt Macy return (ret); 838eda14cbcSMatt Macy } 839eda14cbcSMatt Macy } 840eda14cbcSMatt Macy 841eda14cbcSMatt Macy if (aes_ctx->ac_flags & CCM_MODE) { 842eda14cbcSMatt Macy /* 843eda14cbcSMatt Macy * This is where all the plaintext is returned, make sure 844eda14cbcSMatt Macy * the plaintext buffer is big enough 845eda14cbcSMatt Macy */ 846eda14cbcSMatt Macy size_t pt_len = aes_ctx->ac_data_len; 847eda14cbcSMatt Macy if (data->cd_length < pt_len) { 848eda14cbcSMatt Macy data->cd_length = pt_len; 849eda14cbcSMatt Macy return (CRYPTO_BUFFER_TOO_SMALL); 850eda14cbcSMatt Macy } 851eda14cbcSMatt Macy 852eda14cbcSMatt Macy ASSERT(aes_ctx->ac_processed_data_len == pt_len); 853eda14cbcSMatt Macy ASSERT(aes_ctx->ac_processed_mac_len == aes_ctx->ac_mac_len); 854eda14cbcSMatt Macy saved_offset = data->cd_offset; 855eda14cbcSMatt Macy saved_length = data->cd_length; 856eda14cbcSMatt Macy ret = ccm_decrypt_final((ccm_ctx_t *)aes_ctx, data, 857eda14cbcSMatt Macy AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block, 858eda14cbcSMatt Macy aes_xor_block); 859eda14cbcSMatt Macy if (ret == CRYPTO_SUCCESS) { 860eda14cbcSMatt Macy data->cd_length = data->cd_offset - saved_offset; 861eda14cbcSMatt Macy } else { 862eda14cbcSMatt Macy data->cd_length = saved_length; 863eda14cbcSMatt Macy } 864eda14cbcSMatt Macy 865eda14cbcSMatt Macy data->cd_offset = saved_offset; 866eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) { 867eda14cbcSMatt Macy return (ret); 868eda14cbcSMatt Macy } 869eda14cbcSMatt Macy } else if (aes_ctx->ac_flags & (GCM_MODE|GMAC_MODE)) { 870eda14cbcSMatt Macy /* 871eda14cbcSMatt Macy * This is where all the plaintext is returned, make sure 872eda14cbcSMatt Macy * the plaintext buffer is big enough 873eda14cbcSMatt Macy */ 874eda14cbcSMatt Macy gcm_ctx_t *ctx = (gcm_ctx_t *)aes_ctx; 875eda14cbcSMatt Macy size_t pt_len = ctx->gcm_processed_data_len - ctx->gcm_tag_len; 876eda14cbcSMatt Macy 877eda14cbcSMatt Macy if (data->cd_length < pt_len) { 878eda14cbcSMatt Macy data->cd_length = pt_len; 879eda14cbcSMatt Macy return (CRYPTO_BUFFER_TOO_SMALL); 880eda14cbcSMatt Macy } 881eda14cbcSMatt Macy 882eda14cbcSMatt Macy saved_offset = data->cd_offset; 883eda14cbcSMatt Macy saved_length = data->cd_length; 884eda14cbcSMatt Macy ret = gcm_decrypt_final((gcm_ctx_t *)aes_ctx, data, 885eda14cbcSMatt Macy AES_BLOCK_LEN, aes_encrypt_block, aes_xor_block); 886eda14cbcSMatt Macy if (ret == CRYPTO_SUCCESS) { 887eda14cbcSMatt Macy data->cd_length = data->cd_offset - saved_offset; 888eda14cbcSMatt Macy } else { 889eda14cbcSMatt Macy data->cd_length = saved_length; 890eda14cbcSMatt Macy } 891eda14cbcSMatt Macy 892eda14cbcSMatt Macy data->cd_offset = saved_offset; 893eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) { 894eda14cbcSMatt Macy return (ret); 895eda14cbcSMatt Macy } 896eda14cbcSMatt Macy } 897eda14cbcSMatt Macy 898eda14cbcSMatt Macy 899eda14cbcSMatt Macy if ((aes_ctx->ac_flags & (CTR_MODE|CCM_MODE|GCM_MODE|GMAC_MODE)) == 0) { 900eda14cbcSMatt Macy data->cd_length = 0; 901eda14cbcSMatt Macy } 902eda14cbcSMatt Macy 903eda14cbcSMatt Macy (void) aes_free_context(ctx); 904eda14cbcSMatt Macy 905eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 906eda14cbcSMatt Macy } 907eda14cbcSMatt Macy 908eda14cbcSMatt Macy static int 909eda14cbcSMatt Macy aes_encrypt_atomic(crypto_provider_handle_t provider, 910eda14cbcSMatt Macy crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 911eda14cbcSMatt Macy crypto_key_t *key, crypto_data_t *plaintext, crypto_data_t *ciphertext, 912eda14cbcSMatt Macy crypto_spi_ctx_template_t template, crypto_req_handle_t req) 913eda14cbcSMatt Macy { 914*e92ffd9bSMartin Matuska (void) provider, (void) session_id; 915eda14cbcSMatt Macy aes_ctx_t aes_ctx; /* on the stack */ 916eda14cbcSMatt Macy off_t saved_offset; 917eda14cbcSMatt Macy size_t saved_length; 918eda14cbcSMatt Macy size_t length_needed; 919eda14cbcSMatt Macy int ret; 920eda14cbcSMatt Macy 921eda14cbcSMatt Macy ASSERT(ciphertext != NULL); 922eda14cbcSMatt Macy 923eda14cbcSMatt Macy /* 924eda14cbcSMatt Macy * CTR, CCM, GCM, and GMAC modes do not require that plaintext 925eda14cbcSMatt Macy * be a multiple of AES block size. 926eda14cbcSMatt Macy */ 927eda14cbcSMatt Macy switch (mechanism->cm_type) { 928eda14cbcSMatt Macy case AES_CTR_MECH_INFO_TYPE: 929eda14cbcSMatt Macy case AES_CCM_MECH_INFO_TYPE: 930eda14cbcSMatt Macy case AES_GCM_MECH_INFO_TYPE: 931eda14cbcSMatt Macy case AES_GMAC_MECH_INFO_TYPE: 932eda14cbcSMatt Macy break; 933eda14cbcSMatt Macy default: 934eda14cbcSMatt Macy if ((plaintext->cd_length & (AES_BLOCK_LEN - 1)) != 0) 935eda14cbcSMatt Macy return (CRYPTO_DATA_LEN_RANGE); 936eda14cbcSMatt Macy } 937eda14cbcSMatt Macy 938eda14cbcSMatt Macy if ((ret = aes_check_mech_param(mechanism, NULL, 0)) != CRYPTO_SUCCESS) 939eda14cbcSMatt Macy return (ret); 940eda14cbcSMatt Macy 941eda14cbcSMatt Macy bzero(&aes_ctx, sizeof (aes_ctx_t)); 942eda14cbcSMatt Macy 943eda14cbcSMatt Macy ret = aes_common_init_ctx(&aes_ctx, template, mechanism, key, 944eda14cbcSMatt Macy crypto_kmflag(req), B_TRUE); 945eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) 946eda14cbcSMatt Macy return (ret); 947eda14cbcSMatt Macy 948eda14cbcSMatt Macy switch (mechanism->cm_type) { 949eda14cbcSMatt Macy case AES_CCM_MECH_INFO_TYPE: 950eda14cbcSMatt Macy length_needed = plaintext->cd_length + aes_ctx.ac_mac_len; 951eda14cbcSMatt Macy break; 952eda14cbcSMatt Macy case AES_GMAC_MECH_INFO_TYPE: 953eda14cbcSMatt Macy if (plaintext->cd_length != 0) 954eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 95553b70c86SMartin Matuska fallthrough; 956eda14cbcSMatt Macy case AES_GCM_MECH_INFO_TYPE: 957eda14cbcSMatt Macy length_needed = plaintext->cd_length + aes_ctx.ac_tag_len; 958eda14cbcSMatt Macy break; 959eda14cbcSMatt Macy default: 960eda14cbcSMatt Macy length_needed = plaintext->cd_length; 961eda14cbcSMatt Macy } 962eda14cbcSMatt Macy 963eda14cbcSMatt Macy /* return size of buffer needed to store output */ 964eda14cbcSMatt Macy if (ciphertext->cd_length < length_needed) { 965eda14cbcSMatt Macy ciphertext->cd_length = length_needed; 966eda14cbcSMatt Macy ret = CRYPTO_BUFFER_TOO_SMALL; 967eda14cbcSMatt Macy goto out; 968eda14cbcSMatt Macy } 969eda14cbcSMatt Macy 970eda14cbcSMatt Macy saved_offset = ciphertext->cd_offset; 971eda14cbcSMatt Macy saved_length = ciphertext->cd_length; 972eda14cbcSMatt Macy 973eda14cbcSMatt Macy /* 974eda14cbcSMatt Macy * Do an update on the specified input data. 975eda14cbcSMatt Macy */ 976eda14cbcSMatt Macy switch (plaintext->cd_format) { 977eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 978eda14cbcSMatt Macy ret = crypto_update_iov(&aes_ctx, plaintext, ciphertext, 979eda14cbcSMatt Macy aes_encrypt_contiguous_blocks, aes_copy_block64); 980eda14cbcSMatt Macy break; 981eda14cbcSMatt Macy case CRYPTO_DATA_UIO: 982eda14cbcSMatt Macy ret = crypto_update_uio(&aes_ctx, plaintext, ciphertext, 983eda14cbcSMatt Macy aes_encrypt_contiguous_blocks, aes_copy_block64); 984eda14cbcSMatt Macy break; 985eda14cbcSMatt Macy default: 986eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 987eda14cbcSMatt Macy } 988eda14cbcSMatt Macy 989eda14cbcSMatt Macy if (ret == CRYPTO_SUCCESS) { 990eda14cbcSMatt Macy if (mechanism->cm_type == AES_CCM_MECH_INFO_TYPE) { 991eda14cbcSMatt Macy ret = ccm_encrypt_final((ccm_ctx_t *)&aes_ctx, 992eda14cbcSMatt Macy ciphertext, AES_BLOCK_LEN, aes_encrypt_block, 993eda14cbcSMatt Macy aes_xor_block); 994eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) 995eda14cbcSMatt Macy goto out; 996eda14cbcSMatt Macy ASSERT(aes_ctx.ac_remainder_len == 0); 997eda14cbcSMatt Macy } else if (mechanism->cm_type == AES_GCM_MECH_INFO_TYPE || 998eda14cbcSMatt Macy mechanism->cm_type == AES_GMAC_MECH_INFO_TYPE) { 999eda14cbcSMatt Macy ret = gcm_encrypt_final((gcm_ctx_t *)&aes_ctx, 1000eda14cbcSMatt Macy ciphertext, AES_BLOCK_LEN, aes_encrypt_block, 1001eda14cbcSMatt Macy aes_copy_block, aes_xor_block); 1002eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) 1003eda14cbcSMatt Macy goto out; 1004eda14cbcSMatt Macy ASSERT(aes_ctx.ac_remainder_len == 0); 1005eda14cbcSMatt Macy } else if (mechanism->cm_type == AES_CTR_MECH_INFO_TYPE) { 1006eda14cbcSMatt Macy if (aes_ctx.ac_remainder_len > 0) { 1007eda14cbcSMatt Macy ret = ctr_mode_final((ctr_ctx_t *)&aes_ctx, 1008eda14cbcSMatt Macy ciphertext, aes_encrypt_block); 1009eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) 1010eda14cbcSMatt Macy goto out; 1011eda14cbcSMatt Macy } 1012eda14cbcSMatt Macy } else { 1013eda14cbcSMatt Macy ASSERT(aes_ctx.ac_remainder_len == 0); 1014eda14cbcSMatt Macy } 1015eda14cbcSMatt Macy 1016eda14cbcSMatt Macy if (plaintext != ciphertext) { 1017eda14cbcSMatt Macy ciphertext->cd_length = 1018eda14cbcSMatt Macy ciphertext->cd_offset - saved_offset; 1019eda14cbcSMatt Macy } 1020eda14cbcSMatt Macy } else { 1021eda14cbcSMatt Macy ciphertext->cd_length = saved_length; 1022eda14cbcSMatt Macy } 1023eda14cbcSMatt Macy ciphertext->cd_offset = saved_offset; 1024eda14cbcSMatt Macy 1025eda14cbcSMatt Macy out: 1026eda14cbcSMatt Macy if (aes_ctx.ac_flags & PROVIDER_OWNS_KEY_SCHEDULE) { 1027eda14cbcSMatt Macy bzero(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len); 1028eda14cbcSMatt Macy kmem_free(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len); 1029eda14cbcSMatt Macy } 10307877fdebSMatt Macy #ifdef CAN_USE_GCM_ASM 10317877fdebSMatt Macy if (aes_ctx.ac_flags & (GCM_MODE|GMAC_MODE) && 10327877fdebSMatt Macy ((gcm_ctx_t *)&aes_ctx)->gcm_Htable != NULL) { 10337877fdebSMatt Macy 10347877fdebSMatt Macy gcm_ctx_t *ctx = (gcm_ctx_t *)&aes_ctx; 10357877fdebSMatt Macy 10367877fdebSMatt Macy bzero(ctx->gcm_Htable, ctx->gcm_htab_len); 10377877fdebSMatt Macy kmem_free(ctx->gcm_Htable, ctx->gcm_htab_len); 10387877fdebSMatt Macy } 10397877fdebSMatt Macy #endif 1040eda14cbcSMatt Macy 1041eda14cbcSMatt Macy return (ret); 1042eda14cbcSMatt Macy } 1043eda14cbcSMatt Macy 1044eda14cbcSMatt Macy static int 1045eda14cbcSMatt Macy aes_decrypt_atomic(crypto_provider_handle_t provider, 1046eda14cbcSMatt Macy crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1047eda14cbcSMatt Macy crypto_key_t *key, crypto_data_t *ciphertext, crypto_data_t *plaintext, 1048eda14cbcSMatt Macy crypto_spi_ctx_template_t template, crypto_req_handle_t req) 1049eda14cbcSMatt Macy { 1050*e92ffd9bSMartin Matuska (void) provider, (void) session_id; 1051eda14cbcSMatt Macy aes_ctx_t aes_ctx; /* on the stack */ 1052eda14cbcSMatt Macy off_t saved_offset; 1053eda14cbcSMatt Macy size_t saved_length; 1054eda14cbcSMatt Macy size_t length_needed; 1055eda14cbcSMatt Macy int ret; 1056eda14cbcSMatt Macy 1057eda14cbcSMatt Macy ASSERT(plaintext != NULL); 1058eda14cbcSMatt Macy 1059eda14cbcSMatt Macy /* 1060eda14cbcSMatt Macy * CCM, GCM, CTR, and GMAC modes do not require that ciphertext 1061eda14cbcSMatt Macy * be a multiple of AES block size. 1062eda14cbcSMatt Macy */ 1063eda14cbcSMatt Macy switch (mechanism->cm_type) { 1064eda14cbcSMatt Macy case AES_CTR_MECH_INFO_TYPE: 1065eda14cbcSMatt Macy case AES_CCM_MECH_INFO_TYPE: 1066eda14cbcSMatt Macy case AES_GCM_MECH_INFO_TYPE: 1067eda14cbcSMatt Macy case AES_GMAC_MECH_INFO_TYPE: 1068eda14cbcSMatt Macy break; 1069eda14cbcSMatt Macy default: 1070eda14cbcSMatt Macy if ((ciphertext->cd_length & (AES_BLOCK_LEN - 1)) != 0) 1071eda14cbcSMatt Macy return (CRYPTO_ENCRYPTED_DATA_LEN_RANGE); 1072eda14cbcSMatt Macy } 1073eda14cbcSMatt Macy 1074eda14cbcSMatt Macy if ((ret = aes_check_mech_param(mechanism, NULL, 0)) != CRYPTO_SUCCESS) 1075eda14cbcSMatt Macy return (ret); 1076eda14cbcSMatt Macy 1077eda14cbcSMatt Macy bzero(&aes_ctx, sizeof (aes_ctx_t)); 1078eda14cbcSMatt Macy 1079eda14cbcSMatt Macy ret = aes_common_init_ctx(&aes_ctx, template, mechanism, key, 1080eda14cbcSMatt Macy crypto_kmflag(req), B_FALSE); 1081eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) 1082eda14cbcSMatt Macy return (ret); 1083eda14cbcSMatt Macy 1084eda14cbcSMatt Macy switch (mechanism->cm_type) { 1085eda14cbcSMatt Macy case AES_CCM_MECH_INFO_TYPE: 1086eda14cbcSMatt Macy length_needed = aes_ctx.ac_data_len; 1087eda14cbcSMatt Macy break; 1088eda14cbcSMatt Macy case AES_GCM_MECH_INFO_TYPE: 1089eda14cbcSMatt Macy length_needed = ciphertext->cd_length - aes_ctx.ac_tag_len; 1090eda14cbcSMatt Macy break; 1091eda14cbcSMatt Macy case AES_GMAC_MECH_INFO_TYPE: 1092eda14cbcSMatt Macy if (plaintext->cd_length != 0) 1093eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 1094eda14cbcSMatt Macy length_needed = 0; 1095eda14cbcSMatt Macy break; 1096eda14cbcSMatt Macy default: 1097eda14cbcSMatt Macy length_needed = ciphertext->cd_length; 1098eda14cbcSMatt Macy } 1099eda14cbcSMatt Macy 1100eda14cbcSMatt Macy /* return size of buffer needed to store output */ 1101eda14cbcSMatt Macy if (plaintext->cd_length < length_needed) { 1102eda14cbcSMatt Macy plaintext->cd_length = length_needed; 1103eda14cbcSMatt Macy ret = CRYPTO_BUFFER_TOO_SMALL; 1104eda14cbcSMatt Macy goto out; 1105eda14cbcSMatt Macy } 1106eda14cbcSMatt Macy 1107eda14cbcSMatt Macy saved_offset = plaintext->cd_offset; 1108eda14cbcSMatt Macy saved_length = plaintext->cd_length; 1109eda14cbcSMatt Macy 1110eda14cbcSMatt Macy if (mechanism->cm_type == AES_GCM_MECH_INFO_TYPE || 1111eda14cbcSMatt Macy mechanism->cm_type == AES_GMAC_MECH_INFO_TYPE) 1112eda14cbcSMatt Macy gcm_set_kmflag((gcm_ctx_t *)&aes_ctx, crypto_kmflag(req)); 1113eda14cbcSMatt Macy 1114eda14cbcSMatt Macy /* 1115eda14cbcSMatt Macy * Do an update on the specified input data. 1116eda14cbcSMatt Macy */ 1117eda14cbcSMatt Macy switch (ciphertext->cd_format) { 1118eda14cbcSMatt Macy case CRYPTO_DATA_RAW: 1119eda14cbcSMatt Macy ret = crypto_update_iov(&aes_ctx, ciphertext, plaintext, 1120eda14cbcSMatt Macy aes_decrypt_contiguous_blocks, aes_copy_block64); 1121eda14cbcSMatt Macy break; 1122eda14cbcSMatt Macy case CRYPTO_DATA_UIO: 1123eda14cbcSMatt Macy ret = crypto_update_uio(&aes_ctx, ciphertext, plaintext, 1124eda14cbcSMatt Macy aes_decrypt_contiguous_blocks, aes_copy_block64); 1125eda14cbcSMatt Macy break; 1126eda14cbcSMatt Macy default: 1127eda14cbcSMatt Macy ret = CRYPTO_ARGUMENTS_BAD; 1128eda14cbcSMatt Macy } 1129eda14cbcSMatt Macy 1130eda14cbcSMatt Macy if (ret == CRYPTO_SUCCESS) { 1131eda14cbcSMatt Macy if (mechanism->cm_type == AES_CCM_MECH_INFO_TYPE) { 1132eda14cbcSMatt Macy ASSERT(aes_ctx.ac_processed_data_len 1133eda14cbcSMatt Macy == aes_ctx.ac_data_len); 1134eda14cbcSMatt Macy ASSERT(aes_ctx.ac_processed_mac_len 1135eda14cbcSMatt Macy == aes_ctx.ac_mac_len); 1136eda14cbcSMatt Macy ret = ccm_decrypt_final((ccm_ctx_t *)&aes_ctx, 1137eda14cbcSMatt Macy plaintext, AES_BLOCK_LEN, aes_encrypt_block, 1138eda14cbcSMatt Macy aes_copy_block, aes_xor_block); 1139eda14cbcSMatt Macy ASSERT(aes_ctx.ac_remainder_len == 0); 1140eda14cbcSMatt Macy if ((ret == CRYPTO_SUCCESS) && 1141eda14cbcSMatt Macy (ciphertext != plaintext)) { 1142eda14cbcSMatt Macy plaintext->cd_length = 1143eda14cbcSMatt Macy plaintext->cd_offset - saved_offset; 1144eda14cbcSMatt Macy } else { 1145eda14cbcSMatt Macy plaintext->cd_length = saved_length; 1146eda14cbcSMatt Macy } 1147eda14cbcSMatt Macy } else if (mechanism->cm_type == AES_GCM_MECH_INFO_TYPE || 1148eda14cbcSMatt Macy mechanism->cm_type == AES_GMAC_MECH_INFO_TYPE) { 1149eda14cbcSMatt Macy ret = gcm_decrypt_final((gcm_ctx_t *)&aes_ctx, 1150eda14cbcSMatt Macy plaintext, AES_BLOCK_LEN, aes_encrypt_block, 1151eda14cbcSMatt Macy aes_xor_block); 1152eda14cbcSMatt Macy ASSERT(aes_ctx.ac_remainder_len == 0); 1153eda14cbcSMatt Macy if ((ret == CRYPTO_SUCCESS) && 1154eda14cbcSMatt Macy (ciphertext != plaintext)) { 1155eda14cbcSMatt Macy plaintext->cd_length = 1156eda14cbcSMatt Macy plaintext->cd_offset - saved_offset; 1157eda14cbcSMatt Macy } else { 1158eda14cbcSMatt Macy plaintext->cd_length = saved_length; 1159eda14cbcSMatt Macy } 1160eda14cbcSMatt Macy } else if (mechanism->cm_type != AES_CTR_MECH_INFO_TYPE) { 1161eda14cbcSMatt Macy ASSERT(aes_ctx.ac_remainder_len == 0); 1162eda14cbcSMatt Macy if (ciphertext != plaintext) 1163eda14cbcSMatt Macy plaintext->cd_length = 1164eda14cbcSMatt Macy plaintext->cd_offset - saved_offset; 1165eda14cbcSMatt Macy } else { 1166eda14cbcSMatt Macy if (aes_ctx.ac_remainder_len > 0) { 1167eda14cbcSMatt Macy ret = ctr_mode_final((ctr_ctx_t *)&aes_ctx, 1168eda14cbcSMatt Macy plaintext, aes_encrypt_block); 1169eda14cbcSMatt Macy if (ret == CRYPTO_DATA_LEN_RANGE) 1170eda14cbcSMatt Macy ret = CRYPTO_ENCRYPTED_DATA_LEN_RANGE; 1171eda14cbcSMatt Macy if (ret != CRYPTO_SUCCESS) 1172eda14cbcSMatt Macy goto out; 1173eda14cbcSMatt Macy } 1174eda14cbcSMatt Macy if (ciphertext != plaintext) 1175eda14cbcSMatt Macy plaintext->cd_length = 1176eda14cbcSMatt Macy plaintext->cd_offset - saved_offset; 1177eda14cbcSMatt Macy } 1178eda14cbcSMatt Macy } else { 1179eda14cbcSMatt Macy plaintext->cd_length = saved_length; 1180eda14cbcSMatt Macy } 1181eda14cbcSMatt Macy plaintext->cd_offset = saved_offset; 1182eda14cbcSMatt Macy 1183eda14cbcSMatt Macy out: 1184eda14cbcSMatt Macy if (aes_ctx.ac_flags & PROVIDER_OWNS_KEY_SCHEDULE) { 1185eda14cbcSMatt Macy bzero(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len); 1186eda14cbcSMatt Macy kmem_free(aes_ctx.ac_keysched, aes_ctx.ac_keysched_len); 1187eda14cbcSMatt Macy } 1188eda14cbcSMatt Macy 1189eda14cbcSMatt Macy if (aes_ctx.ac_flags & CCM_MODE) { 1190eda14cbcSMatt Macy if (aes_ctx.ac_pt_buf != NULL) { 1191eda14cbcSMatt Macy vmem_free(aes_ctx.ac_pt_buf, aes_ctx.ac_data_len); 1192eda14cbcSMatt Macy } 1193eda14cbcSMatt Macy } else if (aes_ctx.ac_flags & (GCM_MODE|GMAC_MODE)) { 1194eda14cbcSMatt Macy if (((gcm_ctx_t *)&aes_ctx)->gcm_pt_buf != NULL) { 1195eda14cbcSMatt Macy vmem_free(((gcm_ctx_t *)&aes_ctx)->gcm_pt_buf, 1196eda14cbcSMatt Macy ((gcm_ctx_t *)&aes_ctx)->gcm_pt_buf_len); 1197eda14cbcSMatt Macy } 11987877fdebSMatt Macy #ifdef CAN_USE_GCM_ASM 11997877fdebSMatt Macy if (((gcm_ctx_t *)&aes_ctx)->gcm_Htable != NULL) { 12007877fdebSMatt Macy gcm_ctx_t *ctx = (gcm_ctx_t *)&aes_ctx; 12017877fdebSMatt Macy 12027877fdebSMatt Macy bzero(ctx->gcm_Htable, ctx->gcm_htab_len); 12037877fdebSMatt Macy kmem_free(ctx->gcm_Htable, ctx->gcm_htab_len); 12047877fdebSMatt Macy } 12057877fdebSMatt Macy #endif 1206eda14cbcSMatt Macy } 1207eda14cbcSMatt Macy 1208eda14cbcSMatt Macy return (ret); 1209eda14cbcSMatt Macy } 1210eda14cbcSMatt Macy 1211eda14cbcSMatt Macy /* 1212eda14cbcSMatt Macy * KCF software provider context template entry points. 1213eda14cbcSMatt Macy */ 1214eda14cbcSMatt Macy static int 1215eda14cbcSMatt Macy aes_create_ctx_template(crypto_provider_handle_t provider, 1216eda14cbcSMatt Macy crypto_mechanism_t *mechanism, crypto_key_t *key, 1217eda14cbcSMatt Macy crypto_spi_ctx_template_t *tmpl, size_t *tmpl_size, crypto_req_handle_t req) 1218eda14cbcSMatt Macy { 1219*e92ffd9bSMartin Matuska (void) provider; 1220eda14cbcSMatt Macy void *keysched; 1221eda14cbcSMatt Macy size_t size; 1222eda14cbcSMatt Macy int rv; 1223eda14cbcSMatt Macy 1224eda14cbcSMatt Macy if (mechanism->cm_type != AES_ECB_MECH_INFO_TYPE && 1225eda14cbcSMatt Macy mechanism->cm_type != AES_CBC_MECH_INFO_TYPE && 1226eda14cbcSMatt Macy mechanism->cm_type != AES_CTR_MECH_INFO_TYPE && 1227eda14cbcSMatt Macy mechanism->cm_type != AES_CCM_MECH_INFO_TYPE && 1228eda14cbcSMatt Macy mechanism->cm_type != AES_GCM_MECH_INFO_TYPE && 1229eda14cbcSMatt Macy mechanism->cm_type != AES_GMAC_MECH_INFO_TYPE) 1230eda14cbcSMatt Macy return (CRYPTO_MECHANISM_INVALID); 1231eda14cbcSMatt Macy 1232eda14cbcSMatt Macy if ((keysched = aes_alloc_keysched(&size, 1233eda14cbcSMatt Macy crypto_kmflag(req))) == NULL) { 1234eda14cbcSMatt Macy return (CRYPTO_HOST_MEMORY); 1235eda14cbcSMatt Macy } 1236eda14cbcSMatt Macy 1237eda14cbcSMatt Macy /* 1238eda14cbcSMatt Macy * Initialize key schedule. Key length information is stored 1239eda14cbcSMatt Macy * in the key. 1240eda14cbcSMatt Macy */ 1241eda14cbcSMatt Macy if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS) { 1242eda14cbcSMatt Macy bzero(keysched, size); 1243eda14cbcSMatt Macy kmem_free(keysched, size); 1244eda14cbcSMatt Macy return (rv); 1245eda14cbcSMatt Macy } 1246eda14cbcSMatt Macy 1247eda14cbcSMatt Macy *tmpl = keysched; 1248eda14cbcSMatt Macy *tmpl_size = size; 1249eda14cbcSMatt Macy 1250eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 1251eda14cbcSMatt Macy } 1252eda14cbcSMatt Macy 1253eda14cbcSMatt Macy 1254eda14cbcSMatt Macy static int 1255eda14cbcSMatt Macy aes_free_context(crypto_ctx_t *ctx) 1256eda14cbcSMatt Macy { 1257eda14cbcSMatt Macy aes_ctx_t *aes_ctx = ctx->cc_provider_private; 1258eda14cbcSMatt Macy 1259eda14cbcSMatt Macy if (aes_ctx != NULL) { 1260eda14cbcSMatt Macy if (aes_ctx->ac_flags & PROVIDER_OWNS_KEY_SCHEDULE) { 1261eda14cbcSMatt Macy ASSERT(aes_ctx->ac_keysched_len != 0); 1262eda14cbcSMatt Macy bzero(aes_ctx->ac_keysched, aes_ctx->ac_keysched_len); 1263eda14cbcSMatt Macy kmem_free(aes_ctx->ac_keysched, 1264eda14cbcSMatt Macy aes_ctx->ac_keysched_len); 1265eda14cbcSMatt Macy } 1266eda14cbcSMatt Macy crypto_free_mode_ctx(aes_ctx); 1267eda14cbcSMatt Macy ctx->cc_provider_private = NULL; 1268eda14cbcSMatt Macy } 1269eda14cbcSMatt Macy 1270eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 1271eda14cbcSMatt Macy } 1272eda14cbcSMatt Macy 1273eda14cbcSMatt Macy 1274eda14cbcSMatt Macy static int 1275eda14cbcSMatt Macy aes_common_init_ctx(aes_ctx_t *aes_ctx, crypto_spi_ctx_template_t *template, 1276eda14cbcSMatt Macy crypto_mechanism_t *mechanism, crypto_key_t *key, int kmflag, 1277eda14cbcSMatt Macy boolean_t is_encrypt_init) 1278eda14cbcSMatt Macy { 1279eda14cbcSMatt Macy int rv = CRYPTO_SUCCESS; 1280eda14cbcSMatt Macy void *keysched; 1281eda14cbcSMatt Macy size_t size = 0; 1282eda14cbcSMatt Macy 1283eda14cbcSMatt Macy if (template == NULL) { 1284eda14cbcSMatt Macy if ((keysched = aes_alloc_keysched(&size, kmflag)) == NULL) 1285eda14cbcSMatt Macy return (CRYPTO_HOST_MEMORY); 1286eda14cbcSMatt Macy /* 1287eda14cbcSMatt Macy * Initialize key schedule. 1288eda14cbcSMatt Macy * Key length is stored in the key. 1289eda14cbcSMatt Macy */ 1290eda14cbcSMatt Macy if ((rv = init_keysched(key, keysched)) != CRYPTO_SUCCESS) { 1291eda14cbcSMatt Macy kmem_free(keysched, size); 1292eda14cbcSMatt Macy return (rv); 1293eda14cbcSMatt Macy } 1294eda14cbcSMatt Macy 1295eda14cbcSMatt Macy aes_ctx->ac_flags |= PROVIDER_OWNS_KEY_SCHEDULE; 1296eda14cbcSMatt Macy aes_ctx->ac_keysched_len = size; 1297eda14cbcSMatt Macy } else { 1298eda14cbcSMatt Macy keysched = template; 1299eda14cbcSMatt Macy } 1300eda14cbcSMatt Macy aes_ctx->ac_keysched = keysched; 1301eda14cbcSMatt Macy 1302eda14cbcSMatt Macy switch (mechanism->cm_type) { 1303eda14cbcSMatt Macy case AES_CBC_MECH_INFO_TYPE: 1304eda14cbcSMatt Macy rv = cbc_init_ctx((cbc_ctx_t *)aes_ctx, mechanism->cm_param, 1305eda14cbcSMatt Macy mechanism->cm_param_len, AES_BLOCK_LEN, aes_copy_block64); 1306eda14cbcSMatt Macy break; 1307eda14cbcSMatt Macy case AES_CTR_MECH_INFO_TYPE: { 1308eda14cbcSMatt Macy CK_AES_CTR_PARAMS *pp; 1309eda14cbcSMatt Macy 1310eda14cbcSMatt Macy if (mechanism->cm_param == NULL || 1311eda14cbcSMatt Macy mechanism->cm_param_len != sizeof (CK_AES_CTR_PARAMS)) { 1312eda14cbcSMatt Macy return (CRYPTO_MECHANISM_PARAM_INVALID); 1313eda14cbcSMatt Macy } 1314eda14cbcSMatt Macy pp = (CK_AES_CTR_PARAMS *)(void *)mechanism->cm_param; 1315eda14cbcSMatt Macy rv = ctr_init_ctx((ctr_ctx_t *)aes_ctx, pp->ulCounterBits, 1316eda14cbcSMatt Macy pp->cb, aes_copy_block); 1317eda14cbcSMatt Macy break; 1318eda14cbcSMatt Macy } 1319eda14cbcSMatt Macy case AES_CCM_MECH_INFO_TYPE: 1320eda14cbcSMatt Macy if (mechanism->cm_param == NULL || 1321eda14cbcSMatt Macy mechanism->cm_param_len != sizeof (CK_AES_CCM_PARAMS)) { 1322eda14cbcSMatt Macy return (CRYPTO_MECHANISM_PARAM_INVALID); 1323eda14cbcSMatt Macy } 1324eda14cbcSMatt Macy rv = ccm_init_ctx((ccm_ctx_t *)aes_ctx, mechanism->cm_param, 1325eda14cbcSMatt Macy kmflag, is_encrypt_init, AES_BLOCK_LEN, aes_encrypt_block, 1326eda14cbcSMatt Macy aes_xor_block); 1327eda14cbcSMatt Macy break; 1328eda14cbcSMatt Macy case AES_GCM_MECH_INFO_TYPE: 1329eda14cbcSMatt Macy if (mechanism->cm_param == NULL || 1330eda14cbcSMatt Macy mechanism->cm_param_len != sizeof (CK_AES_GCM_PARAMS)) { 1331eda14cbcSMatt Macy return (CRYPTO_MECHANISM_PARAM_INVALID); 1332eda14cbcSMatt Macy } 1333eda14cbcSMatt Macy rv = gcm_init_ctx((gcm_ctx_t *)aes_ctx, mechanism->cm_param, 1334eda14cbcSMatt Macy AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block, 1335eda14cbcSMatt Macy aes_xor_block); 1336eda14cbcSMatt Macy break; 1337eda14cbcSMatt Macy case AES_GMAC_MECH_INFO_TYPE: 1338eda14cbcSMatt Macy if (mechanism->cm_param == NULL || 1339eda14cbcSMatt Macy mechanism->cm_param_len != sizeof (CK_AES_GMAC_PARAMS)) { 1340eda14cbcSMatt Macy return (CRYPTO_MECHANISM_PARAM_INVALID); 1341eda14cbcSMatt Macy } 1342eda14cbcSMatt Macy rv = gmac_init_ctx((gcm_ctx_t *)aes_ctx, mechanism->cm_param, 1343eda14cbcSMatt Macy AES_BLOCK_LEN, aes_encrypt_block, aes_copy_block, 1344eda14cbcSMatt Macy aes_xor_block); 1345eda14cbcSMatt Macy break; 1346eda14cbcSMatt Macy case AES_ECB_MECH_INFO_TYPE: 1347eda14cbcSMatt Macy aes_ctx->ac_flags |= ECB_MODE; 1348eda14cbcSMatt Macy } 1349eda14cbcSMatt Macy 1350eda14cbcSMatt Macy if (rv != CRYPTO_SUCCESS) { 1351eda14cbcSMatt Macy if (aes_ctx->ac_flags & PROVIDER_OWNS_KEY_SCHEDULE) { 1352eda14cbcSMatt Macy bzero(keysched, size); 1353eda14cbcSMatt Macy kmem_free(keysched, size); 1354eda14cbcSMatt Macy } 1355eda14cbcSMatt Macy } 1356eda14cbcSMatt Macy 1357eda14cbcSMatt Macy return (rv); 1358eda14cbcSMatt Macy } 1359eda14cbcSMatt Macy 1360eda14cbcSMatt Macy static int 1361eda14cbcSMatt Macy process_gmac_mech(crypto_mechanism_t *mech, crypto_data_t *data, 1362eda14cbcSMatt Macy CK_AES_GCM_PARAMS *gcm_params) 1363eda14cbcSMatt Macy { 1364eda14cbcSMatt Macy /* LINTED: pointer alignment */ 1365eda14cbcSMatt Macy CK_AES_GMAC_PARAMS *params = (CK_AES_GMAC_PARAMS *)mech->cm_param; 1366eda14cbcSMatt Macy 1367eda14cbcSMatt Macy if (mech->cm_type != AES_GMAC_MECH_INFO_TYPE) 1368eda14cbcSMatt Macy return (CRYPTO_MECHANISM_INVALID); 1369eda14cbcSMatt Macy 1370eda14cbcSMatt Macy if (mech->cm_param_len != sizeof (CK_AES_GMAC_PARAMS)) 1371eda14cbcSMatt Macy return (CRYPTO_MECHANISM_PARAM_INVALID); 1372eda14cbcSMatt Macy 1373eda14cbcSMatt Macy if (params->pIv == NULL) 1374eda14cbcSMatt Macy return (CRYPTO_MECHANISM_PARAM_INVALID); 1375eda14cbcSMatt Macy 1376eda14cbcSMatt Macy gcm_params->pIv = params->pIv; 1377eda14cbcSMatt Macy gcm_params->ulIvLen = AES_GMAC_IV_LEN; 1378eda14cbcSMatt Macy gcm_params->ulTagBits = AES_GMAC_TAG_BITS; 1379eda14cbcSMatt Macy 1380eda14cbcSMatt Macy if (data == NULL) 1381eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 1382eda14cbcSMatt Macy 1383eda14cbcSMatt Macy if (data->cd_format != CRYPTO_DATA_RAW) 1384eda14cbcSMatt Macy return (CRYPTO_ARGUMENTS_BAD); 1385eda14cbcSMatt Macy 1386eda14cbcSMatt Macy gcm_params->pAAD = (uchar_t *)data->cd_raw.iov_base; 1387eda14cbcSMatt Macy gcm_params->ulAADLen = data->cd_length; 1388eda14cbcSMatt Macy return (CRYPTO_SUCCESS); 1389eda14cbcSMatt Macy } 1390eda14cbcSMatt Macy 1391eda14cbcSMatt Macy static int 1392eda14cbcSMatt Macy aes_mac_atomic(crypto_provider_handle_t provider, 1393eda14cbcSMatt Macy crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1394eda14cbcSMatt Macy crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac, 1395eda14cbcSMatt Macy crypto_spi_ctx_template_t template, crypto_req_handle_t req) 1396eda14cbcSMatt Macy { 1397eda14cbcSMatt Macy CK_AES_GCM_PARAMS gcm_params; 1398eda14cbcSMatt Macy crypto_mechanism_t gcm_mech; 1399eda14cbcSMatt Macy int rv; 1400eda14cbcSMatt Macy 1401eda14cbcSMatt Macy if ((rv = process_gmac_mech(mechanism, data, &gcm_params)) 1402eda14cbcSMatt Macy != CRYPTO_SUCCESS) 1403eda14cbcSMatt Macy return (rv); 1404eda14cbcSMatt Macy 1405eda14cbcSMatt Macy gcm_mech.cm_type = AES_GCM_MECH_INFO_TYPE; 1406eda14cbcSMatt Macy gcm_mech.cm_param_len = sizeof (CK_AES_GCM_PARAMS); 1407eda14cbcSMatt Macy gcm_mech.cm_param = (char *)&gcm_params; 1408eda14cbcSMatt Macy 1409eda14cbcSMatt Macy return (aes_encrypt_atomic(provider, session_id, &gcm_mech, 1410eda14cbcSMatt Macy key, &null_crypto_data, mac, template, req)); 1411eda14cbcSMatt Macy } 1412eda14cbcSMatt Macy 1413eda14cbcSMatt Macy static int 1414eda14cbcSMatt Macy aes_mac_verify_atomic(crypto_provider_handle_t provider, 1415eda14cbcSMatt Macy crypto_session_id_t session_id, crypto_mechanism_t *mechanism, 1416eda14cbcSMatt Macy crypto_key_t *key, crypto_data_t *data, crypto_data_t *mac, 1417eda14cbcSMatt Macy crypto_spi_ctx_template_t template, crypto_req_handle_t req) 1418eda14cbcSMatt Macy { 1419eda14cbcSMatt Macy CK_AES_GCM_PARAMS gcm_params; 1420eda14cbcSMatt Macy crypto_mechanism_t gcm_mech; 1421eda14cbcSMatt Macy int rv; 1422eda14cbcSMatt Macy 1423eda14cbcSMatt Macy if ((rv = process_gmac_mech(mechanism, data, &gcm_params)) 1424eda14cbcSMatt Macy != CRYPTO_SUCCESS) 1425eda14cbcSMatt Macy return (rv); 1426eda14cbcSMatt Macy 1427eda14cbcSMatt Macy gcm_mech.cm_type = AES_GCM_MECH_INFO_TYPE; 1428eda14cbcSMatt Macy gcm_mech.cm_param_len = sizeof (CK_AES_GCM_PARAMS); 1429eda14cbcSMatt Macy gcm_mech.cm_param = (char *)&gcm_params; 1430eda14cbcSMatt Macy 1431eda14cbcSMatt Macy return (aes_decrypt_atomic(provider, session_id, &gcm_mech, 1432eda14cbcSMatt Macy key, mac, &null_crypto_data, template, req)); 1433eda14cbcSMatt Macy } 1434