161145dc2SMartin Matuska // SPDX-License-Identifier: CDDL-1.0 2eda14cbcSMatt Macy /* 3eda14cbcSMatt Macy * CDDL HEADER START 4eda14cbcSMatt Macy * 5eda14cbcSMatt Macy * The contents of this file are subject to the terms of the 6eda14cbcSMatt Macy * Common Development and Distribution License (the "License"). 7eda14cbcSMatt Macy * You may not use this file except in compliance with the License. 8eda14cbcSMatt Macy * 9eda14cbcSMatt Macy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10271171e0SMartin Matuska * or https://opensource.org/licenses/CDDL-1.0. 11eda14cbcSMatt Macy * See the License for the specific language governing permissions 12eda14cbcSMatt Macy * and limitations under the License. 13eda14cbcSMatt Macy * 14eda14cbcSMatt Macy * When distributing Covered Code, include this CDDL HEADER in each 15eda14cbcSMatt Macy * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16eda14cbcSMatt Macy * If applicable, add the following below this CDDL HEADER, with the 17eda14cbcSMatt Macy * fields enclosed by brackets "[]" replaced with your own identifying 18eda14cbcSMatt Macy * information: Portions Copyright [yyyy] [name of copyright owner] 19eda14cbcSMatt Macy * 20eda14cbcSMatt Macy * CDDL HEADER END 21eda14cbcSMatt Macy */ 22eda14cbcSMatt Macy /* 23eda14cbcSMatt Macy * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24eda14cbcSMatt Macy * Use is subject to license terms. 25eda14cbcSMatt Macy */ 26eda14cbcSMatt Macy 27eda14cbcSMatt Macy #ifndef _COMMON_CRYPTO_MODES_H 28eda14cbcSMatt Macy #define _COMMON_CRYPTO_MODES_H 29eda14cbcSMatt Macy 30eda14cbcSMatt Macy #ifdef __cplusplus 31eda14cbcSMatt Macy extern "C" { 32eda14cbcSMatt Macy #endif 33eda14cbcSMatt Macy 34eda14cbcSMatt Macy #include <sys/zfs_context.h> 35eda14cbcSMatt Macy #include <sys/crypto/common.h> 36eda14cbcSMatt Macy #include <sys/crypto/impl.h> 37eda14cbcSMatt Macy 38eda14cbcSMatt Macy /* 39eda14cbcSMatt Macy * Does the build chain support all instructions needed for the GCM assembler 40eda14cbcSMatt Macy * routines. AVX support should imply AES-NI and PCLMULQDQ, but make sure 41eda14cbcSMatt Macy * anyhow. 42eda14cbcSMatt Macy */ 43eda14cbcSMatt Macy #if defined(__x86_64__) && defined(HAVE_AVX) && \ 44eda14cbcSMatt Macy defined(HAVE_AES) && defined(HAVE_PCLMULQDQ) 45*53a2e263SMartin Matuska #define CAN_USE_GCM_ASM (HAVE_VAES && HAVE_VPCLMULQDQ ? 2 : 1) 46eda14cbcSMatt Macy extern boolean_t gcm_avx_can_use_movbe; 47eda14cbcSMatt Macy #endif 48eda14cbcSMatt Macy 49eda14cbcSMatt Macy #define CCM_MODE 0x00000010 50eda14cbcSMatt Macy #define GCM_MODE 0x00000020 51eda14cbcSMatt Macy 52eda14cbcSMatt Macy /* 53eda14cbcSMatt Macy * cc_keysched: Pointer to key schedule. 54eda14cbcSMatt Macy * 55eda14cbcSMatt Macy * cc_keysched_len: Length of the key schedule. 56eda14cbcSMatt Macy * 57eda14cbcSMatt Macy * cc_remainder: This is for residual data, i.e. data that can't 58eda14cbcSMatt Macy * be processed because there are too few bytes. 59eda14cbcSMatt Macy * Must wait until more data arrives. 60eda14cbcSMatt Macy * 61eda14cbcSMatt Macy * cc_remainder_len: Number of bytes in cc_remainder. 62eda14cbcSMatt Macy * 63eda14cbcSMatt Macy * cc_iv: Scratch buffer that sometimes contains the IV. 64eda14cbcSMatt Macy * 65eda14cbcSMatt Macy * cc_lastp: Pointer to previous block of ciphertext. 66eda14cbcSMatt Macy * 67eda14cbcSMatt Macy * cc_copy_to: Pointer to where encrypted residual data needs 68eda14cbcSMatt Macy * to be copied. 69eda14cbcSMatt Macy * 70eda14cbcSMatt Macy * cc_flags: PROVIDER_OWNS_KEY_SCHEDULE 71eda14cbcSMatt Macy * When a context is freed, it is necessary 72eda14cbcSMatt Macy * to know whether the key schedule was allocated 73eda14cbcSMatt Macy * by the caller, or internally, e.g. an init routine. 74eda14cbcSMatt Macy * If allocated by the latter, then it needs to be freed. 75eda14cbcSMatt Macy * 7675e1fea6SMartin Matuska * CCM_MODE 77eda14cbcSMatt Macy */ 78eda14cbcSMatt Macy struct common_ctx { 79eda14cbcSMatt Macy void *cc_keysched; 80eda14cbcSMatt Macy size_t cc_keysched_len; 81eda14cbcSMatt Macy uint64_t cc_iv[2]; 82eda14cbcSMatt Macy uint64_t cc_remainder[2]; 83eda14cbcSMatt Macy size_t cc_remainder_len; 84eda14cbcSMatt Macy uint8_t *cc_lastp; 85eda14cbcSMatt Macy uint8_t *cc_copy_to; 86eda14cbcSMatt Macy uint32_t cc_flags; 87eda14cbcSMatt Macy }; 88eda14cbcSMatt Macy 89eda14cbcSMatt Macy typedef struct common_ctx common_ctx_t; 90eda14cbcSMatt Macy 91eda14cbcSMatt Macy /* 92eda14cbcSMatt Macy * 93eda14cbcSMatt Macy * ccm_mac_len: Stores length of the MAC in CCM mode. 94eda14cbcSMatt Macy * ccm_mac_buf: Stores the intermediate value for MAC in CCM encrypt. 95eda14cbcSMatt Macy * In CCM decrypt, stores the input MAC value. 96eda14cbcSMatt Macy * ccm_data_len: Length of the plaintext for CCM mode encrypt, or 97eda14cbcSMatt Macy * length of the ciphertext for CCM mode decrypt. 98eda14cbcSMatt Macy * ccm_processed_data_len: 99eda14cbcSMatt Macy * Length of processed plaintext in CCM mode encrypt, 100eda14cbcSMatt Macy * or length of processed ciphertext for CCM mode decrypt. 101eda14cbcSMatt Macy * ccm_processed_mac_len: 102eda14cbcSMatt Macy * Length of MAC data accumulated in CCM mode decrypt. 103eda14cbcSMatt Macy * 104eda14cbcSMatt Macy * ccm_pt_buf: Only used in CCM mode decrypt. It stores the 105eda14cbcSMatt Macy * decrypted plaintext to be returned when 106eda14cbcSMatt Macy * MAC verification succeeds in decrypt_final. 107eda14cbcSMatt Macy * Memory for this should be allocated in the AES module. 108eda14cbcSMatt Macy * 109eda14cbcSMatt Macy */ 110eda14cbcSMatt Macy typedef struct ccm_ctx { 111eda14cbcSMatt Macy struct common_ctx ccm_common; 112eda14cbcSMatt Macy uint32_t ccm_tmp[4]; 113eda14cbcSMatt Macy size_t ccm_mac_len; 114eda14cbcSMatt Macy uint64_t ccm_mac_buf[2]; 115eda14cbcSMatt Macy size_t ccm_data_len; 116eda14cbcSMatt Macy size_t ccm_processed_data_len; 117eda14cbcSMatt Macy size_t ccm_processed_mac_len; 118eda14cbcSMatt Macy uint8_t *ccm_pt_buf; 119eda14cbcSMatt Macy uint64_t ccm_mac_input_buf[2]; 120eda14cbcSMatt Macy uint64_t ccm_counter_mask; 121eda14cbcSMatt Macy } ccm_ctx_t; 122eda14cbcSMatt Macy 123eda14cbcSMatt Macy #define ccm_keysched ccm_common.cc_keysched 124eda14cbcSMatt Macy #define ccm_keysched_len ccm_common.cc_keysched_len 125eda14cbcSMatt Macy #define ccm_cb ccm_common.cc_iv 126eda14cbcSMatt Macy #define ccm_remainder ccm_common.cc_remainder 127eda14cbcSMatt Macy #define ccm_remainder_len ccm_common.cc_remainder_len 128eda14cbcSMatt Macy #define ccm_lastp ccm_common.cc_lastp 129eda14cbcSMatt Macy #define ccm_copy_to ccm_common.cc_copy_to 130eda14cbcSMatt Macy #define ccm_flags ccm_common.cc_flags 131eda14cbcSMatt Macy 132*53a2e263SMartin Matuska #ifdef CAN_USE_GCM_ASM 133*53a2e263SMartin Matuska typedef enum gcm_impl { 134*53a2e263SMartin Matuska GCM_IMPL_GENERIC = 0, 135*53a2e263SMartin Matuska GCM_IMPL_AVX, 136*53a2e263SMartin Matuska GCM_IMPL_AVX2, 137*53a2e263SMartin Matuska GCM_IMPL_MAX, 138*53a2e263SMartin Matuska } gcm_impl; 139*53a2e263SMartin Matuska #endif 140*53a2e263SMartin Matuska 141eda14cbcSMatt Macy /* 142eda14cbcSMatt Macy * gcm_tag_len: Length of authentication tag. 143eda14cbcSMatt Macy * 144eda14cbcSMatt Macy * gcm_ghash: Stores output from the GHASH function. 145eda14cbcSMatt Macy * 146eda14cbcSMatt Macy * gcm_processed_data_len: 147eda14cbcSMatt Macy * Length of processed plaintext (encrypt) or 148eda14cbcSMatt Macy * length of processed ciphertext (decrypt). 149eda14cbcSMatt Macy * 150eda14cbcSMatt Macy * gcm_pt_buf: Stores the decrypted plaintext returned by 151eda14cbcSMatt Macy * decrypt_final when the computed authentication 152eda14cbcSMatt Macy * tag matches the user supplied tag. 153eda14cbcSMatt Macy * 154eda14cbcSMatt Macy * gcm_pt_buf_len: Length of the plaintext buffer. 155eda14cbcSMatt Macy * 156eda14cbcSMatt Macy * gcm_H: Subkey. 157eda14cbcSMatt Macy * 158eda14cbcSMatt Macy * gcm_Htable: Pre-computed and pre-shifted H, H^2, ... H^6 for the 159eda14cbcSMatt Macy * Karatsuba Algorithm in host byte order. 160eda14cbcSMatt Macy * 161eda14cbcSMatt Macy * gcm_J0: Pre-counter block generated from the IV. 162eda14cbcSMatt Macy * 163eda14cbcSMatt Macy * gcm_len_a_len_c: 64-bit representations of the bit lengths of 164eda14cbcSMatt Macy * AAD and ciphertext. 165eda14cbcSMatt Macy */ 166eda14cbcSMatt Macy typedef struct gcm_ctx { 167eda14cbcSMatt Macy struct common_ctx gcm_common; 168eda14cbcSMatt Macy size_t gcm_tag_len; 169eda14cbcSMatt Macy size_t gcm_processed_data_len; 170eda14cbcSMatt Macy size_t gcm_pt_buf_len; 171eda14cbcSMatt Macy uint32_t gcm_tmp[4]; 172eda14cbcSMatt Macy /* 1737877fdebSMatt Macy * The offset of gcm_Htable relative to gcm_ghash, (32), is hard coded 1747877fdebSMatt Macy * in aesni-gcm-x86_64.S, so please don't change (or adjust there). 175eda14cbcSMatt Macy */ 176eda14cbcSMatt Macy uint64_t gcm_ghash[2]; 177eda14cbcSMatt Macy uint64_t gcm_H[2]; 178eda14cbcSMatt Macy #ifdef CAN_USE_GCM_ASM 1797877fdebSMatt Macy uint64_t *gcm_Htable; 1807877fdebSMatt Macy size_t gcm_htab_len; 181eda14cbcSMatt Macy #endif 182eda14cbcSMatt Macy uint64_t gcm_J0[2]; 183eda14cbcSMatt Macy uint64_t gcm_len_a_len_c[2]; 184eda14cbcSMatt Macy uint8_t *gcm_pt_buf; 185eda14cbcSMatt Macy #ifdef CAN_USE_GCM_ASM 186*53a2e263SMartin Matuska enum gcm_impl impl; 187eda14cbcSMatt Macy #endif 188eda14cbcSMatt Macy } gcm_ctx_t; 189eda14cbcSMatt Macy 190eda14cbcSMatt Macy #define gcm_keysched gcm_common.cc_keysched 191eda14cbcSMatt Macy #define gcm_keysched_len gcm_common.cc_keysched_len 192eda14cbcSMatt Macy #define gcm_cb gcm_common.cc_iv 193eda14cbcSMatt Macy #define gcm_remainder gcm_common.cc_remainder 194eda14cbcSMatt Macy #define gcm_remainder_len gcm_common.cc_remainder_len 195eda14cbcSMatt Macy #define gcm_lastp gcm_common.cc_lastp 196eda14cbcSMatt Macy #define gcm_copy_to gcm_common.cc_copy_to 197eda14cbcSMatt Macy #define gcm_flags gcm_common.cc_flags 198eda14cbcSMatt Macy 1992a58b312SMartin Matuska void gcm_clear_ctx(gcm_ctx_t *ctx); 2002a58b312SMartin Matuska 201eda14cbcSMatt Macy typedef struct aes_ctx { 202eda14cbcSMatt Macy union { 203eda14cbcSMatt Macy ccm_ctx_t acu_ccm; 204eda14cbcSMatt Macy gcm_ctx_t acu_gcm; 205eda14cbcSMatt Macy } acu; 206eda14cbcSMatt Macy } aes_ctx_t; 207eda14cbcSMatt Macy 20875e1fea6SMartin Matuska #define ac_flags acu.acu_ccm.ccm_common.cc_flags 20975e1fea6SMartin Matuska #define ac_remainder_len acu.acu_ccm.ccm_common.cc_remainder_len 21075e1fea6SMartin Matuska #define ac_keysched acu.acu_ccm.ccm_common.cc_keysched 21175e1fea6SMartin Matuska #define ac_keysched_len acu.acu_ccm.ccm_common.cc_keysched_len 21275e1fea6SMartin Matuska #define ac_iv acu.acu_ccm.ccm_common.cc_iv 21375e1fea6SMartin Matuska #define ac_lastp acu.acu_ccm.ccm_common.cc_lastp 214eda14cbcSMatt Macy #define ac_pt_buf acu.acu_ccm.ccm_pt_buf 215eda14cbcSMatt Macy #define ac_mac_len acu.acu_ccm.ccm_mac_len 216eda14cbcSMatt Macy #define ac_data_len acu.acu_ccm.ccm_data_len 217eda14cbcSMatt Macy #define ac_processed_mac_len acu.acu_ccm.ccm_processed_mac_len 218eda14cbcSMatt Macy #define ac_processed_data_len acu.acu_ccm.ccm_processed_data_len 219eda14cbcSMatt Macy #define ac_tag_len acu.acu_gcm.gcm_tag_len 220eda14cbcSMatt Macy 221eda14cbcSMatt Macy extern int ccm_mode_encrypt_contiguous_blocks(ccm_ctx_t *, char *, size_t, 222eda14cbcSMatt Macy crypto_data_t *, size_t, 223eda14cbcSMatt Macy int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 224eda14cbcSMatt Macy void (*copy_block)(uint8_t *, uint8_t *), 225eda14cbcSMatt Macy void (*xor_block)(uint8_t *, uint8_t *)); 226eda14cbcSMatt Macy 227eda14cbcSMatt Macy extern int ccm_mode_decrypt_contiguous_blocks(ccm_ctx_t *, char *, size_t, 228eda14cbcSMatt Macy crypto_data_t *, size_t, 229eda14cbcSMatt Macy int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 230eda14cbcSMatt Macy void (*copy_block)(uint8_t *, uint8_t *), 231eda14cbcSMatt Macy void (*xor_block)(uint8_t *, uint8_t *)); 232eda14cbcSMatt Macy 233eda14cbcSMatt Macy extern int gcm_mode_encrypt_contiguous_blocks(gcm_ctx_t *, char *, size_t, 234eda14cbcSMatt Macy crypto_data_t *, size_t, 235eda14cbcSMatt Macy int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 236eda14cbcSMatt Macy void (*copy_block)(uint8_t *, uint8_t *), 237eda14cbcSMatt Macy void (*xor_block)(uint8_t *, uint8_t *)); 238eda14cbcSMatt Macy 239eda14cbcSMatt Macy extern int gcm_mode_decrypt_contiguous_blocks(gcm_ctx_t *, char *, size_t, 240eda14cbcSMatt Macy crypto_data_t *, size_t, 241eda14cbcSMatt Macy int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 242eda14cbcSMatt Macy void (*copy_block)(uint8_t *, uint8_t *), 243eda14cbcSMatt Macy void (*xor_block)(uint8_t *, uint8_t *)); 244eda14cbcSMatt Macy 245eda14cbcSMatt Macy int ccm_encrypt_final(ccm_ctx_t *, crypto_data_t *, size_t, 246eda14cbcSMatt Macy int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 247eda14cbcSMatt Macy void (*xor_block)(uint8_t *, uint8_t *)); 248eda14cbcSMatt Macy 249eda14cbcSMatt Macy int gcm_encrypt_final(gcm_ctx_t *, crypto_data_t *, size_t, 250eda14cbcSMatt Macy int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 251eda14cbcSMatt Macy void (*copy_block)(uint8_t *, uint8_t *), 252eda14cbcSMatt Macy void (*xor_block)(uint8_t *, uint8_t *)); 253eda14cbcSMatt Macy 254eda14cbcSMatt Macy extern int ccm_decrypt_final(ccm_ctx_t *, crypto_data_t *, size_t, 255eda14cbcSMatt Macy int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 256eda14cbcSMatt Macy void (*copy_block)(uint8_t *, uint8_t *), 257eda14cbcSMatt Macy void (*xor_block)(uint8_t *, uint8_t *)); 258eda14cbcSMatt Macy 259eda14cbcSMatt Macy extern int gcm_decrypt_final(gcm_ctx_t *, crypto_data_t *, size_t, 260eda14cbcSMatt Macy int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 261eda14cbcSMatt Macy void (*xor_block)(uint8_t *, uint8_t *)); 262eda14cbcSMatt Macy 263eda14cbcSMatt Macy extern int ccm_init_ctx(ccm_ctx_t *, char *, int, boolean_t, size_t, 264eda14cbcSMatt Macy int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 265eda14cbcSMatt Macy void (*xor_block)(uint8_t *, uint8_t *)); 266eda14cbcSMatt Macy 267eda14cbcSMatt Macy extern int gcm_init_ctx(gcm_ctx_t *, char *, size_t, 268eda14cbcSMatt Macy int (*encrypt_block)(const void *, const uint8_t *, uint8_t *), 269eda14cbcSMatt Macy void (*copy_block)(uint8_t *, uint8_t *), 270eda14cbcSMatt Macy void (*xor_block)(uint8_t *, uint8_t *)); 271eda14cbcSMatt Macy 272eda14cbcSMatt Macy extern void calculate_ccm_mac(ccm_ctx_t *, uint8_t *, 273eda14cbcSMatt Macy int (*encrypt_block)(const void *, const uint8_t *, uint8_t *)); 274eda14cbcSMatt Macy 275eda14cbcSMatt Macy extern void gcm_mul(uint64_t *, uint64_t *, uint64_t *); 276eda14cbcSMatt Macy 277eda14cbcSMatt Macy extern void crypto_init_ptrs(crypto_data_t *, void **, offset_t *); 278eda14cbcSMatt Macy extern void crypto_get_ptrs(crypto_data_t *, void **, offset_t *, 279eda14cbcSMatt Macy uint8_t **, size_t *, uint8_t **, size_t); 280eda14cbcSMatt Macy 281eda14cbcSMatt Macy extern void *ccm_alloc_ctx(int); 282eda14cbcSMatt Macy extern void *gcm_alloc_ctx(int); 283eda14cbcSMatt Macy extern void crypto_free_mode_ctx(void *); 284eda14cbcSMatt Macy 285eda14cbcSMatt Macy #ifdef __cplusplus 286eda14cbcSMatt Macy } 287eda14cbcSMatt Macy #endif 288eda14cbcSMatt Macy 289eda14cbcSMatt Macy #endif /* _COMMON_CRYPTO_MODES_H */ 290