From: "Fabio M. Di Nitto" <fdinitto@xxxxxxxxxx> - cleanup include list - reorder code and functions (crypto then hash) - split crypt/decrypt/hash functions - some micro optimizations by dropping a few memcpy - make the code more readable (better var names and buffers mapping) - improve exit paths on error (return codes and free) - store crypto header size instead of recalculating it per packet Signed-off-by: Fabio M. Di Nitto <fdinitto@xxxxxxxxxx> --- exec/totemcrypto.c | 632 +++++++++++++++++++++++++--------------------------- 1 files changed, 304 insertions(+), 328 deletions(-) diff --git a/exec/totemcrypto.c b/exec/totemcrypto.c index 8b21533..49ed00e 100644 --- a/exec/totemcrypto.c +++ b/exec/totemcrypto.c @@ -6,6 +6,7 @@ * Author: Steven Dake (sdake@xxxxxxxxxx) * Christine Caulfield (ccaulfie@xxxxxxxxxx) * Jan Friesse (jfriesse@xxxxxxxxxx) + * Fabio M. Di Nitto (fdinitto@xxxxxxxxxx) * * This software licensed under BSD license, the text of which follows: * @@ -34,42 +35,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#include <config.h> - -#include <assert.h> -#include <pthread.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <netdb.h> -#include <sys/un.h> -#include <sys/ioctl.h> -#include <sys/param.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <sched.h> -#include <time.h> -#include <sys/time.h> -#include <sys/poll.h> -#include <limits.h> - -#include <corosync/sq.h> -#include <corosync/swab.h> -#include <corosync/list.h> -#include <qb/qbdefs.h> -#include <qb/qbloop.h> -#define LOGSYS_UTILS_ONLY 1 -#include <corosync/logsys.h> -#include <corosync/totem/totem.h> -#include "totemcrypto.h" - -#include "util.h" +#include "config.h" #include <nss.h> #include <pk11pub.h> @@ -78,7 +44,14 @@ #include <blapit.h> #include <hasht.h> -#define SALT_SIZE 16 +#define LOGSYS_UTILS_ONLY 1 +#include <corosync/logsys.h> +#include <corosync/totem/totem.h> +#include "totemcrypto.h" + +/* + * define onwire crypto header + */ struct crypto_config_header { uint8_t crypto_cipher_type; @@ -87,6 +60,12 @@ struct crypto_config_header { uint8_t __pad1; } __attribute__((packed)); +/* + * crypto definitions and conversion tables + */ + +#define SALT_SIZE 16 + enum crypto_crypt_t { CRYPTO_CIPHER_TYPE_NONE = 0, CRYPTO_CIPHER_TYPE_AES256 = 1 @@ -107,6 +86,10 @@ size_t cypher_block_len[] = { AES_BLOCK_SIZE /* CRYPTO_CIPHER_TYPE_AES256 */ }; +/* + * hash definitions and conversion tables + */ + enum crypto_hash_t { CRYPTO_HASH_TYPE_NONE = 0, CRYPTO_HASH_TYPE_MD5 = 1, @@ -155,6 +138,8 @@ struct crypto_instance { enum crypto_hash_t crypto_hash_type; + unsigned int crypto_header_size; + void (*log_printf_func) ( int level, int subsys, @@ -178,117 +163,73 @@ do { \ (const char *)format, ##args); \ } while (0); -#define LOGSYS_PERROR(err_num, level, fmt, args...) \ -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, \ - __FUNCTION__, __FILE__, __LINE__, \ - fmt ": %s (%d)", ##args, _error_ptr, err_num); \ -} while(0) - -static int init_nss_crypto(struct crypto_instance *instance, - const char *crypto_cipher_type, - const char *crypto_hash_type) +/* + * crypt/decrypt functions + */ + +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_AES256; +} + +static int init_nss_crypto(struct crypto_instance *instance) { 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"); + if (!cipher_to_nss[instance->crypto_cipher_type]) { return 0; } - log_printf(instance->log_level_notice, - "Initializing transmit/receive security: NSS crypto: %s hash: %s", - crypto_cipher_type, crypto_hash_type); + crypt_param.type = siBuffer; + crypt_param.data = instance->private_key; + crypt_param.len = cipher_key_len[instance->crypto_cipher_type]; - if (NSS_NoDB_Init(".") != SECSuccess) { - log_printf(instance->log_level_security, "NSS initialization failed (err %d)", + 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; - } - - 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; - } + return -1; } - 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 = 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()); + return -1; } return 0; -out: - return -1; } -static int encrypt_and_sign_nss ( +static int encrypt_nss( struct crypto_instance *instance, const unsigned char *buf_in, const size_t buf_in_len, unsigned char *buf_out, size_t *buf_out_len) { - PK11Context* enc_context = NULL; + PK11Context* crypt_context = NULL; SECItem crypt_param; - SECItem hash_param; SECItem *nss_sec_param = NULL; - - unsigned char *outdata; int tmp1_outlen = 0; unsigned int tmp2_outlen = 0; - - unsigned char salt[SALT_SIZE]; - unsigned char hash_block[hash_block_len[instance->crypto_hash_type]]; - - outdata = buf_out + hash_len[instance->crypto_hash_type]; + unsigned char *salt = buf_out; + unsigned char *data = buf_out + SALT_SIZE; + int err = -1; if (!cipher_to_nss[instance->crypto_cipher_type]) { - memcpy(outdata, buf_in, buf_in_len); + memcpy(buf_out, buf_in, buf_in_len); *buf_out_len = buf_in_len; - goto only_hash; + return 0; } if (PK11_GenerateRandom (salt, SALT_SIZE) != SECSuccess) { @@ -297,7 +238,6 @@ static int encrypt_and_sign_nss ( PR_GetError()); goto out; } - memcpy(outdata, salt, SALT_SIZE); crypt_param.type = siBuffer; crypt_param.data = salt; @@ -315,11 +255,11 @@ static int encrypt_and_sign_nss ( /* * 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); - if (!enc_context) { + crypt_context = PK11_CreateContextBySymKey (cipher_to_nss[instance->crypto_cipher_type], + CKA_ENCRYPT, + instance->nss_sym_key, + nss_sec_param); + if (!crypt_context) { log_printf(instance->log_level_security, "PK11_CreateContext failed (encrypt) crypt_type=%d (err %d)", (int)cipher_to_nss[instance->crypto_cipher_type], @@ -327,9 +267,9 @@ static int encrypt_and_sign_nss ( goto out; } - if (PK11_CipherOp(enc_context, outdata + SALT_SIZE, + if (PK11_CipherOp(crypt_context, data, &tmp1_outlen, - FRAME_SIZE_MAX - (sizeof(struct crypto_config_header) + hash_len[instance->crypto_hash_type] + SALT_SIZE), + FRAME_SIZE_MAX - instance->crypto_header_size, (unsigned char *)buf_in, buf_in_len) != SECSuccess) { log_printf(instance->log_level_security, "PK11_CipherOp failed (encrypt) crypt_type=%d (err %d)", @@ -337,7 +277,8 @@ static int encrypt_and_sign_nss ( PR_GetError()); goto out; } - if (PK11_DigestFinal(enc_context, outdata + SALT_SIZE + tmp1_outlen, + + if (PK11_DigestFinal(crypt_context, data + 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)", @@ -347,260 +288,317 @@ static int encrypt_and_sign_nss ( } - if (enc_context) { - PK11_DestroyContext(enc_context, PR_TRUE); - enc_context = 0; - } - *buf_out_len = tmp1_outlen + tmp2_outlen + SALT_SIZE; -only_hash: + err = 0; - if (!hash_to_nss[instance->crypto_hash_type]) { - goto no_hash; +out: + if (crypt_context) { + PK11_DestroyContext(crypt_context, PR_TRUE); } + if (nss_sec_param) { + SECITEM_FreeItem(nss_sec_param, PR_TRUE); + } + return err; +} - /* Now do the digest */ - hash_param.type = siBuffer; - hash_param.data = 0; - hash_param.len = 0; +static int decrypt_nss ( + struct crypto_instance *instance, + unsigned char *buf, + int *buf_len) +{ + PK11Context* decrypt_context = NULL; + SECItem decrypt_param; + int tmp1_outlen = 0; + unsigned int tmp2_outlen = 0; + unsigned char *salt = buf; + unsigned char *data = salt + SALT_SIZE; + int datalen = *buf_len - SALT_SIZE; + unsigned char outbuf[FRAME_SIZE_MAX]; + int outbuf_len; + int err = -1; - enc_context = PK11_CreateContextBySymKey(hash_to_nss[instance->crypto_hash_type], - CKA_SIGN, - instance->nss_sym_key_sign, - &hash_param); - if (!enc_context) { - 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 (!cipher_to_nss[instance->crypto_cipher_type]) { + return 0; } - if (PK11_DigestBegin(enc_context) != SECSuccess) { + /* Create cipher context for decryption */ + decrypt_param.type = siBuffer; + decrypt_param.data = salt; + decrypt_param.len = SALT_SIZE; + + decrypt_context = PK11_CreateContextBySymKey(cipher_to_nss[instance->crypto_cipher_type], + CKA_DECRYPT, + instance->nss_sym_key, &decrypt_param); + if (!decrypt_context) { log_printf(instance->log_level_security, - "PK11_DigestBegin failed (hash) hash_type=%d (err %d)", - (int)hash_to_nss[instance->crypto_hash_type], + "PK11_CreateContext (decrypt) failed (err %d)", PR_GetError()); goto out; } - if (PK11_DigestOp(enc_context, - outdata, - *buf_out_len) != SECSuccess) { + if (PK11_CipherOp(decrypt_context, outbuf, &tmp1_outlen, + sizeof(outbuf), data, datalen) != SECSuccess) { log_printf(instance->log_level_security, - "PK11_DigestOp failed (hash) hash_type=%d (err %d)", - (int)hash_to_nss[instance->crypto_hash_type], + "PK11_CipherOp (decrypt) failed (err %d)", PR_GetError()); goto out; } - if (PK11_DigestFinal(enc_context, - hash_block, - &tmp2_outlen, - hash_block_len[instance->crypto_hash_type]) != SECSuccess) { + + if (PK11_DigestFinal(decrypt_context, outbuf + tmp1_outlen, &tmp2_outlen, + sizeof(outbuf) - tmp1_outlen) != 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()); + "PK11_DigestFinal (decrypt) failed (err %d)", + PR_GetError()); goto out; } - if (enc_context) { - PK11_DestroyContext(enc_context, PR_TRUE); - enc_context = 0; - } - - memcpy(buf_out, hash_block, hash_len[instance->crypto_hash_type]); + outbuf_len = tmp1_outlen + tmp2_outlen; - *buf_out_len = *buf_out_len + hash_len[instance->crypto_hash_type]; + memset(buf, 0, *buf_len); + memcpy(buf, outbuf, outbuf_len); -no_hash: + *buf_len = outbuf_len; - SECITEM_FreeItem(nss_sec_param, PR_TRUE); - - return 0; + err = 0; out: - if (enc_context) { - PK11_DestroyContext(enc_context, PR_TRUE); + if (decrypt_context) { + PK11_DestroyContext(decrypt_context, PR_TRUE); } - if (nss_sec_param) { - SECITEM_FreeItem(nss_sec_param, PR_TRUE); + + return err; +} + + +/* + * hash/hmac/digest functions + */ + +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, "md5") == 0) { + return CRYPTO_HASH_TYPE_MD5; + } else if (strcmp(crypto_hash_type, "sha1") == 0) { + return CRYPTO_HASH_TYPE_SHA1; + } else if (strcmp(crypto_hash_type, "sha256") == 0) { + return CRYPTO_HASH_TYPE_SHA256; + } else if (strcmp(crypto_hash_type, "sha384") == 0) { + return CRYPTO_HASH_TYPE_SHA384; + } else if (strcmp(crypto_hash_type, "sha512") == 0) { + return CRYPTO_HASH_TYPE_SHA512; } - return -1; + + return CRYPTO_HASH_TYPE_SHA1; } -static int authenticate_and_decrypt_nss ( - struct crypto_instance *instance, - unsigned char *buf, - int *buf_len) +static int init_nss_hash(struct crypto_instance *instance) { - PK11Context* enc_context = NULL; - SECItem crypt_param; + PK11SlotInfo* hash_slot = NULL; SECItem hash_param; - unsigned char hash_block[hash_block_len[instance->crypto_hash_type]]; - int tmp1_outlen = 0; - unsigned int tmp2_outlen = 0; + if (!hash_to_nss[instance->crypto_hash_type]) { + return 0; + } - unsigned char *data; - size_t datalen; + hash_param.type = siBuffer; + hash_param.data = 0; + hash_param.len = 0; - unsigned char outbuf[FRAME_SIZE_MAX]; + 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()); + return -1; + } - int result_len; + 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()); + return -1; + } - data = buf + hash_len[instance->crypto_hash_type]; - datalen = *buf_len - hash_len[instance->crypto_hash_type]; + return 0; +} - if (!hash_to_nss[instance->crypto_hash_type]) { - goto only_decrypt; - } +static int calculate_nss_hash( + struct crypto_instance *instance, + const unsigned char *buf, + const size_t buf_len, + unsigned char *hash) +{ + PK11Context* hash_context = NULL; + SECItem hash_param; + unsigned int hash_tmp_outlen = 0; + unsigned char hash_block[hash_block_len[instance->crypto_hash_type]]; + int err = -1; + /* Now do the digest */ 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, - &hash_param); - if (!enc_context) { + hash_context = PK11_CreateContextBySymKey(hash_to_nss[instance->crypto_hash_type], + CKA_SIGN, + instance->nss_sym_key_sign, + &hash_param); + + if (!hash_context) { log_printf(instance->log_level_security, - "PK11_CreateContext failed (check digest) err %d", + "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) { + if (PK11_DigestBegin(hash_context) != SECSuccess) { log_printf(instance->log_level_security, - "PK11_DigestBegin failed (check digest) err %d", - PR_GetError()); + "PK11_DigestBegin failed (hash) hash_type=%d (err %d)", + (int)hash_to_nss[instance->crypto_hash_type], + PR_GetError()); goto out; } - if (PK11_DigestOp(enc_context, data, datalen) != SECSuccess) { + if (PK11_DigestOp(hash_context, + buf, + buf_len) != SECSuccess) { log_printf(instance->log_level_security, - "PK11_DigestOp failed (check digest) err %d", + "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, hash_block, - &tmp2_outlen, hash_block_len[instance->crypto_hash_type]) != SECSuccess) { + if (PK11_DigestFinal(hash_context, + hash_block, + &hash_tmp_outlen, + hash_block_len[instance->crypto_hash_type]) != SECSuccess) { log_printf(instance->log_level_security, - "PK11_DigestFinal failed (check digest) err %d", + "PK11_DigestFinale failed (hash) hash_type=%d (err %d)", + (int)hash_to_nss[instance->crypto_hash_type], PR_GetError()); goto out; } - if (enc_context) { - PK11_DestroyContext(enc_context, PR_TRUE); - enc_context = 0; - } + memcpy(hash, hash_block, hash_len[instance->crypto_hash_type]); + err = 0; - if (memcmp(hash_block, buf, tmp2_outlen) != 0) { - log_printf(instance->log_level_error, "Digest does not match"); - goto out; +out: + if (hash_context) { + PK11_DestroyContext(hash_context, PR_TRUE); } -only_decrypt: - - if (!cipher_to_nss[instance->crypto_cipher_type]) { - memcpy(outbuf, data, datalen); - result_len = datalen; - goto no_decrypt; - } + return err; +} - /* Create cipher context for decryption */ - crypt_param.type = siBuffer; - crypt_param.data = data; - crypt_param.len = SALT_SIZE; +/* + * global/glue nss functions + */ - /* - * Get rid of salt - */ - data += SALT_SIZE; - datalen -= SALT_SIZE; +static int init_nss_db(struct crypto_instance *instance) +{ + if ((!cipher_to_nss[instance->crypto_cipher_type]) && + (!hash_to_nss[instance->crypto_hash_type])) { + return 0; + } - 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)", + if (NSS_NoDB_Init(".") != SECSuccess) { + log_printf(instance->log_level_security, "NSS DB initialization failed (err %d)", PR_GetError()); - goto out; + return -1; } - if (PK11_CipherOp(enc_context, outbuf, &tmp1_outlen, - sizeof(outbuf), data, datalen) != SECSuccess) { - log_printf(instance->log_level_security, - "PK11_CipherOp (decrypt) failed (err %d)", - PR_GetError()); - goto out; + return 0; +} + +static int init_nss(struct crypto_instance *instance, + const char *crypto_cipher_type, + const char *crypto_hash_type) +{ + log_printf(instance->log_level_notice, + "Initializing transmit/receive security (NSS) crypto: %s hash: %s", + crypto_cipher_type, crypto_hash_type); + + if (init_nss_db(instance) < 0) { + return -1; } - if (PK11_DigestFinal(enc_context, outbuf + 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; + + if (init_nss_crypto(instance) < 0) { + return -1; } - if (enc_context) { - PK11_DestroyContext(enc_context, PR_TRUE); - enc_context = 0; + if (init_nss_hash(instance) < 0) { + return -1; } - result_len = tmp1_outlen + tmp2_outlen; + return 0; +} -no_decrypt: +static int encrypt_and_sign_nss ( + struct crypto_instance *instance, + const unsigned char *buf_in, + const size_t buf_in_len, + unsigned char *buf_out, + size_t *buf_out_len) +{ + unsigned char *hash = buf_out; + unsigned char *data = hash + hash_len[instance->crypto_hash_type]; - memset(buf, 0, *buf_len); - memcpy(buf, outbuf, result_len); + if (encrypt_nss(instance, buf_in, buf_in_len, data, buf_out_len) < 0) { + return -1; + } - *buf_len = result_len; + if (hash_to_nss[instance->crypto_hash_type]) { + if (calculate_nss_hash(instance, data, *buf_out_len, hash) < 0) { + return -1; + } + *buf_out_len = *buf_out_len + hash_len[instance->crypto_hash_type]; + } return 0; - -out: - if (enc_context) { - PK11_DestroyContext(enc_context, PR_TRUE); - } - return -1; } -static int string_to_crypto_cipher_type(const char* crypto_cipher_type) +static int authenticate_and_decrypt_nss ( + struct crypto_instance *instance, + unsigned char *buf, + int *buf_len) { - 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; + if (hash_to_nss[instance->crypto_hash_type]) { + unsigned char tmp_hash[hash_len[instance->crypto_hash_type]]; + unsigned char *hash = buf; + unsigned char *data = hash + hash_len[instance->crypto_hash_type]; + int datalen = *buf_len - hash_len[instance->crypto_hash_type]; + + if (calculate_nss_hash(instance, data, datalen, tmp_hash) < 0) { + return -1; + } + + if (memcmp(tmp_hash, hash, hash_len[instance->crypto_hash_type]) != 0) { + log_printf(instance->log_level_error, "Digest does not match"); + return -1; + } + + memmove(buf, data, datalen); + *buf_len = datalen; } - return CRYPTO_CIPHER_TYPE_AES256; -} -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, "md5") == 0) { - return CRYPTO_HASH_TYPE_MD5; - } else if (strcmp(crypto_hash_type, "sha1") == 0) { - return CRYPTO_HASH_TYPE_SHA1; - } else if (strcmp(crypto_hash_type, "sha256") == 0) { - return CRYPTO_HASH_TYPE_SHA256; - } else if (strcmp(crypto_hash_type, "sha384") == 0) { - return CRYPTO_HASH_TYPE_SHA384; - } else if (strcmp(crypto_hash_type, "sha512") == 0) { - return CRYPTO_HASH_TYPE_SHA512; + if (decrypt_nss(instance, buf, buf_len) < 0) { + return -1; } - return CRYPTO_HASH_TYPE_SHA1; + return 0; } +/* + * exported API + */ + size_t crypto_sec_header_size( const char *crypto_cipher_type, const char *crypto_hash_type) @@ -630,26 +628,19 @@ int crypto_encrypt_and_sign ( unsigned char *buf_out, size_t *buf_out_len) { - int err = 0; - struct crypto_config_header *cch; + struct crypto_config_header *cch = (struct crypto_config_header *)buf_out; + int err; - cch = (struct crypto_config_header *)buf_out; cch->crypto_cipher_type = instance->crypto_cipher_type; cch->crypto_hash_type = instance->crypto_hash_type; cch->__pad0 = 0; cch->__pad1 = 0; - if ((!cipher_to_nss[instance->crypto_cipher_type]) && - (!hash_to_nss[instance->crypto_hash_type])) { - memcpy(buf_out + sizeof(struct crypto_config_header), buf_in, buf_in_len); - *buf_out_len = buf_in_len; - err = 0; - } else { - err = encrypt_and_sign_nss(instance, - buf_in, buf_in_len, - buf_out + sizeof(struct crypto_config_header), - buf_out_len); - } + buf_out += sizeof(struct crypto_config_header); + + err = encrypt_and_sign_nss(instance, + buf_in, buf_in_len, + buf_out, buf_out_len); *buf_out_len = *buf_out_len + sizeof(struct crypto_config_header); @@ -661,9 +652,7 @@ int crypto_authenticate_and_decrypt (struct crypto_instance *instance, int *buf_len) { int err = 0; - struct crypto_config_header *cch; - - cch = (struct crypto_config_header *)buf; + struct crypto_config_header *cch = (struct crypto_config_header *)buf; /* * decode crypto config of incoming packets @@ -688,28 +677,13 @@ int crypto_authenticate_and_decrypt (struct crypto_instance *instance, } /* - * invalidate config header + * invalidate config header and kill it */ cch = NULL; - - /* - * and kill it - */ - *buf_len = *buf_len - sizeof(struct crypto_config_header); + *buf_len -= sizeof(struct crypto_config_header); memmove(buf, buf + sizeof(struct crypto_config_header), *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])) { - err = 0; - } else { - err = authenticate_and_decrypt_nss(instance, buf, buf_len); - } - - return err; + return authenticate_and_decrypt_nss(instance, buf, buf_len); } struct crypto_instance *crypto_init( @@ -743,13 +717,15 @@ struct crypto_instance *crypto_init( 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->crypto_header_size = crypto_sec_header_size(crypto_cipher_type, crypto_hash_type); + instance->log_printf_func = log_printf_func; instance->log_level_security = log_level_security; instance->log_level_notice = log_level_notice; instance->log_level_error = log_level_error; instance->log_subsys_id = log_subsys_id; - if (init_nss_crypto(instance, crypto_cipher_type, crypto_hash_type) < 0) { + if (init_nss(instance, crypto_cipher_type, crypto_hash_type) < 0) { free(instance); return(NULL); } -- 1.7.7.6 _______________________________________________ discuss mailing list discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss