diff --git a/libknet/totemcrypto.c b/libknet/totemcrypto.c new file mode 100644 index 00000000..dc6b863d --- /dev/null +++ b/libknet/totemcrypto.c @@ -0,0 +1,737 @@ +/* + * Copyright (c) 2006-2012 Red Hat, Inc. + * + * All rights reserved. + * + * Author: Steven Dake (sdake@redhat.com) + * Christine Caulfield (ccaulfie@redhat.com) + * Jan Friesse (jfriesse@redhat.com) + * Fabio M. Di Nitto (fdinitto@redhat.com) + * + * 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 +#include +#include +#include +#include +#include + +#define LOGSYS_UTILS_ONLY 1 +#include +#include +#include "totemcrypto.h" + +/* + * define onwire crypto header + */ + +struct crypto_config_header { + uint8_t crypto_cipher_type; + uint8_t crypto_hash_type; + uint8_t __pad0; + 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 +}; + +CK_MECHANISM_TYPE cipher_to_nss[] = { + 0, /* CRYPTO_CIPHER_TYPE_NONE */ + CKM_AES_CBC_PAD /* CRYPTO_CIPHER_TYPE_AES256 */ +}; + +size_t cipher_key_len[] = { + 0, /* CRYPTO_CIPHER_TYPE_NONE */ + 32, /* CRYPTO_CIPHER_TYPE_AES256 */ +}; + +size_t cypher_block_len[] = { + 0, /* CRYPTO_CIPHER_TYPE_NONE */ + 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, + CRYPTO_HASH_TYPE_SHA1 = 2, + CRYPTO_HASH_TYPE_SHA256 = 3, + CRYPTO_HASH_TYPE_SHA384 = 4, + CRYPTO_HASH_TYPE_SHA512 = 5 +}; + +CK_MECHANISM_TYPE hash_to_nss[] = { + 0, /* CRYPTO_HASH_TYPE_NONE */ + CKM_MD5_HMAC, /* CRYPTO_HASH_TYPE_MD5 */ + CKM_SHA_1_HMAC, /* CRYPTO_HASH_TYPE_SHA1 */ + CKM_SHA256_HMAC, /* CRYPTO_HASH_TYPE_SHA256 */ + CKM_SHA384_HMAC, /* CRYPTO_HASH_TYPE_SHA384 */ + CKM_SHA512_HMAC /* CRYPTO_HASH_TYPE_SHA512 */ +}; + +size_t hash_len[] = { + 0, /* CRYPTO_HASH_TYPE_NONE */ + MD5_LENGTH, /* CRYPTO_HASH_TYPE_MD5 */ + SHA1_LENGTH, /* CRYPTO_HASH_TYPE_SHA1 */ + SHA256_LENGTH, /* CRYPTO_HASH_TYPE_SHA256 */ + SHA384_LENGTH, /* CRYPTO_HASH_TYPE_SHA384 */ + SHA512_LENGTH /* CRYPTO_HASH_TYPE_SHA512 */ +}; + +size_t hash_block_len[] = { + 0, /* CRYPTO_HASH_TYPE_NONE */ + MD5_BLOCK_LENGTH, /* CRYPTO_HASH_TYPE_MD5 */ + SHA1_BLOCK_LENGTH, /* CRYPTO_HASH_TYPE_SHA1 */ + SHA256_BLOCK_LENGTH, /* CRYPTO_HASH_TYPE_SHA256 */ + SHA384_BLOCK_LENGTH, /* CRYPTO_HASH_TYPE_SHA384 */ + SHA512_BLOCK_LENGTH /* CRYPTO_HASH_TYPE_SHA512 */ +}; + +struct crypto_instance { + PK11SymKey *nss_sym_key; + PK11SymKey *nss_sym_key_sign; + + unsigned char private_key[1024]; + + unsigned int private_key_len; + + enum crypto_crypt_t crypto_cipher_type; + + enum crypto_hash_t crypto_hash_type; + + unsigned int crypto_header_size; + + 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); + +/* + * 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; + SECItem crypt_param; + + if (!cipher_to_nss[instance->crypto_cipher_type]) { + return 0; + } + + 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()); + return -1; + } + + 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; + } + + PK11_FreeSlot(crypt_slot); + + return 0; +} + +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* crypt_context = NULL; + SECItem crypt_param; + SECItem *nss_sec_param = NULL; + int tmp1_outlen = 0; + unsigned int tmp2_outlen = 0; + unsigned char *salt = buf_out; + unsigned char *data = buf_out + SALT_SIZE; + int err = -1; + + if (!cipher_to_nss[instance->crypto_cipher_type]) { + memcpy(buf_out, buf_in, buf_in_len); + *buf_out_len = buf_in_len; + return 0; + } + + if (PK11_GenerateRandom (salt, SALT_SIZE) != SECSuccess) { + log_printf(instance->log_level_security, + "Failure to generate a random number %d", + PR_GetError()); + goto out; + } + + crypt_param.type = siBuffer; + crypt_param.data = salt; + crypt_param.len = SALT_SIZE; + + 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()); + goto out; + } + + /* + * Create cipher context for encryption + */ + 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], + PR_GetError()); + goto out; + } + + if (PK11_CipherOp(crypt_context, data, + &tmp1_outlen, + 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)", + (int)cipher_to_nss[instance->crypto_cipher_type], + PR_GetError()); + goto out; + } + + 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)", + (int)cipher_to_nss[instance->crypto_cipher_type], + PR_GetError()); + goto out; + + } + + *buf_out_len = tmp1_outlen + tmp2_outlen + SALT_SIZE; + + err = 0; + +out: + if (crypt_context) { + PK11_DestroyContext(crypt_context, PR_TRUE); + } + if (nss_sec_param) { + SECITEM_FreeItem(nss_sec_param, PR_TRUE); + } + return err; +} + +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; + + if (!cipher_to_nss[instance->crypto_cipher_type]) { + return 0; + } + + /* 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_CreateContext (decrypt) failed (err %d)", + PR_GetError()); + goto out; + } + + if (PK11_CipherOp(decrypt_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; + } + + if (PK11_DigestFinal(decrypt_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; + } + + outbuf_len = tmp1_outlen + tmp2_outlen; + + memset(buf, 0, *buf_len); + memcpy(buf, outbuf, outbuf_len); + + *buf_len = outbuf_len; + + err = 0; + +out: + if (decrypt_context) { + PK11_DestroyContext(decrypt_context, 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 CRYPTO_HASH_TYPE_SHA1; +} + +static int init_nss_hash(struct crypto_instance *instance) +{ + PK11SlotInfo* hash_slot = NULL; + SECItem hash_param; + + if (!hash_to_nss[instance->crypto_hash_type]) { + return 0; + } + + 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()); + return -1; + } + + 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; + } + + PK11_FreeSlot(hash_slot); + + return 0; +} + +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; + + 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 (hash) hash_type=%d (err %d)", + (int)hash_to_nss[instance->crypto_hash_type], + PR_GetError()); + goto out; + } + + if (PK11_DigestBegin(hash_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; + } + + if (PK11_DigestOp(hash_context, + buf, + buf_len) != 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(hash_context, + hash_block, + &hash_tmp_outlen, + hash_block_len[instance->crypto_hash_type]) != 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; + } + + memcpy(hash, hash_block, hash_len[instance->crypto_hash_type]); + err = 0; + +out: + if (hash_context) { + PK11_DestroyContext(hash_context, PR_TRUE); + } + + return err; +} + +/* + * global/glue nss functions + */ + +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; + } + + if (NSS_NoDB_Init(".") != SECSuccess) { + log_printf(instance->log_level_security, "NSS DB initialization failed (err %d)", + PR_GetError()); + return -1; + } + + 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 (init_nss_crypto(instance) < 0) { + return -1; + } + + if (init_nss_hash(instance) < 0) { + return -1; + } + + return 0; +} + +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]; + + if (encrypt_nss(instance, buf_in, buf_in_len, data, buf_out_len) < 0) { + return -1; + } + + 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; +} + +static int authenticate_and_decrypt_nss ( + struct crypto_instance *instance, + unsigned char *buf, + int *buf_len) +{ + 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; + } + + if (decrypt_nss(instance, buf, buf_len) < 0) { + return -1; + } + + return 0; +} + +/* + * exported API + */ + +size_t crypto_sec_header_size( + const char *crypto_cipher_type, + const char *crypto_hash_type) +{ + int crypto_cipher = string_to_crypto_cipher_type(crypto_cipher_type); + int crypto_hash = string_to_crypto_hash_type(crypto_hash_type); + size_t hdr_size = 0; + + hdr_size = sizeof(struct crypto_config_header); + + if (crypto_hash) { + hdr_size += hash_len[crypto_hash]; + } + + if (crypto_cipher) { + hdr_size += SALT_SIZE; + hdr_size += cypher_block_len[crypto_cipher]; + } + + return hdr_size; +} + +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) +{ + struct crypto_config_header *cch = (struct crypto_config_header *)buf_out; + int err; + + cch->crypto_cipher_type = instance->crypto_cipher_type; + cch->crypto_hash_type = instance->crypto_hash_type; + cch->__pad0 = 0; + cch->__pad1 = 0; + + 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); + + return err; +} + +int crypto_authenticate_and_decrypt (struct crypto_instance *instance, + unsigned char *buf, + int *buf_len) +{ + struct crypto_config_header *cch = (struct crypto_config_header *)buf; + + /* + * decode crypto config of incoming packets + */ + + if (cch->crypto_cipher_type != instance->crypto_cipher_type) { + log_printf(instance->log_level_security, + "Incoming packet has different crypto type. Rejecting"); + return -1; + } + + if (cch->crypto_hash_type != instance->crypto_hash_type) { + log_printf(instance->log_level_security, + "Incoming packet has different hash type. Rejecting"); + return -1; + } + + if ((cch->__pad0 != 0) || (cch->__pad1 != 0)) { + log_printf(instance->log_level_security, + "Incoming packet appears to have features not supported by this version of corosync. Rejecting"); + return -1; + } + + /* + * invalidate config header and kill it + */ + cch = NULL; + *buf_len -= sizeof(struct crypto_config_header); + memmove(buf, buf + sizeof(struct crypto_config_header), *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, + const char *crypto_cipher_type, + const char *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_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(instance, crypto_cipher_type, crypto_hash_type) < 0) { + free(instance); + return(NULL); + } + + return (instance); +} diff --git a/libknet/totemcrypto.h b/libknet/totemcrypto.h new file mode 100644 index 00000000..7c06c391 --- /dev/null +++ b/libknet/totemcrypto.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2006-2012 Red Hat, Inc. + * + * All rights reserved. + * + * Author: Steven Dake (sdake@redhat.com) + * Christine Caulfield (ccaulfie@redhat.com) + * Jan Friesse (jfriesse@redhat.com) + * + * 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 + +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 ( + 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, + const char *crypto_cipher_type, + const char *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 */