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 | |