LCOV - code coverage report
Current view: top level - ballet/aes - fd_aes_gcm.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 16 16 100.0 %
Date: 2026-09-08 04:28:46 Functions: 5 90 5.6 %

          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             : /* FD_AES_GCM_ALIGN: minimum alignment of fd_aes_gcm_t.
      37             :    Large enough to satisfy alignment requirements on all architectures. */
      38             : #define FD_AES_GCM_ALIGN (64UL)
      39             : 
      40             : struct fd_aes_gcm_aesni_key {
      41             :   uchar key_enc[ 240 ];
      42             :   uchar key_dec[ 240 ];
      43             :   uint  key_sz; /* 16, 24, or 32 */
      44             : };
      45             : typedef struct fd_aes_gcm_aesni_key fd_aes_gcm_aesni_key_t;
      46             : 
      47             : /* Do not change. These offsets are hardcoded in fd_aes_gcm_aesni.S. */
      48             : struct __attribute__((aligned(FD_AES_GCM_ALIGN))) fd_aes_gcm_aesni_state {
      49             :   fd_aes_gcm_aesni_key_t key;
      50             :   uchar pad1[  12 ];
      51             :   uchar gcm [ 208 ];
      52             :   uchar iv  [  12 ];
      53             :   uchar pad2[  52 ];
      54             : };
      55             : typedef struct fd_aes_gcm_aesni_state fd_aes_gcm_aesni_t;
      56             : 
      57             : /* AVX10 backend internals ********************************************/
      58             : 
      59             : /* Do not change. These offsets are hardcoded in fd_aes_gcm_avx10.S. */
      60             : struct __attribute__((aligned(FD_AES_GCM_ALIGN))) fd_aes_gcm_avx10_state {
      61             :   fd_aes_gcm_aesni_key_t key;
      62             :   uchar pad1[  28 ];
      63             :   uchar gcm [ 320 ];
      64             :   uchar iv  [  12 ];
      65             :   uchar pad2[  52 ];
      66             : };
      67             : typedef struct fd_aes_gcm_avx10_state fd_aes_gcm_avx10_t;
      68             : 
      69             : /* Backend selection **************************************************/
      70             : 
      71             : #if FD_HAS_AVX512 && FD_HAS_GFNI && FD_HAS_AESNI
      72             : #define FD_AES_GCM_IMPL 3 /* AVX10.1/512, VAES, VPCLMUL */
      73             : #elif FD_HAS_AVX && FD_HAS_AESNI
      74             : #define FD_AES_GCM_IMPL 2 /* AVX2, VAES */
      75             : #elif FD_HAS_AESNI
      76             : #define FD_AES_GCM_IMPL 1 /* AESNI */
      77             : #else
      78             : #define FD_AES_GCM_IMPL 0 /* Portable */
      79             : #endif
      80             : 
      81             : #if FD_AES_GCM_IMPL == 0
      82             : 
      83             :   typedef fd_aes_gcm_ref_t    fd_aes_gcm_t;
      84     4220575 :   #define fd_aes_gcm_init     fd_aes_gcm_init_ref
      85     2105729 :   #define fd_aes_gcm_encrypt  fd_aes_gcm_encrypt_ref
      86     2105244 :   #define fd_aes_gcm_decrypt  fd_aes_gcm_decrypt_ref
      87             : 
      88             : #elif FD_AES_GCM_IMPL == 1
      89             : 
      90             :   typedef fd_aes_gcm_aesni_t  fd_aes_gcm_t;
      91             :   #define fd_aes_gcm_init     fd_aes_gcm_init_aesni
      92             :   #define fd_aes_gcm_encrypt  fd_aes_gcm_encrypt_aesni
      93             :   #define fd_aes_gcm_decrypt  fd_aes_gcm_decrypt_aesni
      94             : 
      95             : #elif FD_AES_GCM_IMPL == 2
      96             : 
      97             :   typedef fd_aes_gcm_aesni_t  fd_aes_gcm_t;
      98    15100973 :   #define fd_aes_gcm_init     fd_aes_gcm_init_avx2
      99     7545927 :   #define fd_aes_gcm_encrypt  fd_aes_gcm_encrypt_avx2
     100     7545442 :   #define fd_aes_gcm_decrypt  fd_aes_gcm_decrypt_avx2
     101             : 
     102             : #elif FD_AES_GCM_IMPL == 3
     103             : 
     104             :   typedef fd_aes_gcm_avx10_t  fd_aes_gcm_t;
     105    16766381 :   #define fd_aes_gcm_init     fd_aes_gcm_init_avx10_512
     106     8378631 :   #define fd_aes_gcm_encrypt  fd_aes_gcm_encrypt_avx10_512
     107     8378146 :   #define fd_aes_gcm_decrypt  fd_aes_gcm_decrypt_avx10_512
     108             : 
     109             : #endif
     110             : 
     111             : /* Public API *********************************************************/
     112             : 
     113             : #define FD_AES_GCM_TAG_SZ (16UL)
     114       97572 : #define FD_AES_GCM_IV_SZ  (12UL)
     115             : 
     116             : FD_PROTOTYPES_BEGIN
     117             : 
     118             : /* fd_aes_gcm_init initializes an fd_aes_gcm_t object for encrypt or
     119             :    decrypt use.  key_sz is in bytes, 16/24/32 for AES-128/192/256 */
     120             : 
     121             : void
     122             : fd_aes_gcm_init( fd_aes_gcm_t * aes_gcm,
     123             :                  uchar const *  key,
     124             :                  ulong          key_sz,
     125             :                  uchar const    iv[ 12 ] );
     126             : 
     127             : static inline void
     128             : fd_aes_128_gcm_init( fd_aes_gcm_t * aes_gcm,
     129             :                      uchar const    key[ 16 ],
     130    36087913 :                      uchar const    iv [ 12 ] ) {
     131    36087913 :   fd_aes_gcm_init( aes_gcm, key, 16UL, iv );
     132    36087913 : }
     133             : 
     134             : static inline void
     135             : fd_aes_256_gcm_init( fd_aes_gcm_t * aes_gcm,
     136             :                      uchar const    key[ 32 ],
     137           6 :                      uchar const    iv [ 12 ] ) {
     138           6 :   fd_aes_gcm_init( aes_gcm, key, 32UL, iv );
     139           6 : }
     140             : 
     141             : /* fd_aes_gcm_aead_{encrypt,decrypt} implements the AES-GCM AEAD cipher
     142             :    c points to the ciphertext buffer.  p points to the plaintext buffer.
     143             :    sz is the length of the p and c buffers.  p,c,sz do not have align-
     144             :    ment requirements.  iv points to the 12 byte initialization vector.
     145             :    aad points to the 'associated data' buffer (with size aad_sz).  tag
     146             :    points to the 16 byte authentication tag (written by both decrypt and
     147             :    encrypt).
     148             : 
     149             :    (AAD serves to mix in arbitrary additional data into the auth tag,
     150             :    such that tampering with the AAD results in a decryption failure)
     151             : 
     152             :    fd_aes_gcm_encrypt reads plaintext from p, writes ciphertext to
     153             :    c, and writes the auth tag to 'tag'.  encrypt cannot fail.
     154             : 
     155             :    fd_aes_gcm_decrypt reads the expected auth tag and ciphertext,
     156             :    and writes the decrypted plaintext to p.  Ciphertext and auth tag are
     157             :    usually transmitted as-is over a network packet.  Returns 1 on
     158             :    success, or 0 on failure.  Reasons for failure include:  Corrupt
     159             :    ciphertext, corrupt sz, corrupt AAD, or corrupt tag (could be due to
     160             :    network corruption or malicious tampering). */
     161             : 
     162             : void
     163             : fd_aes_gcm_encrypt( fd_aes_gcm_t * aes_gcm,
     164             :                     uchar *        c,
     165             :                     uchar const *  p,
     166             :                     ulong          sz,
     167             :                     uchar const *  aad,
     168             :                     ulong          aad_sz,
     169             :                     uchar          tag[ 16 ] );
     170             : 
     171             : int
     172             : fd_aes_gcm_decrypt( fd_aes_gcm_t * aes_gcm,
     173             :                     uchar const *  c,
     174             :                     uchar *        p,
     175             :                     ulong          sz,
     176             :                     uchar const *  aad,
     177             :                     ulong          aad_sz,
     178             :                     uchar const    tag[ 16 ] );
     179             : 
     180             : #define FD_AES_GCM_DECRYPT_FAIL (0)
     181             : #define FD_AES_GCM_DECRYPT_OK   (1)
     182             : 
     183             : FD_PROTOTYPES_END
     184             : 
     185             : #endif /* HEADER_fd_src_ballet_aes_fd_aes_gcm_h */

Generated by: LCOV version 1.14