chiark / gitweb /
server/peer.c, etc.: Introduce who-goes-there protocol.
[tripe] / server / chal.c
1 /* -*-c-*-
2  *
3  * Cryptographic challenges
4  *
5  * (c) 2005 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of Trivial IP Encryption (TrIPE).
11  *
12  * TrIPE is free software: you can redistribute it and/or modify it under
13  * the terms of the GNU General Public License as published by the Free
14  * Software Foundation; either version 3 of the License, or (at your
15  * option) any later version.
16  *
17  * TrIPE is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20  * for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with TrIPE.  If not, see <https://www.gnu.org/licenses/>.
24  */
25
26 /*----- Header files ------------------------------------------------------*/
27
28 #include "tripe.h"
29
30 /*----- Static variables --------------------------------------------------*/
31
32 static bulkchal *bchal;
33 static uint32 oseq;
34 static seqwin iseq;
35
36 /*----- Challenges --------------------------------------------------------*/
37
38 /* --- @c_genkey@ --- *
39  *
40  * Arguments:   ---
41  *
42  * Returns:     ---
43  *
44  * Use:         Generates a new challenge key.
45  */
46
47 static void c_genkey(void)
48 {
49   bulkalgs *bulk = master->algs.bulk;
50
51   if (bchal && bchal->ops == bulk->ops && oseq < 0x07ffffff) return;
52   if (bchal) bchal->ops->freechal(bchal);
53   bchal = bulk->ops->genchal(bulk);
54   bchal->ops = bulk->ops;
55   oseq = 0;
56   seq_reset(&iseq);
57 }
58
59 /* --- @c_new@ --- *
60  *
61  * Arguments:   @const void *m@ = pointer to associated message, or null
62  *              @size_t msz@ = length of associated message
63  *              @buf *b@ = where to put the challenge
64  *
65  * Returns:     Zero if OK, nonzero on error.
66  *
67  * Use:         Issues a new challenge.
68  */
69
70 int c_new(const void *m, size_t msz, buf *b)
71 {
72   const octet *p;
73   octet *t;
74   int rc;
75
76   c_genkey();
77   p = BCUR(b);
78   if (buf_putu32(b, oseq) || (t = buf_get(b, bchal->tagsz)) == 0)
79     { rc = -1; goto done; }
80   if (bchal->ops->chaltag(bchal, m, msz, oseq, t)) { rc = -1; goto done; }
81   IF_TRACING(T_CHAL, {
82     trace(T_CHAL, "chal: issuing challenge %lu", (unsigned long)oseq);
83     if (msz) trace_block(T_CRYPTO, "chal: message block", m, msz);
84     trace_block(T_CRYPTO, "chal: challenge block", p, BCUR(b) - p);
85   })
86   rc = 0;
87 done:
88   oseq++;
89   return (rc);
90 }
91
92 /* --- @c_check@ --- *
93  *
94  * Arguments:   @const void *m@ = pointer to associated message, or null
95  *              @size_t msz@ = length of associated message
96  *              @buf *b@ = where to find the challenge
97  *
98  * Returns:     Zero if OK, nonzero if it didn't work.
99  *
100  * Use:         Checks a challenge.  On failure, the buffer is broken.
101  */
102
103 int c_check(const void *m, size_t msz, buf *b)
104 {
105   const octet *p, *t;
106   uint32 seq;
107
108   if (!bchal) {
109     a_warn("CHAL", "impossible-challenge", A_END);
110     goto fail;
111   }
112   p = BCUR(b);
113   if (buf_getu32(b, &seq) || (t = buf_get(b, bchal->tagsz)) == 0) {
114     a_warn("CHAL", "invalid-challenge", A_END);
115     goto fail;
116   }
117   IF_TRACING(T_CHAL, {
118     trace(T_CHAL, "chal: checking challenge, seq = %lu", (unsigned long)seq);
119     if (msz) trace_block(T_CRYPTO, "chal: message block", m, msz);
120     trace_block(T_CRYPTO, "chal: check challenge", p, BCUR(b) - p);
121   })
122   if (bchal->ops->chalvrf(bchal, m, msz, seq, t)) {
123     a_warn("CHAL", "incorrect-tag", A_END);
124     goto fail;
125   }
126   if (seq_check(&iseq, seq, "CHAL")) goto fail;
127   T( trace(T_CHAL, "chal: challenge ok"); )
128   return (0);
129
130 fail:
131   buf_break(b);
132   return (-1);
133 }
134
135 /*----- That's all, folks -------------------------------------------------*/