chiark / gitweb /
Use new Catacomb `rand_quick' to gather entropy from other fast sources.
[tripe] / server / tripe.h
index b4eee1b37c780d58e9c69d7391beec7708a40253..a967ae6d778b56d93d2c0f23c86ea62089d5107a 100644 (file)
@@ -89,6 +89,7 @@
 #include <mLib/versioncmp.h>
 
 #include <catacomb/buf.h>
+#include <catacomb/ct.h>
 
 #include <catacomb/gcipher.h>
 #include <catacomb/gmac.h>
 
 #define SEC(n) (n##u)
 #define MIN(n) (n##u * 60u)
+#define F_2P32 (65536.0*65536.0)
 #define MEG(n) (n##ul * 1024ul * 1024ul)
 
+/* --- Timing parameters --- */
+
+#define T_EXP MIN(60)                  /* Expiry time for a key */
+#define T_REGEN MIN(40)                        /* Regeneration time for a key */
+
+#define T_VALID SEC(20)                        /* Challenge validity period */
+#define T_RETRYMIN SEC(2)              /* Minimum retry interval */
+#define T_RETRYMAX MIN(5)              /* Maximum retry interval */
+#define T_RETRYGROW (5.0/4.0)          /* Retry interval growth factor */
+
+#define T_WOBBLE (1.0/3.0)             /* Relative timer randomness */
+
 /* --- Other things --- */
 
 #define PKBUFSZ 65536
 
 /*----- Cipher selections -------------------------------------------------*/
 
-typedef struct algswitch {
-  const gccipher *c;                   /* Symmetric encryption scheme */
-  const gccipher *mgf;                 /* Mask-generation function */
+typedef struct keyset keyset;
+typedef struct algswitch algswitch;
+
+typedef struct bulkcrypto {
+  const char *name;
+  unsigned prim;
+  int (*check)(const algswitch */*a*/, dstr */*e*/);
+  size_t (*overhead)(const algswitch */*a*/);
+  int (*encrypt)(keyset */*ks*/, unsigned /*ty*/, buf */*b*/, buf */*bb*/);
+  int (*decrypt)(keyset */*ks*/, unsigned /*ty*/,
+                buf */*b*/, buf */*bb*/, uint32 */*seq*/);
+} bulkcrypto;
+
+#define BCP_CIPHER 1
+#define BCP_MAC 2
+#define BCP_BLKC 4
+
+struct algswitch {
   const gchash *h;                     /* Hash function */
+  const gccipher *mgf;                 /* Mask-generation function */
+  const struct bulkcrypto *bulk;       /* Bulk crypto transformation */
+  const gccipher *c;                   /* Symmetric encryption scheme */
   const gcmac *m;                      /* Message authentication code */
+  const gccipher *b;                   /* Block cipher */
   size_t hashsz;                       /* Hash output size */
   size_t tagsz;                                /* Length to truncate MAC tags */
   size_t expsz;                                /* Size of data to process */
-  size_t cksz, mksz;                   /* Key lengths for @c@ and @m@ */
-} algswitch;
+  size_t cksz, mksz, bksz;             /* Key lengths for things */
+};
 
 typedef struct kdata {
   unsigned ref;                                /* Reference counter */
@@ -177,6 +210,8 @@ typedef struct knode {
 
 #define HASH_STRING(h, s) GH_HASH((h), (s), sizeof(s))
 
+extern const struct bulkcrypto bulktab[];
+
 /*----- Data structures ---------------------------------------------------*/
 
 /* --- Socket addresses --- *
@@ -223,7 +258,7 @@ typedef struct seqwin {
  * expiry.
  */
 
-typedef struct keyset {
+struct keyset {
   struct keyset *next;                 /* Next active keyset in the list */
   unsigned ref;                                /* Reference count for keyset */
   struct peer *p;                      /* Pointer to peer structure */
@@ -231,12 +266,16 @@ typedef struct keyset {
   unsigned long sz_exp, sz_regen;      /* Data limits for the keyset */
   T( unsigned seq; )                   /* Sequence number for tracing */
   unsigned f;                          /* Various useful flags */
-  gcipher *cin, *cout;                 /* Keyset ciphers for encryption */
+  const bulkcrypto *bulk;              /* Bulk crypto transform */
   size_t tagsz;                                /* Length to truncate MAC tags */
-  gmac *min, *mout;                    /* Keyset MACs for integrity */
+  struct ksdir {
+    gcipher *c;                                /* Keyset cipher for encryption */
+    gmac *m;                           /* Keyset MAC for integrity */
+    gcipher *b;                                /* Block cipher, just in case */
+  } in, out;
   uint32 oseq;                         /* Outbound sequence number */
   seqwin iseq;                         /* Inbound sequence number */
-} keyset;
+};
 
 #define KSF_LISTEN 1u                  /* Don't encrypt packets yet */
 #define KSF_LINK 2u                    /* Key is in a linked list */
@@ -256,6 +295,10 @@ typedef struct keyset {
  * Clive Jones.
  */
 
+typedef struct retry {
+  double t;                            /* Current retry time */
+} retry;
+
 #define KX_NCHAL 16u
 
 typedef struct kxchal {
@@ -265,6 +308,7 @@ typedef struct kxchal {
   keyset *ks;                          /* Pointer to temporary keyset */
   unsigned f;                          /* Various useful flags */
   sel_timer t;                         /* Response timer for challenge */
+  retry rs;                            /* Retry state */
   octet hc[MAXHASHSZ];                 /* Hash of his challenge */
   octet ck[MAXHASHSZ];                 /* His magical check value */
   octet hswrq_in[MAXHASHSZ];           /* Inbound switch request message */
@@ -281,6 +325,7 @@ typedef struct keyexch {
   unsigned f;                          /* Various useful flags */
   unsigned s;                          /* Current state in exchange */
   sel_timer t;                         /* Timer for next exchange */
+  retry rs;                            /* Retry state */
   mp *alpha;                           /* My temporary secret */
   ge *c;                               /* My challenge */
   ge *rx;                              /* The expected response */
@@ -531,7 +576,8 @@ extern unsigned tr_flags;           /* Trace options flags */
 
 /*----- Other macros ------------------------------------------------------*/
 
-#define TIMER noise_timer(RAND_GLOBAL)
+#define QUICKRAND                                                      \
+  do { rand_quick(RAND_GLOBAL); noise_timer(RAND_GLOBAL); } while (0)
 
 /*----- Key management ----------------------------------------------------*/
 
@@ -729,15 +775,6 @@ extern keyset *ks_gen(const void */*k*/,
                      size_t /*x*/, size_t /*y*/, size_t /*z*/,
                      peer */*p*/);
 
-/* --- @ks_tregen@ --- *
- *
- * Arguments:  @keyset *ks@ = pointer to a keyset
- *
- * Returns:    The time at which moves ought to be made to replace this key.
- */
-
-extern time_t ks_tregen(keyset */*ks*/);
-
 /* --- @ks_activate@ --- *
  *
  * Arguments:  @keyset *ks@ = pointer to a keyset
@@ -766,6 +803,11 @@ extern void ks_activate(keyset */*ks*/);
  *             ought to be replaced' notification is only ever given once
  *             for each key.  Also note that this call forces a keyset to be
  *             used even if it's marked as not for data output.
+ *
+ *             The encryption transform is permitted to corrupt @buf_u@ for
+ *             its own purposes.  Neither the source nor destination should
+ *             be within @buf_u@; and callers mustn't expect anything stored
+ *             in @buf_u@ to still
  */
 
 extern int ks_encrypt(keyset */*ks*/, unsigned /*ty*/,
@@ -785,6 +827,11 @@ extern int ks_encrypt(keyset */*ks*/, unsigned /*ty*/,
  * Use:                Attempts to decrypt a message using a given key.  Note that
  *             requesting decryption with a key directly won't clear a
  *             marking that it's not for encryption.
+ *
+ *             The decryption transform is permitted to corrupt @buf_u@ for
+ *             its own purposes.  Neither the source nor destination should
+ *             be within @buf_u@; and callers mustn't expect anything stored
+ *             in @buf_u@ to still
  */
 
 extern int ks_decrypt(keyset */*ks*/, unsigned /*ty*/,
@@ -893,7 +940,7 @@ extern int c_check(buf */*b*/);
  *
  * Arguments:  @dstr *d@ = where to leave the formatted message
  *             @const char *fmt@ = pointer to format string
- *             @va_list ap@ = arguments in list
+ *             @va_list *ap@ = arguments in list
  *
  * Returns:    ---
  *
@@ -918,7 +965,7 @@ extern int c_check(buf */*b*/);
  *               * "[!]..." ... -- @dstr_putf@-like string as single token
  */
 
-extern void a_vformat(dstr */*d*/, const char */*fmt*/, va_list /*ap*/);
+extern void a_vformat(dstr */*d*/, const char */*fmt*/, va_list */*ap*/);
 
 /* --- @a_format@ --- *
  *
@@ -931,7 +978,7 @@ extern void a_vformat(dstr */*d*/, const char */*fmt*/, va_list /*ap*/);
  *             presentation.
  */
 
-extern void a_format(dstr */*d*/, const char */*fmt*/, ...);
+extern void EXECL_LIKE(0) a_format(dstr */*d*/, const char */*fmt*/, ...);
 
 /* --- @a_warn@ --- *
  *
@@ -943,7 +990,7 @@ extern void a_format(dstr */*d*/, const char */*fmt*/, ...);
  * Use:                Informs all admin connections of a warning.
  */
 
-extern void a_warn(const char */*fmt*/, ...);
+extern void EXECL_LIKE(0) a_warn(const char */*fmt*/, ...);
 
 /* --- @a_notify@ --- *
  *
@@ -955,7 +1002,7 @@ extern void a_warn(const char */*fmt*/, ...);
  * Use:                Sends a notification to interested admin connections.
  */
 
-extern void a_notify(const char */*fmt*/, ...);
+extern void EXECL_LIKE(0) a_notify(const char */*fmt*/, ...);
 
 /* --- @a_create@ --- *
  *
@@ -1086,7 +1133,8 @@ extern void am_remove(addrmap */*m*/, void */*i*/);
  * Use:                Writes a trace message.
  */
 
-T( extern void ps_trace(unsigned /*mask*/, const char */*fmt*/, ...); )
+T( extern void PRINTF_LIKE(2, 3)
+     ps_trace(unsigned /*mask*/, const char */*fmt*/, ...); )
 
 /* --- @ps_warn@ --- *
  *
@@ -1098,7 +1146,7 @@ T( extern void ps_trace(unsigned /*mask*/, const char */*fmt*/, ...); )
  * Use:                Writes a warning message.
  */
 
-extern void ps_warn(const char */*fmt*/, ...);
+extern void PRINTF_LIKE(1, 2) ps_warn(const char */*fmt*/, ...);
 
 /* --- @ps_tunfd@ --- *
  *