ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
crypto.c File Reference

🔐 Core cryptography: encryption/decryption, key exchange, authentication, and session rekeying with BearSSL More...

Go to the source code of this file.

Macros

#define CRYPTO_RESULT_STRING_COUNT   (sizeof(g_crypto_result_strings) / sizeof(g_crypto_result_strings[0]))
 

Functions

crypto_result_t crypto_init (crypto_context_t *ctx)
 Initialize libsodium and crypto context.
 
crypto_result_t crypto_init_with_password (crypto_context_t *ctx, const char *password)
 Initialize with password-based encryption.
 
void crypto_destroy (crypto_context_t *ctx)
 Cleanup crypto context with secure memory wiping.
 
crypto_result_t crypto_generate_keypair (crypto_context_t *ctx)
 Generate new X25519 key pair for key exchange.
 
crypto_result_t crypto_get_public_key (const crypto_context_t *ctx, uint8_t *public_key_out)
 Get public key for sending to peer (step 1 of handshake)
 
crypto_result_t crypto_set_peer_public_key (crypto_context_t *ctx, const uint8_t *peer_public_key)
 Set peer's public key and compute shared secret (step 2 of handshake)
 
bool crypto_is_ready (const crypto_context_t *ctx)
 Check if key exchange is complete and ready for encryption.
 
crypto_result_t crypto_validate_password (const char *password)
 Validate password length requirements.
 
crypto_result_t crypto_derive_password_key (crypto_context_t *ctx, const char *password)
 Derive key from password using Argon2id.
 
bool crypto_verify_password (const crypto_context_t *ctx, const char *password)
 Verify password matches stored salt/key.
 
crypto_result_t crypto_derive_password_encryption_key (const char *password, uint8_t encryption_key[SECRETBOX_KEY_SIZE])
 
crypto_result_t crypto_encrypt (crypto_context_t *ctx, const uint8_t *plaintext, size_t plaintext_len, uint8_t *ciphertext_out, size_t ciphertext_out_size, size_t *ciphertext_len_out)
 Encrypt data using XSalsa20-Poly1305.
 
crypto_result_t crypto_decrypt (crypto_context_t *ctx, const uint8_t *ciphertext, size_t ciphertext_len, uint8_t *plaintext_out, size_t plaintext_out_size, size_t *plaintext_len_out)
 Decrypt data using XSalsa20-Poly1305.
 
const char * crypto_result_to_string (crypto_result_t result)
 Convert crypto result to human-readable string.
 
void crypto_get_status (const crypto_context_t *ctx, char *status_buffer, size_t buffer_size)
 Get crypto context status information for debugging.
 
bool crypto_secure_compare (const uint8_t *lhs, const uint8_t *rhs, size_t len)
 Secure constant-time comparison of byte arrays.
 
crypto_result_t crypto_random_bytes (uint8_t *buffer, size_t len)
 Generate cryptographically secure random bytes.
 
crypto_result_t crypto_create_public_key_packet (const crypto_context_t *ctx, uint8_t *packet_out, size_t packet_size, size_t *packet_len_out)
 Create public key packet for network transmission.
 
crypto_result_t crypto_process_public_key_packet (crypto_context_t *ctx, const uint8_t *packet, size_t packet_len)
 Process received public key packet from peer.
 
crypto_result_t crypto_create_encrypted_packet (crypto_context_t *ctx, const uint8_t *data, size_t data_len, uint8_t *packet_out, size_t packet_size, size_t *packet_len_out)
 Create encrypted data packet for network transmission.
 
crypto_result_t crypto_process_encrypted_packet (crypto_context_t *ctx, const uint8_t *packet, size_t packet_len, uint8_t *data_out, size_t data_size, size_t *data_len_out)
 Process received encrypted packet from peer.
 
crypto_result_t crypto_generate_nonce (uint8_t nonce[32])
 Generate random nonce for authentication.
 
crypto_result_t crypto_compute_hmac (crypto_context_t *ctx, const uint8_t key[32], const uint8_t data[32], uint8_t hmac[32])
 Compute HMAC-SHA256 for fixed 32-byte data.
 
crypto_result_t crypto_compute_hmac_ex (const crypto_context_t *ctx, const uint8_t key[32], const uint8_t *data, size_t data_len, uint8_t hmac[32])
 Compute HMAC-SHA256 for variable-length data.
 
bool crypto_verify_hmac (const uint8_t key[32], const uint8_t data[32], const uint8_t expected_hmac[32])
 Verify HMAC-SHA256 for fixed 32-byte data.
 
bool crypto_verify_hmac_ex (const uint8_t key[32], const uint8_t *data, size_t data_len, const uint8_t expected_hmac[32])
 Verify HMAC-SHA256 for variable-length data.
 
crypto_result_t crypto_compute_auth_response (const crypto_context_t *ctx, const uint8_t nonce[32], uint8_t hmac_out[32])
 Compute authentication response HMAC bound to DH shared_secret.
 
bool crypto_verify_auth_response (const crypto_context_t *ctx, const uint8_t nonce[32], const uint8_t expected_hmac[32])
 Verify authentication response HMAC bound to DH shared_secret.
 
crypto_result_t crypto_create_auth_challenge (const crypto_context_t *ctx, uint8_t *packet_out, size_t packet_size, size_t *packet_len_out)
 Create authentication challenge packet.
 
crypto_result_t crypto_process_auth_challenge (crypto_context_t *ctx, const uint8_t *packet, size_t packet_len)
 Process authentication challenge packet.
 
crypto_result_t crypto_process_auth_response (crypto_context_t *ctx, const uint8_t *packet, size_t packet_len)
 Process authentication response packet.
 
asciichat_error_t crypto_compute_password_hmac (crypto_context_t *ctx, const uint8_t *password_key, const uint8_t *nonce, const uint8_t *shared_secret, uint8_t *hmac_out)
 Compute password-based HMAC for authentication.
 
asciichat_error_t crypto_verify_peer_signature (const uint8_t *peer_public_key, const uint8_t *ephemeral_key, size_t ephemeral_key_size, const uint8_t *signature)
 Verify peer's signature on ephemeral key.
 
asciichat_error_t crypto_sign_ephemeral_key (const private_key_t *private_key, const uint8_t *ephemeral_key, size_t ephemeral_key_size, uint8_t *signature_out)
 Sign ephemeral key with private key.
 
void crypto_combine_auth_data (const uint8_t *hmac, const uint8_t *challenge_nonce, uint8_t *combined_out)
 Combine HMAC and challenge nonce for transmission.
 
void crypto_extract_auth_data (const uint8_t *combined_data, uint8_t *hmac_out, uint8_t *challenge_out)
 Extract HMAC and challenge nonce from combined data.
 
bool crypto_should_rekey (const crypto_context_t *ctx)
 Check if rekeying should be triggered based on time or packet count thresholds.
 
crypto_result_t crypto_rekey_init (crypto_context_t *ctx)
 Initiate rekeying by generating new ephemeral keys.
 
crypto_result_t crypto_rekey_process_request (crypto_context_t *ctx, const uint8_t *peer_new_public_key)
 Process REKEY_REQUEST from peer (responder side)
 
crypto_result_t crypto_rekey_process_response (crypto_context_t *ctx, const uint8_t *peer_new_public_key)
 Process REKEY_RESPONSE from peer (initiator side)
 
crypto_result_t crypto_rekey_commit (crypto_context_t *ctx)
 Commit to new keys after successful REKEY_COMPLETE.
 
void crypto_rekey_abort (crypto_context_t *ctx)
 Abort rekeying and fallback to old keys.
 
void crypto_get_rekey_status (const crypto_context_t *ctx, char *status_buffer, size_t buffer_size)
 Get the current rekeying state for debugging/logging.
 

Detailed Description

🔐 Core cryptography: encryption/decryption, key exchange, authentication, and session rekeying with BearSSL

Definition in file lib/crypto/crypto.c.

Macro Definition Documentation

◆ CRYPTO_RESULT_STRING_COUNT

#define CRYPTO_RESULT_STRING_COUNT   (sizeof(g_crypto_result_strings) / sizeof(g_crypto_result_strings[0]))

Definition at line 595 of file lib/crypto/crypto.c.

Function Documentation

◆ crypto_derive_password_encryption_key()

crypto_result_t crypto_derive_password_encryption_key ( const char *  password,
uint8_t  encryption_key[SECRETBOX_KEY_SIZE] 
)

Definition at line 387 of file lib/crypto/crypto.c.

388 {
389 if (!password || !encryption_key) {
391 "crypto_derive_password_encryption_key: Invalid parameters (password=%p, encryption_key=%p)", password,
392 encryption_key);
394 }
395
396 // Validate password length requirements
397 crypto_result_t validation_result = crypto_validate_password(password);
398 if (validation_result != CRYPTO_OK) {
399 return validation_result;
400 }
401
402 // Use deterministic salt for consistent key derivation across client/server
403 // Salt must be exactly ARGON2ID_SALT_SIZE (32) bytes
404 const char *deterministic_salt = "ascii-chat-password-salt-v1";
405 uint8_t salt[ARGON2ID_SALT_SIZE]; // Use maximum size for buffer
406 size_t salt_str_len = strlen(deterministic_salt);
407
408 // Zero-initialize the salt buffer first
409 memset(salt, 0, ARGON2ID_SALT_SIZE);
410
411 // Copy the salt string (will be padded with zeros to ARGON2ID_SALT_SIZE)
412 memcpy(salt, deterministic_salt, (salt_str_len < ARGON2ID_SALT_SIZE) ? salt_str_len : ARGON2ID_SALT_SIZE);
413
414 // Derive key using Argon2id (memory-hard, secure against GPU attacks)
415 if (crypto_pwhash(encryption_key, SECRETBOX_KEY_SIZE, password, strlen(password), salt,
416 crypto_pwhash_OPSLIMIT_INTERACTIVE, // ~0.1 seconds
417 crypto_pwhash_MEMLIMIT_INTERACTIVE, // ~64MB
418 crypto_pwhash_ALG_DEFAULT) != 0) {
419 SET_ERRNO(ERROR_CRYPTO, "Password encryption key derivation failed - possibly out of memory");
421 }
422
423 log_dev("Password encryption key derived successfully using Argon2id");
424 return CRYPTO_OK;
425}
unsigned char uint8_t
Definition common.h:56
crypto_result_t
Cryptographic operation result codes.
#define SECRETBOX_KEY_SIZE
Secretbox key size in bytes.
crypto_result_t crypto_validate_password(const char *password)
Validate password length requirements.
#define ARGON2ID_SALT_SIZE
Argon2id salt size in bytes.
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it, returning the error code.
@ ERROR_CRYPTO
Definition error_codes.h:96
@ ERROR_INVALID_PARAM
#define log_dev(...)
Log a DEV message (most verbose, development only)
Definition log/log.h:534

References ARGON2ID_SALT_SIZE, CRYPTO_ERROR_INVALID_PARAMS, CRYPTO_ERROR_PASSWORD_DERIVATION, CRYPTO_OK, crypto_validate_password(), ERROR_CRYPTO, ERROR_INVALID_PARAM, log_dev, SECRETBOX_KEY_SIZE, and SET_ERRNO.