From: "Fabio M. Di Nitto" <fdinitto@xxxxxxxxxx> this add 2 bytes at the end of the each packet to propagate config info. in case there is a config mismatch packet must be rejected. Signed-off-by: Fabio M. Di Nitto <fdinitto@xxxxxxxxxx> --- exec/totemcrypto.c | 100 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 85 insertions(+), 15 deletions(-) diff --git a/exec/totemcrypto.c b/exec/totemcrypto.c index 24415b5..eb718b1 100644 --- a/exec/totemcrypto.c +++ b/exec/totemcrypto.c @@ -85,6 +85,11 @@ struct crypto_security_header { char msg[0]; } __attribute__((packed)); +struct crypto_config_header { + uint8_t crypto_cipher_type; + uint8_t crypto_hash_type; +} __attribute__((packed)); + struct crypto_instance { PK11SymKey *nss_sym_key; PK11SymKey *nss_sym_key_sign; @@ -516,10 +521,37 @@ out: return -1; } +static int string_to_crypto_cipher_type(const char* crypto_cipher_type) +{ + if (strcmp(crypto_cipher_type, "none") == 0) { + return CRYPTO_CIPHER_TYPE_NONE; + } else if (strcmp(crypto_cipher_type, "aes256") == 0) { + return CRYPTO_CIPHER_TYPE_AES256; + } + return CRYPTO_CIPHER_TYPE_NONE; +} + +static int string_to_crypto_hash_type(const char* crypto_hash_type) +{ + if (strcmp(crypto_hash_type, "none") == 0) { + return CRYPTO_HASH_TYPE_NONE; + } else if (strcmp(crypto_hash_type, "sha1") == 0) { + return CRYPTO_HASH_TYPE_SHA1; + } + + return CRYPTO_HASH_TYPE_NONE; +} + size_t crypto_sec_header_size( const char *crypto_cipher_type, const char *crypto_hash_type) { + int crypto_cipher = string_to_crypto_cipher_type(crypto_cipher_type); + int crypto_hash = string_to_crypto_hash_type(crypto_hash_type); + + if ((!crypto_cipher) && (!crypto_hash)) { + return 2; + } /* * TODO: crypto_cipher_type determines the crypto BLOCK size * crypto_hash_type determines the HASH_SIZE @@ -534,6 +566,8 @@ int crypto_encrypt_and_sign ( unsigned char *buf_out, size_t *buf_out_len) { + int err = 0; + /* * if crypto is totally disabled, let's skip complex parsing */ @@ -541,25 +575,70 @@ int crypto_encrypt_and_sign ( (!hash_to_nss[instance->crypto_hash_type])) { memcpy(buf_out, buf_in, buf_in_len); *buf_out_len = buf_in_len; - return 0; + err = 0; + } else { + err = encrypt_and_sign_nss(instance, + buf_in, buf_in_len, + buf_out, buf_out_len); } - return (encrypt_and_sign_nss(instance, buf_in, buf_in_len, buf_out, buf_out_len)); + /* + * Add 2 bytes to the tail of each packet to + * propagate crypto info for this packet. + */ + if (!err) { + size_t out_len = *buf_out_len; + struct crypto_config_header *cch; + + cch = (struct crypto_config_header *)&buf_out[*buf_out_len]; + + cch->crypto_cipher_type = instance->crypto_cipher_type; + cch->crypto_hash_type = instance->crypto_hash_type; + + *buf_out_len = *buf_out_len + 2; + } + + return err; } int crypto_authenticate_and_decrypt (struct crypto_instance *instance, unsigned char *buf, int *buf_len) { + int err = 0; + struct crypto_config_header *cch; + + cch = (struct crypto_config_header *)&buf[*buf_len - 2]; + + /* + * decode crypto config of incoming packets + */ + + if (cch->crypto_cipher_type != instance->crypto_cipher_type) { + log_printf(instance->log_level_security, + "Incoming packet has different crypto type. Rejecting"); + return -1; + } + + if (cch->crypto_hash_type != instance->crypto_hash_type) { + log_printf(instance->log_level_security, + "Incoming packet has different hash type. Rejecting"); + return -1; + } + /* * if crypto is totally disabled, there is no work for us */ if ((!cipher_to_nss[instance->crypto_cipher_type]) && (!hash_to_nss[instance->crypto_hash_type])) { - return 0; + *buf_len = *buf_len - 2; + err = 0; + } else { + *buf_len = *buf_len - 2; + err = authenticate_and_decrypt_nss(instance, buf, buf_len); } - return (authenticate_and_decrypt_nss(instance, buf, buf_len)); + return err; } struct crypto_instance *crypto_init( @@ -590,17 +669,8 @@ struct crypto_instance *crypto_init( memcpy(instance->private_key, private_key, private_key_len); instance->private_key_len = private_key_len; - if (strcmp(crypto_cipher_type, "none") == 0) { - instance->crypto_cipher_type = CRYPTO_CIPHER_TYPE_NONE; - } else if (strcmp(crypto_cipher_type, "aes256") == 0) { - instance->crypto_cipher_type = CRYPTO_CIPHER_TYPE_AES256; - } - - if (strcmp(crypto_hash_type, "none") == 0) { - instance->crypto_hash_type = CRYPTO_HASH_TYPE_NONE; - } else if (strcmp(crypto_hash_type, "sha1") == 0) { - instance->crypto_hash_type = CRYPTO_HASH_TYPE_SHA1; - } + instance->crypto_cipher_type = string_to_crypto_cipher_type(crypto_cipher_type); + instance->crypto_hash_type = string_to_crypto_hash_type(crypto_hash_type); instance->log_printf_func = log_printf_func; instance->log_level_security = log_level_security; -- 1.7.7.6 _______________________________________________ discuss mailing list discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss