Salsa20.h (8122B)
1 /* 2 * Salsa20 and ChaCha20 Stream Ciphers 3 * 4 * Compliant with: 5 * - Salsa20 specification by Daniel J. Bernstein 6 * - ChaCha20 (RFC 8439) 7 * - Poly1305 MAC (RFC 8439) 8 * 9 * Security Features: 10 * - 256-bit keys 11 * - 64-bit or 96-bit nonces 12 * - Fast software implementation (no hardware needed) 13 * - No timing attacks 14 * - ChaCha20-Poly1305 for authenticated encryption 15 */ 16 17 #ifndef SALSA20_H 18 #define SALSA20_H 19 20 #include <stdint.h> 21 #include <stdlib.h> 22 23 #ifdef __cplusplus 24 extern "C" { 25 #endif 26 27 /* Salsa20/ChaCha20 constants */ 28 #define SALSA20_KEY_SIZE 32 /* 256 bits */ 29 #define SALSA20_NONCE_SIZE 8 /* 64 bits for Salsa20 */ 30 #define CHACHA20_NONCE_SIZE 12 /* 96 bits for ChaCha20 */ 31 #define SALSA20_BLOCK_SIZE 64 /* 512 bits */ 32 #define POLY1305_KEY_SIZE 32 33 #define POLY1305_TAG_SIZE 16 34 35 /* Salsa20 context */ 36 typedef struct { 37 uint32_t state[16]; 38 uint32_t initial_state[16]; 39 uint8_t keystream[64]; 40 size_t keystream_pos; 41 } salsa20_context; 42 43 /* ChaCha20/Poly1305 types - only define if not already defined in ChaCha20-Poly1305.h */ 44 #ifndef CHACHA20_POLY1305_H 45 46 /* ChaCha20 context */ 47 typedef struct { 48 uint32_t state[16]; 49 uint32_t initial_state[16]; 50 uint8_t keystream[64]; 51 size_t keystream_pos; 52 } chacha20_context; 53 54 /* Poly1305 context */ 55 typedef struct { 56 uint32_t r[5]; 57 uint32_t h[5]; 58 uint32_t pad[4]; 59 uint8_t buffer[16]; 60 size_t buffer_len; 61 } poly1305_context; 62 63 /* ChaCha20-Poly1305 AEAD context */ 64 typedef struct { 65 chacha20_context cipher; 66 poly1305_context mac; 67 } chacha20_poly1305_context; 68 69 #endif /* CHACHA20_POLY1305_H */ 70 71 /** 72 * Initialize Salsa20 cipher 73 * 74 * @param ctx Context structure 75 * @param key 256-bit (32 byte) key 76 * @param nonce 64-bit (8 byte) nonce 77 * @param counter Initial counter value (usually 0) 78 * @return 0 on success, -1 on error 79 * 80 * Security Notes: 81 * - NEVER reuse (key, nonce) pairs 82 * - Use unique nonce for each message 83 * - Counter allows seeking in keystream 84 */ 85 int salsa20_init(salsa20_context *ctx, const uint8_t *key, 86 const uint8_t *nonce, uint64_t counter); 87 88 /** 89 * Encrypt/Decrypt with Salsa20 (same operation) 90 * 91 * @param ctx Initialized context 92 * @param input Input data 93 * @param output Output buffer (can be same as input) 94 * @param len Length in bytes 95 * @return 0 on success, -1 on error 96 * 97 * Security Notes: 98 * - XOR cipher: encryption = decryption 99 * - No authentication - use Poly1305 separately 100 * - Fast: ~2-3 GB/s in software 101 */ 102 int salsa20_crypt(salsa20_context *ctx, const uint8_t *input, 103 uint8_t *output, size_t len); 104 105 /* ChaCha20 and Poly1305 functions - only declare if not in ChaCha20-Poly1305.h */ 106 #ifndef CHACHA20_POLY1305_H 107 108 /** 109 * Initialize ChaCha20 cipher (improved Salsa20) 110 * 111 * @param ctx Context structure 112 * @param key 256-bit (32 byte) key 113 * @param nonce 96-bit (12 byte) nonce 114 * @param counter Initial counter value (usually 1) 115 * @return 0 on success, -1 on error 116 * 117 * Security Notes: 118 * - ChaCha20 is more widely used than Salsa20 119 * - Better diffusion than Salsa20 120 * - IETF standard (RFC 8439) 121 */ 122 int chacha20_init(chacha20_context *ctx, const uint8_t *key, 123 const uint8_t *nonce, uint32_t counter); 124 125 /** 126 * Encrypt/Decrypt with ChaCha20 127 * 128 * @param ctx Initialized context 129 * @param input Input data 130 * @param output Output buffer (can be same as input) 131 * @param len Length in bytes 132 * @return 0 on success, -1 on error 133 */ 134 int chacha20_crypt(chacha20_context *ctx, const uint8_t *input, 135 uint8_t *output, size_t len); 136 137 /** 138 * Initialize Poly1305 MAC 139 * 140 * @param ctx Poly1305 context 141 * @param key 256-bit (32 byte) one-time key 142 * @return 0 on success 143 * 144 * Security Notes: 145 * - Key MUST be unique for each message 146 * - Typically derived from ChaCha20 keystream 147 * - One-time authenticator 148 */ 149 int poly1305_init(poly1305_context *ctx, const uint8_t *key); 150 151 /** 152 * Update Poly1305 with data 153 * 154 * @param ctx Poly1305 context 155 * @param data Input data 156 * @param len Data length 157 * @return 0 on success 158 */ 159 int poly1305_update(poly1305_context *ctx, const uint8_t *data, size_t len); 160 161 /** 162 * Finalize Poly1305 and generate tag 163 * 164 * @param ctx Poly1305 context 165 * @param tag Output tag (16 bytes) 166 * @return 0 on success 167 */ 168 int poly1305_finish(poly1305_context *ctx, uint8_t *tag); 169 170 /** 171 * Initialize ChaCha20-Poly1305 AEAD 172 * 173 * @param ctx AEAD context 174 * @param key 256-bit (32 byte) key 175 * @param nonce 96-bit (12 byte) nonce 176 * @return 0 on success, -1 on error 177 * 178 * Security Notes: 179 * - IETF standard (RFC 8439) 180 * - Used in TLS 1.3 181 * - Fast alternative to AES-GCM 182 * - NEVER reuse (key, nonce) pairs 183 */ 184 int chacha20_poly1305_init(chacha20_poly1305_context *ctx, 185 const uint8_t *key, const uint8_t *nonce); 186 187 /** 188 * ChaCha20-Poly1305 AEAD Encryption 189 * 190 * @param ctx Initialized context 191 * @param aad Additional authenticated data (can be NULL) 192 * @param aad_len AAD length 193 * @param plaintext Input plaintext 194 * @param pt_len Plaintext length 195 * @param ciphertext Output ciphertext (pt_len bytes) 196 * @param tag Output authentication tag (16 bytes) 197 * @return 0 on success, -1 on error 198 * 199 * Security Notes: 200 * - Encrypts plaintext and authenticates ciphertext + AAD 201 * - Tag MUST be verified before using plaintext 202 * - Fast: ~1-2 GB/s in software 203 * - No hardware acceleration needed 204 */ 205 int chacha20_poly1305_encrypt(chacha20_poly1305_context *ctx, 206 const uint8_t *aad, size_t aad_len, 207 const uint8_t *plaintext, size_t pt_len, 208 uint8_t *ciphertext, uint8_t *tag); 209 210 /** 211 * ChaCha20-Poly1305 AEAD Decryption 212 * 213 * @param ctx Initialized context 214 * @param aad Additional authenticated data (must match encryption) 215 * @param aad_len AAD length 216 * @param ciphertext Input ciphertext 217 * @param ct_len Ciphertext length 218 * @param tag Authentication tag from encryption (16 bytes) 219 * @param plaintext Output plaintext buffer (ct_len bytes) 220 * @return 0 on success, -1 on authentication failure 221 * 222 * Security Notes: 223 * - Verifies tag before decryption 224 * - Returns -1 if authentication fails 225 * - Plaintext is NOT valid if function returns -1 226 * - Constant-time tag comparison 227 */ 228 int chacha20_poly1305_decrypt(chacha20_poly1305_context *ctx, 229 const uint8_t *aad, size_t aad_len, 230 const uint8_t *ciphertext, size_t ct_len, 231 const uint8_t *tag, uint8_t *plaintext); 232 233 #endif /* CHACHA20_POLY1305_H */ 234 235 /** 236 * Initialize Salsa20-Poly1305 AEAD 237 * 238 * @param ctx AEAD context 239 * @param key 256-bit (32 byte) key 240 * @param nonce 64-bit (8 byte) nonce 241 * @return 0 on success, -1 on error 242 */ 243 typedef struct { 244 salsa20_context cipher; 245 poly1305_context mac; 246 } salsa20_poly1305_context; 247 248 int salsa20_poly1305_init(salsa20_poly1305_context *ctx, 249 const uint8_t *key, const uint8_t *nonce); 250 251 /** 252 * Salsa20-Poly1305 AEAD Encryption 253 */ 254 int salsa20_poly1305_encrypt(salsa20_poly1305_context *ctx, 255 const uint8_t *aad, size_t aad_len, 256 const uint8_t *plaintext, size_t pt_len, 257 uint8_t *ciphertext, uint8_t *tag); 258 259 /** 260 * Salsa20-Poly1305 AEAD Decryption 261 */ 262 int salsa20_poly1305_decrypt(salsa20_poly1305_context *ctx, 263 const uint8_t *aad, size_t aad_len, 264 const uint8_t *ciphertext, size_t ct_len, 265 const uint8_t *tag, uint8_t *plaintext); 266 267 /** 268 * Clean up context (zeros sensitive data) 269 * 270 * @param ctx Context to clean 271 * 272 * Security: Zeros all key material 273 */ 274 void salsa20_cleanup(salsa20_context *ctx); 275 void salsa20_poly1305_cleanup(salsa20_poly1305_context *ctx); 276 277 /* ChaCha20/Poly1305 cleanup - only declare if not in ChaCha20-Poly1305.h */ 278 #ifndef CHACHA20_POLY1305_H 279 void chacha20_cleanup(chacha20_context *ctx); 280 void poly1305_cleanup(poly1305_context *ctx); 281 void chacha20_poly1305_cleanup(chacha20_poly1305_context *ctx); 282 #endif 283 284 #ifdef __cplusplus 285 } 286 #endif 287 288 #endif /* SALSA20_H */