From bf0ead55678a7c5ed3e11a1b500bb83e7facf722 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Wed, 2 Aug 2023 09:36:16 +0200 Subject: implemented ROS recommendations --- ecp/server/server.c | 3 +- ecp/src/ecp/core.c | 94 +++++++++++++++++++++++---------------------- ecp/src/ecp/core.h | 21 ++++++---- ecp/src/ecp/cr.h | 2 + ecp/src/ecp/crypto/crypto.c | 28 ++++++++++++++ ecp/src/ecp/crypto/crypto.h | 5 +++ ecp/test/init.c | 2 +- ecp/test/init_vconn.c | 2 +- 8 files changed, 101 insertions(+), 56 deletions(-) diff --git a/ecp/server/server.c b/ecp/server/server.c index bbe7c4e..d34fb19 100644 --- a/ecp/server/server.c +++ b/ecp/server/server.c @@ -67,7 +67,7 @@ static void conn_free(ECPConnection *conn) { int ecp_init(ECPContext *ctx, ECPConnHandler *vconn_handler, ECPConnHandler *vlink_handler) { int rv; - rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free); + rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free, NULL); if (rv) return rv; rv = ecp_vconn_handler_init(ctx, vconn_handler); @@ -125,7 +125,6 @@ int main(int argc, char *argv[]) { exit(1); } - rv = ecp_addr_init(&addr, argv[3]); if (rv) { fprintf(stderr, "ecp_addr_init RV:%d\n", rv); diff --git a/ecp/src/ecp/core.c b/ecp/src/ecp/core.c index b491c0b..9f9bab5 100644 --- a/ecp/src/ecp/core.c +++ b/ecp/src/ecp/core.c @@ -30,13 +30,14 @@ int ecp_dhkey_gen(ECPDHKey *key) { return ECP_OK; } -int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_conn_new_t conn_new, ecp_conn_free_t conn_free) { +int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_conn_new_t conn_new, ecp_conn_free_t conn_free, ecp_key_checker_t key_checker) { int rv; memset(ctx, 0, sizeof(ECPContext)); ctx->handle_err = handle_err; ctx->conn_new = conn_new; ctx->conn_free = conn_free; + ctx->key_checker = key_checker; rv = ecp_tr_init(ctx); if (rv) return rv; @@ -507,8 +508,7 @@ int ecp_sock_init(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key) { rv = ecp_dhkey_gen(&sock->key[sock->key_curr]); if (rv) return rv; - rv = ecp_bc_key_gen(&sock->minkey); - if (rv) return rv; + arc4random_buf(&sock->ckey, sizeof(sock->ckey)); return ECP_OK; } @@ -559,20 +559,16 @@ void ecp_sock_close(ECPSocket *sock) { ecp_tr_close(sock); } -int ecp_sock_minkey_new(ECPSocket *sock) { - int rv; - +void ecp_sock_ckey_new(ECPSocket *sock) { #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&sock->mutex); #endif - rv = ecp_bc_key_gen(&sock->minkey); + arc4random_buf(&sock->ckey, sizeof(sock->ckey)); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&sock->mutex); #endif - - return rv; } int ecp_sock_dhkey_new(ECPSocket *sock) { @@ -673,55 +669,51 @@ void ecp_sock_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t conn_expi conn_table_expire(sock, to, conn_expired); } -int ecp_sock_expire_inb(ECPSocket *sock, ecp_sts_t to) { - int rv; - - rv = ecp_sock_minkey_new(sock); - if (!rv) conn_table_expire(sock, to, _conn_expired_inb); - - return rv; +void ecp_sock_expire_inb(ECPSocket *sock, ecp_sts_t to) { + ecp_sock_ckey_new(sock); + conn_table_expire(sock, to, _conn_expired_inb); } -int ecp_cookie_gen(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf) { - ecp_bc_ctx_t bc_ctx; - int i; +void ecp_atag_gen(ECPSocket *sock, unsigned char *atag, unsigned char *public_buf, ecp_nonce_t *nonce) { + unsigned char msg[ECP_SIZE_ECDH_PUB+ECP_SIZE_NONCE]; + ecp_hmac_key_t key; #ifdef ECP_WITH_PTHREAD pthread_mutex_lock(&sock->mutex); #endif - bc_ctx = sock->minkey; + memcpy(&key, &sock->ckey, sizeof(sock->ckey)); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&sock->mutex); #endif - for (i=0; imutex); #endif - bc_ctx = sock->minkey; + memcpy(&key, &sock->ckey, sizeof(sock->ckey)); #ifdef ECP_WITH_PTHREAD pthread_mutex_unlock(&sock->mutex); #endif - for (i=0; isock; int i; + ecp_sts_t now = ecp_tm_get_s(); if (idx & ~ECP_ECDH_IDX_MASK) return ECP_ERR_ECDH_IDX; @@ -823,6 +816,8 @@ static int conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_p key = &conn->rkey[_idx]; if (key->valid && (memcmp(public, &key->public, sizeof(key->public)) == 0)) return ECP_ERR_DUP; + if (_ecp_conn_is_open(conn) && (now - conn->keyx_ts < ECP_MIN_KEYX_DT)) return ECP_ERR; + #ifdef ECP_WITH_HTABLE if (ecp_conn_is_inb(conn) && _ecp_conn_is_reg(conn) && (key->valid)) { ecp_ht_remove(sock->conn_table.keys, &key->public); @@ -831,6 +826,7 @@ static int conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_p memcpy(&key->public, public, sizeof(key->public)); key->valid = 1; + conn->keyx_ts = now; #ifdef ECP_WITH_HTABLE if (ecp_conn_is_inb(conn) && _ecp_conn_is_reg(conn)) { @@ -933,6 +929,7 @@ void ecp_conn_init(ECPConnection *conn, ECPSocket *sock, unsigned char ctype) { conn->rkey_curr = ECP_ECDH_IDX_INV; arc4random_buf(&conn->nonce_out, sizeof(conn->nonce_out)); conn->access_ts = ecp_tm_get_s(); + conn->keyx_ts = 0; } int ecp_conn_reset(ECPConnection *conn) { @@ -1607,9 +1604,9 @@ ssize_t ecp_send_init_rep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t ECPBuffer packet; ECPBuffer payload; ECPPktMeta pkt_meta; - unsigned char pkt_buf[ECP_SIZE_PKT_BUF_IREP(1+ECP_SIZE_ECDH_PUB+ECP_SIZE_COOKIE, ECP_MTYPE_INIT_REP, parent)]; - unsigned char pld_buf[ECP_SIZE_PLD_BUF_IREP(1+ECP_SIZE_ECDH_PUB+ECP_SIZE_COOKIE, ECP_MTYPE_INIT_REP, parent)]; - unsigned char cookie[ECP_SIZE_COOKIE]; + unsigned char pkt_buf[ECP_SIZE_PKT_BUF_IREP(1+ECP_SIZE_ECDH_PUB+ECP_SIZE_ATAG, ECP_MTYPE_INIT_REP, parent)]; + unsigned char pld_buf[ECP_SIZE_PLD_BUF_IREP(1+ECP_SIZE_ECDH_PUB+ECP_SIZE_ATAG, ECP_MTYPE_INIT_REP, parent)]; + unsigned char atag[ECP_SIZE_ATAG]; unsigned char *msg; ecp_nonce_t nonce; ssize_t rv; @@ -1623,14 +1620,13 @@ ssize_t ecp_send_init_rep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t ecp_pld_set_type(payload.buffer, payload.size, ECP_MTYPE_INIT_REP); msg = ecp_pld_get_msg(payload.buffer, payload.size); - _rv = ecp_cookie_gen(sock, cookie, public_buf); - if (_rv) return _rv; + ecp_sock_get_nonce(sock, &nonce); + ecp_atag_gen(sock, atag, public_buf, &nonce); _rv = ecp_sock_dhkey_get_pub(sock, msg, (ecp_ecdh_public_t *)(msg+1)); if (_rv) return _rv; - memcpy(msg+1+ECP_SIZE_ECDH_PUB, cookie, ECP_SIZE_COOKIE); + memcpy(msg+1+ECP_SIZE_ECDH_PUB, atag, ECP_SIZE_ATAG); - ecp_sock_get_nonce(sock, &nonce); pkt_meta.cookie = NULL; pkt_meta.shkey = shkey; pkt_meta.nonce = &nonce; @@ -1639,30 +1635,33 @@ ssize_t ecp_send_init_rep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t pkt_meta.s_idx = ECP_ECDH_IDX_PERMA; pkt_meta.c_idx = c_idx; - rv = ecp_pld_send_irep(sock, parent, addr, &packet, &pkt_meta, &payload, ECP_SIZE_PLD(1+ECP_SIZE_ECDH_PUB+ECP_SIZE_COOKIE, ECP_MTYPE_INIT_REP), 0); + rv = ecp_pld_send_irep(sock, parent, addr, &packet, &pkt_meta, &payload, ECP_SIZE_PLD(1+ECP_SIZE_ECDH_PUB+ECP_SIZE_ATAG, ECP_MTYPE_INIT_REP), 0); return rv; } -ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs) { +ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size, unsigned char *nonce_buf, ECP2Buffer *bufs) { ecp_send_open_t send_open_f; - unsigned char *cookie; + unsigned char cookie[ECP_SIZE_COOKIE]; + unsigned char *atag; ssize_t rv; int _rv; - if (msg_size < 1+ECP_SIZE_ECDH_PUB+ECP_SIZE_COOKIE) return ECP_ERR_SIZE; + if (msg_size < 1+ECP_SIZE_ECDH_PUB+ECP_SIZE_ATAG) return ECP_ERR_SIZE; _rv = ecp_conn_dhkey_set_pub(conn, msg[0], (ecp_ecdh_public_t *)(msg+1)); if (_rv) return _rv; - cookie = msg+1+ECP_SIZE_ECDH_PUB; + atag = msg+1+ECP_SIZE_ECDH_PUB; send_open_f = ecp_get_send_open_f(conn); if (send_open_f == NULL) send_open_f = ecp_send_open_req; + memcpy(cookie, nonce_buf, ECP_SIZE_NONCE); + memcpy(cookie+ECP_SIZE_NONCE, atag, ECP_SIZE_ATAG); ecp_tr_release(bufs->packet, 1); rv = send_open_f(conn, cookie); if (rv < 0) return rv; - return 1+ECP_SIZE_ECDH_PUB+ECP_SIZE_COOKIE; + return 1+ECP_SIZE_ECDH_PUB+ECP_SIZE_ATAG; } ssize_t ecp_write_open_req(ECPConnection *conn, ECPBuffer *payload) { @@ -1775,6 +1774,11 @@ ssize_t ecp_handle_open_req(ECPSocket *sock, ECPConnection *parent, unsigned cha if (memcmp(&public, public_buf, ECP_SIZE_ECDH_PUB) != 0) return ECP_ERR_VBOX; remote_key.valid = 1; + + if (sock->ctx->key_checker) { + _rv = sock->ctx->key_checker(sock, &public); + if (_rv) return _rv; + } } conn = ecp_conn_new_inb(sock, ctype); @@ -2305,7 +2309,7 @@ ssize_t ecp_unpack(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, switch (mtype) { case ECP_MTYPE_INIT_REP: { - rv = ecp_handle_init_rep(conn, msg, msg_size, bufs); + rv = ecp_handle_init_rep(conn, msg, msg_size, nonce_buf, bufs); if (rv < 0) goto unpack_err; rv += hdr_size; diff --git a/ecp/src/ecp/core.h b/ecp/src/ecp/core.h index 9be0dc0..09e28f8 100644 --- a/ecp/src/ecp/core.h +++ b/ecp/src/ecp/core.h @@ -49,10 +49,14 @@ #define ECP_MAX_SEQ_FWD 1024 #define ECP_MAX_EXP 100 +#define ECP_MIN_KEYX_DT 3600 + #define ECP_SIZE_PROTO 2 #define ECP_SIZE_NONCE 8 #define ECP_SIZE_MTYPE 1 -#define ECP_SIZE_COOKIE (ECP_SIZE_ECDH_PUB) +#define ECP_SIZE_MTYPE 1 +#define ECP_SIZE_ATAG (ECP_SIZE_HMAC_DIGEST) +#define ECP_SIZE_COOKIE (ECP_SIZE_NONCE+ECP_SIZE_ATAG) #define ECP_SIZE_PKT_HDR (ECP_SIZE_PROTO+1+ECP_SIZE_ECDH_PUB+ECP_SIZE_NONCE) @@ -197,6 +201,7 @@ typedef int (*ecp_conn_expired_t) (struct ECPConnection *conn, ecp_sts_t now, ec typedef void (*ecp_err_handler_t) (struct ECPConnection *conn, unsigned char mtype, int err); typedef struct ECPConnection * (*ecp_conn_new_t) (struct ECPSocket *sock, unsigned char type); typedef void (*ecp_conn_free_t) (struct ECPConnection *conn); +typedef int (*ecp_key_checker_t) (struct ECPSocket *sock, ecp_ecdh_public_t *pub); typedef ssize_t (*ecp_msg_handler_t) (struct ECPConnection *conn, ecp_seq_t seq, unsigned char mtype, unsigned char *msg, size_t msg_size, struct ECP2Buffer *b); typedef int (*ecp_open_handler_t) (struct ECPConnection *conn, struct ECP2Buffer *b); @@ -255,6 +260,7 @@ typedef struct ECPContext { ecp_err_handler_t handle_err; ecp_conn_new_t conn_new; /* inbound connections only */ ecp_conn_free_t conn_free; + ecp_key_checker_t key_checker; ECPConnHandler *handler[ECP_MAX_CTYPE]; ECPConnHandler *handler_sys[ECP_MAX_CTYPE_SYS]; } ECPContext; @@ -282,7 +288,7 @@ typedef struct ECPSocket { ECPDHKey key_perma; ECPDHKey key[ECP_MAX_SOCK_KEY]; unsigned char key_curr; - ecp_bc_ctx_t minkey; + ecp_hmac_key_t ckey; ECPConnTable conn_table; ECPTimer timer; #ifdef ECP_WITH_PTHREAD @@ -308,6 +314,7 @@ typedef struct ECPConnection { unsigned char rkey_curr; ECPDHShkey shkey[ECP_MAX_NODE_KEY][ECP_MAX_NODE_KEY]; ecp_sts_t access_ts; + ecp_sts_t keyx_ts; void *param; #ifdef ECP_WITH_VCONN struct ECPConnection *parent; @@ -323,7 +330,7 @@ typedef struct ECPConnection { int ecp_dhkey_gen(ECPDHKey *key); -int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_conn_new_t conn_new, ecp_conn_free_t conn_free); +int ecp_ctx_init(ECPContext *ctx, ecp_err_handler_t handle_err, ecp_conn_new_t conn_new, ecp_conn_free_t conn_free, ecp_key_checker_t key_checker); int ecp_ctx_set_handler(ECPContext *ctx, unsigned char ctype, ECPConnHandler *handler); ECPConnHandler *ecp_ctx_get_handler(ECPContext *ctx, unsigned char ctype); @@ -338,16 +345,16 @@ int ecp_sock_create(ECPSocket *sock, ECPContext *ctx, ECPDHKey *key); void ecp_sock_destroy(ECPSocket *sock); int ecp_sock_open(ECPSocket *sock, ecp_tr_addr_t *myaddr); void ecp_sock_close(ECPSocket *sock); -int ecp_sock_minkey_new(ECPSocket *sock); +void ecp_sock_ckey_new(ECPSocket *sock); int ecp_sock_dhkey_new(ECPSocket *sock); int ecp_sock_dhkey_get(ECPSocket *sock, unsigned char idx, ECPDHKey *key); int ecp_sock_dhkey_get_pub(ECPSocket *sock, unsigned char *idx, ecp_ecdh_public_t *public); void ecp_sock_get_nonce(ECPSocket *sock, ecp_nonce_t *nonce); void ecp_sock_expire(ECPSocket *sock, ecp_sts_t to, ecp_conn_expired_t conn_expired); -int ecp_sock_expire_inb(ECPSocket *sock, ecp_sts_t to); +void ecp_sock_expire_inb(ECPSocket *sock, ecp_sts_t to); -int ecp_cookie_gen(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf); +void ecp_atag_gen(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf, ecp_nonce_t *nonce); int ecp_cookie_verify(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf); ECPConnection *ecp_conn_new_inb(ECPSocket *sock, unsigned char ctype); @@ -398,7 +405,7 @@ void ecp_err_handle(ECPConnection *conn, unsigned char mtype, int err); ssize_t ecp_send_init_req(ECPConnection *conn, int retry); ssize_t ecp_handle_init_req(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char c_idx, unsigned char *public_buf, ecp_aead_key_t *shkey, ECP2Buffer *bufs); ssize_t ecp_send_init_rep(ECPSocket *sock, ECPConnection *parent, ecp_tr_addr_t *addr, unsigned char c_idx, unsigned char *public_buf, ecp_aead_key_t *shkey); -ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size, ECP2Buffer *bufs); +ssize_t ecp_handle_init_rep(ECPConnection *conn, unsigned char *msg, size_t msg_size, unsigned char *nonce_buf, ECP2Buffer *bufs); ssize_t ecp_write_open_req(ECPConnection *conn, ECPBuffer *payload); ssize_t ecp_send_open_req(ECPConnection *conn, unsigned char *cookie); diff --git a/ecp/src/ecp/cr.h b/ecp/src/ecp/cr.h index 4172656..c5046ed 100644 --- a/ecp/src/ecp/cr.h +++ b/ecp/src/ecp/cr.h @@ -18,3 +18,5 @@ int ecp_ecdsa_verify(unsigned char *m, size_t ml, ecp_ecdsa_signature_t *sig, ec int ecp_bc_key_gen(ecp_bc_ctx_t *key); void ecp_bc_encrypt_block(unsigned char *in, unsigned char *out, ecp_bc_ctx_t *key); void ecp_bc_decrypt_block(unsigned char *in, unsigned char *out, ecp_bc_ctx_t *key); + +void ecp_hmac(unsigned char *hd, ecp_hmac_key_t *k, unsigned char *m, size_t ml); diff --git a/ecp/src/ecp/crypto/crypto.c b/ecp/src/ecp/crypto/crypto.c index ba013fa..8a78702 100644 --- a/ecp/src/ecp/crypto/crypto.c +++ b/ecp/src/ecp/crypto/crypto.c @@ -126,3 +126,31 @@ void ecp_bc_encrypt_block(unsigned char *in, unsigned char *out, ecp_bc_ctx_t *k void ecp_bc_decrypt_block(unsigned char *in, unsigned char *out, ecp_bc_ctx_t *key) { AES_decrypt(in, out, &key->ctx_dec); } + +void ecp_hmac(unsigned char *hd, ecp_hmac_key_t *k, unsigned char *m, size_t ml) { + unsigned char b[SHA_CBLOCK]; + unsigned char d[SHA_DIGEST_LENGTH]; + SHA_CTX ctx; + int i; + + memset(b, 0, sizeof(b)); + memcpy(b, k, ECP_SIZE_HMAC_KEY); + for (i=0; i +#include #define CURVE25519_SIZE_KEY 32 #define CHACHA20_SIZE_KEY 32 @@ -15,6 +16,9 @@ #define ECP_SIZE_ECDSA_SEC 64 #define ECP_SIZE_ECDSA_SIG 32 +#define ECP_SIZE_HMAC_KEY 32 +#define ECP_SIZE_HMAC_DIGEST SHA_DIGEST_LENGTH + #define ECP_SIZE_BC_KEY 16 #define ECP_SIZE_BC_BLOCK 16 @@ -25,6 +29,7 @@ typedef uint8_t ecp_aead_nonce_t[ECP_SIZE_AEAD_NONCE]; typedef uint8_t ecp_ecdsa_public_t[ECP_SIZE_ECDSA_PUB]; typedef uint8_t ecp_ecdsa_private_t[ECP_SIZE_ECDSA_SEC]; typedef uint8_t ecp_ecdsa_signature_t[ECP_SIZE_ECDSA_SIG]; +typedef uint8_t ecp_hmac_key_t[ECP_SIZE_HMAC_KEY]; typedef struct { AES_KEY ctx_enc; AES_KEY ctx_dec; diff --git a/ecp/test/init.c b/ecp/test/init.c index 161742b..b0d91d1 100644 --- a/ecp/test/init.c +++ b/ecp/test/init.c @@ -22,6 +22,6 @@ static void conn_free(ECPConnection *conn) { int ecp_init(ECPContext *ctx) { int rv; - rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free); + rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free, NULL); return rv; } diff --git a/ecp/test/init_vconn.c b/ecp/test/init_vconn.c index b690bec..149b57a 100644 --- a/ecp/test/init_vconn.c +++ b/ecp/test/init_vconn.c @@ -47,7 +47,7 @@ static void conn_free(ECPConnection *conn) { int ecp_init(ECPContext *ctx, ECPConnHandler *vconn_handler, ECPConnHandler *vlink_handler) { int rv; - rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free); + rv = ecp_ctx_init(ctx, handle_err, conn_new, conn_free, NULL); if (rv) return rv; rv = ecp_vconn_handler_init(ctx, vconn_handler); -- cgit v1.2.3