Re: [PATCH 1/2] Rename totemcrypto

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



ACK

On 3/13/2012 5:23 PM, Jan Friesse wrote:
> Signed-off-by: Jan Friesse <jfriesse@xxxxxxxxxx>
> ---
>  exec/Makefile.am   |    4 +-
>  exec/crypto.c      |  484 ----------------------------------------------------
>  exec/crypto.h      |   76 --------
>  exec/totemcrypto.c |  484 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  exec/totemcrypto.h |   76 ++++++++
>  exec/totemudp.c    |    2 +-
>  exec/totemudpu.c   |    2 +-
>  7 files changed, 564 insertions(+), 564 deletions(-)
>  delete mode 100644 exec/crypto.c
>  delete mode 100644 exec/crypto.h
>  create mode 100644 exec/totemcrypto.c
>  create mode 100644 exec/totemcrypto.h
> 
> diff --git a/exec/Makefile.am b/exec/Makefile.am
> index 0db4db6..9075bcd 100644
> --- a/exec/Makefile.am
> +++ b/exec/Makefile.am
> @@ -37,7 +37,7 @@ INCLUDES		= -I$(top_builddir)/include -I$(top_srcdir)/include $(nss_CFLAGS) $(rd
>  
>  TOTEM_SRC		= totemip.c totemnet.c totemudp.c \
>  			  totemudpu.c totemrrp.c totemsrp.c totemmrp.c \
> -			  totempg.c cs_queue.h crypto.c
> +			  totempg.c cs_queue.h totemcrypto.c
>  if BUILD_RDMA
>  TOTEM_SRC		+= totemiba.c
>  endif
> @@ -66,7 +66,7 @@ noinst_HEADERS		= apidef.h mainconfig.h main.h \
>  			  quorum.h service.h timer.h totemconfig.h \
>  			  totemmrp.h totemnet.h totemudp.h totemiba.h totemrrp.h \
>  			  totemudpu.h totemsrp.h util.h vsf.h schedwrk.h \
> -			  sync.h fsm.h votequorum.h vsf_ykd.h crypto.h
> +			  sync.h fsm.h votequorum.h vsf_ykd.h totemcrypto.h
>  
>  if BUILD_DARWIN
>  libtotem_pg.so.$(SONAME): $(TOTEM_OBJS)
> diff --git a/exec/crypto.c b/exec/crypto.c
> deleted file mode 100644
> index 2c6b9ef..0000000
> --- a/exec/crypto.c
> +++ /dev/null
> @@ -1,484 +0,0 @@
> -/*
> - * Copyright (c) 2006-2012 Red Hat, Inc.
> - *
> - * All rights reserved.
> - *
> - * Author: Steven Dake (sdake@xxxxxxxxxx)
> - *         Christine Caulfield (ccaulfie@xxxxxxxxxx)
> - *         Jan Friesse (jfriesse@xxxxxxxxxx)
> - *
> - * This software licensed under BSD license, the text of which follows:
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - * - Redistributions of source code must retain the above copyright notice,
> - *   this list of conditions and the following disclaimer.
> - * - Redistributions in binary form must reproduce the above copyright notice,
> - *   this list of conditions and the following disclaimer in the documentation
> - *   and/or other materials provided with the distribution.
> - * - Neither the name of the MontaVista Software, Inc. nor the names of its
> - *   contributors may be used to endorse or promote products derived from this
> - *   software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> - * 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 "crypto.h"
> -
> -#include "util.h"
> -
> -#include <nss.h>
> -#include <pk11pub.h>
> -#include <pkcs11.h>
> -#include <prerror.h>
> -
> -#define CRYPTO_HMAC_HASH_SIZE 20
> -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 */
> -	char msg[0];
> -} __attribute__((packed));
> -
> -struct crypto_instance {
> -	PK11SymKey   *nss_sym_key;
> -	PK11SymKey   *nss_sym_key_sign;
> -
> -	unsigned char private_key[1024];
> -
> -	unsigned int private_key_len;
> -
> -	int crypto_crypt_type;
> -
> -	int crypto_hash_type;
> -
> -	void (*log_printf_func) (
> -		int level,
> -		int subsys,
> -		const char *function,
> -		const char *file,
> -		int line,
> -		const char *format,
> -		...)__attribute__((format(printf, 6, 7)));
> -
> -	int log_level_security;
> -	int log_level_notice;
> -	int log_level_error;
> -	int log_subsys_id;
> -};
> -
> -#define log_printf(level, format, args...)				\
> -do {									\
> -        instance->log_printf_func (					\
> -		level, instance->log_subsys_id,			\
> -                __FUNCTION__, __FILE__, __LINE__,			\
> -		(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 void init_nss_crypto(struct crypto_instance *instance)
> -{
> -	PK11SlotInfo*      aes_slot = NULL;
> -	PK11SlotInfo*      sha1_slot = NULL;
> -	SECItem            key_item;
> -	SECStatus          rv;
> -
> -	log_printf(instance->log_level_notice,
> -		"Initializing transmit/receive security: NSS AES256CBC/SHA1HMAC (mode %u).", 0);
> -	rv = NSS_NoDB_Init(".");
> -	if (rv != SECSuccess)
> -	{
> -		log_printf(instance->log_level_security, "NSS initialization failed (err %d)",
> -			PR_GetError());
> -		goto out;
> -	}
> -
> -	/*
> -	 * TODO: use instance info!
> -	 */
> -	aes_slot = PK11_GetBestSlot(CKM_AES_CBC_PAD, NULL);
> -	if (aes_slot == NULL)
> -	{
> -		log_printf(instance->log_level_security, "Unable to find security slot (err %d)",
> -			PR_GetError());
> -		goto out;
> -	}
> -
> -	sha1_slot = PK11_GetBestSlot(CKM_SHA_1_HMAC, 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 = 32; /* Use 256 bits */
> -
> -	instance->nss_sym_key = PK11_ImportSymKey(aes_slot,
> -		CKM_AES_CBC_PAD,
> -		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;
> -	}
> -
> -	instance->nss_sym_key_sign = PK11_ImportSymKey(sha1_slot,
> -		CKM_SHA_1_HMAC,
> -		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;
> -	}
> -out:
> -	return;
> -}
> -
> -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)
> -{
> -	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;
> -
> -	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) {
> -		log_printf(instance->log_level_security,
> -			"Failure to generate a random number %d",
> -			PR_GetError());
> -	}
> -
> -	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);
> -
> -	nss_sec_param = PK11_ParamFromIV (
> -		CKM_AES_CBC_PAD,
> -		&iv_item);
> -	if (nss_sec_param == NULL) {
> -		log_printf(instance->log_level_security,
> -			"Failure to set up PKCS11 param (err %d)",
> -			PR_GetError());
> -		return (-1);
> -	}
> -
> -	/*
> -	 * Create cipher context for encryption
> -	 */
> -	enc_context = PK11_CreateContextBySymKey (
> -		CKM_AES_CBC_PAD,
> -		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",
> -			CKM_AES_CBC_PAD,
> -			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_DestroyContext(enc_context, PR_TRUE);
> -
> -	*buf_out_len = tmp1_outlen + tmp2_outlen;
> -
> -	if (rv1 != SECSuccess || rv2 != SECSuccess)
> -		goto out;
> -
> -	/* Now do the digest */
> -	enc_context = PK11_CreateContextBySymKey(CKM_SHA_1_HMAC,
> -		CKA_SIGN, instance->nss_sym_key_sign, &no_params);
> -	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;
> -	}
> -
> -
> -	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));
> -
> -	PK11_DestroyContext(enc_context, PR_TRUE);
> -
> -	if (rv1 != SECSuccess || rv2 != SECSuccess)
> -		goto out;
> -
> -
> -	*buf_out_len = *buf_out_len + sizeof(struct crypto_security_header);
> -	SECITEM_FreeItem(nss_sec_param, PR_TRUE);
> -	return 0;
> -
> -out:
> -	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;
> -	datalen = *buf_len;
> -	data = inbuf + sizeof (struct crypto_security_header) - 16;
> -	datalen = datalen - sizeof (struct crypto_security_header) + 16;
> -
> -	outdata = outbuf + sizeof (struct crypto_security_header);
> -
> -	/* Check the digest */
> -	enc_context = PK11_CreateContextBySymKey (
> -		CKM_SHA_1_HMAC, CKA_SIGN,
> -		instance->nss_sym_key_sign,
> -		&no_params);
> -	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;
> -	}
> -
> -	PK11_DigestBegin(enc_context);
> -
> -	rv1 = PK11_DigestOp(enc_context, data, datalen);
> -	rv2 = PK11_DigestFinal(enc_context, digest, &tmp2_outlen, sizeof(digest));
> -
> -	PK11_DestroyContext(enc_context, PR_TRUE);
> -
> -	if (rv1 != SECSuccess || rv2 != SECSuccess) {
> -		log_printf(instance->log_level_security, "Digest check failed");
> -		return -1;
> -	}
> -
> -	if (memcmp(digest, header->hash_digest, tmp2_outlen) != 0) {
> -		log_printf(instance->log_level_error, "Digest does not match");
> -		return -1;
> -	}
> -
> -	/*
> -	 * Get rid of salt
> -	 */
> -	data += 16;
> -	datalen -= 16;
> -
> -	/* Create cipher context for decryption */
> -	ivdata.type = siBuffer;
> -	ivdata.data = header->salt;
> -	ivdata.len = sizeof(header->salt);
> -
> -	enc_context = PK11_CreateContextBySymKey(
> -		CKM_AES_CBC_PAD,
> -		CKA_DECRYPT,
> -		instance->nss_sym_key, &ivdata);
> -	if (!enc_context) {
> -		log_printf(instance->log_level_security,
> -			"PK11_CreateContext (decrypt) failed (err %d)",
> -			PR_GetError());
> -		return -1;
> -	}
> -
> -	rv1 = PK11_CipherOp(enc_context, outdata, &tmp1_outlen,
> -			    sizeof(outbuf) - sizeof (struct crypto_security_header),
> -			    data, datalen);
> -	if (rv1 != SECSuccess) {
> -		log_printf(instance->log_level_security,
> -			"PK11_CipherOp (decrypt) failed (err %d)",
> -			PR_GetError());
> -	}
> -	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);
> -
> -	memset(buf, 0, *buf_len);
> -	memcpy(buf, outdata, result_len);
> -
> -	*buf_len = result_len;
> -
> -	if (rv1 != SECSuccess || rv2 != SECSuccess)
> -		return -1;
> -
> -	return 0;
> -}
> -
> -size_t crypto_sec_header_size(int crypt_hash_type)
> -{
> -	/*
> -	 * TODO: add switch / size mapping
> -	 */
> -	return sizeof(struct crypto_security_header);
> -}
> -
> -int crypto_encrypt_and_sign (
> -	struct crypto_instance *instance,
> -	const unsigned char *buf_in,
> -	const size_t buf_in_len,
> -	unsigned char *buf_out,
> -	size_t *buf_out_len)
> -{
> -	return (encrypt_and_sign_nss(instance, buf_in, buf_in_len, buf_out, buf_out_len));
> -}
> -
> -int crypto_authenticate_and_decrypt (struct crypto_instance *instance,
> -	unsigned char *buf,
> -	int *buf_len)
> -{
> -	return (authenticate_and_decrypt_nss(instance, buf, buf_len));
> -}
> -
> -struct crypto_instance *crypto_init(
> -	const unsigned char *private_key,
> -	unsigned int private_key_len,
> -	int crypto_crypt_type,
> -	int crypto_hash_type,
> -	void (*log_printf_func) (
> -		int level,
> -		int subsys,
> -                const char *function,
> -                const char *file,
> -                int line,
> -                const char *format,
> -                ...)__attribute__((format(printf, 6, 7))),
> -	int log_level_security,
> -	int log_level_notice,
> -	int log_level_error,
> -	int log_subsys_id)
> -{
> -	struct crypto_instance *instance;
> -	instance = malloc(sizeof(*instance));
> -	if (instance == NULL) {
> -		return (NULL);
> -	}
> -	memset(instance, 0, sizeof(struct crypto_instance));
> -
> -	memcpy(instance->private_key, private_key, private_key_len);
> -	instance->private_key_len = private_key_len;
> -	instance->crypto_crypt_type = crypto_crypt_type;
> -	instance->crypto_hash_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;
> -
> -	init_nss_crypto(instance);
> -
> -	return (instance);
> -}
> diff --git a/exec/crypto.h b/exec/crypto.h
> deleted file mode 100644
> index 74c6434..0000000
> --- a/exec/crypto.h
> +++ /dev/null
> @@ -1,76 +0,0 @@
> -/*
> - * Copyright (c) 2006-2012 Red Hat, Inc.
> - *
> - * All rights reserved.
> - *
> - * Author: Steven Dake (sdake@xxxxxxxxxx)
> - *         Christine Caulfield (ccaulfie@xxxxxxxxxx)
> - *         Jan Friesse (jfriesse@xxxxxxxxxx)
> - *
> - * This software licensed under BSD license, the text of which follows:
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - * - Redistributions of source code must retain the above copyright notice,
> - *   this list of conditions and the following disclaimer.
> - * - Redistributions in binary form must reproduce the above copyright notice,
> - *   this list of conditions and the following disclaimer in the documentation
> - *   and/or other materials provided with the distribution.
> - * - Neither the name of the MontaVista Software, Inc. nor the names of its
> - *   contributors may be used to endorse or promote products derived from this
> - *   software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> - * THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -#ifndef CRYPTO_H_DEFINED
> -#define CRYPTO_H_DEFINED
> -
> -#include <sys/types.h>
> -
> -struct crypto_instance;
> -
> -extern size_t crypto_sec_header_size(
> -	int crypt_hash_type);
> -
> -extern int crypto_authenticate_and_decrypt (
> -	struct crypto_instance *instance,
> -	unsigned char *buf,
> -	int *buf_len);
> -
> -extern int crypto_encrypt_and_sign (
> -	struct crypto_instance *instance,
> -	const unsigned char *buf_in,
> -	const size_t buf_in_len,
> -	unsigned char *buf_out, 
> -	size_t *buf_out_len);
> -
> -extern struct crypto_instance *crypto_init(
> -	const unsigned char *private_key,
> -	unsigned int private_key_len,
> -	int crypto_crypt_type,
> -	int crypto_hash_type,
> -	void (*log_printf_func) (
> -		int level,
> -		int subsys,
> -		const char *function,
> -		const char *file,
> -		int line,
> -		const char *format,
> -		...)__attribute__((format(printf, 6, 7))),
> -	int log_level_security,
> -	int log_level_notice,
> -	int log_level_error,
> -	int log_subsys_id);
> -
> -#endif /* CRYPTO_H_DEFINED */
> diff --git a/exec/totemcrypto.c b/exec/totemcrypto.c
> new file mode 100644
> index 0000000..4ee839e
> --- /dev/null
> +++ b/exec/totemcrypto.c
> @@ -0,0 +1,484 @@
> +/*
> + * Copyright (c) 2006-2012 Red Hat, Inc.
> + *
> + * All rights reserved.
> + *
> + * Author: Steven Dake (sdake@xxxxxxxxxx)
> + *         Christine Caulfield (ccaulfie@xxxxxxxxxx)
> + *         Jan Friesse (jfriesse@xxxxxxxxxx)
> + *
> + * This software licensed under BSD license, the text of which follows:
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are met:
> + *
> + * - Redistributions of source code must retain the above copyright notice,
> + *   this list of conditions and the following disclaimer.
> + * - Redistributions in binary form must reproduce the above copyright notice,
> + *   this list of conditions and the following disclaimer in the documentation
> + *   and/or other materials provided with the distribution.
> + * - Neither the name of the MontaVista Software, Inc. nor the names of its
> + *   contributors may be used to endorse or promote products derived from this
> + *   software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> + * 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 <nss.h>
> +#include <pk11pub.h>
> +#include <pkcs11.h>
> +#include <prerror.h>
> +
> +#define CRYPTO_HMAC_HASH_SIZE 20
> +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 */
> +	char msg[0];
> +} __attribute__((packed));
> +
> +struct crypto_instance {
> +	PK11SymKey   *nss_sym_key;
> +	PK11SymKey   *nss_sym_key_sign;
> +
> +	unsigned char private_key[1024];
> +
> +	unsigned int private_key_len;
> +
> +	int crypto_crypt_type;
> +
> +	int crypto_hash_type;
> +
> +	void (*log_printf_func) (
> +		int level,
> +		int subsys,
> +		const char *function,
> +		const char *file,
> +		int line,
> +		const char *format,
> +		...)__attribute__((format(printf, 6, 7)));
> +
> +	int log_level_security;
> +	int log_level_notice;
> +	int log_level_error;
> +	int log_subsys_id;
> +};
> +
> +#define log_printf(level, format, args...)				\
> +do {									\
> +        instance->log_printf_func (					\
> +		level, instance->log_subsys_id,			\
> +                __FUNCTION__, __FILE__, __LINE__,			\
> +		(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 void init_nss_crypto(struct crypto_instance *instance)
> +{
> +	PK11SlotInfo*      aes_slot = NULL;
> +	PK11SlotInfo*      sha1_slot = NULL;
> +	SECItem            key_item;
> +	SECStatus          rv;
> +
> +	log_printf(instance->log_level_notice,
> +		"Initializing transmit/receive security: NSS AES256CBC/SHA1HMAC (mode %u).", 0);
> +	rv = NSS_NoDB_Init(".");
> +	if (rv != SECSuccess)
> +	{
> +		log_printf(instance->log_level_security, "NSS initialization failed (err %d)",
> +			PR_GetError());
> +		goto out;
> +	}
> +
> +	/*
> +	 * TODO: use instance info!
> +	 */
> +	aes_slot = PK11_GetBestSlot(CKM_AES_CBC_PAD, NULL);
> +	if (aes_slot == NULL)
> +	{
> +		log_printf(instance->log_level_security, "Unable to find security slot (err %d)",
> +			PR_GetError());
> +		goto out;
> +	}
> +
> +	sha1_slot = PK11_GetBestSlot(CKM_SHA_1_HMAC, 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 = 32; /* Use 256 bits */
> +
> +	instance->nss_sym_key = PK11_ImportSymKey(aes_slot,
> +		CKM_AES_CBC_PAD,
> +		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;
> +	}
> +
> +	instance->nss_sym_key_sign = PK11_ImportSymKey(sha1_slot,
> +		CKM_SHA_1_HMAC,
> +		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;
> +	}
> +out:
> +	return;
> +}
> +
> +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)
> +{
> +	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;
> +
> +	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) {
> +		log_printf(instance->log_level_security,
> +			"Failure to generate a random number %d",
> +			PR_GetError());
> +	}
> +
> +	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);
> +
> +	nss_sec_param = PK11_ParamFromIV (
> +		CKM_AES_CBC_PAD,
> +		&iv_item);
> +	if (nss_sec_param == NULL) {
> +		log_printf(instance->log_level_security,
> +			"Failure to set up PKCS11 param (err %d)",
> +			PR_GetError());
> +		return (-1);
> +	}
> +
> +	/*
> +	 * Create cipher context for encryption
> +	 */
> +	enc_context = PK11_CreateContextBySymKey (
> +		CKM_AES_CBC_PAD,
> +		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",
> +			CKM_AES_CBC_PAD,
> +			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_DestroyContext(enc_context, PR_TRUE);
> +
> +	*buf_out_len = tmp1_outlen + tmp2_outlen;
> +
> +	if (rv1 != SECSuccess || rv2 != SECSuccess)
> +		goto out;
> +
> +	/* Now do the digest */
> +	enc_context = PK11_CreateContextBySymKey(CKM_SHA_1_HMAC,
> +		CKA_SIGN, instance->nss_sym_key_sign, &no_params);
> +	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;
> +	}
> +
> +
> +	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));
> +
> +	PK11_DestroyContext(enc_context, PR_TRUE);
> +
> +	if (rv1 != SECSuccess || rv2 != SECSuccess)
> +		goto out;
> +
> +
> +	*buf_out_len = *buf_out_len + sizeof(struct crypto_security_header);
> +	SECITEM_FreeItem(nss_sec_param, PR_TRUE);
> +	return 0;
> +
> +out:
> +	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;
> +	datalen = *buf_len;
> +	data = inbuf + sizeof (struct crypto_security_header) - 16;
> +	datalen = datalen - sizeof (struct crypto_security_header) + 16;
> +
> +	outdata = outbuf + sizeof (struct crypto_security_header);
> +
> +	/* Check the digest */
> +	enc_context = PK11_CreateContextBySymKey (
> +		CKM_SHA_1_HMAC, CKA_SIGN,
> +		instance->nss_sym_key_sign,
> +		&no_params);
> +	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;
> +	}
> +
> +	PK11_DigestBegin(enc_context);
> +
> +	rv1 = PK11_DigestOp(enc_context, data, datalen);
> +	rv2 = PK11_DigestFinal(enc_context, digest, &tmp2_outlen, sizeof(digest));
> +
> +	PK11_DestroyContext(enc_context, PR_TRUE);
> +
> +	if (rv1 != SECSuccess || rv2 != SECSuccess) {
> +		log_printf(instance->log_level_security, "Digest check failed");
> +		return -1;
> +	}
> +
> +	if (memcmp(digest, header->hash_digest, tmp2_outlen) != 0) {
> +		log_printf(instance->log_level_error, "Digest does not match");
> +		return -1;
> +	}
> +
> +	/*
> +	 * Get rid of salt
> +	 */
> +	data += 16;
> +	datalen -= 16;
> +
> +	/* Create cipher context for decryption */
> +	ivdata.type = siBuffer;
> +	ivdata.data = header->salt;
> +	ivdata.len = sizeof(header->salt);
> +
> +	enc_context = PK11_CreateContextBySymKey(
> +		CKM_AES_CBC_PAD,
> +		CKA_DECRYPT,
> +		instance->nss_sym_key, &ivdata);
> +	if (!enc_context) {
> +		log_printf(instance->log_level_security,
> +			"PK11_CreateContext (decrypt) failed (err %d)",
> +			PR_GetError());
> +		return -1;
> +	}
> +
> +	rv1 = PK11_CipherOp(enc_context, outdata, &tmp1_outlen,
> +			    sizeof(outbuf) - sizeof (struct crypto_security_header),
> +			    data, datalen);
> +	if (rv1 != SECSuccess) {
> +		log_printf(instance->log_level_security,
> +			"PK11_CipherOp (decrypt) failed (err %d)",
> +			PR_GetError());
> +	}
> +	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);
> +
> +	memset(buf, 0, *buf_len);
> +	memcpy(buf, outdata, result_len);
> +
> +	*buf_len = result_len;
> +
> +	if (rv1 != SECSuccess || rv2 != SECSuccess)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +size_t crypto_sec_header_size(int crypt_hash_type)
> +{
> +	/*
> +	 * TODO: add switch / size mapping
> +	 */
> +	return sizeof(struct crypto_security_header);
> +}
> +
> +int crypto_encrypt_and_sign (
> +	struct crypto_instance *instance,
> +	const unsigned char *buf_in,
> +	const size_t buf_in_len,
> +	unsigned char *buf_out,
> +	size_t *buf_out_len)
> +{
> +	return (encrypt_and_sign_nss(instance, buf_in, buf_in_len, buf_out, buf_out_len));
> +}
> +
> +int crypto_authenticate_and_decrypt (struct crypto_instance *instance,
> +	unsigned char *buf,
> +	int *buf_len)
> +{
> +	return (authenticate_and_decrypt_nss(instance, buf, buf_len));
> +}
> +
> +struct crypto_instance *crypto_init(
> +	const unsigned char *private_key,
> +	unsigned int private_key_len,
> +	int crypto_crypt_type,
> +	int crypto_hash_type,
> +	void (*log_printf_func) (
> +		int level,
> +		int subsys,
> +                const char *function,
> +                const char *file,
> +                int line,
> +                const char *format,
> +                ...)__attribute__((format(printf, 6, 7))),
> +	int log_level_security,
> +	int log_level_notice,
> +	int log_level_error,
> +	int log_subsys_id)
> +{
> +	struct crypto_instance *instance;
> +	instance = malloc(sizeof(*instance));
> +	if (instance == NULL) {
> +		return (NULL);
> +	}
> +	memset(instance, 0, sizeof(struct crypto_instance));
> +
> +	memcpy(instance->private_key, private_key, private_key_len);
> +	instance->private_key_len = private_key_len;
> +	instance->crypto_crypt_type = crypto_crypt_type;
> +	instance->crypto_hash_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;
> +
> +	init_nss_crypto(instance);
> +
> +	return (instance);
> +}
> diff --git a/exec/totemcrypto.h b/exec/totemcrypto.h
> new file mode 100644
> index 0000000..0758f10
> --- /dev/null
> +++ b/exec/totemcrypto.h
> @@ -0,0 +1,76 @@
> +/*
> + * Copyright (c) 2006-2012 Red Hat, Inc.
> + *
> + * All rights reserved.
> + *
> + * Author: Steven Dake (sdake@xxxxxxxxxx)
> + *         Christine Caulfield (ccaulfie@xxxxxxxxxx)
> + *         Jan Friesse (jfriesse@xxxxxxxxxx)
> + *
> + * This software licensed under BSD license, the text of which follows:
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are met:
> + *
> + * - Redistributions of source code must retain the above copyright notice,
> + *   this list of conditions and the following disclaimer.
> + * - Redistributions in binary form must reproduce the above copyright notice,
> + *   this list of conditions and the following disclaimer in the documentation
> + *   and/or other materials provided with the distribution.
> + * - Neither the name of the MontaVista Software, Inc. nor the names of its
> + *   contributors may be used to endorse or promote products derived from this
> + *   software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> + * THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +#ifndef TOTEMCRYPTO_H_DEFINED
> +#define TOTEMCRYPTO_H_DEFINED
> +
> +#include <sys/types.h>
> +
> +struct crypto_instance;
> +
> +extern size_t crypto_sec_header_size(
> +	int crypt_hash_type);
> +
> +extern int crypto_authenticate_and_decrypt (
> +	struct crypto_instance *instance,
> +	unsigned char *buf,
> +	int *buf_len);
> +
> +extern int crypto_encrypt_and_sign (
> +	struct crypto_instance *instance,
> +	const unsigned char *buf_in,
> +	const size_t buf_in_len,
> +	unsigned char *buf_out, 
> +	size_t *buf_out_len);
> +
> +extern struct crypto_instance *crypto_init(
> +	const unsigned char *private_key,
> +	unsigned int private_key_len,
> +	int crypto_crypt_type,
> +	int crypto_hash_type,
> +	void (*log_printf_func) (
> +		int level,
> +		int subsys,
> +		const char *function,
> +		const char *file,
> +		int line,
> +		const char *format,
> +		...)__attribute__((format(printf, 6, 7))),
> +	int log_level_security,
> +	int log_level_notice,
> +	int log_level_error,
> +	int log_subsys_id);
> +
> +#endif /* TOTEMCRYPTO_H_DEFINED */
> diff --git a/exec/totemudp.c b/exec/totemudp.c
> index b49110b..b6f8126 100644
> --- a/exec/totemudp.c
> +++ b/exec/totemudp.c
> @@ -68,7 +68,7 @@
>  #include "totemudp.h"
>  
>  #include "util.h"
> -#include "crypto.h"
> +#include "totemcrypto.h"
>  
>  #include <nss.h>
>  #include <pk11pub.h>
> diff --git a/exec/totemudpu.c b/exec/totemudpu.c
> index ab1a059..d4530ce 100644
> --- a/exec/totemudpu.c
> +++ b/exec/totemudpu.c
> @@ -68,7 +68,7 @@
>  #include "totemudpu.h"
>  
>  #include "util.h"
> -#include "crypto.h"
> +#include "totemcrypto.h"
>  
>  #include <nss.h>
>  #include <pk11pub.h>

_______________________________________________
discuss mailing list
discuss@xxxxxxxxxxxx
http://lists.corosync.org/mailman/listinfo/discuss


[Index of Archives]     [Linux Clusters]     [Corosync Project]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Linux Kernel]     [Linux SCSI]     [X.Org]

  Powered by Linux