Browse Source

Simplify: Extract common crypto logic into helper functions for both OpenSSL and TinyCrypt

nodeinfo-routing-update
Evgeny 2 months ago
parent
commit
eb721be508
  1. 164
      src/secure_channel.c

164
src/secure_channel.c

@ -73,6 +73,63 @@ sc_status_t sc_init_ctx(sc_context_t *ctx, struct SC_MYKEYS *mykeys) {
return SC_OK;
}
// Common helper functions for input validation and CRC handling
static sc_status_t validate_encrypt_inputs(sc_context_t *ctx, const uint8_t *plaintext,
const uint8_t *ciphertext, const size_t *ciphertext_len,
size_t plaintext_len) {
if (!ctx || !plaintext || !ciphertext || !ciphertext_len) {
return SC_ERR_INVALID_ARG;
}
if (!ctx->session_ready) {
return SC_ERR_NOT_INITIALIZED;
}
if (plaintext_len == 0) {
return SC_ERR_INVALID_ARG;
}
return SC_OK;
}
static sc_status_t validate_decrypt_inputs(sc_context_t *ctx, const uint8_t *ciphertext,
const uint8_t *plaintext, const size_t *plaintext_len,
size_t ciphertext_len) {
if (!ctx || !ciphertext || !plaintext || !plaintext_len) {
return SC_ERR_INVALID_ARG;
}
if (!ctx->session_ready) {
return SC_ERR_NOT_INITIALIZED;
}
if (ciphertext_len < SC_NONCE_SIZE + SC_TAG_SIZE + SC_CRC32_SIZE) {
return SC_ERR_INVALID_ARG;
}
return SC_OK;
}
static void append_crc32(const uint8_t *plaintext, size_t plaintext_len, uint8_t *output) {
memcpy(output, plaintext, plaintext_len);
uint32_t crc = crc32_calc(plaintext, plaintext_len);
output[plaintext_len] = (crc >> 0) & 0xFF;
output[plaintext_len + 1] = (crc >> 8) & 0xFF;
output[plaintext_len + 2] = (crc >> 16) & 0xFF;
output[plaintext_len + 3] = (crc >> 24) & 0xFF;
}
static sc_status_t verify_and_strip_crc32(uint8_t *plaintext_with_crc, size_t total_len,
uint8_t *plaintext, size_t *plaintext_len) {
size_t data_len = total_len - SC_CRC32_SIZE;
uint32_t received_crc = ((uint32_t)plaintext_with_crc[data_len]) |
((uint32_t)plaintext_with_crc[data_len + 1] << 8) |
((uint32_t)plaintext_with_crc[data_len + 2] << 16) |
((uint32_t)plaintext_with_crc[data_len + 3] << 24);
uint32_t calc_crc = crc32_calc(plaintext_with_crc, data_len);
if (received_crc != calc_crc) {
return SC_ERR_CRC_FAILED;
}
memcpy(plaintext, plaintext_with_crc, data_len);
*plaintext_len = data_len;
return SC_OK;
}
#ifdef USE_OPENSSL
// OpenSSL-specific implementations
@ -310,22 +367,11 @@ static void sc_build_nonce(uint64_t counter, uint8_t *nonce_out) {
}
sc_status_t sc_encrypt(sc_context_t *ctx, const uint8_t *plaintext, size_t plaintext_len, uint8_t *ciphertext, size_t *ciphertext_len) {
if (!ctx || !plaintext || !ciphertext || !ciphertext_len) {
return SC_ERR_INVALID_ARG;
}
if (!ctx->session_ready) {
return SC_ERR_NOT_INITIALIZED;
}
if (plaintext_len == 0) {
return SC_ERR_INVALID_ARG;
}
sc_status_t status = validate_encrypt_inputs(ctx, plaintext, ciphertext, ciphertext_len, plaintext_len);
if (status != SC_OK) return status;
uint8_t plaintext_with_crc[plaintext_len + SC_CRC32_SIZE];
memcpy(plaintext_with_crc, plaintext, plaintext_len);
uint32_t crc = crc32_calc(plaintext, plaintext_len);
plaintext_with_crc[plaintext_len] = (crc >> 0) & 0xFF;
plaintext_with_crc[plaintext_len + 1] = (crc >> 8) & 0xFF;
plaintext_with_crc[plaintext_len + 2] = (crc >> 16) & 0xFF;
plaintext_with_crc[plaintext_len + 3] = (crc >> 24) & 0xFF;
append_crc32(plaintext, plaintext_len, plaintext_with_crc);
size_t total_plaintext_len = plaintext_len + SC_CRC32_SIZE;
uint8_t nonce[SC_NONCE_SIZE];
sc_build_nonce(ctx->tx_counter, nonce);
@ -374,15 +420,9 @@ sc_status_t sc_encrypt(sc_context_t *ctx, const uint8_t *plaintext, size_t plain
}
sc_status_t sc_decrypt(sc_context_t *ctx, const uint8_t *ciphertext, size_t ciphertext_len, uint8_t *plaintext, size_t *plaintext_len) {
if (!ctx || !ciphertext || !plaintext || !plaintext_len) {
return SC_ERR_INVALID_ARG;
}
if (!ctx->session_ready) {
return SC_ERR_NOT_INITIALIZED;
}
if (ciphertext_len < SC_NONCE_SIZE + SC_TAG_SIZE + SC_CRC32_SIZE) {
return SC_ERR_INVALID_ARG;
}
sc_status_t status = validate_decrypt_inputs(ctx, ciphertext, plaintext, plaintext_len, ciphertext_len);
if (status != SC_OK) return status;
uint8_t nonce[SC_NONCE_SIZE];
memcpy(nonce, ciphertext, SC_NONCE_SIZE);
const uint8_t *encrypted_data = ciphertext + SC_NONCE_SIZE;
@ -419,19 +459,11 @@ sc_status_t sc_decrypt(sc_context_t *ctx, const uint8_t *ciphertext, size_t ciph
return SC_ERR_AUTH_FAILED;
}
EVP_CIPHER_CTX_free(dctx);
size_t data_len = total_plaintext_len - SC_CRC32_SIZE;
uint32_t expected_crc = crc32_calc(plaintext_with_crc, data_len);
uint32_t received_crc = (plaintext_with_crc[data_len] << 0) |
(plaintext_with_crc[data_len + 1] << 8) |
(plaintext_with_crc[data_len + 2] << 16) |
(plaintext_with_crc[data_len + 3] << 24);
if (expected_crc != received_crc) {
return SC_ERR_CRC_FAILED;
}
memcpy(plaintext, plaintext_with_crc, data_len);
*plaintext_len = data_len;
sc_status_t result = verify_and_strip_crc32(plaintext_with_crc, total_plaintext_len, plaintext, plaintext_len);
if (result == SC_OK) {
ctx->rx_counter++;
return SC_OK;
}
return result;
}
sc_status_t sc_compute_public_key_from_private(const uint8_t *private_key, uint8_t *public_key) {
@ -671,6 +703,9 @@ static void sc_build_nonce(uint64_t counter, uint8_t *nonce_out)
}
sc_status_t sc_encrypt(sc_context_t *ctx, const uint8_t *plaintext, size_t plaintext_len, uint8_t *ciphertext, size_t *ciphertext_len) {
sc_status_t status = validate_encrypt_inputs(ctx, plaintext, ciphertext, ciphertext_len, plaintext_len);
if (status != SC_OK) return status;
uint8_t nonce[SC_NONCE_SIZE];
uint8_t plaintext_with_crc[plaintext_len + SC_CRC32_SIZE];
size_t total_plaintext_len = plaintext_len + SC_CRC32_SIZE;
@ -678,25 +713,8 @@ sc_status_t sc_encrypt(sc_context_t *ctx, const uint8_t *plaintext, size_t plain
struct tc_aes_key_sched_struct sched;
struct tc_ccm_mode_struct ccm_state;
if (!ctx || !plaintext || !ciphertext || !ciphertext_len) {
return SC_ERR_INVALID_ARG;
}
if (!ctx->session_ready) {
return SC_ERR_NOT_INITIALIZED;
}
if (plaintext_len == 0) {
return SC_ERR_INVALID_ARG;
}
/* Добавляем CRC32 к данным */
memcpy(plaintext_with_crc, plaintext, plaintext_len);
uint32_t crc = crc32_calc(plaintext, plaintext_len);
plaintext_with_crc[plaintext_len] = (crc >> 0) & 0xFF;
plaintext_with_crc[plaintext_len + 1] = (crc >> 8) & 0xFF;
plaintext_with_crc[plaintext_len + 2] = (crc >> 16) & 0xFF;
plaintext_with_crc[plaintext_len + 3] = (crc >> 24) & 0xFF;
append_crc32(plaintext, plaintext_len, plaintext_with_crc);
/* Генерируем nonce с таймером */
sc_build_nonce(ctx->tx_counter, nonce);
@ -735,24 +753,15 @@ sc_status_t sc_decrypt(sc_context_t *ctx,
uint8_t *plaintext,
size_t *plaintext_len)
{
sc_status_t status = validate_decrypt_inputs(ctx, ciphertext, plaintext, plaintext_len, ciphertext_len);
if (status != SC_OK) return status;
uint8_t nonce[SC_NONCE_SIZE];
struct tc_aes_key_sched_struct sched;
struct tc_ccm_mode_struct ccm_state;
size_t total_plaintext_len = ciphertext_len - SC_NONCE_SIZE - SC_TAG_SIZE;
uint8_t plaintext_with_crc[total_plaintext_len];
if (!ctx || !ciphertext || !plaintext || !plaintext_len) {
return SC_ERR_INVALID_ARG;
}
if (!ctx->session_ready) {
return SC_ERR_NOT_INITIALIZED;
}
if (ciphertext_len < SC_NONCE_SIZE + SC_TAG_SIZE + SC_CRC32_SIZE) {
return SC_ERR_INVALID_ARG;
}
/* Извлекаем nonce из начала ciphertext */
memcpy(nonce, ciphertext, SC_NONCE_SIZE);
@ -778,25 +787,12 @@ sc_status_t sc_decrypt(sc_context_t *ctx,
return SC_ERR_AUTH_FAILED;
}
/* Проверяем CRC32 */
size_t data_len = total_plaintext_len - SC_CRC32_SIZE;
uint32_t expected_crc = crc32_calc(plaintext_with_crc, data_len);
uint32_t received_crc = (plaintext_with_crc[data_len] << 0) |
(plaintext_with_crc[data_len + 1] << 8) |
(plaintext_with_crc[data_len + 2] << 16) |
(plaintext_with_crc[data_len + 3] << 24);
if (expected_crc != received_crc) {
return SC_ERR_CRC_FAILED;
}
/* Копируем данные без CRC32 */
memcpy(plaintext, plaintext_with_crc, data_len);
*plaintext_len = data_len;
/* Проверяем CRC32 используя helper-функцию */
sc_status_t result = verify_and_strip_crc32(plaintext_with_crc, total_plaintext_len, plaintext, plaintext_len);
if (result == SC_OK) {
ctx->rx_counter++;
return SC_OK;
}
return result;
}
sc_status_t sc_compute_public_key_from_private(const uint8_t *private_key, uint8_t *public_key) {

Loading…
Cancel
Save