47 #define LOGSYS_UTILS_ONLY 1
72 #ifndef AES_256_KEY_LENGTH
73 #define AES_256_KEY_LENGTH 32
76 #ifndef AES_192_KEY_LENGTH
77 #define AES_192_KEY_LENGTH 24
80 #ifndef AES_128_KEY_LENGTH
81 #define AES_128_KEY_LENGTH 16
189 const char *
function,
201 #define log_printf(level, format, args...) \
203 instance->log_printf_func ( \
204 level, instance->log_subsys_id, \
205 __FUNCTION__, __FILE__, __LINE__, \
206 (const char *)format, ##args); \
214 #define MAX_WRAPPED_KEY_LEN 128
220 static int string_to_crypto_cipher_type(
const char* crypto_cipher_type)
222 if (strcmp(crypto_cipher_type,
"none") == 0) {
224 }
else if (strcmp(crypto_cipher_type,
"aes256") == 0) {
226 }
else if (strcmp(crypto_cipher_type,
"aes192") == 0) {
228 }
else if (strcmp(crypto_cipher_type,
"aes128") == 0) {
230 }
else if (strcmp(crypto_cipher_type,
"3des") == 0) {
241 CK_MECHANISM_TYPE cipher;
243 CK_MECHANISM_TYPE wrap_mechanism;
245 PK11SymKey *wrap_key;
246 PK11Context *wrap_key_crypt_context;
247 SECItem tmp_sec_item;
250 int wrap_key_block_size;
255 memset(&key_item, 0,
sizeof(key_item));
259 wrap_key_crypt_context = NULL;
265 memset(pad_key_data, 0,
sizeof(pad_key_data));
268 key_item.type = siBuffer;
269 key_item.data = pad_key_data;
276 operation = CKA_ENCRYPT|CKA_DECRYPT;
282 operation = CKA_SIGN;
291 if (!case_processed) {
296 slot = PK11_GetBestSlot(cipher, NULL);
299 PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
316 wrap_mechanism = PK11_GetBestWrapMechanism(slot);
317 wrap_key_len = PK11_GetBestKeyLength(slot, wrap_mechanism);
318 wrap_key = PK11_KeyGen(slot, wrap_mechanism, NULL, wrap_key_len, NULL);
319 if (wrap_key == NULL) {
321 PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
332 wrap_key_block_size = PK11_GetBlockSize(wrap_mechanism, 0);
333 if (wrap_key_block_size < 0) {
335 PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
338 if (
sizeof(pad_key_data) % wrap_key_block_size != 0) {
340 "wrap key block size (%u).",
sizeof(pad_key_data), (
unsigned int)wrap_key_block_size);
348 memset(&tmp_sec_item, 0,
sizeof(tmp_sec_item));
349 wrap_key_crypt_context = PK11_CreateContextBySymKey(wrap_mechanism, CKA_ENCRYPT,
350 wrap_key, &tmp_sec_item);
351 if (wrap_key_crypt_context == NULL) {
353 PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
357 wrapped_key_len = (int)
sizeof(wrapped_key_data);
359 if (PK11_CipherOp(wrap_key_crypt_context, wrapped_key_data, &wrapped_key_len,
360 sizeof(wrapped_key_data), key_item.data,
sizeof(pad_key_data)) != SECSuccess) {
362 PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
366 if (PK11_Finalize(wrap_key_crypt_context) != SECSuccess) {
368 PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
375 memset(&tmp_sec_item, 0,
sizeof(tmp_sec_item));
376 wrapped_key.data = wrapped_key_data;
377 wrapped_key.len = wrapped_key_len;
379 res_key = PK11_UnwrapSymKey(wrap_key, wrap_mechanism, &tmp_sec_item, &wrapped_key,
380 cipher, operation, key_item.len);
381 if (res_key == NULL) {
383 PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
388 if (wrap_key_crypt_context != NULL) {
389 PK11_DestroyContext(wrap_key_crypt_context, PR_TRUE);
392 if (wrap_key != NULL) {
393 PK11_FreeSymKey(wrap_key);
418 static int encrypt_nss(
420 const unsigned char *buf_in,
421 const size_t buf_in_len,
422 unsigned char *buf_out,
425 PK11Context* crypt_context = NULL;
427 SECItem *nss_sec_param = NULL;
429 unsigned int tmp2_outlen = 0;
430 unsigned char *salt = buf_out;
431 unsigned char *data = buf_out +
SALT_SIZE;
435 memcpy(buf_out, buf_in, buf_in_len);
436 *buf_out_len = buf_in_len;
440 if (PK11_GenerateRandom (salt, SALT_SIZE) != SECSuccess) {
442 "Failure to generate a random number %d",
447 crypt_param.type = siBuffer;
448 crypt_param.data = salt;
453 if (nss_sec_param == NULL) {
455 "Failure to set up PKCS11 param (err %d)",
463 crypt_context = PK11_CreateContextBySymKey (cipher_to_nss[instance->
crypto_cipher_type],
467 if (!crypt_context) {
469 "PK11_CreateContext failed (encrypt) crypt_type=%d (%d): %s",
471 PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
475 if (PK11_CipherOp(crypt_context, data,
478 (
unsigned char *)buf_in, buf_in_len) != SECSuccess) {
480 "PK11_CipherOp failed (encrypt) crypt_type=%d (err %d)",
486 if (PK11_DigestFinal(crypt_context, data + tmp1_outlen,
489 "PK11_DigestFinal failed (encrypt) crypt_type=%d (err %d)",
496 *buf_out_len = tmp1_outlen + tmp2_outlen +
SALT_SIZE;
502 PK11_DestroyContext(crypt_context, PR_TRUE);
505 SECITEM_FreeItem(nss_sec_param, PR_TRUE);
510 static int decrypt_nss (
515 PK11Context* decrypt_context = NULL;
516 SECItem decrypt_param;
518 unsigned int tmp2_outlen = 0;
519 unsigned char *salt = buf;
531 decrypt_param.type = siBuffer;
532 decrypt_param.data = salt;
535 decrypt_context = PK11_CreateContextBySymKey(cipher_to_nss[instance->
crypto_cipher_type],
538 if (!decrypt_context) {
540 "PK11_CreateContext (decrypt) failed (err %d)",
545 if (PK11_CipherOp(decrypt_context, outbuf, &tmp1_outlen,
546 sizeof(outbuf), data, datalen) != SECSuccess) {
548 "PK11_CipherOp (decrypt) failed (err %d)",
553 if (PK11_DigestFinal(decrypt_context, outbuf + tmp1_outlen, &tmp2_outlen,
554 sizeof(outbuf) - tmp1_outlen) != SECSuccess) {
556 "PK11_DigestFinal (decrypt) failed (err %d)",
561 outbuf_len = tmp1_outlen + tmp2_outlen;
563 memset(buf, 0, *buf_len);
564 memcpy(buf, outbuf, outbuf_len);
566 *buf_len = outbuf_len;
571 if (decrypt_context) {
572 PK11_DestroyContext(decrypt_context, PR_TRUE);
583 static int string_to_crypto_hash_type(
const char* crypto_hash_type)
585 if (strcmp(crypto_hash_type,
"none") == 0) {
587 }
else if (strcmp(crypto_hash_type,
"md5") == 0) {
589 }
else if (strcmp(crypto_hash_type,
"sha1") == 0) {
591 }
else if (strcmp(crypto_hash_type,
"sha256") == 0) {
593 }
else if (strcmp(crypto_hash_type,
"sha384") == 0) {
595 }
else if (strcmp(crypto_hash_type,
"sha512") == 0) {
617 static int calculate_nss_hash(
619 const unsigned char *buf,
620 const size_t buf_len,
623 PK11Context* hash_context = NULL;
625 unsigned int hash_tmp_outlen = 0;
630 hash_param.type = siBuffer;
634 hash_context = PK11_CreateContextBySymKey(hash_to_nss[instance->
crypto_hash_type],
641 "PK11_CreateContext failed (hash) hash_type=%d (err %d)",
647 if (PK11_DigestBegin(hash_context) != SECSuccess) {
649 "PK11_DigestBegin failed (hash) hash_type=%d (err %d)",
655 if (PK11_DigestOp(hash_context,
657 buf_len) != SECSuccess) {
659 "PK11_DigestOp failed (hash) hash_type=%d (err %d)",
665 if (PK11_DigestFinal(hash_context,
670 "PK11_DigestFinale failed (hash) hash_type=%d (err %d)",
681 PK11_DestroyContext(hash_context, PR_TRUE);
698 if (NSS_NoDB_Init(NULL) != SECSuccess) {
708 const char *crypto_cipher_type,
709 const char *crypto_hash_type)
712 "Initializing transmit/receive security (NSS) crypto: %s hash: %s",
713 crypto_cipher_type, crypto_hash_type);
715 if (init_nss_db(instance) < 0) {
719 if (init_nss_crypto(instance) < 0) {
723 if (init_nss_hash(instance) < 0) {
730 static int encrypt_and_sign_nss_2_3 (
732 const unsigned char *buf_in,
733 const size_t buf_in_len,
734 unsigned char *buf_out,
737 if (encrypt_nss(instance,
746 if (calculate_nss_hash(instance, buf_out, *buf_out_len, buf_out + *buf_out_len) < 0) {
755 static int authenticate_nss_2_3 (
769 if (calculate_nss_hash(instance, buf, datalen, tmp_hash) < 0) {
773 if (memcmp(tmp_hash, buf + datalen, hash_len[instance->
crypto_hash_type]) != 0) {
783 static int decrypt_nss_2_3 (
802 const char *crypto_cipher_type,
803 const char *crypto_hash_type)
805 int crypto_cipher = string_to_crypto_cipher_type(crypto_cipher_type);
806 int crypto_hash = string_to_crypto_hash_type(crypto_hash_type);
813 hdr_size += hash_len[crypto_hash];
818 if (cypher_block_len[crypto_cipher]) {
819 block_size = cypher_block_len[crypto_cipher];
821 block_size = PK11_GetBlockSize(crypto_cipher, NULL);
822 if (block_size < 0) {
830 hdr_size += (block_size * 2);
859 const unsigned char *buf_in,
860 const size_t buf_in_len,
861 unsigned char *buf_out,
872 err = encrypt_and_sign_nss_2_3(instance,
874 buf_out, buf_out_len);
884 const char *guessed_str;
897 guessed_str =
"Corosync 3.x";
899 guessed_str =
"Corosync 2.2";
901 guessed_str =
"unencrypted Kronosnet";
903 guessed_str =
"unencrypted Corosync 2.0/2.1/1.x/OpenAIS";
905 guessed_str =
"encrypted Kronosnet/Corosync 2.0/2.1/1.x/OpenAIS or unknown";
909 "Unsupported incoming packet (probably sent by %s). Rejecting",
917 "Incoming packet has different hash type. Rejecting");
925 if (authenticate_nss_2_3(instance, buf, buf_len) != 0) {
935 "Incoming packet appears to have features not supported by this version of corosync. Rejecting");
942 if (decrypt_nss_2_3(instance, buf, buf_len) != 0) {
956 const unsigned char *private_key,
957 unsigned int private_key_len,
958 const char *crypto_cipher_type,
959 const char *crypto_hash_type,
963 const char *
function,
974 instance = malloc(
sizeof(*instance));
975 if (instance == NULL) {
980 memcpy(instance->
private_key, private_key, private_key_len);
994 if (init_nss(instance, crypto_cipher_type, crypto_hash_type) < 0) {
unsigned char private_key[1024]
unsigned int crypto_header_size
size_t crypto_sec_header_size(const char *crypto_cipher_type, const char *crypto_hash_type)
size_t crypto_get_current_sec_header_size(const struct crypto_instance *instance)
#define log_printf(level, format, args...)
PK11SymKey * nss_sym_key_sign
enum crypto_crypt_t crypto_cipher_type
#define AES_256_KEY_LENGTH
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)
void(*) in log_level_security)
#define AES_192_KEY_LENGTH
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)
#define MAX_WRAPPED_KEY_LEN
enum crypto_crypt_t __attribute__
unsigned int private_key_len
int crypto_authenticate_and_decrypt(struct crypto_instance *instance, unsigned char *buf, int *buf_len)
enum crypto_hash_t crypto_hash_type
#define AES_128_KEY_LENGTH
void(* log_printf_func)(int level, int subsys, const char *function, const char *file, int line, const char *format,...) __attribute__((format(printf
CK_MECHANISM_TYPE cipher_to_nss[]
size_t cypher_block_len[]
CK_MECHANISM_TYPE hash_to_nss[]