49 const crypto_parameters_packet_t *params) {
50 if (!ctx || !params) {
51 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters: ctx=%p, params=%p", ctx, params);
59 ctx->crypto_ctx.public_key_size = params->kex_public_key_size;
60 ctx->crypto_ctx.auth_public_key_size = params->auth_public_key_size;
61 ctx->crypto_ctx.shared_key_size = params->shared_secret_size;
62 ctx->crypto_ctx.signature_size = params->signature_size;
66 ctx->crypto_ctx.public_key_size = NET_TO_HOST_U16(params->kex_public_key_size);
67 ctx->crypto_ctx.auth_public_key_size = NET_TO_HOST_U16(params->auth_public_key_size);
68 ctx->crypto_ctx.shared_key_size = NET_TO_HOST_U16(params->shared_secret_size);
69 ctx->crypto_ctx.signature_size = NET_TO_HOST_U16(params->signature_size);
72 ctx->crypto_ctx.nonce_size = params->nonce_size;
73 ctx->crypto_ctx.mac_size = params->mac_size;
74 ctx->crypto_ctx.hmac_size = params->hmac_size;
75 ctx->crypto_ctx.auth_challenge_size =
77 ctx->crypto_ctx.encryption_key_size =
78 (uint8_t)ctx->crypto_ctx.shared_key_size;
79 ctx->crypto_ctx.private_key_size = ctx->crypto_ctx.public_key_size;
80 ctx->crypto_ctx.salt_size = ARGON2ID_SALT_SIZE;
82 log_debug(
"Crypto parameters set: kex_key=%u, auth_key=%u, sig=%u, "
83 "secret=%u, nonce=%u, mac=%u, hmac=%u",
84 ctx->crypto_ctx.public_key_size, ctx->crypto_ctx.auth_public_key_size, ctx->crypto_ctx.signature_size,
85 ctx->crypto_ctx.shared_key_size, ctx->crypto_ctx.nonce_size, ctx->crypto_ctx.mac_size,
86 ctx->crypto_ctx.hmac_size);
95 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid parameters: ctx=%p", ctx);
98 switch (packet_type) {
99 case PACKET_TYPE_CRYPTO_CAPABILITIES:
100 if (packet_size !=
sizeof(crypto_capabilities_packet_t)) {
102 return SET_ERRNO(ERROR_NETWORK_PROTOCOL,
"Invalid crypto capabilities packet size: %zu (expected %zu)",
103 packet_size,
sizeof(crypto_capabilities_packet_t));
107 case PACKET_TYPE_CRYPTO_PARAMETERS:
108 if (packet_size !=
sizeof(crypto_parameters_packet_t)) {
109 return SET_ERRNO(ERROR_NETWORK_PROTOCOL,
"Invalid crypto parameters packet size: %zu (expected %zu)", packet_size,
110 sizeof(crypto_parameters_packet_t));
114 case PACKET_TYPE_CRYPTO_KEY_EXCHANGE_INIT:
119 size_t simple_size = ctx->crypto_ctx.public_key_size;
120 size_t authenticated_size =
121 ctx->crypto_ctx.public_key_size + ctx->crypto_ctx.auth_public_key_size + ctx->crypto_ctx.signature_size;
123 if (packet_size != simple_size && packet_size != authenticated_size) {
124 return SET_ERRNO(ERROR_NETWORK_PROTOCOL,
125 "Invalid KEY_EXCHANGE_INIT size: %zu (expected %zu for simple or %zu for authenticated: "
126 "kex=%u + auth=%u + sig=%u)",
127 packet_size, simple_size, authenticated_size, ctx->crypto_ctx.public_key_size,
128 ctx->crypto_ctx.auth_public_key_size, ctx->crypto_ctx.signature_size);
133 case PACKET_TYPE_CRYPTO_KEY_EXCHANGE_RESP:
139 size_t simple_size = ctx->crypto_ctx.public_key_size;
141 size_t ed25519_auth_size = ED25519_PUBLIC_KEY_SIZE;
142 size_t ed25519_sig_size = ED25519_SIGNATURE_SIZE;
143 size_t authenticated_min_size = ctx->crypto_ctx.public_key_size + ed25519_auth_size + ed25519_sig_size;
144 size_t authenticated_max_size = authenticated_min_size + 1 + 40;
146 if (packet_size != simple_size &&
147 (packet_size < authenticated_min_size || packet_size > authenticated_max_size)) {
148 return SET_ERRNO(ERROR_NETWORK_PROTOCOL,
149 "Invalid KEY_EXCHANGE_RESP size: %zu (expected %zu for simple or %zu-%zu for authenticated: "
150 "kex=%u + auth=%u + sig=%u + optional GPG key ID)",
151 packet_size, simple_size, authenticated_min_size, authenticated_max_size,
152 ctx->crypto_ctx.public_key_size, ed25519_auth_size, ed25519_sig_size);
157 case PACKET_TYPE_CRYPTO_AUTH_CHALLENGE:
160 size_t expected_size = AUTH_CHALLENGE_FLAGS_SIZE + ctx->crypto_ctx.auth_challenge_size;
161 if (packet_size != expected_size) {
162 return SET_ERRNO(ERROR_NETWORK_PROTOCOL,
"Invalid AUTH_CHALLENGE size: %zu (expected %zu: flags=%d + nonce=%u)",
163 packet_size, expected_size, AUTH_CHALLENGE_FLAGS_SIZE, ctx->crypto_ctx.auth_challenge_size);
168 case PACKET_TYPE_CRYPTO_AUTH_RESPONSE:
171 size_t min_size = ctx->crypto_ctx.hmac_size + ctx->crypto_ctx.auth_challenge_size;
172 size_t max_size = min_size + 1 + 40;
173 if (packet_size < min_size || packet_size > max_size) {
174 return SET_ERRNO(ERROR_NETWORK_PROTOCOL,
175 "Invalid AUTH_RESPONSE size: %zu (expected %zu-%zu: hmac=%u + "
176 "nonce=%u + optional GPG key ID)",
177 packet_size, min_size, max_size, ctx->crypto_ctx.hmac_size,
178 ctx->crypto_ctx.auth_challenge_size);
183 case PACKET_TYPE_CRYPTO_AUTH_FAILED:
185 if (packet_size > MAX_AUTH_FAILED_PACKET_SIZE) {
186 return SET_ERRNO(ERROR_NETWORK_PROTOCOL,
"Invalid AUTH_FAILED size: %zu (max %d)", packet_size,
187 MAX_AUTH_FAILED_PACKET_SIZE);
191 case PACKET_TYPE_CRYPTO_SERVER_AUTH_RESP:
193 if (packet_size != ctx->crypto_ctx.hmac_size) {
194 return SET_ERRNO(ERROR_NETWORK_PROTOCOL,
"Invalid SERVER_AUTH_RESP size: %zu (expected %u)", packet_size,
195 ctx->crypto_ctx.hmac_size);
199 case PACKET_TYPE_CRYPTO_HANDSHAKE_COMPLETE:
201 if (packet_size != 0) {
202 return SET_ERRNO(ERROR_NETWORK_PROTOCOL,
"Invalid HANDSHAKE_COMPLETE size: %zu (expected 0)", packet_size);
206 case PACKET_TYPE_CRYPTO_NO_ENCRYPTION:
208 if (packet_size != 0) {
209 return SET_ERRNO(ERROR_NETWORK_PROTOCOL,
"Invalid NO_ENCRYPTION size: %zu (expected 0)", packet_size);
213 case PACKET_TYPE_ENCRYPTED:
215 if (packet_size > MAX_ENCRYPTED_PACKET_SIZE) {
216 return SET_ERRNO(ERROR_NETWORK_PROTOCOL,
"Invalid ENCRYPTED size: %zu (max %d)", packet_size,
217 MAX_ENCRYPTED_PACKET_SIZE);
222 return SET_ERRNO(ERROR_NETWORK_PROTOCOL,
"Unknown crypto packet type: %u", packet_type);
425 return SET_ERRNO(ERROR_INVALID_STATE,
"Handshake not ready for rekeying: ctx=%p, ready=%d", ctx,
429 if (!ctx->crypto_ctx.rekey_in_progress || !ctx->crypto_ctx.has_temp_key) {
430 return SET_ERRNO(ERROR_INVALID_STATE,
"No rekey in progress or temp key missing");
434 uint8_t plaintext[1] = {0};
435 uint8_t ciphertext[256];
436 size_t ciphertext_len = 0;
439 uint8_t old_shared_key[CRYPTO_SHARED_KEY_SIZE];
440 memcpy(old_shared_key, ctx->crypto_ctx.shared_key, CRYPTO_SHARED_KEY_SIZE);
441 memcpy(ctx->crypto_ctx.shared_key, ctx->crypto_ctx.temp_shared_key, CRYPTO_SHARED_KEY_SIZE);
444 crypto_result_t result =
445 crypto_encrypt(&ctx->crypto_ctx, plaintext,
sizeof(plaintext), ciphertext,
sizeof(ciphertext), &ciphertext_len);
448 memcpy(ctx->crypto_ctx.shared_key, old_shared_key, CRYPTO_SHARED_KEY_SIZE);
449 sodium_memzero(old_shared_key,
sizeof(old_shared_key));
451 if (result != CRYPTO_OK) {
457 log_debug(
"Sending REKEY_COMPLETE (encrypted with NEW key, %zu bytes)", ciphertext_len);
458 int send_result =
send_packet(socket, PACKET_TYPE_CRYPTO_REKEY_COMPLETE, ciphertext, ciphertext_len);
459 if (send_result != 0) {
461 return SET_ERRNO(ERROR_NETWORK,
"Failed to send REKEY_COMPLETE packet");
466 if (result != CRYPTO_OK) {
470 log_debug(
"Session rekeying completed successfully (initiator side)");
481 return SET_ERRNO(ERROR_INVALID_STATE,
"Handshake not ready for rekeying: ctx=%p, ready=%d", ctx,
486 time_t now = time(NULL);
487 if (ctx->crypto_ctx.rekey_last_request_time > 0) {
488 time_t elapsed = now - ctx->crypto_ctx.rekey_last_request_time;
489 time_t min_request_interval_seconds = (time_t)(REKEY_MIN_REQUEST_INTERVAL / NS_PER_SEC_INT);
490 if (elapsed < min_request_interval_seconds) {
491 return SET_ERRNO(ERROR_CRYPTO,
492 "SECURITY: Rekey request rejected - too frequent (%ld sec since last, minimum %ld sec required)",
493 (
long)elapsed, (
long)min_request_interval_seconds);
498 ctx->crypto_ctx.rekey_last_request_time = now;
501 if (packet_len != CRYPTO_PUBLIC_KEY_SIZE) {
502 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid REKEY_REQUEST packet size: %zu (expected %d)", packet_len,
503 CRYPTO_PUBLIC_KEY_SIZE);
506 log_debug(
"Received REKEY_REQUEST with peer's new ephemeral public key (32 bytes)");
510 if (result != CRYPTO_OK) {
516 if (result != CRYPTO_OK) {
521 log_debug(
"REKEY_REQUEST processed successfully, new shared secret computed (responder side)");
567 return SET_ERRNO(ERROR_INVALID_STATE,
"Handshake not ready for rekeying: ctx=%p, ready=%d", ctx,
571 if (!ctx->crypto_ctx.rekey_in_progress || !ctx->crypto_ctx.has_temp_key) {
572 return SET_ERRNO(ERROR_INVALID_STATE,
"No rekey in progress or temp key missing");
575 log_debug(
"Received REKEY_COMPLETE packet (%zu bytes), verifying with NEW key", packet_len);
578 uint8_t old_shared_key[CRYPTO_SHARED_KEY_SIZE];
579 memcpy(old_shared_key, ctx->crypto_ctx.shared_key, CRYPTO_SHARED_KEY_SIZE);
580 memcpy(ctx->crypto_ctx.shared_key, ctx->crypto_ctx.temp_shared_key, CRYPTO_SHARED_KEY_SIZE);
583 uint8_t plaintext[256];
584 size_t plaintext_len = 0;
585 crypto_result_t result =
586 crypto_decrypt(&ctx->crypto_ctx, packet, packet_len, plaintext,
sizeof(plaintext), &plaintext_len);
589 memcpy(ctx->crypto_ctx.shared_key, old_shared_key, CRYPTO_SHARED_KEY_SIZE);
590 sodium_memzero(old_shared_key,
sizeof(old_shared_key));
592 if (result != CRYPTO_OK) {
594 return SET_ERRNO(ERROR_CRYPTO,
"REKEY_COMPLETE decryption failed (key mismatch): %s",
598 log_debug(
"REKEY_COMPLETE verified successfully, committing to new key");
602 if (result != CRYPTO_OK) {
606 log_debug(
"Session rekeying completed successfully (responder side)");