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
52struct _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
63int ccaes_vng_gcm_decrypt(ccgcm_ctx *key, size_t nbytes,
64 const void *in, void *out);
65
66int ccaes_vng_gcm_encrypt(ccgcm_ctx *key, size_t nbytes,
67 const void *in, void *out);
68
69extern void gcm_init(void *Htable, void *H) __asm__("_gcm_init");
70extern void gcm_gmult(const void *X, const void *Htable, void *out) __asm__("_gcm_gmult");
71extern void gcm_ghash(void *X, void *Htable, const void *in, size_t len) __asm__("_gcm_ghash");
72#ifdef __x86_64__
73extern void gcmEncrypt_SupplementalSSE3(const void*, void*, void*, unsigned int, void*, void*) __asm__("_gcmEncrypt_SupplementalSSE3");
74extern void gcmDecrypt_SupplementalSSE3(const void*, void*, void*, unsigned int, void*, void*) __asm__("_gcmDecrypt_SupplementalSSE3");
75extern void gcmEncrypt_avx1(const void*, void*, void*, unsigned int, void*, void*) __asm__("_gcmEncrypt_avx1");
76extern void gcmDecrypt_avx1(const void*, void*, void*, unsigned int, void*, void*) __asm__("_gcmDecrypt_avx1");
77#else
78extern void gcmEncrypt(const void*, void*, void*, unsigned int, void*, void*) __asm__("_gcmEncrypt");
79extern 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. */
102CC_INLINE
103void
104ccaes_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. */
130CC_INLINE
131void
132ccaes_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