luajitos

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

ChaCha20-Poly1305.h (5485B)


      1 /*
      2  * ChaCha20-Poly1305 AEAD Implementation
      3  *
      4  * Compliant with:
      5  * - RFC 8439 (ChaCha20 and Poly1305 for IETF Protocols)
      6  * - Used in TLS 1.3, WireGuard, OpenSSH
      7  *
      8  * ⚠️  WARNING: 96-bit Nonces - DO NOT use random nonces!
      9  * - MUST use sequential counter nonces (never reuse!)
     10  * - Random nonces have collision risk after ~2^32 messages
     11  * - Consider XChaCha20-Poly1305 for random nonces (192-bit)
     12  *
     13  * Security Features:
     14  * - 256-bit keys
     15  * - 96-bit nonces (MUST be sequential or unique)
     16  * - Authenticated encryption (AEAD)
     17  * - Fast software implementation (~1-2 GB/s)
     18  * - No hardware acceleration needed
     19  * - No timing attacks
     20  * - Simpler than AES-GCM
     21  *
     22  * Advantages over AES-GCM:
     23  * - Faster on CPUs without AES-NI
     24  * - Simpler implementation
     25  * - No cache-timing vulnerabilities
     26  * - Better performance on mobile devices
     27  *
     28  * When to use XChaCha20-Poly1305 instead:
     29  * - You want to use random nonces (simpler, safer)
     30  * - You can't reliably track nonce state
     31  * - You're encrypting many messages (>2^32)
     32  */
     33 
     34 #ifndef CHACHA20_POLY1305_H
     35 #define CHACHA20_POLY1305_H
     36 
     37 #include <stdint.h>
     38 #include <stdlib.h>
     39 
     40 #ifdef __cplusplus
     41 extern "C" {
     42 #endif
     43 
     44 /* Constants */
     45 #define CHACHA20_KEY_SIZE 32      /* 256 bits */
     46 #define CHACHA20_NONCE_SIZE 12    /* 96 bits (IETF version) */
     47 #define CHACHA20_BLOCK_SIZE 64    /* 512 bits */
     48 #define POLY1305_KEY_SIZE 32      /* 256 bits */
     49 #define POLY1305_TAG_SIZE 16      /* 128 bits */
     50 
     51 /* ChaCha20 context */
     52 typedef struct {
     53     uint32_t state[16];
     54     uint8_t keystream[64];
     55     size_t keystream_pos;
     56     uint64_t counter;
     57 } chacha20_context;
     58 
     59 /* Poly1305 context */
     60 typedef struct {
     61     uint32_t r[5];
     62     uint32_t h[5];
     63     uint32_t pad[4];
     64     uint8_t buffer[16];
     65     size_t buffer_len;
     66     uint64_t total_len;
     67 } poly1305_context;
     68 
     69 /* ChaCha20-Poly1305 AEAD context */
     70 typedef struct {
     71     chacha20_context cipher;
     72     poly1305_context mac;
     73     uint64_t aad_len;
     74     uint64_t data_len;
     75 } chacha20_poly1305_context;
     76 
     77 /**
     78  * Initialize ChaCha20-Poly1305 AEAD
     79  *
     80  * @param ctx AEAD context
     81  * @param key 256-bit (32 byte) encryption key
     82  * @param nonce 96-bit (12 byte) nonce
     83  * @return 0 on success, -1 on error
     84  *
     85  * ⚠️  Security Notes:
     86  * - NEVER reuse (key, nonce) pairs
     87  * - DO NOT use random nonces (collision risk after ~2^32 messages)
     88  * - MUST use sequential counter or guaranteed-unique nonces
     89  * - For random nonces, use XChaCha20-Poly1305 instead (192-bit)
     90  * - Used in TLS 1.3, WireGuard, SSH
     91  * - Provides both encryption and authentication
     92  */
     93 int chacha20_poly1305_init(chacha20_poly1305_context *ctx,
     94                            const uint8_t *key,
     95                            const uint8_t *nonce);
     96 
     97 /**
     98  * ChaCha20-Poly1305 AEAD Encryption
     99  *
    100  * @param ctx Initialized context
    101  * @param aad Additional authenticated data (can be NULL if aad_len is 0)
    102  * @param aad_len AAD length in bytes
    103  * @param plaintext Input plaintext
    104  * @param pt_len Plaintext length in bytes
    105  * @param ciphertext Output ciphertext buffer (must be pt_len bytes)
    106  * @param tag Output authentication tag (must be 16 bytes)
    107  * @return 0 on success, -1 on error
    108  *
    109  * Security Notes:
    110  * - AAD is authenticated but not encrypted
    111  * - Maximum plaintext: 2^38 - 64 bytes (~256 GB)
    112  * - Tag must be sent with ciphertext
    113  * - Verify tag before using decrypted data
    114  *
    115  * Performance:
    116  * - ~1-2 GB/s in software (no hardware needed)
    117  * - Faster than AES-GCM on CPUs without AES-NI
    118  */
    119 int chacha20_poly1305_encrypt(chacha20_poly1305_context *ctx,
    120                                const uint8_t *aad, size_t aad_len,
    121                                const uint8_t *plaintext, size_t pt_len,
    122                                uint8_t *ciphertext,
    123                                uint8_t *tag);
    124 
    125 /**
    126  * ChaCha20-Poly1305 AEAD Decryption
    127  *
    128  * @param ctx Initialized context
    129  * @param aad Additional authenticated data (must match encryption)
    130  * @param aad_len AAD length in bytes
    131  * @param ciphertext Input ciphertext
    132  * @param ct_len Ciphertext length in bytes
    133  * @param tag Authentication tag from encryption (16 bytes)
    134  * @param plaintext Output plaintext buffer (must be ct_len bytes)
    135  * @return 0 on success, -1 on authentication failure
    136  *
    137  * Security Notes:
    138  * - Returns -1 if authentication tag doesn't match
    139  * - Plaintext is NOT valid if function returns -1
    140  * - Constant-time tag comparison
    141  * - MUST verify return value before using plaintext
    142  */
    143 int chacha20_poly1305_decrypt(chacha20_poly1305_context *ctx,
    144                                const uint8_t *aad, size_t aad_len,
    145                                const uint8_t *ciphertext, size_t ct_len,
    146                                const uint8_t *tag,
    147                                uint8_t *plaintext);
    148 
    149 /**
    150  * Clean up context (zeros sensitive data)
    151  *
    152  * @param ctx Context to clean
    153  *
    154  * Security: Zeros all key material and state
    155  */
    156 void chacha20_poly1305_cleanup(chacha20_poly1305_context *ctx);
    157 
    158 /**
    159  * Standalone ChaCha20 encryption/decryption
    160  * (Use ChaCha20-Poly1305 AEAD for authenticated encryption)
    161  *
    162  * @param key 256-bit key
    163  * @param nonce 96-bit nonce
    164  * @param counter Initial counter (usually 0 or 1)
    165  * @param input Input data
    166  * @param output Output buffer (can be same as input)
    167  * @param len Data length
    168  * @return 0 on success
    169  */
    170 int chacha20_crypt(const uint8_t *key, const uint8_t *nonce,
    171                    uint32_t counter, const uint8_t *input,
    172                    uint8_t *output, size_t len);
    173 
    174 #ifdef __cplusplus
    175 }
    176 #endif
    177 
    178 #endif /* CHACHA20_POLY1305_H */