chiark / gitweb /
server/chal.c: Capture `master->algs.bulk' in a variable.
[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   if (bchal && bchal->ops == bulk->ops && oseq < 0x07ffffff) return;
51   if (bchal) bchal->ops->freechal(bchal);
52   bchal = bulk->ops->genchal(bulk);
53   bchal->ops = bulk->ops;
54   oseq = 0;
55   seq_reset(&iseq);
56 }
57
58 /* --- @c_new@ --- *
59  *
60  * Arguments:   @buf *b@ = where to put the challenge
61  *
62  * Returns:     Zero if OK, nonzero on error.
63  *
64  * Use:         Issues a new challenge.
65  */
66
67 int c_new(buf *b)
68 {
69   octet *p;
70
71   c_genkey();
72   p = BCUR(b);
73   if (buf_putu32(b, oseq++) || !buf_get(b, bchal->tagsz)) return (-1);
74   if (bchal->ops->chaltag(bchal, p, 4, p + 4)) return (-1);
75   IF_TRACING(T_CHAL, {
76     trace(T_CHAL, "chal: issuing challenge %lu", (unsigned long)(oseq - 1));
77     trace_block(T_CRYPTO, "chal: challenge block", p, BCUR(b) - p);
78   })
79   return (0);
80 }
81
82 /* --- @c_check@ --- *
83  *
84  * Arguments:   @buf *b@ = where to find the challenge
85  *
86  * Returns:     Zero if OK, nonzero if it didn't work.
87  *
88  * Use:         Checks a challenge.  On failure, the buffer is broken.
89  */
90
91 int c_check(buf *b)
92 {
93   const octet *p;
94   size_t sz;
95   uint32 seq;
96
97   if (!bchal) {
98     a_warn("CHAL", "impossible-challenge", A_END);
99     goto fail;
100   }
101   sz = 4 + bchal->tagsz;
102   if ((p = buf_get(b, sz)) == 0) {
103     a_warn("CHAL", "invalid-challenge", A_END);
104     goto fail;
105   }
106   IF_TRACING(T_CHAL, trace_block(T_CRYPTO, "chal: check challenge", p, sz); )
107   if (bchal->ops->chalvrf(bchal, p, 4, p + 4)) {
108     a_warn("CHAL", "incorrect-tag", A_END);
109     goto fail;
110   }
111   seq = LOAD32(p);
112   if (seq_check(&iseq, seq, "CHAL"))
113     goto fail;
114   T( trace(T_CHAL, "chal: checked challenge %lu", (unsigned long)seq); )
115   return (0);
116
117 fail:
118   buf_break(b);
119   return (-1);
120 }
121
122 /*----- That's all, folks -------------------------------------------------*/