From: "Fabio M. Di Nitto" <fdinitto@xxxxxxxxxx>
keep totem.secauth config key for compatibility
if the key is NOT set, crypto will default to aes256/sha1
if the key is set to "off", crypto is disabled.
this reflects pretty much old behavior
keywords totem.crypto_cipher and totem.crypto_hash can
override secauth individually.
Signed-off-by: Fabio M. Di Nitto <fdinitto@xxxxxxxxxx>
---
exec/totemconfig.c | 9 +-
exec/totemcrypto.c | 506 ++++++++++++++++++++++++----------------
exec/totemcrypto.h | 1 +
exec/totemudp.c | 94 ++++----
exec/totemudpu.c | 95 ++++----
include/corosync/totem/totem.h | 2 -
6 files changed, 398 insertions(+), 309 deletions(-)
diff --git a/exec/totemconfig.c b/exec/totemconfig.c
index 931bd7a..1138963 100644
--- a/exec/totemconfig.c
+++ b/exec/totemconfig.c
@@ -129,11 +129,9 @@ static void totem_get_crypto(struct totem_config *totem_config)
tmp_hash = "sha1";
tmp_cipher = "aes256";
- totem_config->secauth = 1;
if (icmap_get_string("totem.secauth", &str) == CS_OK) {
if (strcmp (str, "off") == 0) {
- totem_config->secauth = 0;
tmp_hash = "none";
tmp_cipher = "none";
}
@@ -160,10 +158,6 @@ static void totem_get_crypto(struct totem_config *totem_config)
free(str);
}
- if (strcmp(tmp_hash, "none") == 0 && strcmp(tmp_cipher, "none") == 0) {
- totem_config->secauth = 0;
- }
-
free(totem_config->crypto_cipher_type);
free(totem_config->crypto_hash_type);
@@ -1019,7 +1013,8 @@ int totem_config_keyread (
memset (totem_config->private_key, 0, 128);
totem_config->private_key_len = 128;
- if (totem_config->secauth == 0) {
+ if (strcmp(totem_config->crypto_cipher_type, "none") == 0 &&
+ strcmp(totem_config->crypto_hash_type, "none") == 0) {
return (0);
}
diff --git a/exec/totemcrypto.c b/exec/totemcrypto.c
index 8c0ec91..24415b5 100644
--- a/exec/totemcrypto.c
+++ b/exec/totemcrypto.c
@@ -77,9 +77,11 @@
#include <prerror.h>
#define CRYPTO_HMAC_HASH_SIZE 20
+#define SALT_SIZE 16
+
struct crypto_security_header {
unsigned char hash_digest[CRYPTO_HMAC_HASH_SIZE]; /* The hash *MUST* be first in the data structure */
- unsigned char salt[16]; /* random number */
+ unsigned char salt[SALT_SIZE]; /* random number */
char msg[0];
} __attribute__((packed));
@@ -111,8 +113,8 @@ struct crypto_instance {
};
CK_MECHANISM_TYPE cipher_to_nss[] = {
- 0, /* CRYPTO_CIPHER_TYPE_NONE */
- CKM_AES_CBC_PAD /* CRYPTO_CIPHER_TYPE_AES256 */
+ 0, /* CRYPTO_CIPHER_TYPE_NONE */
+ CKM_AES_CBC_PAD /* CRYPTO_CIPHER_TYPE_AES256 */
};
size_t cipher_key_len[] = {
@@ -121,15 +123,15 @@ size_t cipher_key_len[] = {
};
CK_MECHANISM_TYPE hash_to_nss[] = {
- 0, /* CRYPTO_HASH_TYPE_NONE */
- CKM_SHA_1_HMAC /* CRYPTO_HASH_TYPE_SHA1 */
+ 0, /* CRYPTO_HASH_TYPE_NONE */
+ CKM_SHA_1_HMAC /* CRYPTO_HASH_TYPE_SHA1 */
};
#define log_printf(level, format, args...) \
do { \
- instance->log_printf_func ( \
- level, instance->log_subsys_id, \
- __FUNCTION__, __FILE__, __LINE__, \
+ instance->log_printf_func ( \
+ level, instance->log_subsys_id, \
+ __FUNCTION__, __FILE__, __LINE__, \
(const char *)format, ##args); \
} while (0);
@@ -137,76 +139,86 @@ do { \
do { \
char _error_str[LOGSYS_MAX_PERROR_MSG_LEN]; \
const char *_error_ptr = qb_strerror_r(err_num, _error_str, sizeof(_error_str)); \
- instance->totemudp_log_printf ( \
- level, instance->log_subsys_id, \
+ instance->totemudp_log_printf ( \
+ level, instance->log_subsys_id, \
__FUNCTION__, __FILE__, __LINE__, \
- fmt ": %s (%d)", ##args, _error_ptr, err_num); \
- } while(0)
+ fmt ": %s (%d)", ##args, _error_ptr, err_num); \
+} while(0)
-static void init_nss_crypto(struct crypto_instance *instance)
+static int init_nss_crypto(struct crypto_instance *instance,
+ const char *crypto_cipher_type,
+ const char *crypto_hash_type)
{
- PK11SlotInfo* aes_slot = NULL;
- PK11SlotInfo* sha1_slot = NULL;
- SECItem key_item;
- SECStatus rv;
+ PK11SlotInfo* crypt_slot = NULL;
+ PK11SlotInfo* hash_slot = NULL;
+ SECItem crypt_param;
+ SECItem hash_param;
+
+ if ((!cipher_to_nss[instance->crypto_cipher_type]) &&
+ (!hash_to_nss[instance->crypto_hash_type])) {
+ log_printf(instance->log_level_notice,
+ "Initializing transmit/receive security: NONE");
+ return 0;
+ }
log_printf(instance->log_level_notice,
- "Initializing transmit/receive security: NSS AES256CBC/SHA1HMAC (mode %u).", 0);
- rv = NSS_NoDB_Init(".");
- if (rv != SECSuccess)
- {
+ "Initializing transmit/receive security: NSS crypto: %s hash: %s",
+ crypto_cipher_type, crypto_hash_type);
+
+ if (NSS_NoDB_Init(".") != SECSuccess) {
log_printf(instance->log_level_security, "NSS initialization failed (err %d)",
- PR_GetError());
+ PR_GetError());
goto out;
}
- /*
- * TODO: use instance info!
- */
- aes_slot = PK11_GetBestSlot(cipher_to_nss[instance->crypto_cipher_type], NULL);
- if (aes_slot == NULL)
- {
- log_printf(instance->log_level_security, "Unable to find security slot (err %d)",
- PR_GetError());
- goto out;
+ if (cipher_to_nss[instance->crypto_cipher_type]) {
+ crypt_param.type = siBuffer;
+ crypt_param.data = instance->private_key;
+ crypt_param.len = cipher_key_len[instance->crypto_cipher_type];
+
+ crypt_slot = PK11_GetBestSlot(cipher_to_nss[instance->crypto_cipher_type], NULL);
+ if (crypt_slot == NULL) {
+ log_printf(instance->log_level_security, "Unable to find security slot (err %d)",
+ PR_GetError());
+ goto out;
+ }
+ instance->nss_sym_key = PK11_ImportSymKey(crypt_slot,
+ cipher_to_nss[instance->crypto_cipher_type],
+ PK11_OriginUnwrap, CKA_ENCRYPT|CKA_DECRYPT,
+ &crypt_param, NULL);
+ if (instance->nss_sym_key == NULL) {
+ log_printf(instance->log_level_security, "Failure to import key into NSS (err %d)",
+ PR_GetError());
+ goto out;
+ }
}
- sha1_slot = PK11_GetBestSlot(hash_to_nss[instance->crypto_hash_type], NULL);
- if (sha1_slot == NULL)
- {
- log_printf(instance->log_level_security, "Unable to find security slot (err %d)",
- PR_GetError());
- goto out;
- }
- /*
- * Make the private key into a SymKey that we can use
- */
- key_item.type = siBuffer;
- key_item.data = instance->private_key;
- key_item.len = cipher_key_len[instance->crypto_cipher_type];
-
- instance->nss_sym_key = PK11_ImportSymKey(aes_slot,
- cipher_to_nss[instance->crypto_cipher_type],
- PK11_OriginUnwrap, CKA_ENCRYPT|CKA_DECRYPT,
- &key_item, NULL);
- if (instance->nss_sym_key == NULL)
- {
- log_printf(instance->log_level_security, "Failure to import key into NSS (err %d)",
- PR_GetError());
- goto out;
+ if (hash_to_nss[instance->crypto_hash_type]) {
+ hash_param.type = siBuffer;
+ hash_param.data = 0;
+ hash_param.len = 0;
+
+ hash_slot = PK11_GetBestSlot(hash_to_nss[instance->crypto_hash_type], NULL);
+ if (hash_slot == NULL) {
+ log_printf(instance->log_level_security, "Unable to find security slot (err %d)",
+ PR_GetError());
+ goto out;
+ }
+
+ instance->nss_sym_key_sign = PK11_ImportSymKey(hash_slot,
+ hash_to_nss[instance->crypto_hash_type],
+ PK11_OriginUnwrap, CKA_SIGN,
+ &hash_param, NULL);
+ if (instance->nss_sym_key_sign == NULL) {
+ log_printf(instance->log_level_security, "Failure to import key into NSS (err %d)",
+ PR_GetError());
+ goto out;
+ }
}
- instance->nss_sym_key_sign = PK11_ImportSymKey(sha1_slot,
- hash_to_nss[instance->crypto_hash_type],
- PK11_OriginUnwrap, CKA_SIGN,
- &key_item, NULL);
- if (instance->nss_sym_key_sign == NULL) {
- log_printf(instance->log_level_security, "Failure to import key into NSS (err %d)",
- PR_GetError());
- goto out;
- }
+ return 0;
out:
- return;
+ return -1;
}
static int encrypt_and_sign_nss (
@@ -216,226 +228,301 @@ static int encrypt_and_sign_nss (
unsigned char *buf_out,
size_t *buf_out_len)
{
- PK11Context* enc_context = NULL;
- SECStatus rv1, rv2;
- int tmp1_outlen;
- unsigned int tmp2_outlen;
- unsigned char *outdata;
- SECItem no_params;
- SECItem iv_item;
- struct crypto_security_header *header;
- SECItem *nss_sec_param;
- unsigned char nss_iv_data[16];
- SECStatus rv;
-
- no_params.type = siBuffer;
- no_params.data = 0;
- no_params.len = 0;
-
- tmp1_outlen = tmp2_outlen = 0;
+ PK11Context* enc_context = NULL;
+ SECItem crypt_param;
+ SECItem hash_param;
+ SECItem *nss_sec_param = NULL;
+ struct crypto_security_header *header;
+ unsigned char *outdata;
+ int tmp1_outlen = 0;
+ unsigned int tmp2_outlen = 0;
outdata = buf_out + sizeof (struct crypto_security_header);
header = (struct crypto_security_header *)buf_out;
- rv = PK11_GenerateRandom (
- nss_iv_data,
- sizeof (nss_iv_data));
- if (rv != SECSuccess) {
+ memset(header->salt, 0, SALT_SIZE);
+
+ if (!cipher_to_nss[instance->crypto_cipher_type]) {
+ memcpy(outdata, buf_in, buf_in_len);
+ *buf_out_len = buf_in_len;
+ goto only_hash;
+ }
+
+ if (PK11_GenerateRandom (header->salt, SALT_SIZE) != SECSuccess) {
log_printf(instance->log_level_security,
"Failure to generate a random number %d",
PR_GetError());
+ goto out;
}
- memcpy(header->salt, nss_iv_data, sizeof(nss_iv_data));
- iv_item.type = siBuffer;
- iv_item.data = nss_iv_data;
- iv_item.len = sizeof (nss_iv_data);
+ crypt_param.type = siBuffer;
+ crypt_param.data = header->salt;
+ crypt_param.len = SALT_SIZE;
- nss_sec_param = PK11_ParamFromIV (
- cipher_to_nss[instance->crypto_cipher_type],
- &iv_item);
+ nss_sec_param = PK11_ParamFromIV (cipher_to_nss[instance->crypto_cipher_type],
+ &crypt_param);
if (nss_sec_param == NULL) {
log_printf(instance->log_level_security,
- "Failure to set up PKCS11 param (err %d)",
- PR_GetError());
- return (-1);
+ "Failure to set up PKCS11 param (err %d)",
+ PR_GetError());
+ goto out;
}
/*
* Create cipher context for encryption
*/
- enc_context = PK11_CreateContextBySymKey (
- cipher_to_nss[instance->crypto_cipher_type],
- CKA_ENCRYPT,
- instance->nss_sym_key,
- nss_sec_param);
+ enc_context = PK11_CreateContextBySymKey (cipher_to_nss[instance->crypto_cipher_type],
+ CKA_ENCRYPT,
+ instance->nss_sym_key,
+ nss_sec_param);
if (!enc_context) {
- char err[1024];
- PR_GetErrorText(err);
- err[PR_GetErrorTextLength()] = 0;
log_printf(instance->log_level_security,
- "PK11_CreateContext failed (encrypt) crypt_type=%d (err %d): %s",
- (int)cipher_to_nss[instance->crypto_cipher_type],
- PR_GetError(), err);
- return -1;
- }
- rv1 = PK11_CipherOp(enc_context, outdata,
- &tmp1_outlen, FRAME_SIZE_MAX - sizeof(struct crypto_security_header),
- (unsigned char *)buf_in, buf_in_len);
- rv2 = PK11_DigestFinal(enc_context, outdata + tmp1_outlen, &tmp2_outlen,
- FRAME_SIZE_MAX - tmp1_outlen);
+ "PK11_CreateContext failed (encrypt) crypt_type=%d (err %d)",
+ (int)cipher_to_nss[instance->crypto_cipher_type],
+ PR_GetError());
+ goto out;
+ }
+
+ if (PK11_CipherOp(enc_context, outdata,
+ &tmp1_outlen, FRAME_SIZE_MAX - sizeof(struct crypto_security_header),
+ (unsigned char *)buf_in, buf_in_len) != SECSuccess) {
+ log_printf(instance->log_level_security,
+ "PK11_CipherOp failed (encrypt) crypt_type=%d (err %d)",
+ (int)cipher_to_nss[instance->crypto_cipher_type],
+ PR_GetError());
+ goto out;
+ }
+ if (PK11_DigestFinal(enc_context, outdata + tmp1_outlen,
+ &tmp2_outlen, FRAME_SIZE_MAX - tmp1_outlen) != SECSuccess) {
+ log_printf(instance->log_level_security,
+ "PK11_DigestFinal failed (encrypt) crypt_type=%d (err %d)",
+ (int)cipher_to_nss[instance->crypto_cipher_type],
+ PR_GetError());
+ goto out;
+
+ }
+
PK11_DestroyContext(enc_context, PR_TRUE);
*buf_out_len = tmp1_outlen + tmp2_outlen;
- if (rv1 != SECSuccess || rv2 != SECSuccess)
- goto out;
+only_hash:
+
+ if (!hash_to_nss[instance->crypto_hash_type]) {
+ goto no_hash;
+ }
/* Now do the digest */
+ hash_param.type = siBuffer;
+ hash_param.data = 0;
+ hash_param.len = 0;
+
enc_context = PK11_CreateContextBySymKey(hash_to_nss[instance->crypto_hash_type],
- CKA_SIGN, instance->nss_sym_key_sign, &no_params);
+ CKA_SIGN,
+ instance->nss_sym_key_sign,
+ &hash_param);
if (!enc_context) {
- char err[1024];
- PR_GetErrorText(err);
- err[PR_GetErrorTextLength()] = 0;
- log_printf(instance->log_level_security, "encrypt: PK11_CreateContext failed (digest) err %d: %s",
- PR_GetError(), err);
- return -1;
+ log_printf(instance->log_level_security,
+ "PK11_CreateContext failed (hash) hash_type=%d (err %d)",
+ (int)hash_to_nss[instance->crypto_hash_type],
+ PR_GetError());
+ goto out;
}
+ if (PK11_DigestBegin(enc_context) != SECSuccess) {
+ log_printf(instance->log_level_security,
+ "PK11_DigestBegin failed (hash) hash_type=%d (err %d)",
+ (int)hash_to_nss[instance->crypto_hash_type],
+ PR_GetError());
+ goto out;
+ }
- PK11_DigestBegin(enc_context);
-
- rv1 = PK11_DigestOp(enc_context, outdata - 16, *buf_out_len + 16);
- rv2 = PK11_DigestFinal(enc_context, header->hash_digest, &tmp2_outlen, sizeof(header->hash_digest));
+ if (PK11_DigestOp(enc_context,
+ outdata - SALT_SIZE,
+ *buf_out_len + SALT_SIZE) != SECSuccess) {
+ log_printf(instance->log_level_security,
+ "PK11_DigestOp failed (hash) hash_type=%d (err %d)",
+ (int)hash_to_nss[instance->crypto_hash_type],
+ PR_GetError());
+ goto out;
+ }
+ if (PK11_DigestFinal(enc_context,
+ header->hash_digest,
+ &tmp2_outlen,
+ sizeof(header->hash_digest)) != SECSuccess) {
+ log_printf(instance->log_level_security,
+ "PK11_DigestFinale failed (hash) hash_type=%d (err %d)",
+ (int)hash_to_nss[instance->crypto_hash_type],
+ PR_GetError());
+ goto out;
+ }
PK11_DestroyContext(enc_context, PR_TRUE);
- if (rv1 != SECSuccess || rv2 != SECSuccess)
- goto out;
+no_hash:
- *buf_out_len = *buf_out_len + sizeof(struct crypto_security_header);
SECITEM_FreeItem(nss_sec_param, PR_TRUE);
+
+ *buf_out_len = *buf_out_len + sizeof(struct crypto_security_header);
+
return 0;
out:
+ if (enc_context) {
+ PK11_DestroyContext(enc_context, PR_TRUE);
+ }
+ if (nss_sec_param) {
+ SECITEM_FreeItem(nss_sec_param, PR_TRUE);
+ }
return -1;
}
-
static int authenticate_and_decrypt_nss (
struct crypto_instance *instance,
unsigned char *buf,
int *buf_len)
{
- PK11Context* enc_context = NULL;
- SECStatus rv1, rv2;
- int tmp1_outlen;
- unsigned int tmp2_outlen;
- unsigned char outbuf[FRAME_SIZE_MAX];
- unsigned char digest[CRYPTO_HMAC_HASH_SIZE];
- unsigned char *outdata;
- int result_len;
- unsigned char *data;
- unsigned char *inbuf;
- size_t datalen;
- struct crypto_security_header *header = (struct crypto_security_header *)buf;
- SECItem no_params;
- SECItem ivdata;
-
- no_params.type = siBuffer;
- no_params.data = 0;
- no_params.len = 0;
-
- tmp1_outlen = tmp2_outlen = 0;
- inbuf = (unsigned char *)buf;
+ PK11Context* enc_context = NULL;
+ int tmp1_outlen = 0;
+ unsigned int tmp2_outlen = 0;
+ unsigned char outbuf[FRAME_SIZE_MAX];
+ unsigned char digest[CRYPTO_HMAC_HASH_SIZE];
+ unsigned char *outdata;
+ int result_len;
+ unsigned char *data;
+ size_t datalen;
+ struct crypto_security_header *header = (struct crypto_security_header *)buf;
+ SECItem crypt_param;
+ SECItem hash_param;
+
datalen = *buf_len;
- data = inbuf + sizeof (struct crypto_security_header) - 16;
- datalen = datalen - sizeof (struct crypto_security_header) + 16;
+ data = buf + sizeof (struct crypto_security_header) - SALT_SIZE;
+ datalen = datalen - sizeof (struct crypto_security_header) + SALT_SIZE;
outdata = outbuf + sizeof (struct crypto_security_header);
+ if (!hash_to_nss[instance->crypto_hash_type]) {
+ goto only_decrypt;
+ }
+
+ hash_param.type = siBuffer;
+ hash_param.data = 0;
+ hash_param.len = 0;
+
/* Check the digest */
- enc_context = PK11_CreateContextBySymKey (
- hash_to_nss[instance->crypto_hash_type], CKA_SIGN,
- instance->nss_sym_key_sign,
- &no_params);
+ enc_context = PK11_CreateContextBySymKey (hash_to_nss[instance->crypto_hash_type],
+ CKA_SIGN,
+ instance->nss_sym_key_sign,
+ &hash_param);
if (!enc_context) {
- char err[1024];
- PR_GetErrorText(err);
- err[PR_GetErrorTextLength()] = 0;
- log_printf(instance->log_level_security, "PK11_CreateContext failed (check digest) err %d: %s",
- PR_GetError(), err);
- return -1;
+ log_printf(instance->log_level_security,
+ "PK11_CreateContext failed (check digest) err %d",
+ PR_GetError());
+ goto out;
}
- PK11_DigestBegin(enc_context);
-
- rv1 = PK11_DigestOp(enc_context, data, datalen);
- rv2 = PK11_DigestFinal(enc_context, digest, &tmp2_outlen, sizeof(digest));
+ if (PK11_DigestBegin(enc_context) != SECSuccess) {
+ log_printf(instance->log_level_security,
+ "PK11_DigestBegin failed (check digest) err %d",
+ PR_GetError());
+ goto out;
+ }
- PK11_DestroyContext(enc_context, PR_TRUE);
+ if (PK11_DigestOp(enc_context, data, datalen) != SECSuccess) {
+ log_printf(instance->log_level_security,
+ "PK11_DigestOp failed (check digest) err %d",
+ PR_GetError());
+ goto out;
+ }
- if (rv1 != SECSuccess || rv2 != SECSuccess) {
- log_printf(instance->log_level_security, "Digest check failed");
- return -1;
+ if (PK11_DigestFinal(enc_context, digest,
+ &tmp2_outlen, sizeof(digest)) != SECSuccess) {
+ log_printf(instance->log_level_security,
+ "PK11_DigestFinal failed (check digest) err %d",
+ PR_GetError());
+ goto out;
}
+ PK11_DestroyContext(enc_context, PR_TRUE);
+
if (memcmp(digest, header->hash_digest, tmp2_outlen) != 0) {
log_printf(instance->log_level_error, "Digest does not match");
- return -1;
+ goto out;
+ }
+
+only_decrypt:
+
+ if (!cipher_to_nss[instance->crypto_cipher_type]) {
+ memcpy(outbuf, buf + sizeof (struct crypto_security_header), *buf_len - sizeof (struct crypto_security_header));
+ outdata = outbuf;
+ result_len = *buf_len - sizeof (struct crypto_security_header);
+ goto no_decrypt;
}
/*
* Get rid of salt
*/
- data += 16;
- datalen -= 16;
+ data += SALT_SIZE;
+ datalen -= SALT_SIZE;
/* Create cipher context for decryption */
- ivdata.type = siBuffer;
- ivdata.data = header->salt;
- ivdata.len = sizeof(header->salt);
-
- enc_context = PK11_CreateContextBySymKey(
- cipher_to_nss[instance->crypto_cipher_type],
- CKA_DECRYPT,
- instance->nss_sym_key, &ivdata);
+ crypt_param.type = siBuffer;
+ crypt_param.data = header->salt;
+ crypt_param.len = SALT_SIZE;
+
+ enc_context = PK11_CreateContextBySymKey(cipher_to_nss[instance->crypto_cipher_type],
+ CKA_DECRYPT,
+ instance->nss_sym_key, &crypt_param);
if (!enc_context) {
log_printf(instance->log_level_security,
- "PK11_CreateContext (decrypt) failed (err %d)",
- PR_GetError());
- return -1;
+ "PK11_CreateContext (decrypt) failed (err %d)",
+ PR_GetError());
+ goto out;
}
- rv1 = PK11_CipherOp(enc_context, outdata, &tmp1_outlen,
- sizeof(outbuf) - sizeof (struct crypto_security_header),
- data, datalen);
- if (rv1 != SECSuccess) {
+ if (PK11_CipherOp(enc_context, outdata, &tmp1_outlen,
+ sizeof(outbuf) - sizeof (struct crypto_security_header),
+ data, datalen) != SECSuccess) {
log_printf(instance->log_level_security,
- "PK11_CipherOp (decrypt) failed (err %d)",
- PR_GetError());
+ "PK11_CipherOp (decrypt) failed (err %d)",
+ PR_GetError());
+ goto out;
+ }
+ if (PK11_DigestFinal(enc_context, outdata + tmp1_outlen, &tmp2_outlen,
+ sizeof(outbuf) - tmp1_outlen) != SECSuccess) {
+ log_printf(instance->log_level_security,
+ "PK11_DigestFinal (decrypt) failed (err %d)",
+ PR_GetError());
+ goto out;
}
- rv2 = PK11_DigestFinal(enc_context, outdata + tmp1_outlen, &tmp2_outlen,
- sizeof(outbuf) - tmp1_outlen);
+
PK11_DestroyContext(enc_context, PR_TRUE);
+
result_len = tmp1_outlen + tmp2_outlen + sizeof (struct crypto_security_header);
+no_decrypt:
+
memset(buf, 0, *buf_len);
memcpy(buf, outdata, result_len);
*buf_len = result_len;
- if (rv1 != SECSuccess || rv2 != SECSuccess)
- return -1;
-
return 0;
+
+out:
+ if (enc_context) {
+ PK11_DestroyContext(enc_context, PR_TRUE);
+ }
+ return -1;
}
-size_t crypto_sec_header_size(const char *crypto_hash_type)
+size_t crypto_sec_header_size(
+ const char *crypto_cipher_type,
+ const char *crypto_hash_type)
{
/*
- * TODO: add switch / size mapping
+ * TODO: crypto_cipher_type determines the crypto BLOCK size
+ * crypto_hash_type determines the HASH_SIZE
*/
return sizeof(struct crypto_security_header);
}
@@ -447,6 +534,16 @@ int crypto_encrypt_and_sign (
unsigned char *buf_out,
size_t *buf_out_len)
{
+ /*
+ * if crypto is totally disabled, let's skip complex parsing
+ */
+ if ((!cipher_to_nss[instance->crypto_cipher_type]) &&
+ (!hash_to_nss[instance->crypto_hash_type])) {
+ memcpy(buf_out, buf_in, buf_in_len);
+ *buf_out_len = buf_in_len;
+ return 0;
+ }
+
return (encrypt_and_sign_nss(instance, buf_in, buf_in_len, buf_out, buf_out_len));
}
@@ -454,6 +551,14 @@ int crypto_authenticate_and_decrypt (struct crypto_instance *instance,
unsigned char *buf,
int *buf_len)
{
+ /*
+ * 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;
+ }
+
return (authenticate_and_decrypt_nss(instance, buf, buf_len));
}
@@ -503,7 +608,10 @@ struct crypto_instance *crypto_init(
instance->log_level_error = log_level_error;
instance->log_subsys_id = log_subsys_id;
- init_nss_crypto(instance);
+ if (init_nss_crypto(instance, crypto_cipher_type, crypto_hash_type) < 0) {
+ free(instance);
+ return(NULL);
+ }
return (instance);
}
diff --git a/exec/totemcrypto.h b/exec/totemcrypto.h
index 13fd19b..14ef116 100644
--- a/exec/totemcrypto.h
+++ b/exec/totemcrypto.h
@@ -51,6 +51,7 @@ enum crypto_hash_t {
struct crypto_instance;
extern size_t crypto_sec_header_size(
+ const char *crypto_cipher_type,
const char *crypto_hash_type);
extern int crypto_authenticate_and_decrypt (
diff --git a/exec/totemudp.c b/exec/totemudp.c
index 21a6122..9f3acb9 100644
--- a/exec/totemudp.c
+++ b/exec/totemudp.c
@@ -259,26 +259,24 @@ static inline void ucast_sendmsg (
struct iovec iovec;
int addrlen;
- if (instance->totem_config->secauth == 1) {
+ /*
+ * Encrypt and digest the message
+ */
+ if (crypto_encrypt_and_sign (
+ instance->crypto_inst,
+ (const unsigned char *)msg,
+ msg_len,
+ buf_out,
+ &buf_out_len) != 0) {
/*
- * Encrypt and digest the message
+ * TODO: how to handle error here
*/
- if (crypto_encrypt_and_sign (
- instance->crypto_inst,
- (const unsigned char *)msg,
- msg_len,
- buf_out,
- &buf_out_len) != 0) {
- log_printf(LOGSYS_LEVEL_CRIT, "Unable to crypt? now what?");
- }
-
- iovec.iov_base = (void *)buf_out;
- iovec.iov_len = buf_out_len;
- } else {
- iovec.iov_base = (void *)msg;
- iovec.iov_len = msg_len;
+ log_printf(LOGSYS_LEVEL_CRIT, "Unable to crypt? now what?");
}
+ iovec.iov_base = (void *)buf_out;
+ iovec.iov_len = buf_out_len;
+
/*
* Build unicast message
*/
@@ -323,26 +321,24 @@ static inline void mcast_sendmsg (
struct sockaddr_storage sockaddr;
int addrlen;
- if (instance->totem_config->secauth == 1) {
+ /*
+ * Encrypt and digest the message
+ */
+ if (crypto_encrypt_and_sign (
+ instance->crypto_inst,
+ (const unsigned char *)msg,
+ msg_len,
+ buf_out,
+ &buf_out_len) != 0) {
/*
- * Encrypt and digest the message
+ * TODO: how to handle error here
*/
- if (crypto_encrypt_and_sign (
- instance->crypto_inst,
- (const unsigned char *)msg,
- msg_len,
- buf_out,
- &buf_out_len) != 0) {
- log_printf(LOGSYS_LEVEL_CRIT, "unable to crypt? now what?");
- }
-
- iovec.iov_base = (void *)&buf_out;
- iovec.iov_len = buf_out_len;
- } else {
- iovec.iov_base = (void *)msg;
- iovec.iov_len = msg_len;
+ log_printf(LOGSYS_LEVEL_CRIT, "unable to crypt? now what?");
}
+ iovec.iov_base = (void *)&buf_out;
+ iovec.iov_len = buf_out_len;
+
/*
* Build multicast message
*/
@@ -443,18 +439,16 @@ static int net_deliver_fn (
instance->stats_recv += bytes_received;
}
- if (instance->totem_config->secauth == 1) {
- /*
- * Authenticate and if authenticated, decrypt datagram
- */
- res = crypto_authenticate_and_decrypt (instance->crypto_inst, iovec->iov_base, &bytes_received);
- if (res == -1) {
- log_printf (instance->totemudp_log_level_security, "Received message has invalid digest... ignoring.");
- log_printf (instance->totemudp_log_level_security,
- "Invalid packet data");
- iovec->iov_len = FRAME_SIZE_MAX;
- return 0;
- }
+ /*
+ * Authenticate and if authenticated, decrypt datagram
+ */
+ res = crypto_authenticate_and_decrypt (instance->crypto_inst, iovec->iov_base, &bytes_received);
+ if (res == -1) {
+ log_printf (instance->totemudp_log_level_security, "Received message has invalid digest... ignoring.");
+ log_printf (instance->totemudp_log_level_security,
+ "Invalid packet data");
+ iovec->iov_len = FRAME_SIZE_MAX;
+ return 0;
}
iovec->iov_len = bytes_received;
@@ -1031,6 +1025,9 @@ int totemudp_initialize (
instance->totemudp_log_level_notice,
instance->totemudp_log_level_error,
instance->totemudp_subsys_id);
+ if (instance->crypto_inst == NULL) {
+ return (-1);
+ }
/*
* Initialize local variables for totemudp
*/
@@ -1179,12 +1176,9 @@ extern int totemudp_iface_check (void *udp_context)
extern void totemudp_net_mtu_adjust (void *udp_context, struct totem_config *totem_config)
{
#define UDPIP_HEADER_SIZE (20 + 8) /* 20 bytes for ip 8 bytes for udp */
- if (totem_config->secauth == 1) {
- totem_config->net_mtu -= crypto_sec_header_size(totem_config->crypto_hash_type) +
- UDPIP_HEADER_SIZE;
- } else {
- totem_config->net_mtu -= UDPIP_HEADER_SIZE;
- }
+ totem_config->net_mtu -= crypto_sec_header_size(totem_config->crypto_cipher_type,
+ totem_config->crypto_hash_type) +
+ UDPIP_HEADER_SIZE;
}
const char *totemudp_iface_print (void *udp_context) {
diff --git a/exec/totemudpu.c b/exec/totemudpu.c
index be4ca50..1b48d07 100644
--- a/exec/totemudpu.c
+++ b/exec/totemudpu.c
@@ -247,26 +247,24 @@ static inline void ucast_sendmsg (
struct iovec iovec;
int addrlen;
- if (instance->totem_config->secauth == 1) {
+ /*
+ * Encrypt and digest the message
+ */
+ if (crypto_encrypt_and_sign (
+ instance->crypto_inst,
+ (const unsigned char *)msg,
+ msg_len,
+ buf_out,
+ &buf_out_len) != 0) {
/*
- * Encrypt and digest the message
+ * TODO: how to handle error here
*/
- if (crypto_encrypt_and_sign (
- instance->crypto_inst,
- (const unsigned char *)msg,
- msg_len,
- buf_out,
- &buf_out_len) != 0) {
- log_printf(LOGSYS_LEVEL_CRIT, "unable to crypt? now what?");
- }
-
- iovec.iov_base = (void *)buf_out;
- iovec.iov_len = buf_out_len;
- } else {
- iovec.iov_base = (void *)msg;
- iovec.iov_len = msg_len;
+ log_printf(LOGSYS_LEVEL_CRIT, "unable to crypt? now what?");
}
+ iovec.iov_base = (void *)buf_out;
+ iovec.iov_len = buf_out_len;
+
/*
* Build unicast message
*/
@@ -312,26 +310,24 @@ static inline void mcast_sendmsg (
struct list_head *list;
struct totemudpu_member *member;
- if (instance->totem_config->secauth == 1) {
+ /*
+ * Encrypt and digest the message
+ */
+ if (crypto_encrypt_and_sign (
+ instance->crypto_inst,
+ (const unsigned char *)msg,
+ msg_len,
+ buf_out,
+ &buf_out_len) != 0) {
/*
- * Encrypt and digest the message
+ * TODO: how to handle error here
*/
- if(crypto_encrypt_and_sign (
- instance->crypto_inst,
- (const unsigned char *)msg,
- msg_len,
- buf_out,
- &buf_out_len) != 0) {
- log_printf(LOGSYS_LEVEL_CRIT, "Unable to crypt? now what?");
- }
-
- iovec.iov_base = (void *)buf_out;
- iovec.iov_len = buf_out_len;
- } else {
- iovec.iov_base = (void *)msg;
- iovec.iov_len = msg_len;
+ log_printf(LOGSYS_LEVEL_CRIT, "Unable to crypt? now what?");
}
+ iovec.iov_base = (void *)buf_out;
+ iovec.iov_len = buf_out_len;
+
/*
* Build multicast message
*/
@@ -422,19 +418,17 @@ static int net_deliver_fn (
instance->stats_recv += bytes_received;
}
- if (instance->totem_config->secauth == 1) {
- /*
- * Authenticate and if authenticated, decrypt datagram
- */
+ /*
+ * Authenticate and if authenticated, decrypt datagram
+ */
- res = crypto_authenticate_and_decrypt (instance->crypto_inst, iovec->iov_base, &bytes_received);
- if (res == -1) {
- log_printf (instance->totemudpu_log_level_security, "Received message has invalid digest... ignoring.");
- log_printf (instance->totemudpu_log_level_security,
- "Invalid packet data");
- iovec->iov_len = FRAME_SIZE_MAX;
- return 0;
- }
+ res = crypto_authenticate_and_decrypt (instance->crypto_inst, iovec->iov_base, &bytes_received);
+ if (res == -1) {
+ log_printf (instance->totemudpu_log_level_security, "Received message has invalid digest... ignoring.");
+ log_printf (instance->totemudpu_log_level_security,
+ "Invalid packet data");
+ iovec->iov_len = FRAME_SIZE_MAX;
+ return 0;
}
iovec->iov_len = bytes_received;
@@ -751,7 +745,9 @@ int totemudpu_initialize (
instance->totemudpu_log_level_notice,
instance->totemudpu_log_level_error,
instance->totemudpu_subsys_id);
-
+ if (instance->crypto_inst == NULL) {
+ return (-1);
+ }
/*
* Initialize local variables for totemudpu
*/
@@ -884,12 +880,9 @@ extern int totemudpu_iface_check (void *udpu_context)
extern void totemudpu_net_mtu_adjust (void *udpu_context, struct totem_config *totem_config)
{
#define UDPIP_HEADER_SIZE (20 + 8) /* 20 bytes for ip 8 bytes for udp */
- if (totem_config->secauth == 1) {
- totem_config->net_mtu -= crypto_sec_header_size(totem_config->crypto_hash_type) +
- UDPIP_HEADER_SIZE;
- } else {
- totem_config->net_mtu -= UDPIP_HEADER_SIZE;
- }
+ totem_config->net_mtu -= crypto_sec_header_size(totem_config->crypto_cipher_type,
+ totem_config->crypto_hash_type) +
+ UDPIP_HEADER_SIZE;
}
const char *totemudpu_iface_print (void *udpu_context) {
diff --git a/include/corosync/totem/totem.h b/include/corosync/totem/totem.h
index eba3850..08a459e 100644
--- a/include/corosync/totem/totem.h
+++ b/include/corosync/totem/totem.h
@@ -151,8 +151,6 @@ struct totem_config {
struct totem_logging_configuration totem_logging_configuration;
- unsigned int secauth;
-
unsigned int net_mtu;
unsigned int threads;