From bf0ead55678a7c5ed3e11a1b500bb83e7facf722 Mon Sep 17 00:00:00 2001
From: Uros Majstorovic <majstor@majstor.org>
Date: Wed, 2 Aug 2023 09:36:16 +0200
Subject: implemented ROS recommendations

---
 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 +++
 5 files changed, 98 insertions(+), 52 deletions(-)

(limited to 'ecp/src')

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; i<ECP_SIZE_ECDH_PUB/ECP_SIZE_BC_BLOCK; i++) {
-        ecp_bc_encrypt_block(public_buf + i*ECP_SIZE_BC_BLOCK, cookie + i*ECP_SIZE_BC_BLOCK, &bc_ctx);
-    }
+    memcpy(msg, public_buf, ECP_SIZE_ECDH_PUB);
+    ecp_nonce2buf(msg+ECP_SIZE_ECDH_PUB, nonce);
 
-    return ECP_OK;
+    ecp_hmac(atag, &key, msg, sizeof(msg));
 }
 
 int ecp_cookie_verify(ECPSocket *sock, unsigned char *cookie, unsigned char *public_buf) {
-    ecp_bc_ctx_t bc_ctx;
-    int i;
+    unsigned char msg[ECP_SIZE_ECDH_PUB+ECP_SIZE_NONCE];
+    unsigned char atag[ECP_SIZE_ATAG];
+    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; i<ECP_SIZE_ECDH_PUB/ECP_SIZE_BC_BLOCK; i++) {
-        ecp_bc_decrypt_block(cookie + i*ECP_SIZE_BC_BLOCK, cookie + i*ECP_SIZE_BC_BLOCK, &bc_ctx);
-    }
+    memcpy(msg, public_buf, ECP_SIZE_ECDH_PUB);
+    memcpy(msg+ECP_SIZE_ECDH_PUB, cookie, ECP_SIZE_NONCE);
+    ecp_hmac(atag, &key, msg, sizeof(msg));
 
-    if (memcmp(cookie, public_buf, ECP_SIZE_ECDH_PUB) == 0) return ECP_OK;
+    if (memcmp(cookie+ECP_SIZE_NONCE, atag, ECP_SIZE_ATAG) == 0) return ECP_OK;
     return ECP_ERR_COOKIE;
 }
 
@@ -816,6 +808,7 @@ static int conn_dhkey_set_pub(ECPConnection *conn, unsigned char idx, ecp_ecdh_p
     ECPDHPub *key;
     ECPSocket *sock = conn->sock;
     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<SHA_CBLOCK; i++) {
+        b[i] = b[i] ^ 0x36;
+    }
+
+    SHA1_Init(&ctx);
+    SHA1_Update(&ctx, b, sizeof(b));
+    SHA1_Update(&ctx, m, ml);
+    SHA1_Final(d, &ctx);
+
+    memset(b, 0, sizeof(b));
+    memcpy(b, k, ECP_SIZE_HMAC_KEY);
+    for (i=0; i<SHA_CBLOCK; i++) {
+        b[i] = b[i] ^ 0x5c;
+    }
+    SHA1_Init(&ctx);
+    SHA1_Update(&ctx, b, sizeof(b));
+    SHA1_Update(&ctx, d, sizeof(d));
+    SHA1_Final(hd, &ctx);
+}
diff --git a/ecp/src/ecp/crypto/crypto.h b/ecp/src/ecp/crypto/crypto.h
index 9e55c53..f2986d0 100644
--- a/ecp/src/ecp/crypto/crypto.h
+++ b/ecp/src/ecp/crypto/crypto.h
@@ -1,4 +1,5 @@
 #include <openssl/aes.h>
+#include <openssl/sha.h>
 
 #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;
-- 
cgit v1.2.3