extern state_t state;
+FILE *logfile = NULL;
+
#define NBSERVICES 10
char *services[NBSERVICES] = {
+ "CROSS_CRYPTO_B2R",
"CROSS_CRYPTO_R2B",
"LOCAL_CRYPTO_BLACK",
"LOCAL_CRYPTO_RED",
int main_thread (sub_task_t *s, int id)
{
- if ((s == NULL) || (id != 0) || (id >= NBSERVICES)) {
+ if ((s == NULL) || (id < 0) || (id >= NBSERVICES)) {
VERBOSE (crypto, ERROR, PRINTF ("can't start thread '%d'\n", id));
- return -1;
+ state = error_e;
+ return 1;
}
char *servname = services[id];
service_t *serv = find_service (servname);
if (!serv) {
- VERBOSE (crypto, ERROR, PRINTF ("can't find service '%s'\n", servname));
+ VERBOSE (crypto, ERROR, PRINTF ("can't find service '%s' (%d)\n", servname, id));
+ state = error_e;
return 1;
}
int in = MOREP_Connect (serv->rx);
if (in < 0) {
- VERBOSE (crypto, ERROR, PRINTF ("can't open TX MOREP for service '%s'\n", servname));
+ VERBOSE (crypto, ERROR, PRINTF ("can't open RX MOREP '%s' for service '%s'\n", serv->rx, servname));
+ state = error_e;
return 1;
}
int out = MOREP_Connect (serv->tx);
if (in < 0) {
- VERBOSE (crypto, ERROR, PRINTF ("can't open RX MOREP for service '%s'\n", servname));
+ VERBOSE (crypto, ERROR, PRINTF ("can't open TX MOREP '%s' for service '%s'\n", serv->tx, servname));
MOREP_Close (in);
+ state = error_e;
return 1;
}
/* log received message */
VERBOSE (crypto, INFO, PRINTF ("R:%s [SEQ=%d MSG=%d LEN=%d PDU=%d] %s\n", serv->name, seqnum, msgtype, len, msg->pdu, msg->name));
+ if (logfile) {
+ fprintf (logfile, "R:%s [SEG=%d MSG=%d LEN=%d PDU=%d] %s", serv->name, seqnum, msgtype, len, msg->pdu, msg->name);
+ char buffer[MOREP_PAYLOAD * 3 + 256] = {0};
+ switch (msg->pdu) {
+ case nopdu_e:
+ break;
+ case channel_e:
+ format_channel (&pdu_channel, buffer, sizeof (buffer));
+ break;
+ case clear_data_e:
+ format_clear_data (&pdu_clear_data, buffer, sizeof (buffer));
+ break;
+ case encrypted_data_e:
+ format_encrypted_data (&pdu_encrypted_data, buffer, sizeof (buffer));
+ break;
+ case key_e:
+ format_key (&pdu_key, buffer, sizeof (buffer));
+ break;
+ case prng_param_e:
+ format_prng_param (&pdu_prng_param, buffer, sizeof (buffer));
+ break;
+ case raw_data_e:
+ format_raw_data (&pdu_raw_data, buffer, sizeof (buffer));
+ break;
+ case status_e:
+ format_status (&pdu_status, buffer, sizeof (buffer));
+ break;
+ default:
+ snprintf (buffer, sizeof (buffer), "unknown payload");
+ }
+ fprintf (logfile, "%s\n", buffer);
+ }
/* process message */
rc = 1;
seqnum = MOREP_Send (out, msgtype, payload, len);
/* log transmitted message */
- VERBOSE (crypto, INFO, PRINTF ("T:%s [SEQ=%d MSG=%d PDU=%d] %s\n", serv->name, seqnum, msgtype, msg->pdu, msg->name));
+ VERBOSE (crypto, INFO, PRINTF ("T:%s [SEQ=%d MSG=%d LEN=%d PDU=%d] %s\n", serv->name, seqnum, msgtype, len, msg->pdu, msg->name));
+ if (logfile) {
+ fprintf (logfile, "T:%s [SEG=%d MSG=%d LEN=%d PDU=%d] %s", serv->name, seqnum, msgtype, len, msg->pdu, msg->name);
+ char buffer[MOREP_PAYLOAD * 3 + 256] = {0};
+ switch (msg->pdu) {
+ case nopdu_e:
+ break;
+ case channel_e:
+ format_channel (&pdu_channel, buffer, sizeof (buffer));
+ break;
+ case clear_data_e:
+ format_clear_data (&pdu_clear_data, buffer, sizeof (buffer));
+ break;
+ case encrypted_data_e:
+ format_encrypted_data (&pdu_encrypted_data, buffer, sizeof (buffer));
+ break;
+ case key_e:
+ format_key (&pdu_key, buffer, sizeof (buffer));
+ break;
+ case prng_param_e:
+ format_prng_param (&pdu_prng_param, buffer, sizeof (buffer));
+ break;
+ case raw_data_e:
+ format_raw_data (&pdu_raw_data, buffer, sizeof (buffer));
+ break;
+ case status_e:
+ format_status (&pdu_status, buffer, sizeof (buffer));
+ break;
+ default:
+ snprintf (buffer, sizeof (buffer), "unknown payload");
+ }
+ fprintf (logfile, "%s\n", buffer);
+ }
}
return 0;
if (mode != -1) {
service_t *serv = find_service (servname);
if (serv) {
+ VERBOSE (crypto, DEBUG, PRINTF ("url '%s' for service '%s' on %cX\n", url, servname, mode ? 'R' : 'T'));
if (mode) {
serv->rx = url;
} else {
}
}
+ /* logfile */
+ if (logname) {
+ logfile = (strcmp (logname, "-") == 0) ? stdout : fopen (logname, "w");
+ if (logfile == NULL) {
+ VERBOSE (crypto, WARNING, PRINTF ("can't open log file '%s'\n", logname));
+ }
+ }
+
/* signals */
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
/* main loop */
- while (state != shutdowning_e) {
+ while ((state != shutdowning_e) && (state != error_e)) {
/* booting and starting */
- state = booting_e;
-
+ state = initializing_e;
task_t *task = create_async_task ("CRYPTOMOD", main_thread, 0, NBSERVICES, NULL);
+ while (1) {
+ if (state == booting_e) {
+ kill_all_subtasks (task, SIGTERM);
+ clean_crypto_memory ();
+ state = booting_e;
+ } else if (state == error_e) {
+ break;
+ } else if (state == shutdowning_e) {
+ kill_all_subtasks (task, SIGTERM);
+ clean_crypto_memory ();
+ state = shutdowning_e;
+ break;
+ } else {
+ usleep (100);
+ }
+ }
}
/* cleaning */
- //if ((log) && (log != stdout)) {
- // fclose (log);
- //}
+ if ((logfile) && (logfile != stdout)) {
+ fclose (logfile);
+ }
return 0;
}
--- /dev/null
+/*
+ File name : function.c
+ Projet : MERLIN
+ Date of creation : 2025/05/02
+ Version : 1.0
+ Copyright : Thales SIX
+ Author : Laurent Mazet <laurent.mazet@thalesgroup.com>
+
+ Description : Crypto Module functions
+
+ History :
+ - initial version
+*/
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "cryptomod.h"
+#include "pdu_channel.h"
+#include "pdu_clear_data.h"
+#include "pdu_encrypted_data.h"
+#include "pdu_key.h"
+#include "pdu_prng_param.h"
+#include "pdu_raw_data.h"
+#include "pdu_status.h"
+#include "verbose.h"
+
+#include "function.h"
+
+state_t state = ok_e;
+
+#define NB_KEYS 255
+
+uint8_t *keys[NB_KEYS] = {0};
+
+#define NB_CHANNELS 255
+
+uint8_t channels[NB_CHANNELS] = {0};
+
+int encrypt_func (CLEAR_DATA_t *in, ENCRYPTED_DATA_t *out)
+{
+ state = working_e;
+
+ state = ready_e;
+
+ return 0;
+}
+
+int decrypt_func (ENCRYPTED_DATA_t *in, CLEAR_DATA_t *out)
+{
+ state = working_e;
+
+ state = ready_e;
+
+ return 0;
+}
+
+int load_key_func (KEY_t *in, STATUS_t *out)
+{
+ free (keys[in->key_id]);
+ keys[in->key_id] = (uint8_t *) calloc (1, in->key_len);
+ memcpy (in->key, keys[in->key_id], in->key_len);
+
+ out->status = ok_e;
+
+ return 0;
+}
+
+int unload_key_func (KEY_t *in, STATUS_t *out)
+{
+ out->status = (keys[in->key_id]) ? ok_e : error_e;
+ free (keys[in->key_id]);
+ keys[in->key_id] = NULL;
+
+ return 0;
+}
+
+int erase_key_func (KEY_t *in, STATUS_t *out)
+{
+ if (in->key_id != 255) {
+ VERBOSE (crypto, WARNING, PRINTF ("incorrect ERRASE_KEY message\n"));
+ }
+
+ for (int i = 0; i < NB_KEYS; i++) {
+ free (keys[i]);
+ keys[i] = NULL;
+ }
+
+ out->status = ok_e;
+
+ return 0;
+}
+
+int associate_channel_func (CHANNEL_t *in, STATUS_t *out)
+{
+ channels[in->channel_id] = in->key_id + 1;
+
+ out->status = ok_e;
+
+ return 0;
+}
+
+int dissociate_channel_func (CHANNEL_t *in, STATUS_t *out)
+{
+ out->status = (channels[in->key_id]) ? ok_e : error_e;
+
+ channels[in->key_id] = 0;
+
+ return 0;
+}
+
+int bypass_func (RAW_DATA_t *in, RAW_DATA_t *out)
+{
+ if (in != out) {
+ memcpy (out, in, sizeof (RAW_DATA_t));
+ }
+
+ return 0;
+}
+
+int random_func (PRNG_PARAM_t *in, RAW_DATA_t *out)
+{
+ switch (in->prng_id) {
+ case 0:
+ switch (in->seed_len) {
+ case 0:
+ srand (0);
+ break;
+ case 1:
+ srand (in->seed[0]);
+ break;
+ case 2:
+ srand (in->seed[0] + 256 * in->seed[1]);
+ break;
+ case 3:
+ srand (in->seed[0] + 256 * in->seed[1] + 65536 * in->seed[2]);
+ break;
+ case 4:
+ default:
+ srand (in->seed[0] + 256 * in->seed[1] + 65536 * in->seed[2] + 16777216 * in->seed[3]);
+ break;
+ }
+ out->data_len = in->seq_len;
+ for (int i = 0, r = 0; i < in->seq_len; i++) {
+ if (i % 4) {
+ r = rand ();
+ }
+ out->data[i] = r & 0xff;
+ r >>= 8;
+ }
+ break;
+ default:
+ }
+
+ return 0;
+}
+
+int status_func (void __attribute__ ((unused)) *in, STATUS_t *out)
+{
+ out->status = state;
+
+ return 0;
+}
+
+int authentification_func (RAW_DATA_t *in, RAW_DATA_t *out)
+{
+ char *secret_message = "Secret passphrase";
+ char *correct_answer = "Authenticated";
+ char *wrong_answer = "Not authorized";
+
+ if ((strlen (secret_message) == in->data_len) &&
+ (memcmp (secret_message, in->data, in->data_len) == 0)) {
+ out->data_len = strlen (correct_answer);
+ memcpy (out->data, correct_answer, out->data_len);
+ state = ready_e;
+ } else {
+ out->data_len = strlen (wrong_answer);
+ memcpy (out->data, wrong_answer, out->data_len);
+ state = initializing_e;
+ }
+
+ return 0;
+}
+
+int reboot_func (void __attribute__ ((unused)) *in, STATUS_t *out)
+{
+ state = booting_e;
+ out->status = ok_e;
+
+ return 0;
+}
+
+int zeroize_func (void __attribute__ ((unused)) *in, STATUS_t *out)
+{
+ clean_crypto_memory ();
+ state = ready_e;
+
+ out->status = ok_e;
+
+ return 0;
+}
+
+int lock_crypto_func (void __attribute__ ((unused)) *in, STATUS_t *out)
+{
+ state = shutdowning_e;
+
+ out->status = ok_e;
+
+ return 0;
+}
+
+void clean_crypto_memory (void)
+{
+ for (int i = 0; i < NB_KEYS; i++) {
+ free (keys[i]);
+ }
+ memset (keys, 0, NB_KEYS * sizeof (uint8_t *));
+ memset (channels, 0, NB_CHANNELS * sizeof (uint8_t));
+ state = ready_e;
+}
+
+/* vim: set ts=4 sw=4 si et: */
--- /dev/null
+/*
+ File name : function.h
+ Projet : MERLIN
+ Date of creation : 2025/05/02
+ Version : 1.0
+ Copyright : Thales SIX
+ Author : Laurent Mazet <laurent.mazet@thalesgroup.com>
+
+ Description : Crypto Module functions
+
+ History :
+ - initial version
+*/
+
+#ifndef __FUNCTION_H__
+#define __FUNCTION_H__
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+#include "pdu_channel.h"
+#include "pdu_encrypted_data.h"
+#include "pdu_prng_param.h"
+#include "pdu_status.h"
+#include "pdu_clear_data.h"
+#include "pdu_key.h"
+#include "pdu_raw_data.h"
+#include "pdu_raw_data.h"
+
+__BEGIN_DECLS
+
+int encrypt_func (CLEAR_DATA_t *in, ENCRYPTED_DATA_t *out);
+
+int decrypt_func (ENCRYPTED_DATA_t *in, CLEAR_DATA_t *out);
+
+int load_key_func (KEY_t *in, STATUS_t *out);
+
+int unload_key_func (KEY_t *in, STATUS_t *out);
+
+int erase_key_func (KEY_t *in, STATUS_t *out);
+
+int associate_channel_func (CHANNEL_t *in, STATUS_t *out);
+
+int dissociate_channel_func (CHANNEL_t *in, STATUS_t *out);
+
+int bypass_func (RAW_DATA_t *in, RAW_DATA_t *out);
+
+int random_func (PRNG_PARAM_t *in, RAW_DATA_t *out);
+
+int status_func (void *in, STATUS_t *out);
+
+int authentification_func (RAW_DATA_t *in, RAW_DATA_t *out);
+
+int reboot_func (void *in, STATUS_t *out);
+
+int zeroize_func (void *in, STATUS_t *out);
+
+int lock_crypto_func (void *in, STATUS_t *out);
+
+void clean_crypto_memory (void);
+
+__END_DECLS
+
+#endif /* __FUNCTION_H__ */
+
+/* vim: set ts=4 sw=4 si et: */
{
VERBOSE (morep, TRACE, PRINTF ("MOREP_Connect\n"));
+ if (url == NULL) {
+ VERBOSE (morep, ERROR, PRINTF ("no url defined\n"));
+ return -1;
+ }
+
/* parse url */
MOREP_addr_t addr = {0};
if ((parse_ifname (&addr, url) != 0) ||
#include <assert.h>
#include <malloc.h>
#include <pthread.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
pthread_mutex_lock(&t->stats_mutex);
if (condensed) {
- printf ("%s=[%lu]", t->name, (unsigned long) tsc2ms (t->current_exec_time));
+ VERBOSE (coretools, INFO, PRINTF ("%s=[%lu]", t->name, (unsigned long) tsc2ms (t->current_exec_time)));
} else {
- printf ("task %s prio=%d cpu=%s last run in %lu µs [count=%d overtimes=%lu overloads=%lu, min=%lu average=%lu max=%lu]\n",
+ VERBOSE (coretools, INFO, PRINTF ("task %s prio=%d cpu=%s last run in %lu µs [count=%d overtimes=%lu overloads=%lu, min=%lu average=%lu max=%lu]\n",
t->name, t->priority, t->cpu_list,
(unsigned long) tsc2ms (t->current_exec_time), t->count, t->overtimes,
t->overloads, (unsigned long) tsc2ms (t->min_exec_time),
t->count ? (unsigned long) tsc2ms (t->cumul_exec_time / t->count) : 0,
- (unsigned long) tsc2ms (t->max_exec_time));
+ (unsigned long) tsc2ms (t->max_exec_time)));
}
pthread_mutex_unlock(&t->stats_mutex);
t->min_exec_time = t->current_exec_time;
if (t->current_exec_time > t->max_allowed_time) {
- VERBOSE (coretools, 1, printf ("Warning: task %s[%d] too slow %luus\n", t->name, s->sub_task_id, (unsigned long) tsc2ms (t->current_exec_time)));
+ VERBOSE (coretools, WARNING, PRINTF ("task %s[%d] too slow %luus\n", t->name, s->sub_task_id, (unsigned long) tsc2ms (t->current_exec_time)));
t->overtimes++;
}
char ascii_time[80];
time_t my_time = time(NULL);
strftime(ascii_time, sizeof(ascii_time), "%T", localtime(&my_time));
- VERBOSE (coretools, 0, printf ("%s: task %s[%d], big overtime %luus\n", ascii_time, t->name, s->sub_task_id, (unsigned long) tsc2ms (t->current_exec_time)));
+ VERBOSE (coretools, ERROR, printf ("%s: task %s[%d], big overtime %luus\n", ascii_time, t->name, s->sub_task_id, (unsigned long) tsc2ms (t->current_exec_time)));
}
pthread_mutex_unlock (&t->stats_mutex);
assert (t->sub_task_list);
t->nb_sub_tasks = nb_sub_tasks;
- printf("Creating task %s[%d] prio=%d cpu=%s ttl=%d\n", t->name, t->nb_sub_tasks, t->priority, t->cpu_list, (int)(max_allowed_time_us));
+ VERBOSE (coretools, INFO, PRINTF ("Creating task %s[%d] prio=%d cpu=%s ttl=%d\n", t->name, t->nb_sub_tasks, t->priority, t->cpu_list, (int)(max_allowed_time_us)));
pthread_attr_t tattr;
int ret = 0;
pthread_mutex_init (&s->condition_mutex, NULL);
pthread_cond_init (&s->condition_cond, NULL);
- while (1) {
- t->task (s, s->sub_task_id);
- }
+ while (!t->task (s, s->sub_task_id)) { }
return NULL;
}
assert (t->sub_task_list);
t->nb_sub_tasks = nb_sub_tasks;
- printf("Creating task %s[%d] prio=%d cpu=%s\n", t->name, t->nb_sub_tasks, t->priority, t->cpu_list);
+ VERBOSE (coretools, INFO, PRINTF ("Creating task %s[%d] prio=%d cpu=%s\n", t->name, t->nb_sub_tasks, t->priority, t->cpu_list));
pthread_attr_t tattr;
int ret = 0;
return t;
}
+void kill_all_subtasks (task_t *t, int sig)
+{
+ for (int i = 0; i < t->nb_sub_tasks; i++) {
+ pthread_kill (t->sub_task_list[i].thread, sig);
+ }
+ free (t->sub_task_list);
+ free (t);
+}
+
/* vi:set tabstop=4 expandtab shiftwidth=4: this line set vi mode */
void task_stat (task_t * t, int condensed);
+void kill_all_subtasks (task_t *t, int sig);
+
#endif /* __TASK_H__ */
/* vi:set tabstop=4 expandtab shiftwidth=4: this line set vi mode */