Line data Source code
1 : #ifndef HEADER_fd_src_ballet_aes_fd_aes_gcm_h 2 : #define HEADER_fd_src_ballet_aes_fd_aes_gcm_h 3 : 4 : #include "../fd_ballet_base.h" 5 : 6 : /* AES-GCM ************************************************************/ 7 : 8 : /* fd_aes_gcm are APIs for authenticated AES-GCM encryption of messages. 9 : Compatible with TLS 1.3 and QUIC. 10 : 11 : AES-GCM is an extension of the AES-CTR stream cipher, adding the 12 : ability to detect malicious tampering of the ciphertext. (Henceforth 13 : referred to as 'authentication'.) Additionally, can protect a 14 : variable-sz unencrypted 'additional data' blob. 15 : 16 : ### Optimization Notes 17 : 18 : Currently supports 'all-in-one' API only, wherein the entire plain- 19 : text is encrypted/decrypted in a single blocking call. API may 20 : change in the future to support a batched 'multi block' API or 21 : streaming mode of operation. 22 : 23 : AES-GCM offers opportunity for processing of multiple AES blocks in 24 : parallel. However, the computation of the auth tag is a sequential 25 : chain with depth of block count of message. In QUIC, the max 26 : AES-GCM msg sz is limited by the packet MTU. Thus, auth tag 27 : processing can still be vectorized by processing independent packets 28 : in parallel. */ 29 : 30 : /* Reference backend internals ****************************************/ 31 : 32 : #include "fd_aes_gcm_ref.h" 33 : 34 : /* AES-NI backend internals *******************************************/ 35 : 36 : struct fd_aes_gcm_aesni_key { 37 : uchar key_enc[ 240 ]; 38 : uchar key_dec[ 240 ]; 39 : uint key_sz; /* 16 */ 40 : }; 41 : typedef struct fd_aes_gcm_aesni_key fd_aes_gcm_aesni_key_t; 42 : 43 : /* Do not change. These offsets are hardcoded in fd_aes_gcm_aesni.S. */ 44 : struct fd_aes_gcm_aesni_state { 45 : fd_aes_gcm_aesni_key_t key; 46 : uchar pad1[ 12 ]; 47 : uchar gcm [ 208 ]; 48 : uchar iv [ 12 ]; 49 : uchar pad2[ 52 ]; 50 : }; 51 : typedef struct fd_aes_gcm_aesni_state fd_aes_gcm_aesni_t; 52 : 53 : /* AVX10 backend internals ********************************************/ 54 : 55 : /* Do not change. These offsets are hardcoded in fd_aes_gcm_avx10.S. */ 56 : struct fd_aes_gcm_avx10_state { 57 : fd_aes_gcm_aesni_key_t key; 58 : uchar pad1[ 28 ]; 59 : uchar gcm [ 320 ]; 60 : uchar iv [ 12 ]; 61 : uchar pad2[ 52 ]; 62 : }; 63 : typedef struct fd_aes_gcm_avx10_state fd_aes_gcm_avx10_t; 64 : 65 : /* Backend selection **************************************************/ 66 : 67 : #if FD_HAS_AVX512 && FD_HAS_GFNI && FD_HAS_AESNI 68 : #define FD_AES_GCM_IMPL 3 /* AVX10.1/512, VAES, VPCLMUL */ 69 : #elif FD_HAS_AVX && FD_HAS_AESNI 70 : #define FD_AES_GCM_IMPL 2 /* AVX2, VAES */ 71 : #elif FD_HAS_AESNI 72 : #define FD_AES_GCM_IMPL 1 /* AESNI */ 73 : #else 74 : #define FD_AES_GCM_IMPL 0 /* Portable */ 75 : #endif 76 : 77 : #if FD_AES_GCM_IMPL == 0 78 : 79 : typedef fd_aes_gcm_ref_t fd_aes_gcm_t; 80 8571387 : #define fd_aes_128_gcm_init fd_aes_128_gcm_init_ref 81 4416902 : #define fd_aes_gcm_encrypt fd_aes_gcm_encrypt_ref 82 4154485 : #define fd_aes_gcm_decrypt fd_aes_gcm_decrypt_ref 83 : 84 : #elif FD_AES_GCM_IMPL == 1 85 : 86 : typedef fd_aes_gcm_aesni_t fd_aes_gcm_t; 87 : #define fd_aes_128_gcm_init fd_aes_128_gcm_init_aesni 88 : #define fd_aes_gcm_encrypt fd_aes_gcm_encrypt_aesni 89 : #define fd_aes_gcm_decrypt fd_aes_gcm_decrypt_aesni 90 : 91 : #elif FD_AES_GCM_IMPL == 2 92 : 93 : typedef fd_aes_gcm_aesni_t fd_aes_gcm_t; 94 25719072 : #define fd_aes_128_gcm_init fd_aes_128_gcm_init_avx2 95 13094777 : #define fd_aes_gcm_encrypt fd_aes_gcm_encrypt_avx2 96 12624295 : #define fd_aes_gcm_decrypt fd_aes_gcm_decrypt_avx2 97 : 98 : #elif FD_AES_GCM_IMPL == 3 99 : 100 : typedef fd_aes_gcm_avx10_t fd_aes_gcm_t; 101 27328905 : #define fd_aes_128_gcm_init fd_aes_128_gcm_init_avx10_512 102 13901092 : #define fd_aes_gcm_encrypt fd_aes_gcm_encrypt_avx10_512 103 13427813 : #define fd_aes_gcm_decrypt fd_aes_gcm_decrypt_avx10_512 104 : 105 : #endif 106 : 107 : /* Public API *********************************************************/ 108 : 109 : /* FD_AES_GCM_ALIGN: minimum alignment of fd_aes_gcm_t. 110 : Large enough to satisfy alignment requirements on all architectures. */ 111 : #define FD_AES_GCM_ALIGN (64UL) 112 : 113 : #define FD_AES_GCM_TAG_SZ (16UL) 114 72984 : #define FD_AES_GCM_IV_SZ (12UL) 115 : 116 : FD_PROTOTYPES_BEGIN 117 : 118 : /* fd_aes_128_gcm_init initializes an fd_aes_gcm_t object for 119 : encrypt or decrypt use. aes_gcm points to unused and uninitialized 120 : memory aligned to FD_AES_GCM_STATE_ALIGN with sizeof(fd_aes_gcm_t) 121 : bytes available. */ 122 : 123 : void 124 : fd_aes_128_gcm_init( fd_aes_gcm_t * aes_gcm, 125 : uchar const key[ 16 ], 126 : uchar const iv [ 12 ] ); 127 : 128 : /* fd_aes_gcm_aead_{encrypt,decrypt} implements the AES-GCM AEAD cipher 129 : c points to the ciphertext buffer. p points to the plaintext buffer. 130 : sz is the length of the p and c buffers. p,c,sz do not have align- 131 : ment requirements. iv points to the 12 byte initialization vector. 132 : aad points to the 'associated data' buffer (with size aad_sz). tag 133 : points to the 16 byte authentication tag (written by both decrypt and 134 : encrypt). 135 : 136 : (AAD serves to mix in arbitrary additional data into the auth tag, 137 : such that tampering with the AAD results in a decryption failure) 138 : 139 : fd_aes_gcm_encrypt reads plaintext from p, writes ciphertext to 140 : c, and writes the auth tag to 'tag'. encrypt cannot fail. 141 : 142 : fd_aes_gcm_decrypt reads the expected auth tag and ciphertext, 143 : and writes the decrypted plaintext to p. Ciphertext and auth tag are 144 : usually transmitted as-is over a network packet. Returns 1 on 145 : success, or 0 on failure. Reasons for failure include: Corrupt 146 : ciphertext, corrupt sz, corrupt AAD, or corrupt tag (could be due to 147 : network corruption or malicious tampering). */ 148 : 149 : void 150 : fd_aes_gcm_encrypt( fd_aes_gcm_t * aes_gcm, 151 : uchar * c, 152 : uchar const * p, 153 : ulong sz, 154 : uchar const * aad, 155 : ulong aad_sz, 156 : uchar tag[ 16 ] ); 157 : 158 : int 159 : fd_aes_gcm_decrypt( fd_aes_gcm_t * aes_gcm, 160 : uchar const * c, 161 : uchar * p, 162 : ulong sz, 163 : uchar const * aad, 164 : ulong aad_sz, 165 : uchar const tag[ 16 ] ); 166 : 167 : #define FD_AES_GCM_DECRYPT_FAIL (0) 168 : #define FD_AES_GCM_DECRYPT_OK (1) 169 : 170 : FD_PROTOTYPES_END 171 : 172 : #endif /* HEADER_fd_src_ballet_aes_fd_aes_gcm_h */