| 1 | /* Copyright (c) (2015-2019,2021) Apple Inc. All rights reserved. |
| 2 | * |
| 3 | * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which |
| 4 | * is contained in the License.txt file distributed with corecrypto) and only to |
| 5 | * people who accept that license. IMPORTANT: Any license rights granted to you by |
| 6 | * Apple Inc. (if any) are limited to internal use within your organization only on |
| 7 | * devices and computers you own or control, for the sole purpose of verifying the |
| 8 | * security characteristics and correct functioning of the Apple Software. You may |
| 9 | * not, directly or indirectly, redistribute the Apple Software or any portions thereof. |
| 10 | * |
| 11 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
| 12 | * |
| 13 | * This file contains Original Code and/or Modifications of Original Code |
| 14 | * as defined in and that are subject to the Apple Public Source License |
| 15 | * Version 2.0 (the 'License'). You may not use this file except in |
| 16 | * compliance with the License. The rights granted to you under the License |
| 17 | * may not be used to create, or enable the creation or redistribution of, |
| 18 | * unlawful or unlicensed copies of an Apple operating system, or to |
| 19 | * circumvent, violate, or enable the circumvention or violation of, any |
| 20 | * terms of an Apple operating system software license agreement. |
| 21 | * |
| 22 | * Please obtain a copy of the License at |
| 23 | * http://www.opensource.apple.com/apsl/ and read it before using this file. |
| 24 | * |
| 25 | * The Original Code and all software distributed under the License are |
| 26 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
| 27 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
| 28 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, |
| 29 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
| 30 | * Please see the License for the specific language governing rights and |
| 31 | * limitations under the License. |
| 32 | * |
| 33 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
| 34 | */ |
| 35 | |
| 36 | #ifndef _CORECRYPTO_CCAES_VNG_GCM_H_ |
| 37 | #define _CORECRYPTO_CCAES_VNG_GCM_H_ |
| 38 | |
| 39 | #include <corecrypto/ccaes.h> |
| 40 | |
| 41 | #if (CCAES_INTEL_ASM && defined(__x86_64__)) || \ |
| 42 | (CCAES_ARM_ASM && defined(__ARM_NEON__)) |
| 43 | #define CCMODE_GCM_VNG_SPEEDUP 1 |
| 44 | #else |
| 45 | #define CCMODE_GCM_VNG_SPEEDUP 0 |
| 46 | #endif |
| 47 | |
| 48 | #include "ccmode_internal.h" |
| 49 | |
| 50 | #if CCMODE_GCM_VNG_SPEEDUP |
| 51 | |
| 52 | struct _cc_vng_gcm_tables { |
| 53 | #if !defined(__arm64__) && defined(__ARM_NEON__) |
| 54 | unsigned char Htable[8 * 2] CC_ALIGNED(16); |
| 55 | #else |
| 56 | unsigned char Htable[16 * 8 * 2] CC_ALIGNED(16); |
| 57 | #endif |
| 58 | }; |
| 59 | |
| 60 | #define VNG_GCM_TABLE_SIZE sizeof(struct _cc_vng_gcm_tables) |
| 61 | #define CCMODE_GCM_VNG_KEY_Htable(K) (((struct _cc_vng_gcm_tables*)&_CCMODE_GCM_KEY(K)->u[0])->Htable) |
| 62 | |
| 63 | int ccaes_vng_gcm_decrypt(ccgcm_ctx *key, size_t nbytes, |
| 64 | const void *in, void *out); |
| 65 | |
| 66 | int ccaes_vng_gcm_encrypt(ccgcm_ctx *key, size_t nbytes, |
| 67 | const void *in, void *out); |
| 68 | |
| 69 | extern void gcm_init(void *Htable, void *H) __asm__("_gcm_init" ); |
| 70 | extern void gcm_gmult(const void *X, const void *Htable, void *out) __asm__("_gcm_gmult" ); |
| 71 | extern void gcm_ghash(void *X, void *Htable, const void *in, size_t len) __asm__("_gcm_ghash" ); |
| 72 | #ifdef __x86_64__ |
| 73 | extern void gcmEncrypt_SupplementalSSE3(const void*, void*, void*, unsigned int, void*, void*) __asm__("_gcmEncrypt_SupplementalSSE3" ); |
| 74 | extern void gcmDecrypt_SupplementalSSE3(const void*, void*, void*, unsigned int, void*, void*) __asm__("_gcmDecrypt_SupplementalSSE3" ); |
| 75 | extern void gcmEncrypt_avx1(const void*, void*, void*, unsigned int, void*, void*) __asm__("_gcmEncrypt_avx1" ); |
| 76 | extern void gcmDecrypt_avx1(const void*, void*, void*, unsigned int, void*, void*) __asm__("_gcmDecrypt_avx1" ); |
| 77 | #else |
| 78 | extern void gcmEncrypt(const void*, void*, void*, unsigned int, void*, void*) __asm__("_gcmEncrypt" ); |
| 79 | extern void gcmDecrypt(const void*, void*, void*, unsigned int, void*, void*) __asm__("_gcmDecrypt" ); |
| 80 | #endif |
| 81 | |
| 82 | /* Use this to statically initialize a ccmode_gcm object for encryption. */ |
| 83 | #define CCAES_VNG_GCM_ENCRYPT(ECB_ENCRYPT) { \ |
| 84 | .size = ccn_sizeof_size(sizeof(struct _ccmode_gcm_key)) \ |
| 85 | + GCM_ECB_KEY_SIZE(ECB_ENCRYPT) \ |
| 86 | + VNG_GCM_TABLE_SIZE, \ |
| 87 | .block_size = 1, \ |
| 88 | .init = ccmode_gcm_init, \ |
| 89 | .set_iv = ccmode_gcm_set_iv, \ |
| 90 | .gmac = ccmode_gcm_aad, \ |
| 91 | .gcm = ccaes_vng_gcm_encrypt, \ |
| 92 | .finalize = ccmode_gcm_finalize, \ |
| 93 | .reset = ccmode_gcm_reset, \ |
| 94 | .custom = (ECB_ENCRYPT), \ |
| 95 | .encdec = CCMODE_GCM_ENCRYPTOR\ |
| 96 | } |
| 97 | |
| 98 | /* Use these function to runtime initialize a ccmode_gcm encrypt object (for |
| 99 | * example if it's part of a larger structure). For GCM you always pass a |
| 100 | * ecb encrypt mode implementation of some underlying algorithm as the ecb |
| 101 | * parameter. */ |
| 102 | CC_INLINE |
| 103 | void |
| 104 | ccaes_vng_factory_gcm_encrypt(struct ccmode_gcm *gcm) |
| 105 | { |
| 106 | struct ccmode_gcm gcm_encrypt = CCAES_VNG_GCM_ENCRYPT(ccaes_ecb_encrypt_mode()); |
| 107 | *gcm = gcm_encrypt; |
| 108 | } |
| 109 | |
| 110 | /* Use this to statically initialize a ccmode_gcm object for decryption. */ |
| 111 | #define CCAES_VNG_GCM_DECRYPT(ECB_ENCRYPT) { \ |
| 112 | .size = ccn_sizeof_size(sizeof(struct _ccmode_gcm_key)) \ |
| 113 | + GCM_ECB_KEY_SIZE(ECB_ENCRYPT) \ |
| 114 | + VNG_GCM_TABLE_SIZE, \ |
| 115 | .block_size = 1, \ |
| 116 | .init = ccmode_gcm_init, \ |
| 117 | .set_iv = ccmode_gcm_set_iv, \ |
| 118 | .gmac = ccmode_gcm_aad, \ |
| 119 | .gcm = ccaes_vng_gcm_decrypt, \ |
| 120 | .finalize = ccmode_gcm_finalize, \ |
| 121 | .reset = ccmode_gcm_reset, \ |
| 122 | .custom = (ECB_ENCRYPT), \ |
| 123 | .encdec = CCMODE_GCM_DECRYPTOR\ |
| 124 | } |
| 125 | |
| 126 | /* Use these function to runtime initialize a ccmode_gcm decrypt object (for |
| 127 | * example if it's part of a larger structure). For GCM you always pass a |
| 128 | * ecb encrypt mode implementation of some underlying algorithm as the ecb |
| 129 | * parameter. */ |
| 130 | CC_INLINE |
| 131 | void |
| 132 | ccaes_vng_factory_gcm_decrypt(struct ccmode_gcm *gcm) |
| 133 | { |
| 134 | struct ccmode_gcm gcm_decrypt = CCAES_VNG_GCM_DECRYPT(ccaes_ecb_encrypt_mode()); |
| 135 | *gcm = gcm_decrypt; |
| 136 | } |
| 137 | #endif /* CCMODE_GCM_VNG_SPEEDUP */ |
| 138 | |
| 139 | #endif /* _CORECRYPTO_CCAES_VNG_GCM_H_ */ |
| 140 | |