chiark / gitweb /
changelog: document changes since 0.6.0
[secnet.git] / magic.h
1 /* Magic numbers used within secnet */
2 /*
3  * This file is part of secnet.
4  * See README for full list of copyright holders.
5  *
6  * secnet is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  * 
11  * secnet is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License
17  * version 3 along with secnet; if not, see
18  * https://www.gnu.org/licenses/gpl.html.
19  */
20
21 #ifndef magic_h
22 #define magic_h
23
24 /* Encode a pair of 16 bit major and minor codes as a single 32-bit label.
25  * The encoding is strange for historical reasons.  Suppose that the nibbles
26  * of the major number are (from high to low) a, b, c, d, and the minor
27  * number has nibbles w, x, y, z.  (Here, a, b, c, d are variables, not hex
28  * digits.)  We scramble them to form a message label as follows.
29  *
30  *      0 d 0 d 0 d 0 d
31  *      0 0 0 a b c 0 0
32  *      z 0 0 0 0 0 z 0
33  *      w x y 0 0 0 0 0
34  *      ---------------
35  *      f g h i j k l m
36  *
37  * and calculate the nibbles f, g, ..., m of the message label (higher
38  * significance on the left) by XORing the columns.  It can be shown that
39  * this is invertible using linear algebra in GF(16), but but it's easier to
40  * notice that d = m, z = l, c = k XOR d, b = j, a = i XOR d, y = h,
41  * x = g XOR d, and w = f XOR z.
42  *
43  * Encoding in the forward direction, from a major/minor pair to a label, is
44  * (almost?) always done on constants, so its performance is fairly
45  * unimportant.  There is a compatibility constraint on the patterns produced
46  * with a = b = c = w = x = y = 0.  Subject to that, I wanted to find an
47  * invertible GF(16)-linear transformation which would let me recover the
48  * major and minor numbers with relatively little calculation.
49  */
50
51 #define MSGCODE(major, minor)                                           \
52         ((((uint32_t)(major)&0x0000000fu) <<  0) ^                      \
53          (((uint32_t)(major)&0x0000000fu) <<  8) ^                      \
54          (((uint32_t)(major)&0x0000000fu) << 16) ^                      \
55          (((uint32_t)(major)&0x0000000fu) << 24) ^                      \
56          (((uint32_t)(major)&0x0000fff0u) <<  4) ^                      \
57          (((uint32_t)(minor)&0x0000000fu) <<  4) ^                      \
58          (((uint32_t)(minor)&0x0000000fu) << 28) ^                      \
59          (((uint32_t)(minor)&0x0000fff0u) << 16))
60
61 /* Extract major and minor codes from a 32-bit message label. */
62 #define MSGMAJOR(label)                                                 \
63         ((((uint32_t)(label)&0x0000000fu) <<  0) ^                      \
64          (((uint32_t)(label)&0x0000000fu) <<  4) ^                      \
65          (((uint32_t)(label)&0x0000000fu) << 12) ^                      \
66          (((uint32_t)(label)&0x000fff00u) >>  4))
67 #define MSGMINOR(label)                                                 \
68         ((((uint32_t)(label)&0x000000ffu) <<  8) ^                      \
69          (((uint32_t)(label)&0x000000f0u) >>  4) ^                      \
70          (((uint32_t)(label)&0xfff00000u) >> 16))
71
72 #define LABEL_NAK       MSGCODE(     0, 0)
73 #define LABEL_MSG0      MSGCODE(0x2020, 0) /* ! */
74 #define LABEL_MSG1      MSGCODE(     1, 0)
75 #define LABEL_MSG2      MSGCODE(     2, 0)
76 #define LABEL_MSG3      MSGCODE(     3, 0)
77 #define LABEL_MSG3BIS   MSGCODE(     3, 1)
78 #define LABEL_MSG4      MSGCODE(     4, 0)
79 #define LABEL_MSG5      MSGCODE(     5, 0)
80 #define LABEL_MSG6      MSGCODE(     6, 0)
81 #define LABEL_MSG7      MSGCODE(     7, 0)
82 #define LABEL_MSG8      MSGCODE(     8, 0)
83 #define LABEL_MSG9      MSGCODE(     9, 0)
84 #define LABEL_PROD      MSGCODE(    10, 0)
85
86 /*
87  * The capability mask is a set of bits, one for each optional feature
88  * supported.  The capability numbers for transforms are set in the
89  * configuration (and should correspond between the two sites), although
90  * there are sensible defaults.
91  *
92  * Advertising a nonzero capability mask promises that the receiver
93  * understands LABEL_MSG3BIS messages, which contain an additional byte
94  * specifying the transform capability number actually chosen by the MSG3
95  * sender.
96  *
97  * Aside from that, an empty bitmask is treated the same as
98  *  1u<<CAPAB_BIT_ANCIENTTRANSFORM
99  */
100
101 /* uses of the 32-bit capability bitmap */
102 #define CAPAB_TRANSFORM_MASK  0x0000ffff
103 #define CAPAB_PRIORITY_MOBILE 0x80000000 /* mobile site has MSG1 priority */
104 /* remaining bits are unused */
105
106 /* bit indices, 0 is ls bit */
107 #define CAPAB_BIT_USER_MIN              0
108 #define CAPAB_BIT_USER_MAX              7
109 #define CAPAB_BIT_SERPENT256CBC         8
110 #define CAPAB_BIT_EAXSERPENT            9
111 #define CAPAB_BIT_MAX                  15
112
113 #define CAPAB_BIT_ANCIENTTRANSFORM CAPAB_BIT_SERPENT256CBC
114
115 #endif /* magic_h */