diff --git a/TODO b/TODO index 7403cc1c..1971551b 100644 --- a/TODO +++ b/TODO @@ -1,98 +1,96 @@ 0.1 --- compress: should only compress user data, we will add a bit in the data header to indicate if the pckt is compressed or not (save time). this approach allow runtime change of compress. open questions are: methods? level? zlib? lzo? bz? lzma? xz? how much do we save by compressin our header? custom compress callback_fn? -cryto: make api generic for different methods != nss to match compress - review API and config to make sure we save memcpy - also expand API to support dual key for rekey process. +cryto: expand API to support dual key for rekey process. compress must happen before encrypt config: we need ato add config/vty for link_handler_policy, link_timeout and link_priority for active/passive Look into link status changes notification (maybe a signal to a thread? or write to a pipe) ring: * support 8 listener per node. * index pointer list general: * what to log log to file: who logins, config changes and link status changes log to vty: cmd execution failure * consider splitting tests/* based on what they test (tap_test -> libtap/) ? vty: * split cmd_files * basic show info * fix check_param for ip/prefix/crypto 0.2 --- libtap: * add man pages * improve tests to cover thread safety and more error codes 0.3 --- * benchmark tests: - all critical paths in ring.c 0.4 --- general: * add statistics * add init script / spec file * v4/v6 (bindv6only check via cli) vty: * add optional options * sorting * tab completion on options 0.5 --- * pong count 0.6 --- * dynip 0.7 --- * review ring api for libknetring shared lib * review tap api for libknettap shared lib * review vty api for libknetvty shared lib 1.0-pre ------- tests: * coverity * unit test: - test all public APIs - write ad-doc tests for internal complex functions - not required to test return codes from external libs directly (we are not testing glibc) - test all code paths we write - no 0.9/1.0 release without max testing coverage for the core diff --git a/libknet/Makefile.am b/libknet/Makefile.am index d3ccc66b..0219fa32 100644 --- a/libknet/Makefile.am +++ b/libknet/Makefile.am @@ -1,25 +1,27 @@ MAINTAINERCLEANFILES = Makefile.in LIBS = -lpthread \ -version-info $(libversion) libversion = 0:0:0 sources = \ common.c \ handle.c \ host.c \ listener.c \ + crypto.c \ nsscrypto.c \ etherfilter.c include_HEADERS = libknet.h noinst_HEADERS = libknet-private.h \ + crypto.h \ nsscrypto.h lib_LTLIBRARIES = libknet.la libknet_la_SOURCES = $(sources) libknet_la_CFLAGS = $(nss_CFLAGS) libknet_la_LIBADD = $(nss_LIBS) diff --git a/libknet/crypto.c b/libknet/crypto.c new file mode 100644 index 00000000..bad8e4da --- /dev/null +++ b/libknet/crypto.c @@ -0,0 +1,72 @@ +#include "config.h" + +#include + +#include "crypto.h" +#include "nsscrypto.h" +#include "libknet-private.h" + +#ifdef CRYPTO_DEBUG +#define log_printf(format, args...) fprintf(stderr, format "\n", ##args); +#else +#define log_printf(format, args...); +#endif + +/* + * exported API + */ + +int crypto_encrypt_and_sign ( + struct crypto_instance *instance, + const unsigned char *buf_in, + const ssize_t buf_in_len, + unsigned char *buf_out, + ssize_t *buf_out_len) +{ + return nsscrypto_encrypt_and_sign(instance->model_instance, + buf_in, buf_in_len, buf_out, buf_out_len); +} + +int crypto_authenticate_and_decrypt (struct crypto_instance *instance, + unsigned char *buf, + ssize_t *buf_len) +{ + return nsscrypto_authenticate_and_decrypt(instance->model_instance, buf, buf_len); +} + +int crypto_init( + knet_handle_t knet_h, + struct knet_handle_crypto_cfg *knet_handle_crypto_cfg) +{ + log_printf("Initizializing crypto module [%s/%s/%s]", + knet_handle_crypto_cfg->crypto_model, + knet_handle_crypto_cfg->crypto_cipher_type, + knet_handle_crypto_cfg->crypto_hash_type); + + knet_h->crypto_instance = malloc(sizeof(struct crypto_instance)); + + if (!knet_h->crypto_instance) { + log_printf("no memory from crypto"); + return -1; + } + + /* do the model switch here */ + if (nsscrypto_init(knet_h, knet_handle_crypto_cfg)) { + free(knet_h->crypto_instance); + return -1; + } + + return nsscrypto_init(knet_h, knet_handle_crypto_cfg); +} + +void crypto_fini( + knet_handle_t knet_h) +{ + if (knet_h->crypto_instance) { + nsscrypto_fini(knet_h); + free(knet_h->crypto_instance); + knet_h->crypto_instance = NULL; + } + + return; +} diff --git a/libknet/nsscrypto.h b/libknet/crypto.h similarity index 76% copy from libknet/nsscrypto.h copy to libknet/crypto.h index 2ae7216c..011a72d1 100644 --- a/libknet/nsscrypto.h +++ b/libknet/crypto.h @@ -1,28 +1,31 @@ -#ifndef NSSCRYPTO_H_DEFINED -#define NSSCRYPTO_H_DEFINED +#ifndef CRYPTO_H_DEFINED +#define CRYPTO_H_DEFINED #include #include "libknet.h" -struct crypto_instance; +struct crypto_instance { + int model; + void *model_instance; +}; int crypto_authenticate_and_decrypt ( struct crypto_instance *instance, unsigned char *buf, ssize_t *buf_len); int crypto_encrypt_and_sign ( struct crypto_instance *instance, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len); int crypto_init( knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet_handle_crypto_cfg); void crypto_fini( knet_handle_t knet_h); -#endif /* NSSCRYPTO_H_DEFINED */ +#endif /* CRYPTO_H_DEFINED */ diff --git a/libknet/handle.c b/libknet/handle.c index 1edcdf4e..28e385c6 100644 --- a/libknet/handle.c +++ b/libknet/handle.c @@ -1,705 +1,705 @@ #include "config.h" #include #include #include #include #include #include #include "libknet-private.h" -#include "nsscrypto.h" +#include "crypto.h" #define KNET_MAX_EVENTS 8 #define KNET_PING_TIMERES 200000 static void *_handle_tap_to_links_thread(void *data); static void *_handle_recv_from_links_thread(void *data); static void *_handle_heartbt_thread(void *data); static void *_handle_dst_link_handler_thread(void *data); knet_handle_t knet_handle_new(const struct knet_handle_cfg *knet_handle_cfg) { knet_handle_t knet_h; struct epoll_event ev; /* * validate incoming config request */ if (knet_handle_cfg == NULL) { errno = EINVAL; return NULL; } if (knet_handle_cfg->fd <= 0) { errno = EINVAL; return NULL; } if ((knet_h = malloc(sizeof(struct knet_handle))) == NULL) return NULL; memset(knet_h, 0, sizeof(struct knet_handle)); knet_h->node_id = knet_handle_cfg->node_id; knet_h->sockfd = knet_handle_cfg->fd; if (pipe(knet_h->pipefd)) goto exit_fail1; if ((_fdset_cloexec(knet_h->pipefd[0])) || (_fdset_cloexec(knet_h->pipefd[1])) || (_fdset_nonblock(knet_h->pipefd[0])) || (_fdset_nonblock(knet_h->pipefd[1]))) goto exit_fail2; knet_h->dst_host_filter = knet_handle_cfg->dst_host_filter; knet_h->dst_host_filter_fn = knet_handle_cfg->dst_host_filter_fn; if ((knet_h->dst_host_filter) && (!knet_h->dst_host_filter_fn)) goto exit_fail2; if ((knet_h->tap_to_links_buf = malloc(KNET_DATABUFSIZE))== NULL) goto exit_fail2; memset(knet_h->tap_to_links_buf, 0, KNET_DATABUFSIZE); if ((knet_h->recv_from_links_buf = malloc(KNET_DATABUFSIZE))== NULL) goto exit_fail3; memset(knet_h->recv_from_links_buf, 0, KNET_DATABUFSIZE); if ((knet_h->pingbuf = malloc(KNET_PINGBUFSIZE))== NULL) goto exit_fail4; memset(knet_h->pingbuf, 0, KNET_PINGBUFSIZE); if (pthread_rwlock_init(&knet_h->list_rwlock, NULL) != 0) goto exit_fail5; knet_h->tap_to_links_epollfd = epoll_create(KNET_MAX_EVENTS); knet_h->recv_from_links_epollfd = epoll_create(KNET_MAX_EVENTS); knet_h->dst_link_handler_epollfd = epoll_create(KNET_MAX_EVENTS); if ((knet_h->tap_to_links_epollfd < 0) || (knet_h->recv_from_links_epollfd < 0) || (knet_h->dst_link_handler_epollfd < 0)) goto exit_fail6; if ((_fdset_cloexec(knet_h->tap_to_links_epollfd) != 0) || (_fdset_cloexec(knet_h->recv_from_links_epollfd) != 0) || (_fdset_cloexec(knet_h->dst_link_handler_epollfd) != 0)) goto exit_fail6; memset(&ev, 0, sizeof(struct epoll_event)); ev.events = EPOLLIN; ev.data.fd = knet_h->sockfd; if (epoll_ctl(knet_h->tap_to_links_epollfd, EPOLL_CTL_ADD, knet_h->sockfd, &ev) != 0) goto exit_fail6; memset(&ev, 0, sizeof(struct epoll_event)); ev.events = EPOLLIN; ev.data.fd = knet_h->pipefd[0]; if (epoll_ctl(knet_h->dst_link_handler_epollfd, EPOLL_CTL_ADD, knet_h->pipefd[0], &ev) != 0) goto exit_fail6; if (pthread_create(&knet_h->dst_link_handler_thread, 0, _handle_dst_link_handler_thread, (void *) knet_h) != 0) goto exit_fail6; if (pthread_create(&knet_h->tap_to_links_thread, 0, _handle_tap_to_links_thread, (void *) knet_h) != 0) goto exit_fail7; if (pthread_create(&knet_h->recv_from_links_thread, 0, _handle_recv_from_links_thread, (void *) knet_h) != 0) goto exit_fail8; if (pthread_create(&knet_h->heartbt_thread, 0, _handle_heartbt_thread, (void *) knet_h) != 0) goto exit_fail9; return knet_h; exit_fail9: pthread_cancel(knet_h->recv_from_links_thread); exit_fail8: pthread_cancel(knet_h->tap_to_links_thread); exit_fail7: pthread_cancel(knet_h->dst_link_handler_thread); exit_fail6: if (knet_h->tap_to_links_epollfd >= 0) close(knet_h->tap_to_links_epollfd); if (knet_h->recv_from_links_epollfd >= 0) close(knet_h->recv_from_links_epollfd); if (knet_h->dst_link_handler_epollfd >= 0) close(knet_h->dst_link_handler_epollfd); pthread_rwlock_destroy(&knet_h->list_rwlock); exit_fail5: free(knet_h->pingbuf); exit_fail4: free(knet_h->recv_from_links_buf); exit_fail3: free(knet_h->tap_to_links_buf); exit_fail2: close(knet_h->pipefd[0]); close(knet_h->pipefd[1]); exit_fail1: free(knet_h); return NULL; } int knet_handle_free(knet_handle_t knet_h) { void *retval; if ((knet_h->host_head != NULL) || (knet_h->listener_head != NULL)) goto exit_busy; pthread_cancel(knet_h->heartbt_thread); pthread_join(knet_h->heartbt_thread, &retval); if (retval != PTHREAD_CANCELED) goto exit_busy; pthread_cancel(knet_h->tap_to_links_thread); pthread_join(knet_h->tap_to_links_thread, &retval); if (retval != PTHREAD_CANCELED) goto exit_busy; pthread_cancel(knet_h->recv_from_links_thread); pthread_join(knet_h->recv_from_links_thread, &retval); if (retval != PTHREAD_CANCELED) goto exit_busy; pthread_cancel(knet_h->dst_link_handler_thread); pthread_join(knet_h->dst_link_handler_thread, &retval); if (retval != PTHREAD_CANCELED) goto exit_busy; close(knet_h->tap_to_links_epollfd); close(knet_h->recv_from_links_epollfd); close(knet_h->dst_link_handler_epollfd); close(knet_h->pipefd[0]); close(knet_h->pipefd[1]); pthread_rwlock_destroy(&knet_h->list_rwlock); free(knet_h->tap_to_links_buf); free(knet_h->recv_from_links_buf); free(knet_h->pingbuf); crypto_fini(knet_h); free(knet_h); return 0; exit_busy: errno = EBUSY; return -EBUSY; } void knet_handle_setfwd(knet_handle_t knet_h, int enabled) { knet_h->enabled = (enabled == 1) ? 1 : 0; } int knet_handle_crypto(knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet_handle_crypto_cfg) { if (knet_h->enabled) return -1; return crypto_init(knet_h, knet_handle_crypto_cfg); } void knet_link_timeout(struct knet_link *lnk, time_t interval, time_t timeout, int precision) { lnk->ping_interval = interval * 1000; /* microseconds */ lnk->pong_timeout = timeout * 1000; /* microseconds */ lnk->latency_fix = precision; lnk->latency_exp = precision - \ ((lnk->ping_interval * precision) / 8000000); } static void _handle_tap_to_links(knet_handle_t knet_h) { ssize_t inlen, len, outlen; struct knet_host *dst_host; int link_idx; uint16_t dst_host_ids[KNET_MAX_HOST]; size_t dst_host_ids_entries = 0; int bcast = 1; unsigned char *outbuf = (unsigned char *)knet_h->tap_to_links_buf; inlen = read(knet_h->sockfd, knet_h->tap_to_links_buf->kf_data, KNET_DATABUFSIZE - (KNET_FRAME_SIZE + sizeof(seq_num_t))); if (inlen == 0) { /* TODO: disconnection, should never happen! */ return; } outlen = len = inlen + KNET_FRAME_SIZE + sizeof(seq_num_t); if (knet_h->enabled != 1) /* data forward is disabled */ return; if (knet_h->dst_host_filter) { bcast = knet_h->dst_host_filter_fn( (const unsigned char *)knet_h->tap_to_links_buf->kf_data, inlen, knet_h->tap_to_links_buf->kf_node, dst_host_ids, &dst_host_ids_entries); if (bcast < 0) return; if ((!bcast) && (!dst_host_ids_entries)) return; } if (pthread_rwlock_rdlock(&knet_h->list_rwlock) != 0) return; if (!bcast) { int host_idx; for (host_idx = 0; host_idx < dst_host_ids_entries; host_idx++) { dst_host = knet_h->host_index[dst_host_ids[host_idx]]; if (!dst_host) continue; knet_h->tap_to_links_buf->kf_seq_num = htons(++dst_host->ucast_seq_num_tx); if (knet_h->crypto_instance) { if (crypto_encrypt_and_sign(knet_h->crypto_instance, (const unsigned char *)knet_h->tap_to_links_buf, len, knet_h->tap_to_links_buf_crypt, &outlen) < 0) { pthread_rwlock_unlock(&knet_h->list_rwlock); return; } outbuf = knet_h->tap_to_links_buf_crypt; } for (link_idx = 0; link_idx < dst_host->active_link_entries; link_idx++) { sendto(dst_host->link[dst_host->active_links[link_idx]].sock, outbuf, outlen, MSG_DONTWAIT, (struct sockaddr *) &dst_host->link[dst_host->active_links[link_idx]].address, sizeof(struct sockaddr_storage)); if ((dst_host->link_handler_policy == KNET_LINK_POLICY_RR) && (dst_host->active_link_entries > 1)) { uint8_t cur_link_id = dst_host->active_links[0]; memmove(&dst_host->active_links[0], &dst_host->active_links[1], KNET_MAX_LINK - 1); dst_host->active_links[dst_host->active_link_entries - 1] = cur_link_id; break; } } } } else { knet_h->tap_to_links_buf->kf_seq_num = htons(++knet_h->bcast_seq_num_tx); if (knet_h->crypto_instance) { if (crypto_encrypt_and_sign(knet_h->crypto_instance, (const unsigned char *)knet_h->tap_to_links_buf, len, knet_h->tap_to_links_buf_crypt, &outlen) < 0) { pthread_rwlock_unlock(&knet_h->list_rwlock); return; } outbuf = knet_h->tap_to_links_buf_crypt; } for (dst_host = knet_h->host_head; dst_host != NULL; dst_host = dst_host->next) { for (link_idx = 0; link_idx < dst_host->active_link_entries; link_idx++) { sendto(dst_host->link[dst_host->active_links[link_idx]].sock, outbuf, outlen, MSG_DONTWAIT, (struct sockaddr *) &dst_host->link[dst_host->active_links[link_idx]].address, sizeof(struct sockaddr_storage)); if ((dst_host->link_handler_policy == KNET_LINK_POLICY_RR) && (dst_host->active_link_entries > 1)) { uint8_t cur_link_id = dst_host->active_links[0]; memmove(&dst_host->active_links[0], &dst_host->active_links[1], KNET_MAX_LINK - 1); dst_host->active_links[dst_host->active_link_entries - 1] = cur_link_id; break; } } } } pthread_rwlock_unlock(&knet_h->list_rwlock); } static void _handle_recv_from_links(knet_handle_t knet_h, int sockfd) { ssize_t len, outlen; struct sockaddr_storage address; socklen_t addrlen; struct knet_host *src_host; struct knet_link *src_link; unsigned long long latency_last; uint16_t dst_host_ids[KNET_MAX_HOST]; size_t dst_host_ids_entries = 0; int bcast = 1; unsigned char *outbuf = (unsigned char *)knet_h->recv_from_links_buf; if (pthread_rwlock_rdlock(&knet_h->list_rwlock) != 0) return; addrlen = sizeof(struct sockaddr_storage); len = recvfrom(sockfd, knet_h->recv_from_links_buf, KNET_DATABUFSIZE, MSG_DONTWAIT, (struct sockaddr *) &address, &addrlen); if (knet_h->crypto_instance) { if (crypto_authenticate_and_decrypt(knet_h->crypto_instance, (unsigned char *)knet_h->recv_from_links_buf, &len) < 0) goto exit_unlock; } if (len < (KNET_FRAME_SIZE + 1)) goto exit_unlock; if (ntohl(knet_h->recv_from_links_buf->kf_magic) != KNET_FRAME_MAGIC) goto exit_unlock; if (knet_h->recv_from_links_buf->kf_version != KNET_FRAME_VERSION) goto exit_unlock; knet_h->recv_from_links_buf->kf_node = ntohs(knet_h->recv_from_links_buf->kf_node); src_host = knet_h->host_index[knet_h->recv_from_links_buf->kf_node]; if (src_host == NULL) { /* host not found */ goto exit_unlock; } src_link = NULL; if ((knet_h->recv_from_links_buf->kf_type & KNET_FRAME_PMSK) != 0) { src_link = src_host->link + (knet_h->recv_from_links_buf->kf_link % KNET_MAX_LINK); } switch (knet_h->recv_from_links_buf->kf_type) { case KNET_FRAME_DATA: if (knet_h->enabled != 1) /* data forward is disabled */ break; knet_h->recv_from_links_buf->kf_seq_num = ntohs(knet_h->recv_from_links_buf->kf_seq_num); if (knet_h->dst_host_filter) { int host_idx; int found = 0; bcast = knet_h->dst_host_filter_fn( (const unsigned char *)knet_h->recv_from_links_buf->kf_data, len, knet_h->recv_from_links_buf->kf_node, dst_host_ids, &dst_host_ids_entries); if (bcast < 0) goto exit_unlock; if ((!bcast) && (!dst_host_ids_entries)) goto exit_unlock; /* check if we are dst for this packet */ if (!bcast) { for (host_idx = 0; host_idx < dst_host_ids_entries; host_idx++) { if (dst_host_ids[host_idx] == knet_h->node_id) { found = 1; break; } } if (!found) goto exit_unlock; } } if (!knet_should_deliver(src_host, bcast, knet_h->recv_from_links_buf->kf_seq_num)) goto exit_unlock; if (write(knet_h->sockfd, knet_h->recv_from_links_buf->kf_data, len - (KNET_FRAME_SIZE + sizeof(seq_num_t))) == len - (KNET_FRAME_SIZE + sizeof(seq_num_t))) knet_has_been_delivered(src_host, bcast, knet_h->recv_from_links_buf->kf_seq_num); break; case KNET_FRAME_PING: outlen = KNET_PINGBUFSIZE; knet_h->recv_from_links_buf->kf_type = KNET_FRAME_PONG; knet_h->recv_from_links_buf->kf_node = htons(knet_h->node_id); if (knet_h->crypto_instance) { if (crypto_encrypt_and_sign(knet_h->crypto_instance, (const unsigned char *)knet_h->recv_from_links_buf, len, knet_h->recv_from_links_buf_crypt, &outlen) < 0) break; outbuf = knet_h->recv_from_links_buf_crypt; } sendto(src_link->sock, outbuf, outlen, MSG_DONTWAIT, (struct sockaddr *) &src_link->address, sizeof(struct sockaddr_storage)); break; case KNET_FRAME_PONG: clock_gettime(CLOCK_MONOTONIC, &src_link->pong_last); timespec_diff(knet_h->recv_from_links_buf->kf_time, src_link->pong_last, &latency_last); src_link->latency = ((src_link->latency * src_link->latency_exp) + ((latency_last / 1000llu) * (src_link->latency_fix - src_link->latency_exp))) / src_link->latency_fix; if (src_link->latency < src_link->pong_timeout) { if (!src_link->connected) { int write_retry = 0; src_link->connected = 1; try_again: if (write(knet_h->pipefd[1], &src_host->node_id, sizeof(src_host->node_id)) != sizeof(src_host->node_id)) { if ((write_retry < 10) && ((errno = EAGAIN) || (errno = EWOULDBLOCK))) { write_retry++; goto try_again; } /* define what to do if we can't add a link */ } } } break; default: goto exit_unlock; } exit_unlock: pthread_rwlock_unlock(&knet_h->list_rwlock); } static void _handle_dst_link_updates(knet_handle_t knet_h) { uint16_t dst_host_id; struct knet_host *dst_host; int link_idx; int best_priority = -1; if (read(knet_h->pipefd[0], &dst_host_id, sizeof(dst_host_id)) != sizeof(dst_host_id)) return; if (pthread_rwlock_wrlock(&knet_h->list_rwlock) != 0) return; dst_host = knet_h->host_index[dst_host_id]; if (!dst_host) goto out_unlock; dst_host->active_link_entries = 0; for (link_idx = 0; link_idx < KNET_MAX_LINK; link_idx++) { if (dst_host->link[link_idx].configured != 1) /* link is not configured */ continue; if (dst_host->link[link_idx].connected != 1) /* link is not enabled */ continue; if (dst_host->link_handler_policy == KNET_LINK_POLICY_PASSIVE) { /* for passive we look for the only active link with higher priority */ if (dst_host->link[link_idx].priority > best_priority) { dst_host->active_links[0] = link_idx; best_priority = dst_host->link[link_idx].priority; } dst_host->active_link_entries = 1; } else { /* for RR and ACTIVE we need to copy all available links */ dst_host->active_links[dst_host->active_link_entries] = link_idx; dst_host->active_link_entries++; } } /* no active links, we can clean the circular buffers and indexes */ if (!dst_host->active_link_entries) { memset(dst_host->bcast_circular_buffer, 0, KNET_CBUFFER_SIZE); memset(dst_host->ucast_circular_buffer, 0, KNET_CBUFFER_SIZE); dst_host->bcast_seq_num_rx = 0; dst_host->ucast_seq_num_rx = 0; } out_unlock: pthread_rwlock_unlock(&knet_h->list_rwlock); return; } static void _handle_check_each(knet_handle_t knet_h, struct knet_host *dst_host, struct knet_link *dst_link) { int len; ssize_t outlen = KNET_PINGBUFSIZE; struct timespec clock_now, pong_last; unsigned long long diff_ping; unsigned char *outbuf = (unsigned char *)knet_h->pingbuf; /* caching last pong to avoid race conditions */ pong_last = dst_link->pong_last; if (clock_gettime(CLOCK_MONOTONIC, &clock_now) != 0) return; timespec_diff(dst_link->ping_last, clock_now, &diff_ping); if (diff_ping >= (dst_link->ping_interval * 1000llu)) { knet_h->pingbuf->kf_time = clock_now; knet_h->pingbuf->kf_link = dst_link->link_id; if (knet_h->crypto_instance) { if (crypto_encrypt_and_sign(knet_h->crypto_instance, (const unsigned char *)knet_h->pingbuf, KNET_PINGBUFSIZE, knet_h->pingbuf_crypt, &outlen) < 0) return; outbuf = knet_h->pingbuf_crypt; } len = sendto(dst_link->sock, outbuf, outlen, MSG_DONTWAIT, (struct sockaddr *) &dst_link->address, sizeof(struct sockaddr_storage)); if (len == outlen) dst_link->ping_last = clock_now; } if (dst_link->connected == 1) { timespec_diff(pong_last, clock_now, &diff_ping); if (diff_ping >= (dst_link->pong_timeout * 1000llu)) { int write_retry = 0; dst_link->connected = 0; try_again: if (write(knet_h->pipefd[1], &dst_host->node_id, sizeof(dst_host->node_id)) != sizeof(dst_host->node_id)) { if ((write_retry < 10) && ((errno = EAGAIN) || (errno = EWOULDBLOCK))) { write_retry++; goto try_again; } /* define what to do if we can't deactivate a link */ } } } } static void *_handle_heartbt_thread(void *data) { knet_handle_t knet_h; struct knet_host *dst_host; int link_idx; knet_h = (knet_handle_t) data; /* preparing ping buffer */ knet_h->pingbuf->kf_magic = htonl(KNET_FRAME_MAGIC); knet_h->pingbuf->kf_version = KNET_FRAME_VERSION; knet_h->pingbuf->kf_type = KNET_FRAME_PING; knet_h->pingbuf->kf_node = htons(knet_h->node_id); while (1) { usleep(KNET_PING_TIMERES); if (pthread_rwlock_rdlock(&knet_h->list_rwlock) != 0) continue; for (dst_host = knet_h->host_head; dst_host != NULL; dst_host = dst_host->next) { for (link_idx = 0; link_idx < KNET_MAX_LINK; link_idx++) { if (dst_host->link[link_idx].configured != 1) continue; _handle_check_each(knet_h, dst_host, &dst_host->link[link_idx]); } } pthread_rwlock_unlock(&knet_h->list_rwlock); } return NULL; } static void *_handle_tap_to_links_thread(void *data) { knet_handle_t knet_h; struct epoll_event events[KNET_MAX_EVENTS]; knet_h = (knet_handle_t) data; /* preparing data buffer */ knet_h->tap_to_links_buf->kf_magic = htonl(KNET_FRAME_MAGIC); knet_h->tap_to_links_buf->kf_version = KNET_FRAME_VERSION; knet_h->tap_to_links_buf->kf_type = KNET_FRAME_DATA; knet_h->tap_to_links_buf->kf_node = htons(knet_h->node_id); while (1) { if (epoll_wait(knet_h->tap_to_links_epollfd, events, KNET_MAX_EVENTS, -1) >= 1) _handle_tap_to_links(knet_h); } return NULL; } static void *_handle_recv_from_links_thread(void *data) { int i, nev; knet_handle_t knet_h = (knet_handle_t) data; struct epoll_event events[KNET_MAX_EVENTS]; while (1) { nev = epoll_wait(knet_h->recv_from_links_epollfd, events, KNET_MAX_EVENTS, -1); for (i = 0; i < nev; i++) { _handle_recv_from_links(knet_h, events[i].data.fd); } } return NULL; } static void *_handle_dst_link_handler_thread(void *data) { knet_handle_t knet_h = (knet_handle_t) data; struct epoll_event events[KNET_MAX_EVENTS]; while (1) { if (epoll_wait(knet_h->dst_link_handler_epollfd, events, KNET_MAX_EVENTS, -1) >= 1) _handle_dst_link_updates(knet_h); } return NULL; } diff --git a/libknet/nsscrypto.c b/libknet/nsscrypto.c index 14ca3c05..917147e3 100644 --- a/libknet/nsscrypto.c +++ b/libknet/nsscrypto.c @@ -1,600 +1,618 @@ #include "config.h" #include #include #include #include #include #include +#include "crypto.h" #include "nsscrypto.h" #include "libknet-private.h" #ifdef CRYPTO_DEBUG #define log_printf(format, args...) fprintf(stderr, format "\n", ##args); #else #define log_printf(format, args...); #endif /* * crypto definitions and conversion tables */ #define SALT_SIZE 16 #define KNET_DATABUFSIZE_CRYPT KNET_DATABUFSIZE * 2 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 { +struct nsscrypto_instance { PK11SymKey *nss_sym_key; PK11SymKey *nss_sym_key_sign; unsigned char *private_key; unsigned int private_key_len; int crypto_cipher_type; int 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 -1; } -static int init_nss_crypto(struct crypto_instance *instance) +static int init_nss_crypto(struct nsscrypto_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("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("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, + struct nsscrypto_instance *instance, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_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 (PK11_GenerateRandom (salt, SALT_SIZE) != SECSuccess) { log_printf("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("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("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, KNET_DATABUFSIZE_CRYPT, (unsigned char *)buf_in, buf_in_len) != SECSuccess) { log_printf("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, KNET_DATABUFSIZE_CRYPT - tmp1_outlen) != SECSuccess) { log_printf("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, + struct nsscrypto_instance *instance, unsigned char *buf, ssize_t *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[KNET_DATABUFSIZE_CRYPT]; int outbuf_len; int err = -1; /* 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("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("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("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 -1; } -static int init_nss_hash(struct crypto_instance *instance) +static int init_nss_hash(struct nsscrypto_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("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("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, + struct nsscrypto_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("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("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("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("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) +static int init_nss_db(struct nsscrypto_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("NSS DB initialization failed (err %d)", PR_GetError()); return -1; } return 0; } -static int init_nss(struct crypto_instance *instance) +static int init_nss(struct nsscrypto_instance *instance) { 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; } /* * exported API */ -int crypto_encrypt_and_sign ( - struct crypto_instance *instance, +int nsscrypto_encrypt_and_sign ( + struct nsscrypto_instance *instance, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { if (cipher_to_nss[instance->crypto_cipher_type]) { if (encrypt_nss(instance, buf_in, buf_in_len, buf_out, buf_out_len) < 0) { return -1; } } else { memcpy(buf_out, buf_in, buf_in_len); *buf_out_len = buf_in_len; } if (hash_to_nss[instance->crypto_hash_type]) { if (calculate_nss_hash(instance, buf_out, *buf_out_len, buf_out + *buf_out_len) < 0) { return -1; } *buf_out_len = *buf_out_len + hash_len[instance->crypto_hash_type]; } return 0; } -int crypto_authenticate_and_decrypt (struct crypto_instance *instance, +int nsscrypto_authenticate_and_decrypt (struct nsscrypto_instance *instance, unsigned char *buf, ssize_t *buf_len) { if (hash_to_nss[instance->crypto_hash_type]) { unsigned char tmp_hash[hash_len[instance->crypto_hash_type]]; if (calculate_nss_hash(instance, buf, *buf_len - hash_len[instance->crypto_hash_type], tmp_hash) < 0) { return -1; } if (memcmp(tmp_hash, buf + (*buf_len - hash_len[instance->crypto_hash_type]), hash_len[instance->crypto_hash_type]) != 0) { log_printf("Digest does not match"); return -1; } *buf_len = *buf_len - hash_len[instance->crypto_hash_type]; } if (cipher_to_nss[instance->crypto_cipher_type]) { if (decrypt_nss(instance, buf, buf_len) < 0) { return -1; } } return 0; } -int crypto_init( +int nsscrypto_init( knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet_handle_crypto_cfg) { + struct nsscrypto_instance *nsscrypto_instance = NULL; + log_printf("Initizializing nss crypto module [%s/%s]", knet_handle_crypto_cfg->crypto_cipher_type, knet_handle_crypto_cfg->crypto_hash_type); - knet_h->crypto_instance = malloc(sizeof(struct crypto_instance)); - if (!knet_h->crypto_instance) { + knet_h->crypto_instance->model_instance = malloc(sizeof(struct nsscrypto_instance)); + if (!knet_h->crypto_instance->model_instance) { return -1; } - memset(knet_h->crypto_instance, 0, sizeof(struct crypto_instance)); + nsscrypto_instance = knet_h->crypto_instance->model_instance; + + memset(nsscrypto_instance, 0, sizeof(struct nsscrypto_instance)); if (!knet_handle_crypto_cfg->crypto_cipher_type) { goto out_err; } - knet_h->crypto_instance->crypto_cipher_type = string_to_crypto_cipher_type(knet_handle_crypto_cfg->crypto_cipher_type); - if (knet_h->crypto_instance->crypto_cipher_type < 0) { + nsscrypto_instance->crypto_cipher_type = string_to_crypto_cipher_type(knet_handle_crypto_cfg->crypto_cipher_type); + if (nsscrypto_instance->crypto_cipher_type < 0) { goto out_err; } if (!knet_handle_crypto_cfg->crypto_hash_type) { goto out_err; } - knet_h->crypto_instance->crypto_hash_type = string_to_crypto_hash_type(knet_handle_crypto_cfg->crypto_hash_type); - if (knet_h->crypto_instance->crypto_hash_type < 0) { + nsscrypto_instance->crypto_hash_type = string_to_crypto_hash_type(knet_handle_crypto_cfg->crypto_hash_type); + if (nsscrypto_instance->crypto_hash_type < 0) { goto out_err; } - knet_h->crypto_instance->private_key = knet_handle_crypto_cfg->private_key; - knet_h->crypto_instance->private_key_len = knet_handle_crypto_cfg->private_key_len; + nsscrypto_instance->private_key = knet_handle_crypto_cfg->private_key; + nsscrypto_instance->private_key_len = knet_handle_crypto_cfg->private_key_len; - if ((knet_h->crypto_instance->crypto_cipher_type > 0) || - (knet_h->crypto_instance->crypto_hash_type > 0)) { - if ((!knet_h->crypto_instance->private_key) || - (knet_h->crypto_instance->private_key_len < KNET_MIN_KEY_LEN) || - (knet_h->crypto_instance->private_key_len > KNET_MAX_KEY_LEN)) { + if ((nsscrypto_instance->crypto_cipher_type > 0) || + (nsscrypto_instance->crypto_hash_type > 0)) { + if ((!nsscrypto_instance->private_key) || + (nsscrypto_instance->private_key_len < KNET_MIN_KEY_LEN) || + (nsscrypto_instance->private_key_len > KNET_MAX_KEY_LEN)) { goto out_err; } } knet_h->tap_to_links_buf_crypt = malloc(KNET_DATABUFSIZE_CRYPT); if (!knet_h->tap_to_links_buf_crypt) goto out_err; knet_h->pingbuf_crypt = malloc(KNET_DATABUFSIZE_CRYPT); if (!knet_h->pingbuf_crypt) goto out_err; knet_h->recv_from_links_buf_crypt = malloc(KNET_DATABUFSIZE_CRYPT); if (!knet_h->recv_from_links_buf_crypt) goto out_err; - knet_h->crypto_instance->private_key = knet_handle_crypto_cfg->private_key; - knet_h->crypto_instance->private_key_len = knet_handle_crypto_cfg->private_key_len; + nsscrypto_instance->private_key = knet_handle_crypto_cfg->private_key; + nsscrypto_instance->private_key_len = knet_handle_crypto_cfg->private_key_len; - if (init_nss(knet_h->crypto_instance) < 0) { + if (init_nss(nsscrypto_instance) < 0) { goto out_err; } return 0; out_err: - crypto_fini(knet_h); + nsscrypto_fini(knet_h); return -1; } -void crypto_fini( +void nsscrypto_fini( knet_handle_t knet_h) { - if (knet_h->crypto_instance) { - if (knet_h->crypto_instance->nss_sym_key) - PK11_FreeSymKey(knet_h->crypto_instance->nss_sym_key); - if (knet_h->crypto_instance->nss_sym_key_sign) - PK11_FreeSymKey(knet_h->crypto_instance->nss_sym_key_sign); - if (knet_h->pingbuf_crypt) + struct nsscrypto_instance *nsscrypto_instance = knet_h->crypto_instance->model_instance; + + if (nsscrypto_instance) { + if (nsscrypto_instance->nss_sym_key) { + PK11_FreeSymKey(nsscrypto_instance->nss_sym_key); + nsscrypto_instance->nss_sym_key = NULL; + } + if (nsscrypto_instance->nss_sym_key_sign) { + PK11_FreeSymKey(nsscrypto_instance->nss_sym_key_sign); + nsscrypto_instance->nss_sym_key_sign = NULL; + } + if (knet_h->pingbuf_crypt) { free(knet_h->pingbuf_crypt); - if (knet_h->tap_to_links_buf_crypt) + knet_h->pingbuf_crypt = NULL; + } + if (knet_h->tap_to_links_buf_crypt) { free(knet_h->tap_to_links_buf_crypt); - if (knet_h->recv_from_links_buf_crypt) + knet_h->tap_to_links_buf_crypt = NULL; + } + if (knet_h->recv_from_links_buf_crypt) { free(knet_h->recv_from_links_buf_crypt); - free(knet_h->crypto_instance); - knet_h->crypto_instance = NULL; + knet_h->recv_from_links_buf_crypt = NULL; + } + + free(nsscrypto_instance); + knet_h->crypto_instance->model_instance = NULL; } return; } diff --git a/libknet/nsscrypto.h b/libknet/nsscrypto.h index 2ae7216c..38c25ec9 100644 --- a/libknet/nsscrypto.h +++ b/libknet/nsscrypto.h @@ -1,28 +1,28 @@ #ifndef NSSCRYPTO_H_DEFINED #define NSSCRYPTO_H_DEFINED #include #include "libknet.h" -struct crypto_instance; +struct nsscrypto_instance; -int crypto_authenticate_and_decrypt ( - struct crypto_instance *instance, +int nsscrypto_authenticate_and_decrypt ( + struct nsscrypto_instance *instance, unsigned char *buf, ssize_t *buf_len); -int crypto_encrypt_and_sign ( - struct crypto_instance *instance, +int nsscrypto_encrypt_and_sign ( + struct nsscrypto_instance *instance, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len); -int crypto_init( +int nsscrypto_init( knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet_handle_crypto_cfg); -void crypto_fini( +void nsscrypto_fini( knet_handle_t knet_h); #endif /* NSSCRYPTO_H_DEFINED */